From 0b39b2926709b0609df93803b6503ea10052c03e Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Thu, 29 Jun 2006 11:53:31 -0700 Subject: [PATCH] --- yaml --- r: 31222 b: refs/heads/master c: 0950c358ee8e969fce45ba363ca1deaf211e57b0 h: refs/heads/master v: v3 --- [refs] | 2 +- trunk/CREDITS | 4 +- trunk/Documentation/DocBook/Makefile | 3 +- trunk/Documentation/DocBook/genericirq.tmpl | 474 +++++ trunk/Documentation/IRQ.txt | 22 + .../feature-removal-schedule.txt | 10 + trunk/Documentation/kernel-parameters.txt | 9 +- trunk/Documentation/keys-request-key.txt | 54 +- trunk/Documentation/keys.txt | 29 + .../Documentation/watchdog/pcwd-watchdog.txt | 75 +- .../watchdog/src/watchdog-simple.c | 15 + .../watchdog/src/watchdog-test.c | 68 + trunk/Documentation/watchdog/watchdog-api.txt | 56 +- trunk/Documentation/watchdog/watchdog.txt | 23 +- trunk/arch/alpha/kernel/irq.c | 8 +- trunk/arch/alpha/kernel/irq_alpha.c | 2 +- trunk/arch/alpha/kernel/irq_i8259.c | 2 +- trunk/arch/alpha/kernel/irq_pyxis.c | 2 +- trunk/arch/alpha/kernel/irq_srm.c | 2 +- trunk/arch/alpha/kernel/pci.c | 4 +- trunk/arch/alpha/kernel/sys_alcor.c | 2 +- trunk/arch/alpha/kernel/sys_cabriolet.c | 2 +- trunk/arch/alpha/kernel/sys_dp264.c | 2 +- trunk/arch/alpha/kernel/sys_eb64p.c | 2 +- trunk/arch/alpha/kernel/sys_eiger.c | 2 +- trunk/arch/alpha/kernel/sys_jensen.c | 10 +- trunk/arch/alpha/kernel/sys_marvel.c | 6 +- trunk/arch/alpha/kernel/sys_mikasa.c | 2 +- trunk/arch/alpha/kernel/sys_noritake.c | 2 +- trunk/arch/alpha/kernel/sys_rawhide.c | 2 +- trunk/arch/alpha/kernel/sys_rx164.c | 2 +- trunk/arch/alpha/kernel/sys_sable.c | 2 +- trunk/arch/alpha/kernel/sys_takara.c | 2 +- trunk/arch/alpha/kernel/sys_titan.c | 2 +- trunk/arch/alpha/kernel/sys_wildfire.c | 6 +- trunk/arch/arm/Kconfig | 9 + trunk/arch/arm/kernel/Makefile | 3 + trunk/arch/arm/kernel/armksyms.c | 13 +- trunk/arch/arm/kernel/asm-offsets.c | 3 + trunk/arch/arm/kernel/bios32.c | 6 +- trunk/arch/arm/kernel/crunch-bits.S | 305 +++ trunk/arch/arm/kernel/crunch.c | 83 + trunk/arch/arm/kernel/entry-armv.S | 6 + trunk/arch/arm/kernel/ptrace.c | 36 + trunk/arch/arm/kernel/setup.c | 42 +- trunk/arch/arm/kernel/signal.c | 39 + trunk/arch/arm/kernel/vmlinux.lds.S | 8 + trunk/arch/arm/lib/Makefile | 13 +- trunk/arch/arm/lib/backtrace.S | 5 +- trunk/arch/arm/lib/clear_user.S | 4 +- trunk/arch/arm/lib/copy_from_user.S | 4 +- trunk/arch/arm/lib/copy_to_user.S | 4 +- trunk/arch/arm/lib/strncpy_from_user.S | 2 +- trunk/arch/arm/lib/strnlen_user.S | 4 +- trunk/arch/arm/lib/uaccess.S | 8 +- trunk/arch/arm/mach-ep93xx/Kconfig | 11 + trunk/arch/arm/mach-ep93xx/Makefile | 1 + trunk/arch/arm/mach-ep93xx/edb9315.c | 62 + trunk/arch/arm/mach-ep93xx/gesbc9312.c | 2 +- trunk/arch/arm/mach-ep93xx/ts72xx.c | 2 +- trunk/arch/arm/mach-ixp23xx/espresso.c | 2 +- trunk/arch/arm/mach-ixp23xx/ixdp2351.c | 2 +- trunk/arch/arm/mach-ixp23xx/roadrunner.c | 2 +- trunk/arch/arm/mach-pxa/irq.c | 4 +- trunk/arch/arm/mach-s3c2410/s3c244x.c | 1 + trunk/arch/arm/mm/Kconfig | 67 +- trunk/arch/arm/mm/Makefile | 10 +- trunk/arch/arm/mm/init.c | 2 - trunk/arch/arm/mm/iomap.c | 55 + trunk/arch/arm/mm/ioremap.c | 47 - trunk/arch/arm/mm/nommu.c | 39 + trunk/arch/arm/mm/proc-arm1020.S | 9 + trunk/arch/arm/mm/proc-arm1020e.S | 9 + trunk/arch/arm/mm/proc-arm1022.S | 9 + trunk/arch/arm/mm/proc-arm1026.S | 9 + trunk/arch/arm/mm/proc-arm6_7.S | 15 + trunk/arch/arm/mm/proc-arm720.S | 12 + trunk/arch/arm/mm/proc-arm920.S | 9 + trunk/arch/arm/mm/proc-arm922.S | 9 + trunk/arch/arm/mm/proc-arm925.S | 10 + trunk/arch/arm/mm/proc-arm926.S | 9 + trunk/arch/arm/mm/proc-sa110.S | 11 + trunk/arch/arm/mm/proc-sa1100.S | 11 + trunk/arch/arm/mm/proc-v6.S | 7 + trunk/arch/cris/Kconfig | 4 + trunk/arch/cris/arch-v10/kernel/irq.c | 2 +- trunk/arch/cris/arch-v32/drivers/pci/bios.c | 4 +- trunk/arch/cris/arch-v32/kernel/irq.c | 2 +- trunk/arch/cris/kernel/irq.c | 2 +- trunk/arch/frv/mb93090-mb00/pci-frv.c | 4 +- trunk/arch/i386/Kconfig | 4 + trunk/arch/i386/kernel/efi.c | 6 +- trunk/arch/i386/kernel/i8259.c | 6 +- trunk/arch/i386/kernel/io_apic.c | 27 +- trunk/arch/i386/kernel/irq.c | 19 +- trunk/arch/i386/kernel/setup.c | 2 + trunk/arch/i386/kernel/sysenter.c | 10 +- trunk/arch/i386/mach-visws/setup.c | 8 +- trunk/arch/i386/mach-visws/visws_apic.c | 12 +- trunk/arch/i386/mach-voyager/voyager_smp.c | 2 +- trunk/arch/i386/pci/i386.c | 4 +- trunk/arch/ia64/Kconfig | 7 + trunk/arch/ia64/configs/tiger_defconfig | 2 +- trunk/arch/ia64/hp/sim/hpsim_irq.c | 6 +- trunk/arch/ia64/kernel/iosapic.c | 24 +- trunk/arch/ia64/kernel/irq.c | 24 +- trunk/arch/ia64/kernel/irq_ia64.c | 4 +- trunk/arch/ia64/kernel/irq_lsapic.c | 10 +- trunk/arch/ia64/kernel/mca.c | 2 +- trunk/arch/ia64/kernel/palinfo.c | 2 +- trunk/arch/ia64/kernel/perfmon.c | 4 +- trunk/arch/ia64/kernel/smpboot.c | 8 +- trunk/arch/ia64/pci/pci.c | 2 +- trunk/arch/ia64/sn/kernel/irq.c | 4 +- trunk/arch/ia64/sn/kernel/setup.c | 12 +- trunk/arch/ia64/sn/pci/tioca_provider.c | 2 +- trunk/arch/m32r/kernel/irq.c | 2 +- trunk/arch/m32r/kernel/setup_m32104ut.c | 8 +- trunk/arch/m32r/kernel/setup_m32700ut.c | 28 +- trunk/arch/m32r/kernel/setup_mappi.c | 16 +- trunk/arch/m32r/kernel/setup_mappi2.c | 20 +- trunk/arch/m32r/kernel/setup_mappi3.c | 20 +- trunk/arch/m32r/kernel/setup_oaks32r.c | 12 +- trunk/arch/m32r/kernel/setup_opsput.c | 28 +- trunk/arch/m32r/kernel/setup_usrv.c | 18 +- trunk/arch/m68knommu/Kconfig | 53 + trunk/arch/m68knommu/kernel/comempci.c | 3 +- trunk/arch/m68knommu/kernel/vmlinux.lds.S | 66 +- trunk/arch/m68knommu/platform/68328/Makefile | 1 + trunk/arch/m68knommu/platform/68328/ints.c | 20 +- trunk/arch/m68knommu/platform/68328/romvec.S | 37 + trunk/arch/m68knommu/platform/68360/config.c | 14 +- trunk/arch/m68knommu/platform/68360/ints.c | 1 + .../arch/m68knommu/platform/68EZ328/config.c | 14 +- .../arch/m68knommu/platform/68VZ328/config.c | 14 +- trunk/arch/mips/Kconfig | 5 + trunk/arch/mips/au1000/common/irq.c | 20 +- trunk/arch/mips/au1000/pb1200/irqmap.c | 2 +- trunk/arch/mips/ddb5xxx/ddb5477/irq_5477.c | 2 +- trunk/arch/mips/dec/ioasic-irq.c | 4 +- trunk/arch/mips/dec/kn02-irq.c | 2 +- trunk/arch/mips/gt64120/ev64120/irq.c | 2 +- trunk/arch/mips/ite-boards/generic/irq.c | 4 +- trunk/arch/mips/jazz/irq.c | 2 +- trunk/arch/mips/jmr3927/rbhma3100/irq.c | 2 +- trunk/arch/mips/kernel/i8259.c | 4 +- trunk/arch/mips/kernel/irq-msc01.c | 4 +- trunk/arch/mips/kernel/irq-mv6434x.c | 2 +- trunk/arch/mips/kernel/irq-rm7000.c | 2 +- trunk/arch/mips/kernel/irq-rm9000.c | 4 +- trunk/arch/mips/kernel/irq.c | 4 +- trunk/arch/mips/kernel/irq_cpu.c | 4 +- trunk/arch/mips/lasat/interrupt.c | 2 +- trunk/arch/mips/mips-boards/atlas/atlas_int.c | 2 +- trunk/arch/mips/momentum/ocelot_c/cpci-irq.c | 2 +- trunk/arch/mips/momentum/ocelot_c/uart-irq.c | 4 +- trunk/arch/mips/pci/pci.c | 4 +- trunk/arch/mips/philips/pnx8550/common/int.c | 10 +- trunk/arch/mips/pmc-sierra/yosemite/ht.c | 4 +- trunk/arch/mips/sgi-ip22/ip22-eisa.c | 4 +- trunk/arch/mips/sgi-ip22/ip22-int.c | 2 +- trunk/arch/mips/sgi-ip27/ip27-irq.c | 2 +- trunk/arch/mips/sgi-ip32/ip32-irq.c | 2 +- trunk/arch/mips/sibyte/bcm1480/irq.c | 4 +- trunk/arch/mips/sibyte/sb1250/irq.c | 4 +- trunk/arch/mips/sni/irq.c | 2 +- trunk/arch/mips/tx4927/common/tx4927_irq.c | 4 +- .../toshiba_rbtx4927/toshiba_rbtx4927_irq.c | 14 +- trunk/arch/mips/tx4938/common/irq.c | 4 +- trunk/arch/mips/tx4938/toshiba_rbtx4938/irq.c | 2 +- trunk/arch/mips/vr41xx/common/icu.c | 4 +- trunk/arch/mips/vr41xx/common/irq.c | 4 +- trunk/arch/mips/vr41xx/common/vrc4173.c | 2 +- trunk/arch/mips/vr41xx/nec-cmbvr4133/irq.c | 2 +- trunk/arch/parisc/Kconfig | 4 + trunk/arch/parisc/kernel/cache.c | 28 +- trunk/arch/parisc/kernel/entry.S | 6 +- trunk/arch/parisc/kernel/firmware.c | 46 +- trunk/arch/parisc/kernel/irq.c | 29 +- trunk/arch/parisc/kernel/module.c | 63 +- trunk/arch/parisc/kernel/pci.c | 2 +- trunk/arch/parisc/kernel/pdc_chassis.c | 109 +- trunk/arch/parisc/kernel/ptrace.c | 8 +- trunk/arch/parisc/kernel/real2.S | 9 - trunk/arch/parisc/kernel/setup.c | 5 + trunk/arch/parisc/kernel/signal.c | 20 +- trunk/arch/parisc/kernel/syscall.S | 14 +- trunk/arch/parisc/kernel/time.c | 18 +- trunk/arch/parisc/kernel/traps.c | 84 +- trunk/arch/parisc/kernel/unaligned.c | 18 +- trunk/arch/powerpc/Kconfig | 30 +- trunk/arch/powerpc/Kconfig.debug | 9 +- trunk/arch/powerpc/configs/cell_defconfig | 7 +- .../powerpc/configs/mpc7448_hpc2_defconfig | 923 +++++++++ trunk/arch/powerpc/kernel/Makefile | 3 +- trunk/arch/powerpc/kernel/cpu_setup_power4.S | 14 +- trunk/arch/powerpc/kernel/cputable.c | 12 - trunk/arch/powerpc/kernel/crash.c | 153 +- trunk/arch/powerpc/kernel/head_64.S | 62 +- trunk/arch/powerpc/kernel/iommu.c | 30 + trunk/arch/powerpc/kernel/irq.c | 10 +- trunk/arch/powerpc/kernel/legacy_serial.c | 11 + trunk/arch/powerpc/kernel/lparcfg.c | 147 +- trunk/arch/powerpc/kernel/machine_kexec_64.c | 4 +- trunk/arch/powerpc/kernel/misc.S | 203 ++ trunk/arch/powerpc/kernel/misc_32.S | 156 -- trunk/arch/powerpc/kernel/misc_64.S | 223 +- trunk/arch/powerpc/kernel/paca.c | 1 - trunk/arch/powerpc/kernel/pci_32.c | 47 +- trunk/arch/powerpc/kernel/pci_64.c | 4 +- trunk/arch/powerpc/kernel/prom.c | 49 +- trunk/arch/powerpc/kernel/rtas.c | 119 +- trunk/arch/powerpc/kernel/setup_64.c | 22 +- trunk/arch/powerpc/kernel/traps.c | 27 +- trunk/arch/powerpc/kernel/udbg.c | 7 +- trunk/arch/powerpc/mm/hash_native_64.c | 3 +- trunk/arch/powerpc/mm/hash_utils_64.c | 106 +- trunk/arch/powerpc/mm/mmu_context_64.c | 2 + trunk/arch/powerpc/platforms/83xx/pci.c | 5 +- trunk/arch/powerpc/platforms/85xx/pci.c | 5 +- trunk/arch/powerpc/platforms/86xx/Kconfig | 6 +- trunk/arch/powerpc/platforms/86xx/Makefile | 3 - .../powerpc/platforms/86xx/mpc8641_hpcn.h | 1 - trunk/arch/powerpc/platforms/86xx/mpc86xx.h | 8 +- .../powerpc/platforms/86xx/mpc86xx_hpcn.c | 129 +- .../arch/powerpc/platforms/86xx/mpc86xx_smp.c | 10 +- trunk/arch/powerpc/platforms/86xx/pci.c | 137 +- trunk/arch/powerpc/platforms/Makefile | 1 + trunk/arch/powerpc/platforms/cell/Kconfig | 2 +- trunk/arch/powerpc/platforms/cell/interrupt.c | 4 +- trunk/arch/powerpc/platforms/cell/setup.c | 16 +- .../arch/powerpc/platforms/cell/spider-pic.c | 4 +- trunk/arch/powerpc/platforms/cell/spu_base.c | 8 +- .../arch/powerpc/platforms/cell/spufs/file.c | 10 +- .../powerpc/platforms/cell/spufs/switch.c | 6 +- trunk/arch/powerpc/platforms/chrp/pci.c | 4 +- .../powerpc/platforms/embedded6xx/Kconfig | 15 + .../powerpc/platforms/embedded6xx/Makefile | 4 + .../platforms/embedded6xx/mpc7448_hpc2.c | 335 +++ .../platforms/embedded6xx/mpc7448_hpc2.h | 26 + trunk/arch/powerpc/platforms/iseries/dt.c | 2 + trunk/arch/powerpc/platforms/iseries/htab.c | 4 +- trunk/arch/powerpc/platforms/iseries/irq.c | 6 +- .../arch/powerpc/platforms/iseries/lpevents.c | 55 +- trunk/arch/powerpc/platforms/iseries/proc.c | 1 - trunk/arch/powerpc/platforms/iseries/setup.c | 19 +- trunk/arch/powerpc/platforms/maple/pci.c | 5 +- trunk/arch/powerpc/platforms/maple/setup.c | 7 +- .../powerpc/platforms/powermac/backlight.c | 14 +- trunk/arch/powerpc/platforms/powermac/pci.c | 5 +- trunk/arch/powerpc/platforms/powermac/pic.c | 4 +- trunk/arch/powerpc/platforms/powermac/setup.c | 9 +- trunk/arch/powerpc/platforms/pseries/iommu.c | 33 + trunk/arch/powerpc/platforms/pseries/lpar.c | 4 +- trunk/arch/powerpc/platforms/pseries/setup.c | 10 +- trunk/arch/powerpc/platforms/pseries/xics.c | 12 +- trunk/arch/powerpc/sysdev/Makefile | 2 + trunk/arch/powerpc/sysdev/dart.h | 6 +- trunk/arch/powerpc/sysdev/dart_iommu.c | 49 +- trunk/arch/powerpc/sysdev/i8259.c | 2 +- trunk/arch/powerpc/sysdev/ipic.c | 2 +- trunk/arch/powerpc/sysdev/mpic.c | 10 +- trunk/arch/powerpc/sysdev/todc.c | 392 ++++ trunk/arch/powerpc/sysdev/tsi108_dev.c | 145 ++ trunk/arch/powerpc/sysdev/tsi108_pci.c | 412 ++++ trunk/arch/ppc/8xx_io/commproc.c | 2 +- trunk/arch/ppc/kernel/pci.c | 52 +- trunk/arch/ppc/platforms/apus_setup.c | 4 +- trunk/arch/ppc/platforms/sbc82xx.c | 2 +- trunk/arch/ppc/syslib/cpc700_pic.c | 4 +- trunk/arch/ppc/syslib/cpm2_pic.c | 2 +- trunk/arch/ppc/syslib/gt64260_pic.c | 2 +- trunk/arch/ppc/syslib/m82xx_pci.c | 2 +- trunk/arch/ppc/syslib/m8xx_setup.c | 4 +- trunk/arch/ppc/syslib/mpc52xx_pic.c | 4 +- trunk/arch/ppc/syslib/mv64360_pic.c | 2 +- trunk/arch/ppc/syslib/open_pic.c | 8 +- trunk/arch/ppc/syslib/open_pic2.c | 2 +- trunk/arch/ppc/syslib/ppc403_pic.c | 2 +- trunk/arch/ppc/syslib/ppc4xx_pic.c | 2 +- trunk/arch/ppc/syslib/xilinx_pic.c | 2 +- trunk/arch/s390/appldata/appldata.h | 24 +- trunk/arch/s390/appldata/appldata_base.c | 42 +- trunk/arch/s390/appldata/appldata_mem.c | 5 +- trunk/arch/s390/appldata/appldata_net_sum.c | 5 +- trunk/arch/s390/appldata/appldata_os.c | 98 +- trunk/arch/s390/kernel/binfmt_elf32.c | 5 - trunk/arch/s390/kernel/entry.S | 80 +- trunk/arch/s390/kernel/entry64.S | 80 +- trunk/arch/s390/kernel/head.S | 22 +- trunk/arch/s390/kernel/head31.S | 77 +- trunk/arch/s390/kernel/head64.S | 79 +- trunk/arch/s390/kernel/s390_ksyms.c | 2 - trunk/arch/s390/kernel/setup.c | 55 +- trunk/arch/s390/kernel/traps.c | 8 +- trunk/arch/sh/boards/adx/irq_maskreg.c | 2 +- trunk/arch/sh/boards/bigsur/irq.c | 4 +- trunk/arch/sh/boards/cqreek/irq.c | 4 +- trunk/arch/sh/boards/dreamcast/setup.c | 2 +- trunk/arch/sh/boards/ec3104/setup.c | 2 +- trunk/arch/sh/boards/harp/irq.c | 2 +- trunk/arch/sh/boards/mpc1211/pci.c | 4 +- trunk/arch/sh/boards/mpc1211/setup.c | 2 +- trunk/arch/sh/boards/overdrive/galileo.c | 2 +- trunk/arch/sh/boards/overdrive/irq.c | 2 +- .../arch/sh/boards/renesas/hs7751rvoip/irq.c | 2 +- trunk/arch/sh/boards/renesas/rts7751r2d/irq.c | 2 +- trunk/arch/sh/boards/renesas/systemh/irq.c | 2 +- trunk/arch/sh/boards/se/73180/irq.c | 2 +- trunk/arch/sh/boards/superh/microdev/irq.c | 2 +- trunk/arch/sh/cchips/hd6446x/hd64461/setup.c | 2 +- trunk/arch/sh/cchips/hd6446x/hd64465/setup.c | 2 +- trunk/arch/sh/cchips/voyagergx/irq.c | 2 +- trunk/arch/sh/drivers/pci/pci.c | 6 +- trunk/arch/sh/kernel/cpu/irq/imask.c | 2 +- trunk/arch/sh/kernel/cpu/irq/intc2.c | 2 +- trunk/arch/sh/kernel/cpu/irq/ipr.c | 2 +- trunk/arch/sh/kernel/cpu/irq/pint.c | 2 +- trunk/arch/sh/kernel/irq.c | 2 +- trunk/arch/sh64/kernel/irq.c | 2 +- trunk/arch/sh64/kernel/irq_intc.c | 4 +- trunk/arch/sh64/kernel/pcibios.c | 4 +- trunk/arch/sh64/mach-cayman/irq.c | 2 +- trunk/arch/sparc/kernel/ioport.c | 8 +- trunk/arch/sparc/kernel/pcic.c | 2 +- trunk/arch/sparc/kernel/setup.c | 2 +- trunk/arch/sparc64/kernel/irq.c | 12 +- trunk/arch/sparc64/kernel/pci.c | 2 +- trunk/arch/um/kernel/irq.c | 6 +- trunk/arch/v850/kernel/irq.c | 6 +- trunk/arch/v850/kernel/rte_mb_a_pci.c | 2 +- trunk/arch/x86_64/Kconfig | 2 + trunk/arch/x86_64/kernel/i8259.c | 6 +- trunk/arch/x86_64/kernel/io_apic.c | 25 +- trunk/arch/x86_64/kernel/irq.c | 14 +- trunk/arch/x86_64/kernel/nmi.c | 2 + trunk/arch/xtensa/kernel/irq.c | 4 +- trunk/arch/xtensa/kernel/pci.c | 6 +- trunk/drivers/amba/bus.c | 5 +- trunk/drivers/atm/ambassador.c | 3 +- trunk/drivers/atm/firestream.c | 5 +- trunk/drivers/block/loop.c | 4 +- trunk/drivers/block/paride/pf.c | 2 +- trunk/drivers/block/rd.c | 2 +- trunk/drivers/block/sx8.c | 5 +- trunk/drivers/char/Kconfig | 1 + trunk/drivers/char/applicom.c | 9 +- trunk/drivers/char/ipmi/ipmi_msghandler.c | 7 +- trunk/drivers/char/ipmi/ipmi_si_intf.c | 67 - trunk/drivers/char/ipmi/ipmi_watchdog.c | 18 +- trunk/drivers/char/istallion.c | 1819 ++++++----------- trunk/drivers/char/mxser.c | 1 - trunk/drivers/char/n_tty.c | 6 +- trunk/drivers/char/pty.c | 2 +- trunk/drivers/char/stallion.c | 3 + trunk/drivers/char/tty_io.c | 68 +- trunk/drivers/char/vr41xx_giu.c | 4 +- trunk/drivers/char/watchdog/at91_wdt.c | 82 +- trunk/drivers/char/watchdog/i8xx_tco.c | 28 +- trunk/drivers/char/watchdog/pcwd_pci.c | 30 +- trunk/drivers/char/watchdog/pcwd_usb.c | 23 + trunk/drivers/ide/Kconfig | 9 +- trunk/drivers/ide/ide-io.c | 2 +- trunk/drivers/ide/ide-iops.c | 4 + trunk/drivers/ide/pci/aec62xx.c | 19 +- trunk/drivers/ide/pci/cmd64x.c | 15 - trunk/drivers/ide/pci/hpt34x.c | 2 +- trunk/drivers/ide/pci/pdc202xx_new.c | 6 +- trunk/drivers/ide/pci/pdc202xx_old.c | 119 +- trunk/drivers/ide/pci/sc1200.c | 4 +- trunk/drivers/ide/pci/serverworks.c | 53 +- trunk/drivers/ide/pci/siimage.c | 62 +- trunk/drivers/ide/pci/sl82c105.c | 4 +- trunk/drivers/ide/pci/slc90e66.c | 11 +- trunk/drivers/ide/ppc/pmac.c | 125 -- trunk/drivers/ieee1394/ohci1394.c | 17 +- .../infiniband/hw/ipath/ipath_driver.c | 8 +- .../drivers/infiniband/hw/mthca/mthca_main.c | 5 +- trunk/drivers/input/joystick/db9.c | 2 +- trunk/drivers/input/keyboard/atkbd.c | 2 +- trunk/drivers/input/misc/wistron_btns.c | 19 + trunk/drivers/input/serio/ct82c710.c | 6 +- trunk/drivers/isdn/hisax/hfc_pci.c | 2 +- trunk/drivers/isdn/hisax/telespci.c | 5 +- trunk/drivers/isdn/i4l/isdn_x25iface.c | 4 +- trunk/drivers/macintosh/Kconfig | 12 + trunk/drivers/macintosh/Makefile | 1 + trunk/drivers/macintosh/macio_asic.c | 4 +- trunk/drivers/macintosh/via-pmu-led.c | 144 ++ trunk/drivers/md/raid5.c | 1 - trunk/drivers/media/video/bt8xx/bttv-driver.c | 10 +- trunk/drivers/media/video/cx88/cx88-alsa.c | 8 +- trunk/drivers/media/video/cx88/cx88-core.c | 4 +- trunk/drivers/media/video/cx88/cx88-mpeg.c | 4 +- trunk/drivers/media/video/cx88/cx88-video.c | 4 +- .../media/video/saa7134/saa7134-core.c | 8 +- trunk/drivers/message/i2o/iop.c | 14 +- trunk/drivers/mmc/mmci.c | 4 +- trunk/drivers/mtd/devices/pmc551.c | 8 +- trunk/drivers/mtd/maps/amd76xrom.c | 5 +- trunk/drivers/mtd/maps/ichxrom.c | 5 +- trunk/drivers/mtd/maps/scx200_docflash.c | 5 +- trunk/drivers/mtd/maps/sun_uflash.c | 5 +- trunk/drivers/net/3c59x.c | 6 +- trunk/drivers/net/8139cp.c | 11 +- trunk/drivers/net/8139too.c | 6 +- trunk/drivers/net/e100.c | 4 +- trunk/drivers/net/skge.c | 4 +- trunk/drivers/net/sky2.c | 6 +- trunk/drivers/net/tulip/de2104x.c | 9 +- trunk/drivers/net/tulip/tulip_core.c | 6 +- trunk/drivers/net/typhoon.c | 5 +- trunk/drivers/net/wan/dscc4.c | 12 +- trunk/drivers/net/wan/pc300_drv.c | 4 +- trunk/drivers/parisc/Kconfig | 33 +- trunk/drivers/parisc/dino.c | 4 +- trunk/drivers/parisc/eisa.c | 2 +- trunk/drivers/parisc/gsc.c | 8 +- trunk/drivers/parisc/iosapic.c | 2 +- trunk/drivers/parisc/pdc_stable.c | 223 +- trunk/drivers/parisc/sba_iommu.c | 17 +- trunk/drivers/parisc/superio.c | 2 +- trunk/drivers/pci/bus.c | 10 +- trunk/drivers/pci/hotplug/cpcihp_zt5550.c | 9 +- trunk/drivers/pci/hotplug/cpqphp_core.c | 10 +- trunk/drivers/pci/hotplug/pciehp_hpc.c | 5 +- trunk/drivers/pci/hotplug/shpchp_sysfs.c | 18 +- trunk/drivers/pci/msi.c | 6 +- trunk/drivers/pci/pci-sysfs.c | 4 +- trunk/drivers/pci/pci.c | 6 +- trunk/drivers/pci/pci.h | 6 +- trunk/drivers/pci/proc.c | 20 +- trunk/drivers/pci/rom.c | 10 +- trunk/drivers/pci/setup-bus.c | 6 +- trunk/drivers/pci/setup-res.c | 34 +- trunk/drivers/pcmcia/hd64465_ss.c | 6 +- trunk/drivers/pcmcia/i82365.c | 5 +- trunk/drivers/pcmcia/pd6729.c | 3 +- trunk/drivers/pcmcia/rsrc_nonstatic.c | 26 +- trunk/drivers/pcmcia/tcic.c | 5 +- trunk/drivers/pnp/interface.c | 8 +- trunk/drivers/pnp/manager.c | 15 +- trunk/drivers/pnp/resource.c | 8 +- trunk/drivers/rtc/Kconfig | 10 + trunk/drivers/rtc/Makefile | 1 + trunk/drivers/rtc/rtc-rs5c348.c | 246 +++ trunk/drivers/s390/block/dasd.c | 105 +- trunk/drivers/s390/block/dasd_3370_erp.c | 27 +- trunk/drivers/s390/block/dasd_3990_erp.c | 189 +- trunk/drivers/s390/block/dasd_9336_erp.c | 27 +- trunk/drivers/s390/block/dasd_9343_erp.c | 2 +- trunk/drivers/s390/block/dasd_devmap.c | 102 +- trunk/drivers/s390/block/dasd_diag.c | 6 +- trunk/drivers/s390/block/dasd_diag.h | 2 +- trunk/drivers/s390/block/dasd_eckd.c | 337 +-- trunk/drivers/s390/block/dasd_eckd.h | 24 +- trunk/drivers/s390/block/dasd_eer.c | 4 +- trunk/drivers/s390/block/dasd_erp.c | 8 +- trunk/drivers/s390/block/dasd_fba.c | 49 +- trunk/drivers/s390/block/dasd_fba.h | 2 +- trunk/drivers/s390/block/dasd_int.h | 39 +- trunk/drivers/s390/block/dasd_ioctl.c | 12 +- trunk/drivers/s390/char/raw3270.c | 67 +- trunk/drivers/s390/cio/blacklist.c | 35 +- trunk/drivers/s390/cio/ccwgroup.c | 17 +- trunk/drivers/s390/cio/chsc.c | 6 +- trunk/drivers/s390/cio/cmf.c | 623 ++++-- trunk/drivers/s390/cio/css.c | 63 + trunk/drivers/s390/cio/device.c | 4 +- trunk/drivers/s390/cio/device.h | 10 + trunk/drivers/s390/cio/device_fsm.c | 20 +- trunk/drivers/s390/cio/device_ops.c | 10 +- trunk/drivers/s390/s390mach.c | 5 +- trunk/drivers/scsi/sata_via.c | 8 +- trunk/drivers/serial/68328serial.c | 102 +- trunk/drivers/serial/8250_pci.c | 4 +- trunk/drivers/serial/crisv10.c | 6 - trunk/drivers/serial/jsm/jsm_tty.c | 7 - trunk/drivers/sn/ioc4.c | 2 +- trunk/drivers/spi/spi.c | 1 + trunk/drivers/usb/host/sl811-hcd.c | 10 +- trunk/drivers/usb/serial/ir-usb.c | 3 +- trunk/drivers/video/aty/radeon_backlight.c | 6 +- trunk/drivers/video/console/vgacon.c | 12 +- trunk/drivers/video/sgivwfb.c | 6 +- trunk/fs/9p/mux.c | 2 + trunk/fs/9p/v9fs_vfs.h | 2 +- trunk/fs/9p/vfs_addr.c | 2 +- trunk/fs/9p/vfs_inode.c | 2 +- trunk/fs/adfs/inode.c | 2 +- trunk/fs/affs/affs.h | 6 +- trunk/fs/affs/file.c | 4 +- trunk/fs/affs/symlink.c | 2 +- trunk/fs/afs/file.c | 2 +- trunk/fs/afs/internal.h | 2 +- trunk/fs/befs/linuxvfs.c | 2 +- trunk/fs/bfs/bfs.h | 2 +- trunk/fs/bfs/file.c | 2 +- trunk/fs/block_dev.c | 2 +- trunk/fs/buffer.c | 2 +- trunk/fs/cifs/cifsfs.h | 4 +- trunk/fs/cifs/file.c | 4 +- trunk/fs/coda/symlink.c | 2 +- trunk/fs/configfs/inode.c | 2 +- trunk/fs/cramfs/inode.c | 4 +- trunk/fs/efs/inode.c | 2 +- trunk/fs/efs/symlink.c | 2 +- trunk/fs/ext2/ext2.h | 6 +- trunk/fs/ext2/inode.c | 6 +- trunk/fs/ext3/inode.c | 6 +- trunk/fs/fat/inode.c | 2 +- trunk/fs/freevxfs/vxfs_immed.c | 2 +- trunk/fs/freevxfs/vxfs_inode.c | 6 +- trunk/fs/freevxfs/vxfs_subr.c | 2 +- trunk/fs/fuse/file.c | 2 +- trunk/fs/hfs/hfs_fs.h | 4 +- trunk/fs/hfs/inode.c | 4 +- trunk/fs/hfsplus/hfsplus_fs.h | 4 +- trunk/fs/hfsplus/inode.c | 4 +- trunk/fs/hostfs/hostfs_kern.c | 6 +- trunk/fs/hpfs/file.c | 2 +- trunk/fs/hpfs/hpfs_fn.h | 4 +- trunk/fs/hpfs/namei.c | 2 +- trunk/fs/hugetlbfs/inode.c | 4 +- trunk/fs/inode.c | 2 +- trunk/fs/isofs/compress.c | 2 +- trunk/fs/isofs/inode.c | 2 +- trunk/fs/isofs/isofs.h | 2 +- trunk/fs/isofs/rock.c | 2 +- trunk/fs/isofs/zisofs.h | 2 +- trunk/fs/jffs/inode-v23.c | 4 +- trunk/fs/jffs2/file.c | 2 +- trunk/fs/jffs2/os-linux.h | 2 +- trunk/fs/jfs/inode.c | 2 +- trunk/fs/jfs/jfs_inode.h | 2 +- trunk/fs/jfs/jfs_metapage.c | 2 +- trunk/fs/jfs/jfs_metapage.h | 2 +- trunk/fs/minix/inode.c | 2 +- trunk/fs/ncpfs/inode.c | 2 +- trunk/fs/ncpfs/symlink.c | 2 +- trunk/fs/nfs/file.c | 2 +- trunk/fs/ntfs/aops.c | 4 +- trunk/fs/ntfs/ntfs.h | 4 +- trunk/fs/ocfs2/aops.c | 2 +- trunk/fs/ocfs2/inode.h | 2 +- trunk/fs/qnx4/inode.c | 2 +- trunk/fs/ramfs/file-mmu.c | 2 +- trunk/fs/ramfs/file-nommu.c | 2 +- trunk/fs/ramfs/internal.h | 2 +- trunk/fs/reiserfs/inode.c | 2 +- trunk/fs/romfs/inode.c | 2 +- trunk/fs/smbfs/file.c | 2 +- trunk/fs/smbfs/proto.h | 2 +- trunk/fs/sysfs/inode.c | 2 +- trunk/fs/sysv/itree.c | 2 +- trunk/fs/sysv/sysv.h | 2 +- trunk/fs/udf/file.c | 2 +- trunk/fs/udf/inode.c | 2 +- trunk/fs/udf/symlink.c | 2 +- trunk/fs/udf/udfdecl.h | 6 +- trunk/fs/ufs/inode.c | 8 +- trunk/fs/xfs/linux-2.6/xfs_aops.c | 2 +- trunk/fs/xfs/linux-2.6/xfs_aops.h | 2 +- trunk/fs/xfs/linux-2.6/xfs_buf.c | 2 +- trunk/include/asm-alpha/hw_irq.h | 2 - .../include/asm-arm/arch-at91rm9200/memory.h | 2 - trunk/include/asm-arm/arch-h720x/memory.h | 2 - trunk/include/asm-arm/arch-imx/memory.h | 6 +- trunk/include/asm-arm/arch-ixp23xx/ixp23xx.h | 11 - trunk/include/asm-arm/arch-ixp23xx/platform.h | 10 + .../include/asm-arm/arch-ixp23xx/uncompress.h | 2 +- trunk/include/asm-arm/arch-s3c2410/regs-dsc.h | 16 +- trunk/include/asm-arm/bugs.h | 4 + trunk/include/asm-arm/domain.h | 7 + trunk/include/asm-arm/fpstate.h | 8 + trunk/include/asm-arm/mach/map.h | 9 +- trunk/include/asm-arm/mach/pci.h | 2 +- trunk/include/asm-arm/memory.h | 75 +- trunk/include/asm-arm/mmu.h | 16 + trunk/include/asm-arm/mmu_context.h | 2 + trunk/include/asm-arm/page-nommu.h | 51 + trunk/include/asm-arm/page.h | 8 + trunk/include/asm-arm/pgalloc.h | 8 +- trunk/include/asm-arm/pgtable-nommu.h | 123 ++ trunk/include/asm-arm/pgtable.h | 10 +- trunk/include/asm-arm/proc-fns.h | 4 + trunk/include/asm-arm/ptrace.h | 5 + trunk/include/asm-arm/thread_info.h | 6 + trunk/include/asm-arm/uaccess.h | 184 +- trunk/include/asm-arm/ucontext.h | 14 + trunk/include/asm-cris/hw_irq.h | 2 - trunk/include/asm-cris/irq.h | 5 - trunk/include/asm-generic/vmlinux.lds.h | 28 + trunk/include/asm-i386/hw_irq.h | 10 - .../include/asm-i386/mach-visws/setup_arch.h | 3 + trunk/include/asm-ia64/hw_irq.h | 3 +- trunk/include/asm-ia64/irq.h | 5 - trunk/include/asm-ia64/sn/sn_sal.h | 10 + trunk/include/asm-m32r/hw_irq.h | 5 - trunk/include/asm-m68knommu/bootstd.h | 12 +- trunk/include/asm-mips/hw_irq.h | 8 +- trunk/include/asm-mips/mach-mips/irq.h | 6 - trunk/include/asm-parisc/assembly.h | 2 + trunk/include/asm-parisc/compat.h | 11 + trunk/include/asm-parisc/hw_irq.h | 9 - trunk/include/asm-parisc/irq.h | 5 - trunk/include/asm-parisc/pdc.h | 21 +- trunk/include/asm-parisc/pgtable.h | 8 +- trunk/include/asm-parisc/processor.h | 14 +- trunk/include/asm-parisc/system.h | 26 +- trunk/include/asm-parisc/uaccess.h | 9 +- trunk/include/asm-parisc/unistd.h | 5 - trunk/include/asm-powerpc/cputable.h | 48 +- trunk/include/asm-powerpc/hw_irq.h | 18 +- trunk/include/asm-powerpc/irq.h | 5 - .../include/asm-powerpc/iseries/it_lp_queue.h | 40 +- trunk/include/asm-powerpc/kdump.h | 2 + trunk/include/asm-powerpc/kexec.h | 9 +- trunk/include/asm-powerpc/machdep.h | 2 + trunk/include/asm-powerpc/mmu.h | 1 - trunk/include/asm-powerpc/mmu_context.h | 7 +- trunk/include/asm-powerpc/mpc86xx.h | 5 - trunk/include/asm-powerpc/pci.h | 2 +- trunk/include/asm-powerpc/rtas.h | 3 + trunk/include/asm-powerpc/time.h | 6 +- trunk/include/asm-powerpc/todc.h | 487 +++++ trunk/include/asm-powerpc/tsi108.h | 109 + trunk/include/asm-powerpc/udbg.h | 3 +- trunk/include/asm-ppc/pci.h | 2 +- trunk/include/asm-s390/bitops.h | 42 +- trunk/include/asm-s390/cio.h | 2 + trunk/include/asm-s390/cmb.h | 4 - trunk/include/asm-s390/dasd.h | 8 +- trunk/include/asm-s390/thread_info.h | 1 + trunk/include/asm-s390/unistd.h | 4 +- trunk/include/asm-sh/hw_irq.h | 5 - trunk/include/asm-sh64/hw_irq.h | 1 - trunk/include/asm-um/hw_irq.h | 3 - trunk/include/asm-v850/hw_irq.h | 4 - trunk/include/asm-x86_64/hw_irq.h | 9 - trunk/include/asm-xtensa/hw_irq.h | 4 - trunk/include/linux/ac97_codec.h | 2 +- trunk/include/linux/coda_linux.h | 4 +- trunk/include/linux/efs_fs.h | 2 +- trunk/include/linux/fs.h | 4 +- trunk/include/linux/ide.h | 1 + trunk/include/linux/interrupt.h | 14 + trunk/include/linux/ioport.h | 27 +- trunk/include/linux/irq.h | 346 +++- trunk/include/linux/isdn/tpam.h | 55 - trunk/include/linux/kbd_kern.h | 4 +- trunk/include/linux/key.h | 8 +- trunk/include/linux/module.h | 20 + trunk/include/linux/nfs_fs.h | 2 +- trunk/include/linux/pci.h | 13 +- trunk/include/linux/plist.h | 1 + trunk/include/linux/pnp.h | 7 +- trunk/include/linux/reiserfs_fs.h | 2 +- trunk/include/linux/spi/spi.h | 6 +- trunk/include/linux/tty.h | 2 - trunk/include/linux/tty_flip.h | 2 +- trunk/include/linux/types.h | 7 + trunk/include/linux/ufs_fs.h | 2 +- trunk/include/linux/watchdog.h | 10 +- trunk/kernel/irq/Makefile | 2 +- trunk/kernel/irq/autoprobe.c | 56 +- trunk/kernel/irq/chip.c | 525 +++++ trunk/kernel/irq/handle.c | 118 +- trunk/kernel/irq/internals.h | 46 + trunk/kernel/irq/manage.c | 156 +- trunk/kernel/irq/migration.c | 20 +- trunk/kernel/irq/proc.c | 30 +- trunk/kernel/irq/resend.c | 78 + trunk/kernel/irq/spurious.c | 33 +- trunk/kernel/kexec.c | 6 +- trunk/kernel/module.c | 101 +- trunk/kernel/resource.c | 52 +- trunk/lib/Kconfig.debug | 16 + trunk/lib/vsprintf.c | 2 +- trunk/mm/Kconfig | 8 +- trunk/mm/filemap.c | 13 +- trunk/mm/filemap.h | 4 +- trunk/mm/filemap_xip.c | 2 +- trunk/mm/shmem.c | 4 +- trunk/mm/swap_state.c | 2 +- trunk/net/bluetooth/rfcomm/tty.c | 8 +- trunk/security/keys/internal.h | 1 + trunk/security/keys/keyctl.c | 2 +- trunk/security/keys/request_key.c | 44 +- trunk/sound/arm/aaci.c | 5 +- trunk/sound/drivers/mpu401/mpu401.c | 5 +- trunk/sound/isa/es18xx.c | 3 +- trunk/sound/isa/gus/interwave.c | 8 +- trunk/sound/isa/sb/sb16.c | 3 +- trunk/sound/oss/Kconfig | 13 + trunk/sound/oss/cs4232.c | 2 +- trunk/sound/oss/forte.c | 5 +- trunk/sound/oss/via82cxxx_audio.c | 2 +- trunk/sound/pci/bt87x.c | 5 +- trunk/sound/pci/sonicvibes.c | 4 +- trunk/sound/ppc/pmac.c | 14 +- trunk/sound/sparc/cs4231.c | 4 +- trunk/sound/sparc/dbri.c | 4 +- 703 files changed, 12130 insertions(+), 5760 deletions(-) create mode 100644 trunk/Documentation/DocBook/genericirq.tmpl create mode 100644 trunk/Documentation/IRQ.txt create mode 100644 trunk/Documentation/watchdog/src/watchdog-simple.c create mode 100644 trunk/Documentation/watchdog/src/watchdog-test.c create mode 100644 trunk/arch/arm/kernel/crunch-bits.S create mode 100644 trunk/arch/arm/kernel/crunch.c create mode 100644 trunk/arch/arm/mach-ep93xx/edb9315.c create mode 100644 trunk/arch/arm/mm/iomap.c create mode 100644 trunk/arch/arm/mm/nommu.c create mode 100644 trunk/arch/m68knommu/platform/68328/romvec.S create mode 100644 trunk/arch/powerpc/configs/mpc7448_hpc2_defconfig create mode 100644 trunk/arch/powerpc/kernel/misc.S create mode 100644 trunk/arch/powerpc/platforms/embedded6xx/Makefile create mode 100644 trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c create mode 100644 trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h create mode 100644 trunk/arch/powerpc/sysdev/todc.c create mode 100644 trunk/arch/powerpc/sysdev/tsi108_dev.c create mode 100644 trunk/arch/powerpc/sysdev/tsi108_pci.c create mode 100644 trunk/drivers/macintosh/via-pmu-led.c create mode 100644 trunk/drivers/rtc/rtc-rs5c348.c create mode 100644 trunk/include/asm-arm/page-nommu.h create mode 100644 trunk/include/asm-arm/pgtable-nommu.h create mode 100644 trunk/include/asm-powerpc/todc.h create mode 100644 trunk/include/asm-powerpc/tsi108.h delete mode 100644 trunk/include/linux/isdn/tpam.h create mode 100644 trunk/kernel/irq/chip.c create mode 100644 trunk/kernel/irq/resend.c diff --git a/[refs] b/[refs] index b4ade0bfec0d..5e148d4441ef 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 8caf7aa26e0797e5706043f94c491acd1a08636a +refs/heads/master: 0950c358ee8e969fce45ba363ca1deaf211e57b0 diff --git a/trunk/CREDITS b/trunk/CREDITS index 85c7c70b7044..66b9e7a9abff 100644 --- a/trunk/CREDITS +++ b/trunk/CREDITS @@ -3401,10 +3401,10 @@ S: Czech Republic N: Thibaut Varene E: T-Bone@parisc-linux.org -W: http://www.parisc-linux.org/ +W: http://www.parisc-linux.org/~varenet/ P: 1024D/B7D2F063 E67C 0D43 A75E 12A5 BB1C FA2F 1E32 C3DA B7D2 F063 D: PA-RISC port minion, PDC and GSCPS2 drivers, debuglocks and other bits -D: Some bits in an ARM port, S1D13XXX FB driver, random patches here and there +D: Some ARM at91rm9200 bits, S1D13XXX FB driver, random patches here and there D: AD1889 sound driver S: Paris, France diff --git a/trunk/Documentation/DocBook/Makefile b/trunk/Documentation/DocBook/Makefile index 5a2882d275ba..66e1cf733571 100644 --- a/trunk/Documentation/DocBook/Makefile +++ b/trunk/Documentation/DocBook/Makefile @@ -10,7 +10,8 @@ DOCBOOKS := wanbook.xml z8530book.xml mcabook.xml videobook.xml \ kernel-hacking.xml kernel-locking.xml deviceiobook.xml \ procfs-guide.xml writing_usb_driver.xml \ kernel-api.xml journal-api.xml lsm.xml usb.xml \ - gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml + gadget.xml libata.xml mtdnand.xml librs.xml rapidio.xml \ + genericirq.xml ### # The build process is as follows (targets): diff --git a/trunk/Documentation/DocBook/genericirq.tmpl b/trunk/Documentation/DocBook/genericirq.tmpl new file mode 100644 index 000000000000..0f4a4b6321e4 --- /dev/null +++ b/trunk/Documentation/DocBook/genericirq.tmpl @@ -0,0 +1,474 @@ + + + + + + Linux generic IRQ handling + + + + Thomas + Gleixner + +
+ tglx@linutronix.de +
+
+
+ + Ingo + Molnar + +
+ mingo@elte.hu +
+
+
+
+ + + 2005-2006 + Thomas Gleixner + + + 2005-2006 + Ingo Molnar + + + + + This documentation 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. + + + + This program is distributed in the hope that it will be + useful, but WITHOUT ANY WARRANTY; without even the implied + warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + See the GNU General Public License for more details. + + + + You should have received a copy of the GNU General Public + License along with this program; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, + MA 02111-1307 USA + + + + For more details see the file COPYING in the source + distribution of Linux. + + +
+ + + + + Introduction + + The generic interrupt handling layer is designed to provide a + complete abstraction of interrupt handling for device drivers. + It is able to handle all the different types of interrupt controller + hardware. Device drivers use generic API functions to request, enable, + disable and free interrupts. The drivers do not have to know anything + about interrupt hardware details, so they can be used on different + platforms without code changes. + + + This documentation is provided to developers who want to implement + an interrupt subsystem based for their architecture, with the help + of the generic IRQ handling layer. + + + + + Rationale + + The original implementation of interrupt handling in Linux is using + the __do_IRQ() super-handler, which is able to deal with every + type of interrupt logic. + + + Originally, Russell King identified different types of handlers to + build a quite universal set for the ARM interrupt handler + implementation in Linux 2.5/2.6. He distinguished between: + + Level type + Edge type + Simple type + + In the SMP world of the __do_IRQ() super-handler another type + was identified: + + Per CPU type + + + + This split implementation of highlevel IRQ handlers allows us to + optimize the flow of the interrupt handling for each specific + interrupt type. This reduces complexity in that particular codepath + and allows the optimized handling of a given type. + + + The original general IRQ implementation used hw_interrupt_type + structures and their ->ack(), ->end() [etc.] callbacks to + differentiate the flow control in the super-handler. This leads to + a mix of flow logic and lowlevel hardware logic, and it also leads + to unnecessary code duplication: for example in i386, there is a + ioapic_level_irq and a ioapic_edge_irq irq-type which share many + of the lowlevel details but have different flow handling. + + + A more natural abstraction is the clean separation of the + 'irq flow' and the 'chip details'. + + + Analysing a couple of architecture's IRQ subsystem implementations + reveals that most of them can use a generic set of 'irq flow' + methods and only need to add the chip level specific code. + The separation is also valuable for (sub)architectures + which need specific quirks in the irq flow itself but not in the + chip-details - and thus provides a more transparent IRQ subsystem + design. + + + Each interrupt descriptor is assigned its own highlevel flow + handler, which is normally one of the generic + implementations. (This highlevel flow handler implementation also + makes it simple to provide demultiplexing handlers which can be + found in embedded platforms on various architectures.) + + + The separation makes the generic interrupt handling layer more + flexible and extensible. For example, an (sub)architecture can + use a generic irq-flow implementation for 'level type' interrupts + and add a (sub)architecture specific 'edge type' implementation. + + + To make the transition to the new model easier and prevent the + breakage of existing implementations, the __do_IRQ() super-handler + is still available. This leads to a kind of duality for the time + being. Over time the new model should be used in more and more + architectures, as it enables smaller and cleaner IRQ subsystems. + + + + Known Bugs And Assumptions + + None (knock on wood). + + + + + Abstraction layers + + There are three main levels of abstraction in the interrupt code: + + Highlevel driver API + Highlevel IRQ flow handlers + Chiplevel hardware encapsulation + + + + Interrupt control flow + + Each interrupt is described by an interrupt descriptor structure + irq_desc. The interrupt is referenced by an 'unsigned int' numeric + value which selects the corresponding interrupt decription structure + in the descriptor structures array. + The descriptor structure contains status information and pointers + to the interrupt flow method and the interrupt chip structure + which are assigned to this interrupt. + + + Whenever an interrupt triggers, the lowlevel arch code calls into + the generic interrupt code by calling desc->handle_irq(). + This highlevel IRQ handling function only uses desc->chip primitives + referenced by the assigned chip descriptor structure. + + + + Highlevel Driver API + + The highlevel Driver API consists of following functions: + + request_irq() + free_irq() + disable_irq() + enable_irq() + disable_irq_nosync() (SMP only) + synchronize_irq() (SMP only) + set_irq_type() + set_irq_wake() + set_irq_data() + set_irq_chip() + set_irq_chip_data() + + See the autogenerated function documentation for details. + + + + Highlevel IRQ flow handlers + + The generic layer provides a set of pre-defined irq-flow methods: + + handle_level_irq + handle_edge_irq + handle_simple_irq + handle_percpu_irq + + The interrupt flow handlers (either predefined or architecture + specific) are assigned to specific interrupts by the architecture + either during bootup or during device initialization. + + + Default flow implementations + + Helper functions + + The helper functions call the chip primitives and + are used by the default flow implementations. + The following helper functions are implemented (simplified excerpt): + +default_enable(irq) +{ + desc->chip->unmask(irq); +} + +default_disable(irq) +{ + if (!delay_disable(irq)) + desc->chip->mask(irq); +} + +default_ack(irq) +{ + chip->ack(irq); +} + +default_mask_ack(irq) +{ + if (chip->mask_ack) { + chip->mask_ack(irq); + } else { + chip->mask(irq); + chip->ack(irq); + } +} + +noop(irq) +{ +} + + + + + + + Default flow handler implementations + + Default Level IRQ flow handler + + handle_level_irq provides a generic implementation + for level-triggered interrupts. + + + The following control flow is implemented (simplified excerpt): + +desc->chip->start(); +handle_IRQ_event(desc->action); +desc->chip->end(); + + + + + Default Edge IRQ flow handler + + handle_edge_irq provides a generic implementation + for edge-triggered interrupts. + + + The following control flow is implemented (simplified excerpt): + +if (desc->status & running) { + desc->chip->hold(); + desc->status |= pending | masked; + return; +} +desc->chip->start(); +desc->status |= running; +do { + if (desc->status & masked) + desc->chip->enable(); + desc-status &= ~pending; + handle_IRQ_event(desc->action); +} while (status & pending); +desc-status &= ~running; +desc->chip->end(); + + + + + Default simple IRQ flow handler + + handle_simple_irq provides a generic implementation + for simple interrupts. + + + Note: The simple flow handler does not call any + handler/chip primitives. + + + The following control flow is implemented (simplified excerpt): + +handle_IRQ_event(desc->action); + + + + + Default per CPU flow handler + + handle_percpu_irq provides a generic implementation + for per CPU interrupts. + + + Per CPU interrupts are only available on SMP and + the handler provides a simplified version without + locking. + + + The following control flow is implemented (simplified excerpt): + +desc->chip->start(); +handle_IRQ_event(desc->action); +desc->chip->end(); + + + + + + Quirks and optimizations + + The generic functions are intended for 'clean' architectures and chips, + which have no platform-specific IRQ handling quirks. If an architecture + needs to implement quirks on the 'flow' level then it can do so by + overriding the highlevel irq-flow handler. + + + + Delayed interrupt disable + + This per interrupt selectable feature, which was introduced by Russell + King in the ARM interrupt implementation, does not mask an interrupt + at the hardware level when disable_irq() is called. The interrupt is + kept enabled and is masked in the flow handler when an interrupt event + happens. This prevents losing edge interrupts on hardware which does + not store an edge interrupt event while the interrupt is disabled at + the hardware level. When an interrupt arrives while the IRQ_DISABLED + flag is set, then the interrupt is masked at the hardware level and + the IRQ_PENDING bit is set. When the interrupt is re-enabled by + enable_irq() the pending bit is checked and if it is set, the + interrupt is resent either via hardware or by a software resend + mechanism. (It's necessary to enable CONFIG_HARDIRQS_SW_RESEND when + you want to use the delayed interrupt disable feature and your + hardware is not capable of retriggering an interrupt.) + The delayed interrupt disable can be runtime enabled, per interrupt, + by setting the IRQ_DELAYED_DISABLE flag in the irq_desc status field. + + + + + Chiplevel hardware encapsulation + + The chip level hardware descriptor structure irq_chip + contains all the direct chip relevant functions, which + can be utilized by the irq flow implementations. + + ack() + mask_ack() - Optional, recommended for performance + mask() + unmask() + retrigger() - Optional + set_type() - Optional + set_wake() - Optional + + These primitives are strictly intended to mean what they say: ack means + ACK, masking means masking of an IRQ line, etc. It is up to the flow + handler(s) to use these basic units of lowlevel functionality. + + + + + + __do_IRQ entry point + + The original implementation __do_IRQ() is an alternative entry + point for all types of interrupts. + + + This handler turned out to be not suitable for all + interrupt hardware and was therefore reimplemented with split + functionality for egde/level/simple/percpu interrupts. This is not + only a functional optimization. It also shortens code paths for + interrupts. + + + To make use of the split implementation, replace the call to + __do_IRQ by a call to desc->chip->handle_irq() and associate + the appropriate handler function to desc->chip->handle_irq(). + In most cases the generic handler implementations should + be sufficient. + + + + + Locking on SMP + + The locking of chip registers is up to the architecture that + defines the chip primitives. There is a chip->lock field that can be used + for serialization, but the generic layer does not touch it. The per-irq + structure is protected via desc->lock, by the generic layer. + + + + Structures + + This chapter contains the autogenerated documentation of the structures which are + used in the generic IRQ layer. + +!Iinclude/linux/irq.h + + + + Public Functions Provided + + This chapter contains the autogenerated documentation of the kernel API functions + which are exported. + +!Ekernel/irq/manage.c +!Ekernel/irq/chip.c + + + + Internal Functions Provided + + This chapter contains the autogenerated documentation of the internal functions. + +!Ikernel/irq/handle.c +!Ikernel/irq/chip.c + + + + Credits + + The following people have contributed to this document: + + Thomas Gleixnertglx@linutronix.de + Ingo Molnarmingo@elte.hu + + + +
diff --git a/trunk/Documentation/IRQ.txt b/trunk/Documentation/IRQ.txt new file mode 100644 index 000000000000..1011e7175021 --- /dev/null +++ b/trunk/Documentation/IRQ.txt @@ -0,0 +1,22 @@ +What is an IRQ? + +An IRQ is an interrupt request from a device. +Currently they can come in over a pin, or over a packet. +Several devices may be connected to the same pin thus +sharing an IRQ. + +An IRQ number is a kernel identifier used to talk about a hardware +interrupt source. Typically this is an index into the global irq_desc +array, but except for what linux/interrupt.h implements the details +are architecture specific. + +An IRQ number is an enumeration of the possible interrupt sources on a +machine. Typically what is enumerated is the number of input pins on +all of the interrupt controller in the system. In the case of ISA +what is enumerated are the 16 input pins on the two i8259 interrupt +controllers. + +Architectures can assign additional meaning to the IRQ numbers, and +are encouraged to in the case where there is any manual configuration +of the hardware involved. The ISA IRQs are a classic example of +assigning this kind of additional meaning. diff --git a/trunk/Documentation/feature-removal-schedule.txt b/trunk/Documentation/feature-removal-schedule.txt index 027285d0c26c..033ac91da07a 100644 --- a/trunk/Documentation/feature-removal-schedule.txt +++ b/trunk/Documentation/feature-removal-schedule.txt @@ -177,6 +177,16 @@ Who: Jean Delvare --------------------------- +What: Unused EXPORT_SYMBOL/EXPORT_SYMBOL_GPL exports + (temporary transition config option provided until then) + The transition config option will also be removed at the same time. +When: before 2.6.19 +Why: Unused symbols are both increasing the size of the kernel binary + and are often a sign of "wrong API" +Who: Arjan van de Ven + +--------------------------- + What: remove EXPORT_SYMBOL(tasklist_lock) When: August 2006 Files: kernel/fork.c diff --git a/trunk/Documentation/kernel-parameters.txt b/trunk/Documentation/kernel-parameters.txt index 0d189c93eeaf..25f8d20dac53 100644 --- a/trunk/Documentation/kernel-parameters.txt +++ b/trunk/Documentation/kernel-parameters.txt @@ -1689,9 +1689,14 @@ running once the system is up. decrease the size and leave more room for directly mapped kernel RAM. - vmhalt= [KNL,S390] + vmhalt= [KNL,S390] Perform z/VM CP command after system halt. + Format: - vmpoff= [KNL,S390] + vmpanic= [KNL,S390] Perform z/VM CP command after kernel panic. + Format: + + vmpoff= [KNL,S390] Perform z/VM CP command after power off. + Format: waveartist= [HW,OSS] Format: ,,, diff --git a/trunk/Documentation/keys-request-key.txt b/trunk/Documentation/keys-request-key.txt index 22488d791168..c1f64fdf84cb 100644 --- a/trunk/Documentation/keys-request-key.txt +++ b/trunk/Documentation/keys-request-key.txt @@ -3,16 +3,23 @@ =================== The key request service is part of the key retention service (refer to -Documentation/keys.txt). This document explains more fully how that the -requesting algorithm works. +Documentation/keys.txt). This document explains more fully how the requesting +algorithm works. The process starts by either the kernel requesting a service by calling -request_key(): +request_key*(): struct key *request_key(const struct key_type *type, const char *description, const char *callout_string); +or: + + struct key *request_key_with_auxdata(const struct key_type *type, + const char *description, + const char *callout_string, + void *aux); + Or by userspace invoking the request_key system call: key_serial_t request_key(const char *type, @@ -20,16 +27,26 @@ Or by userspace invoking the request_key system call: const char *callout_info, key_serial_t dest_keyring); -The main difference between the two access points is that the in-kernel -interface does not need to link the key to a keyring to prevent it from being -immediately destroyed. The kernel interface returns a pointer directly to the -key, and it's up to the caller to destroy the key. +The main difference between the access points is that the in-kernel interface +does not need to link the key to a keyring to prevent it from being immediately +destroyed. The kernel interface returns a pointer directly to the key, and +it's up to the caller to destroy the key. + +The request_key_with_auxdata() call is like the in-kernel request_key() call, +except that it permits auxiliary data to be passed to the upcaller (the default +is NULL). This is only useful for those key types that define their own upcall +mechanism rather than using /sbin/request-key. The userspace interface links the key to a keyring associated with the process to prevent the key from going away, and returns the serial number of the key to the caller. +The following example assumes that the key types involved don't define their +own upcall mechanisms. If they do, then those should be substituted for the +forking and execution of /sbin/request-key. + + =========== THE PROCESS =========== @@ -40,8 +57,8 @@ A request proceeds in the following manner: interface]. (2) request_key() searches the process's subscribed keyrings to see if there's - a suitable key there. If there is, it returns the key. If there isn't, and - callout_info is not set, an error is returned. Otherwise the process + a suitable key there. If there is, it returns the key. If there isn't, + and callout_info is not set, an error is returned. Otherwise the process proceeds to the next step. (3) request_key() sees that A doesn't have the desired key yet, so it creates @@ -62,7 +79,7 @@ A request proceeds in the following manner: instantiation. (7) The program may want to access another key from A's context (say a - Kerberos TGT key). It just requests the appropriate key, and the keyring + Kerberos TGT key). It just requests the appropriate key, and the keyring search notes that the session keyring has auth key V in its bottom level. This will permit it to then search the keyrings of process A with the @@ -79,10 +96,11 @@ A request proceeds in the following manner: (10) The program then exits 0 and request_key() deletes key V and returns key U to the caller. -This also extends further. If key W (step 7 above) didn't exist, key W would be -created uninstantiated, another auth key (X) would be created (as per step 3) -and another copy of /sbin/request-key spawned (as per step 4); but the context -specified by auth key X will still be process A, as it was in auth key V. +This also extends further. If key W (step 7 above) didn't exist, key W would +be created uninstantiated, another auth key (X) would be created (as per step +3) and another copy of /sbin/request-key spawned (as per step 4); but the +context specified by auth key X will still be process A, as it was in auth key +V. This is because process A's keyrings can't simply be attached to /sbin/request-key at the appropriate places because (a) execve will discard two @@ -118,17 +136,17 @@ A search of any particular keyring proceeds in the following fashion: (2) It considers all the non-keyring keys within that keyring and, if any key matches the criteria specified, calls key_permission(SEARCH) on it to see - if the key is allowed to be found. If it is, that key is returned; if + if the key is allowed to be found. If it is, that key is returned; if not, the search continues, and the error code is retained if of higher priority than the one currently set. (3) It then considers all the keyring-type keys in the keyring it's currently - searching. It calls key_permission(SEARCH) on each keyring, and if this + searching. It calls key_permission(SEARCH) on each keyring, and if this grants permission, it recurses, executing steps (2) and (3) on that keyring. The process stops immediately a valid key is found with permission granted to -use it. Any error from a previous match attempt is discarded and the key is +use it. Any error from a previous match attempt is discarded and the key is returned. When search_process_keyrings() is invoked, it performs the following searches @@ -153,7 +171,7 @@ The moment one succeeds, all pending errors are discarded and the found key is returned. Only if all these fail does the whole thing fail with the highest priority -error. Note that several errors may have come from LSM. +error. Note that several errors may have come from LSM. The error priority is: diff --git a/trunk/Documentation/keys.txt b/trunk/Documentation/keys.txt index 61c0fad2fe2f..e373f0212843 100644 --- a/trunk/Documentation/keys.txt +++ b/trunk/Documentation/keys.txt @@ -780,6 +780,17 @@ payload contents" for more information. See also Documentation/keys-request-key.txt. +(*) To search for a key, passing auxiliary data to the upcaller, call: + + struct key *request_key_with_auxdata(const struct key_type *type, + const char *description, + const char *callout_string, + void *aux); + + This is identical to request_key(), except that the auxiliary data is + passed to the key_type->request_key() op if it exists. + + (*) When it is no longer required, the key should be released using: void key_put(struct key *key); @@ -1031,6 +1042,24 @@ The structure has a number of fields, some of which are mandatory: as might happen when the userspace buffer is accessed. + (*) int (*request_key)(struct key *key, struct key *authkey, const char *op, + void *aux); + + This method is optional. If provided, request_key() and + request_key_with_auxdata() will invoke this function rather than + upcalling to /sbin/request-key to operate upon a key of this type. + + The aux parameter is as passed to request_key_with_auxdata() or is NULL + otherwise. Also passed are the key to be operated upon, the + authorisation key for this operation and the operation type (currently + only "create"). + + This function should return only when the upcall is complete. Upon return + the authorisation key will be revoked, and the target key will be + negatively instantiated if it is still uninstantiated. The error will be + returned to the caller of request_key*(). + + ============================ REQUEST-KEY CALLBACK SERVICE ============================ diff --git a/trunk/Documentation/watchdog/pcwd-watchdog.txt b/trunk/Documentation/watchdog/pcwd-watchdog.txt index 12187a33e310..d9ee6336c1d4 100644 --- a/trunk/Documentation/watchdog/pcwd-watchdog.txt +++ b/trunk/Documentation/watchdog/pcwd-watchdog.txt @@ -22,78 +22,9 @@ to run the program with an "&" to run it in the background!) If you want to write a program to be compatible with the PC Watchdog - driver, simply do the following: - --- Snippet of code -- -/* - * Watchdog Driver Test Program - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -int fd; - -/* - * This function simply sends an IOCTL to the driver, which in turn ticks - * the PC Watchdog card to reset its internal timer so it doesn't trigger - * a computer reset. - */ -void keep_alive(void) -{ - int dummy; - - ioctl(fd, WDIOC_KEEPALIVE, &dummy); -} - -/* - * The main program. Run the program with "-d" to disable the card, - * or "-e" to enable the card. - */ -int main(int argc, char *argv[]) -{ - fd = open("/dev/watchdog", O_WRONLY); - - if (fd == -1) { - fprintf(stderr, "Watchdog device not enabled.\n"); - fflush(stderr); - exit(-1); - } - - if (argc > 1) { - if (!strncasecmp(argv[1], "-d", 2)) { - ioctl(fd, WDIOC_SETOPTIONS, WDIOS_DISABLECARD); - fprintf(stderr, "Watchdog card disabled.\n"); - fflush(stderr); - exit(0); - } else if (!strncasecmp(argv[1], "-e", 2)) { - ioctl(fd, WDIOC_SETOPTIONS, WDIOS_ENABLECARD); - fprintf(stderr, "Watchdog card enabled.\n"); - fflush(stderr); - exit(0); - } else { - fprintf(stderr, "-d to disable, -e to enable.\n"); - fprintf(stderr, "run by itself to tick the card.\n"); - fflush(stderr); - exit(0); - } - } else { - fprintf(stderr, "Watchdog Ticking Away!\n"); - fflush(stderr); - } - - while(1) { - keep_alive(); - sleep(1); - } -} --- End snippet -- + driver, simply use of modify the watchdog test program: + Documentation/watchdog/src/watchdog-test.c + Other IOCTL functions include: diff --git a/trunk/Documentation/watchdog/src/watchdog-simple.c b/trunk/Documentation/watchdog/src/watchdog-simple.c new file mode 100644 index 000000000000..85cf17c48669 --- /dev/null +++ b/trunk/Documentation/watchdog/src/watchdog-simple.c @@ -0,0 +1,15 @@ +#include +#include + +int main(int argc, const char *argv[]) { + int fd = open("/dev/watchdog", O_WRONLY); + if (fd == -1) { + perror("watchdog"); + exit(1); + } + while (1) { + write(fd, "\0", 1); + fsync(fd); + sleep(10); + } +} diff --git a/trunk/Documentation/watchdog/src/watchdog-test.c b/trunk/Documentation/watchdog/src/watchdog-test.c new file mode 100644 index 000000000000..65f6c19cb865 --- /dev/null +++ b/trunk/Documentation/watchdog/src/watchdog-test.c @@ -0,0 +1,68 @@ +/* + * Watchdog Driver Test Program + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +int fd; + +/* + * This function simply sends an IOCTL to the driver, which in turn ticks + * the PC Watchdog card to reset its internal timer so it doesn't trigger + * a computer reset. + */ +void keep_alive(void) +{ + int dummy; + + ioctl(fd, WDIOC_KEEPALIVE, &dummy); +} + +/* + * The main program. Run the program with "-d" to disable the card, + * or "-e" to enable the card. + */ +int main(int argc, char *argv[]) +{ + fd = open("/dev/watchdog", O_WRONLY); + + if (fd == -1) { + fprintf(stderr, "Watchdog device not enabled.\n"); + fflush(stderr); + exit(-1); + } + + if (argc > 1) { + if (!strncasecmp(argv[1], "-d", 2)) { + ioctl(fd, WDIOC_SETOPTIONS, WDIOS_DISABLECARD); + fprintf(stderr, "Watchdog card disabled.\n"); + fflush(stderr); + exit(0); + } else if (!strncasecmp(argv[1], "-e", 2)) { + ioctl(fd, WDIOC_SETOPTIONS, WDIOS_ENABLECARD); + fprintf(stderr, "Watchdog card enabled.\n"); + fflush(stderr); + exit(0); + } else { + fprintf(stderr, "-d to disable, -e to enable.\n"); + fprintf(stderr, "run by itself to tick the card.\n"); + fflush(stderr); + exit(0); + } + } else { + fprintf(stderr, "Watchdog Ticking Away!\n"); + fflush(stderr); + } + + while(1) { + keep_alive(); + sleep(1); + } +} diff --git a/trunk/Documentation/watchdog/watchdog-api.txt b/trunk/Documentation/watchdog/watchdog-api.txt index 21ed51173662..958ff3d48be3 100644 --- a/trunk/Documentation/watchdog/watchdog-api.txt +++ b/trunk/Documentation/watchdog/watchdog-api.txt @@ -34,22 +34,7 @@ activates as soon as /dev/watchdog is opened and will reboot unless the watchdog is pinged within a certain time, this time is called the timeout or margin. The simplest way to ping the watchdog is to write some data to the device. So a very simple watchdog daemon would look -like this: - -#include -#include - -int main(int argc, const char *argv[]) { - int fd=open("/dev/watchdog",O_WRONLY); - if (fd==-1) { - perror("watchdog"); - exit(1); - } - while(1) { - write(fd, "\0", 1); - sleep(10); - } -} +like this source file: see Documentation/watchdog/src/watchdog-simple.c A more advanced driver could for example check that a HTTP server is still responding before doing the write call to ping the watchdog. @@ -110,7 +95,40 @@ current timeout using the GETTIMEOUT ioctl. ioctl(fd, WDIOC_GETTIMEOUT, &timeout); printf("The timeout was is %d seconds\n", timeout); -Envinronmental monitoring: +Pretimeouts: + +Some watchdog timers can be set to have a trigger go off before the +actual time they will reset the system. This can be done with an NMI, +interrupt, or other mechanism. This allows Linux to record useful +information (like panic information and kernel coredumps) before it +resets. + + pretimeout = 10; + ioctl(fd, WDIOC_SETPRETIMEOUT, &pretimeout); + +Note that the pretimeout is the number of seconds before the time +when the timeout will go off. It is not the number of seconds until +the pretimeout. So, for instance, if you set the timeout to 60 seconds +and the pretimeout to 10 seconds, the pretimout will go of in 50 +seconds. Setting a pretimeout to zero disables it. + +There is also a get function for getting the pretimeout: + + ioctl(fd, WDIOC_GETPRETIMEOUT, &timeout); + printf("The pretimeout was is %d seconds\n", timeout); + +Not all watchdog drivers will support a pretimeout. + +Get the number of seconds before reboot: + +Some watchdog drivers have the ability to report the remaining time +before the system will reboot. The WDIOC_GETTIMELEFT is the ioctl +that returns the number of seconds before reboot. + + ioctl(fd, WDIOC_GETTIMELEFT, &timeleft); + printf("The timeout was is %d seconds\n", timeleft); + +Environmental monitoring: All watchdog drivers are required return more information about the system, some do temperature, fan and power level monitoring, some can tell you @@ -169,6 +187,10 @@ The watchdog saw a keepalive ping since it was last queried. WDIOF_SETTIMEOUT Can set/get the timeout +The watchdog can do pretimeouts. + + WDIOF_PRETIMEOUT Pretimeout (in seconds), get/set + For those drivers that return any bits set in the option field, the GETSTATUS and GETBOOTSTATUS ioctls can be used to ask for the current diff --git a/trunk/Documentation/watchdog/watchdog.txt b/trunk/Documentation/watchdog/watchdog.txt index dffda29c8799..4b1ff69cc19a 100644 --- a/trunk/Documentation/watchdog/watchdog.txt +++ b/trunk/Documentation/watchdog/watchdog.txt @@ -65,28 +65,7 @@ The external event interfaces on the WDT boards are not currently supported. Minor numbers are however allocated for it. -Example Watchdog Driver ------------------------ - -#include -#include -#include - -int main(int argc, const char *argv[]) -{ - int fd=open("/dev/watchdog",O_WRONLY); - if(fd==-1) - { - perror("watchdog"); - exit(1); - } - while(1) - { - write(fd,"\0",1); - fsync(fd); - sleep(10); - } -} +Example Watchdog Driver: see Documentation/watchdog/src/watchdog-simple.c Contact Information diff --git a/trunk/arch/alpha/kernel/irq.c b/trunk/arch/alpha/kernel/irq.c index da677f829f76..63af36cf7f6e 100644 --- a/trunk/arch/alpha/kernel/irq.c +++ b/trunk/arch/alpha/kernel/irq.c @@ -49,15 +49,15 @@ select_smp_affinity(unsigned int irq) static int last_cpu; int cpu = last_cpu + 1; - if (!irq_desc[irq].handler->set_affinity || irq_user_affinity[irq]) + if (!irq_desc[irq].chip->set_affinity || irq_user_affinity[irq]) return 1; while (!cpu_possible(cpu)) cpu = (cpu < (NR_CPUS-1) ? cpu + 1 : 0); last_cpu = cpu; - irq_affinity[irq] = cpumask_of_cpu(cpu); - irq_desc[irq].handler->set_affinity(irq, cpumask_of_cpu(cpu)); + irq_desc[irq].affinity = cpumask_of_cpu(cpu); + irq_desc[irq].chip->set_affinity(irq, cpumask_of_cpu(cpu)); return 0; } #endif /* CONFIG_SMP */ @@ -93,7 +93,7 @@ show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[irq]); #endif - seq_printf(p, " %14s", irq_desc[irq].handler->typename); + seq_printf(p, " %14s", irq_desc[irq].chip->typename); seq_printf(p, " %c%s", (action->flags & SA_INTERRUPT)?'+':' ', action->name); diff --git a/trunk/arch/alpha/kernel/irq_alpha.c b/trunk/arch/alpha/kernel/irq_alpha.c index 9d34ce26e5ef..f20f2dff9c43 100644 --- a/trunk/arch/alpha/kernel/irq_alpha.c +++ b/trunk/arch/alpha/kernel/irq_alpha.c @@ -233,7 +233,7 @@ void __init init_rtc_irq(void) { irq_desc[RTC_IRQ].status = IRQ_DISABLED; - irq_desc[RTC_IRQ].handler = &rtc_irq_type; + irq_desc[RTC_IRQ].chip = &rtc_irq_type; setup_irq(RTC_IRQ, &timer_irqaction); } diff --git a/trunk/arch/alpha/kernel/irq_i8259.c b/trunk/arch/alpha/kernel/irq_i8259.c index b188683b83fd..ac893bd48036 100644 --- a/trunk/arch/alpha/kernel/irq_i8259.c +++ b/trunk/arch/alpha/kernel/irq_i8259.c @@ -109,7 +109,7 @@ init_i8259a_irqs(void) for (i = 0; i < 16; i++) { irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].handler = &i8259a_irq_type; + irq_desc[i].chip = &i8259a_irq_type; } setup_irq(2, &cascade); diff --git a/trunk/arch/alpha/kernel/irq_pyxis.c b/trunk/arch/alpha/kernel/irq_pyxis.c index 146a20b9e3d5..3b581415bab0 100644 --- a/trunk/arch/alpha/kernel/irq_pyxis.c +++ b/trunk/arch/alpha/kernel/irq_pyxis.c @@ -120,7 +120,7 @@ init_pyxis_irqs(unsigned long ignore_mask) if ((ignore_mask >> i) & 1) continue; irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &pyxis_irq_type; + irq_desc[i].chip = &pyxis_irq_type; } setup_irq(16+7, &isa_cascade_irqaction); diff --git a/trunk/arch/alpha/kernel/irq_srm.c b/trunk/arch/alpha/kernel/irq_srm.c index 0a87e466918c..8e4d121f84cc 100644 --- a/trunk/arch/alpha/kernel/irq_srm.c +++ b/trunk/arch/alpha/kernel/irq_srm.c @@ -67,7 +67,7 @@ init_srm_irqs(long max, unsigned long ignore_mask) if (i < 64 && ((ignore_mask >> i) & 1)) continue; irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &srm_irq_type; + irq_desc[i].chip = &srm_irq_type; } } diff --git a/trunk/arch/alpha/kernel/pci.c b/trunk/arch/alpha/kernel/pci.c index 2a8b364c822e..4ea6711e55aa 100644 --- a/trunk/arch/alpha/kernel/pci.c +++ b/trunk/arch/alpha/kernel/pci.c @@ -124,12 +124,12 @@ DECLARE_PCI_FIXUP_FINAL(PCI_ANY_ID, PCI_ANY_ID, pcibios_fixup_final); void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; struct pci_controller *hose = dev->sysdata; unsigned long alignto; - unsigned long start = res->start; + resource_size_t start = res->start; if (res->flags & IORESOURCE_IO) { /* Make sure we start at our min on all hoses */ diff --git a/trunk/arch/alpha/kernel/sys_alcor.c b/trunk/arch/alpha/kernel/sys_alcor.c index d7f0e97fe56f..1a1a2c7a3d94 100644 --- a/trunk/arch/alpha/kernel/sys_alcor.c +++ b/trunk/arch/alpha/kernel/sys_alcor.c @@ -144,7 +144,7 @@ alcor_init_irq(void) if (i >= 16+20 && i <= 16+30) continue; irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &alcor_irq_type; + irq_desc[i].chip = &alcor_irq_type; } i8259a_irq_type.ack = alcor_isa_mask_and_ack_irq; diff --git a/trunk/arch/alpha/kernel/sys_cabriolet.c b/trunk/arch/alpha/kernel/sys_cabriolet.c index 8e3374d34c95..8c9e443d93ad 100644 --- a/trunk/arch/alpha/kernel/sys_cabriolet.c +++ b/trunk/arch/alpha/kernel/sys_cabriolet.c @@ -124,7 +124,7 @@ common_init_irq(void (*srm_dev_int)(unsigned long v, struct pt_regs *r)) for (i = 16; i < 35; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &cabriolet_irq_type; + irq_desc[i].chip = &cabriolet_irq_type; } } diff --git a/trunk/arch/alpha/kernel/sys_dp264.c b/trunk/arch/alpha/kernel/sys_dp264.c index d5da6b1b28ee..b28c8f1c6e10 100644 --- a/trunk/arch/alpha/kernel/sys_dp264.c +++ b/trunk/arch/alpha/kernel/sys_dp264.c @@ -300,7 +300,7 @@ init_tsunami_irqs(struct hw_interrupt_type * ops, int imin, int imax) long i; for (i = imin; i <= imax; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = ops; + irq_desc[i].chip = ops; } } diff --git a/trunk/arch/alpha/kernel/sys_eb64p.c b/trunk/arch/alpha/kernel/sys_eb64p.c index 61a79c354f0b..aeb8e0277905 100644 --- a/trunk/arch/alpha/kernel/sys_eb64p.c +++ b/trunk/arch/alpha/kernel/sys_eb64p.c @@ -137,7 +137,7 @@ eb64p_init_irq(void) for (i = 16; i < 32; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &eb64p_irq_type; + irq_desc[i].chip = &eb64p_irq_type; } common_init_isa_dma(); diff --git a/trunk/arch/alpha/kernel/sys_eiger.c b/trunk/arch/alpha/kernel/sys_eiger.c index bd6e5f0e43c7..64a785baf53a 100644 --- a/trunk/arch/alpha/kernel/sys_eiger.c +++ b/trunk/arch/alpha/kernel/sys_eiger.c @@ -154,7 +154,7 @@ eiger_init_irq(void) for (i = 16; i < 128; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &eiger_irq_type; + irq_desc[i].chip = &eiger_irq_type; } } diff --git a/trunk/arch/alpha/kernel/sys_jensen.c b/trunk/arch/alpha/kernel/sys_jensen.c index fcabb7c96a16..0148e095638f 100644 --- a/trunk/arch/alpha/kernel/sys_jensen.c +++ b/trunk/arch/alpha/kernel/sys_jensen.c @@ -206,11 +206,11 @@ jensen_init_irq(void) { init_i8259a_irqs(); - irq_desc[1].handler = &jensen_local_irq_type; - irq_desc[4].handler = &jensen_local_irq_type; - irq_desc[3].handler = &jensen_local_irq_type; - irq_desc[7].handler = &jensen_local_irq_type; - irq_desc[9].handler = &jensen_local_irq_type; + irq_desc[1].chip = &jensen_local_irq_type; + irq_desc[4].chip = &jensen_local_irq_type; + irq_desc[3].chip = &jensen_local_irq_type; + irq_desc[7].chip = &jensen_local_irq_type; + irq_desc[9].chip = &jensen_local_irq_type; common_init_isa_dma(); } diff --git a/trunk/arch/alpha/kernel/sys_marvel.c b/trunk/arch/alpha/kernel/sys_marvel.c index e32fee505220..36d215954376 100644 --- a/trunk/arch/alpha/kernel/sys_marvel.c +++ b/trunk/arch/alpha/kernel/sys_marvel.c @@ -303,7 +303,7 @@ init_io7_irqs(struct io7 *io7, /* Set up the lsi irqs. */ for (i = 0; i < 128; ++i) { irq_desc[base + i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[base + i].handler = lsi_ops; + irq_desc[base + i].chip = lsi_ops; } /* Disable the implemented irqs in hardware. */ @@ -317,7 +317,7 @@ init_io7_irqs(struct io7 *io7, /* Set up the msi irqs. */ for (i = 128; i < (128 + 512); ++i) { irq_desc[base + i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[base + i].handler = msi_ops; + irq_desc[base + i].chip = msi_ops; } for (i = 0; i < 16; ++i) @@ -335,7 +335,7 @@ marvel_init_irq(void) /* Reserve the legacy irqs. */ for (i = 0; i < 16; ++i) { irq_desc[i].status = IRQ_DISABLED; - irq_desc[i].handler = &marvel_legacy_irq_type; + irq_desc[i].chip = &marvel_legacy_irq_type; } /* Init the io7 irqs. */ diff --git a/trunk/arch/alpha/kernel/sys_mikasa.c b/trunk/arch/alpha/kernel/sys_mikasa.c index d78a0daa6168..b741600e3761 100644 --- a/trunk/arch/alpha/kernel/sys_mikasa.c +++ b/trunk/arch/alpha/kernel/sys_mikasa.c @@ -117,7 +117,7 @@ mikasa_init_irq(void) for (i = 16; i < 32; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &mikasa_irq_type; + irq_desc[i].chip = &mikasa_irq_type; } init_i8259a_irqs(); diff --git a/trunk/arch/alpha/kernel/sys_noritake.c b/trunk/arch/alpha/kernel/sys_noritake.c index 65061f5d7410..55db02d318d7 100644 --- a/trunk/arch/alpha/kernel/sys_noritake.c +++ b/trunk/arch/alpha/kernel/sys_noritake.c @@ -139,7 +139,7 @@ noritake_init_irq(void) for (i = 16; i < 48; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &noritake_irq_type; + irq_desc[i].chip = &noritake_irq_type; } init_i8259a_irqs(); diff --git a/trunk/arch/alpha/kernel/sys_rawhide.c b/trunk/arch/alpha/kernel/sys_rawhide.c index 05888a02a604..949607e3d6fb 100644 --- a/trunk/arch/alpha/kernel/sys_rawhide.c +++ b/trunk/arch/alpha/kernel/sys_rawhide.c @@ -180,7 +180,7 @@ rawhide_init_irq(void) for (i = 16; i < 128; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &rawhide_irq_type; + irq_desc[i].chip = &rawhide_irq_type; } init_i8259a_irqs(); diff --git a/trunk/arch/alpha/kernel/sys_rx164.c b/trunk/arch/alpha/kernel/sys_rx164.c index 58404243057b..6ae506052635 100644 --- a/trunk/arch/alpha/kernel/sys_rx164.c +++ b/trunk/arch/alpha/kernel/sys_rx164.c @@ -117,7 +117,7 @@ rx164_init_irq(void) rx164_update_irq_hw(0); for (i = 16; i < 40; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &rx164_irq_type; + irq_desc[i].chip = &rx164_irq_type; } init_i8259a_irqs(); diff --git a/trunk/arch/alpha/kernel/sys_sable.c b/trunk/arch/alpha/kernel/sys_sable.c index a7ff84474ace..24dea40c9bfe 100644 --- a/trunk/arch/alpha/kernel/sys_sable.c +++ b/trunk/arch/alpha/kernel/sys_sable.c @@ -537,7 +537,7 @@ sable_lynx_init_irq(int nr_irqs) for (i = 0; i < nr_irqs; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &sable_lynx_irq_type; + irq_desc[i].chip = &sable_lynx_irq_type; } common_init_isa_dma(); diff --git a/trunk/arch/alpha/kernel/sys_takara.c b/trunk/arch/alpha/kernel/sys_takara.c index 7955bdfc2db0..2c75cd1fd81a 100644 --- a/trunk/arch/alpha/kernel/sys_takara.c +++ b/trunk/arch/alpha/kernel/sys_takara.c @@ -154,7 +154,7 @@ takara_init_irq(void) for (i = 16; i < 128; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = &takara_irq_type; + irq_desc[i].chip = &takara_irq_type; } common_init_isa_dma(); diff --git a/trunk/arch/alpha/kernel/sys_titan.c b/trunk/arch/alpha/kernel/sys_titan.c index 2551fb49ae09..13f3ed8ed7ac 100644 --- a/trunk/arch/alpha/kernel/sys_titan.c +++ b/trunk/arch/alpha/kernel/sys_titan.c @@ -189,7 +189,7 @@ init_titan_irqs(struct hw_interrupt_type * ops, int imin, int imax) long i; for (i = imin; i <= imax; ++i) { irq_desc[i].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i].handler = ops; + irq_desc[i].chip = ops; } } diff --git a/trunk/arch/alpha/kernel/sys_wildfire.c b/trunk/arch/alpha/kernel/sys_wildfire.c index 1553f470246e..22c5798fe083 100644 --- a/trunk/arch/alpha/kernel/sys_wildfire.c +++ b/trunk/arch/alpha/kernel/sys_wildfire.c @@ -199,14 +199,14 @@ wildfire_init_irq_per_pca(int qbbno, int pcano) if (i == 2) continue; irq_desc[i+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i+irq_bias].handler = &wildfire_irq_type; + irq_desc[i+irq_bias].chip = &wildfire_irq_type; } irq_desc[36+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[36+irq_bias].handler = &wildfire_irq_type; + irq_desc[36+irq_bias].chip = &wildfire_irq_type; for (i = 40; i < 64; ++i) { irq_desc[i+irq_bias].status = IRQ_DISABLED | IRQ_LEVEL; - irq_desc[i+irq_bias].handler = &wildfire_irq_type; + irq_desc[i+irq_bias].chip = &wildfire_irq_type; } setup_irq(32+irq_bias, &isa_enable); diff --git a/trunk/arch/arm/Kconfig b/trunk/arch/arm/Kconfig index 3d1a3fb7d5fc..f123c7c9fc98 100644 --- a/trunk/arch/arm/Kconfig +++ b/trunk/arch/arm/Kconfig @@ -188,23 +188,27 @@ config ARCH_IMX config ARCH_IOP3XX bool "IOP3xx-based" + depends on MMU select PCI help Support for Intel's IOP3XX (XScale) family of processors. config ARCH_IXP4XX bool "IXP4xx-based" + depends on MMU help Support for Intel's IXP4XX (XScale) family of processors. config ARCH_IXP2000 bool "IXP2400/2800-based" + depends on MMU select PCI help Support for Intel's IXP2400/2800 (XScale) family of processors. config ARCH_IXP23XX bool "IXP23XX-based" + depends on MMU select PCI help Support for Intel's IXP23xx (XScale) family of processors. @@ -229,6 +233,7 @@ config ARCH_PNX4008 config ARCH_PXA bool "PXA2xx-based" + depends on MMU select ARCH_MTD_XIP help Support for Intel's PXA2XX processor line. @@ -339,6 +344,10 @@ config XSCALE_PMU depends on CPU_XSCALE && !XSCALE_PMU_TIMER default y +if !MMU +source "arch/arm/Kconfig-nommu" +endif + endmenu source "arch/arm/common/Kconfig" diff --git a/trunk/arch/arm/kernel/Makefile b/trunk/arch/arm/kernel/Makefile index a601b8b55f35..7cffbaef064b 100644 --- a/trunk/arch/arm/kernel/Makefile +++ b/trunk/arch/arm/kernel/Makefile @@ -22,6 +22,9 @@ obj-$(CONFIG_PCI) += bios32.o obj-$(CONFIG_SMP) += smp.o obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o +obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o +AFLAGS_crunch-bits.o := -Wa,-mcpu=ep9312 + obj-$(CONFIG_IWMMXT) += iwmmxt.o AFLAGS_iwmmxt.o := -Wa,-mcpu=iwmmxt diff --git a/trunk/arch/arm/kernel/armksyms.c b/trunk/arch/arm/kernel/armksyms.c index c49b5d4d7fca..da69e660574b 100644 --- a/trunk/arch/arm/kernel/armksyms.c +++ b/trunk/arch/arm/kernel/armksyms.c @@ -109,11 +109,13 @@ EXPORT_SYMBOL(memchr); EXPORT_SYMBOL(__memzero); /* user mem (segment) */ -EXPORT_SYMBOL(__arch_copy_from_user); -EXPORT_SYMBOL(__arch_copy_to_user); -EXPORT_SYMBOL(__arch_clear_user); -EXPORT_SYMBOL(__arch_strnlen_user); -EXPORT_SYMBOL(__arch_strncpy_from_user); +EXPORT_SYMBOL(__strnlen_user); +EXPORT_SYMBOL(__strncpy_from_user); + +#ifdef CONFIG_MMU +EXPORT_SYMBOL(__copy_from_user); +EXPORT_SYMBOL(__copy_to_user); +EXPORT_SYMBOL(__clear_user); EXPORT_SYMBOL(__get_user_1); EXPORT_SYMBOL(__get_user_2); @@ -123,6 +125,7 @@ EXPORT_SYMBOL(__put_user_1); EXPORT_SYMBOL(__put_user_2); EXPORT_SYMBOL(__put_user_4); EXPORT_SYMBOL(__put_user_8); +#endif /* crypto hash */ EXPORT_SYMBOL(sha_transform); diff --git a/trunk/arch/arm/kernel/asm-offsets.c b/trunk/arch/arm/kernel/asm-offsets.c index 396efba9bacd..447ede5143a8 100644 --- a/trunk/arch/arm/kernel/asm-offsets.c +++ b/trunk/arch/arm/kernel/asm-offsets.c @@ -59,6 +59,9 @@ int main(void) DEFINE(TI_VFPSTATE, offsetof(struct thread_info, vfpstate)); #ifdef CONFIG_IWMMXT DEFINE(TI_IWMMXT_STATE, offsetof(struct thread_info, fpstate.iwmmxt)); +#endif +#ifdef CONFIG_CRUNCH + DEFINE(TI_CRUNCH_STATE, offsetof(struct thread_info, crunchstate)); #endif BLANK(); DEFINE(S_R0, offsetof(struct pt_regs, ARM_r0)); diff --git a/trunk/arch/arm/kernel/bios32.c b/trunk/arch/arm/kernel/bios32.c index 302fc1401547..45da06fc1ba1 100644 --- a/trunk/arch/arm/kernel/bios32.c +++ b/trunk/arch/arm/kernel/bios32.c @@ -304,7 +304,7 @@ static inline int pdev_bad_for_parity(struct pci_dev *dev) static void __devinit pdev_fixup_device_resources(struct pci_sys_data *root, struct pci_dev *dev) { - unsigned long offset; + resource_size_t offset; int i; for (i = 0; i < PCI_NUM_RESOURCES; i++) { @@ -634,9 +634,9 @@ char * __init pcibios_setup(char *str) * which might be mirrored at 0x0100-0x03ff.. */ void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { - unsigned long start = res->start; + resource_size_t start = res->start; if (res->flags & IORESOURCE_IO && start & 0x300) start = (start + 0x3ff) & ~0x3ff; diff --git a/trunk/arch/arm/kernel/crunch-bits.S b/trunk/arch/arm/kernel/crunch-bits.S new file mode 100644 index 000000000000..a26886758c67 --- /dev/null +++ b/trunk/arch/arm/kernel/crunch-bits.S @@ -0,0 +1,305 @@ +/* + * arch/arm/kernel/crunch-bits.S + * Cirrus MaverickCrunch context switching and handling + * + * Copyright (C) 2006 Lennert Buytenhek + * + * Shamelessly stolen from the iWMMXt code by Nicolas Pitre, which is + * Copyright (c) 2003-2004, MontaVista Software, Inc. + * + * 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 +#include +#include +#include +#include + +/* + * We can't use hex constants here due to a bug in gas. + */ +#define CRUNCH_MVDX0 0 +#define CRUNCH_MVDX1 8 +#define CRUNCH_MVDX2 16 +#define CRUNCH_MVDX3 24 +#define CRUNCH_MVDX4 32 +#define CRUNCH_MVDX5 40 +#define CRUNCH_MVDX6 48 +#define CRUNCH_MVDX7 56 +#define CRUNCH_MVDX8 64 +#define CRUNCH_MVDX9 72 +#define CRUNCH_MVDX10 80 +#define CRUNCH_MVDX11 88 +#define CRUNCH_MVDX12 96 +#define CRUNCH_MVDX13 104 +#define CRUNCH_MVDX14 112 +#define CRUNCH_MVDX15 120 +#define CRUNCH_MVAX0L 128 +#define CRUNCH_MVAX0M 132 +#define CRUNCH_MVAX0H 136 +#define CRUNCH_MVAX1L 140 +#define CRUNCH_MVAX1M 144 +#define CRUNCH_MVAX1H 148 +#define CRUNCH_MVAX2L 152 +#define CRUNCH_MVAX2M 156 +#define CRUNCH_MVAX2H 160 +#define CRUNCH_MVAX3L 164 +#define CRUNCH_MVAX3M 168 +#define CRUNCH_MVAX3H 172 +#define CRUNCH_DSPSC 176 + +#define CRUNCH_SIZE 184 + + .text + +/* + * Lazy switching of crunch coprocessor context + * + * r10 = struct thread_info pointer + * r9 = ret_from_exception + * lr = undefined instr exit + * + * called from prefetch exception handler with interrupts disabled + */ +ENTRY(crunch_task_enable) + ldr r8, =(EP93XX_APB_VIRT_BASE + 0x00130000) @ syscon addr + + ldr r1, [r8, #0x80] + tst r1, #0x00800000 @ access to crunch enabled? + movne pc, lr @ if so no business here + mov r3, #0xaa @ unlock syscon swlock + str r3, [r8, #0xc0] + orr r1, r1, #0x00800000 @ enable access to crunch + str r1, [r8, #0x80] + + ldr r3, =crunch_owner + add r0, r10, #TI_CRUNCH_STATE @ get task crunch save area + ldr r2, [sp, #60] @ current task pc value + ldr r1, [r3] @ get current crunch owner + str r0, [r3] @ this task now owns crunch + sub r2, r2, #4 @ adjust pc back + str r2, [sp, #60] + + ldr r2, [r8, #0x80] + mov r2, r2 @ flush out enable (@@@) + + teq r1, #0 @ test for last ownership + mov lr, r9 @ normal exit from exception + beq crunch_load @ no owner, skip save + +crunch_save: + cfstr64 mvdx0, [r1, #CRUNCH_MVDX0] @ save 64b registers + cfstr64 mvdx1, [r1, #CRUNCH_MVDX1] + cfstr64 mvdx2, [r1, #CRUNCH_MVDX2] + cfstr64 mvdx3, [r1, #CRUNCH_MVDX3] + cfstr64 mvdx4, [r1, #CRUNCH_MVDX4] + cfstr64 mvdx5, [r1, #CRUNCH_MVDX5] + cfstr64 mvdx6, [r1, #CRUNCH_MVDX6] + cfstr64 mvdx7, [r1, #CRUNCH_MVDX7] + cfstr64 mvdx8, [r1, #CRUNCH_MVDX8] + cfstr64 mvdx9, [r1, #CRUNCH_MVDX9] + cfstr64 mvdx10, [r1, #CRUNCH_MVDX10] + cfstr64 mvdx11, [r1, #CRUNCH_MVDX11] + cfstr64 mvdx12, [r1, #CRUNCH_MVDX12] + cfstr64 mvdx13, [r1, #CRUNCH_MVDX13] + cfstr64 mvdx14, [r1, #CRUNCH_MVDX14] + cfstr64 mvdx15, [r1, #CRUNCH_MVDX15] + +#ifdef __ARMEB__ +#error fix me for ARMEB +#endif + + cfmv32al mvfx0, mvax0 @ save 72b accumulators + cfstr32 mvfx0, [r1, #CRUNCH_MVAX0L] + cfmv32am mvfx0, mvax0 + cfstr32 mvfx0, [r1, #CRUNCH_MVAX0M] + cfmv32ah mvfx0, mvax0 + cfstr32 mvfx0, [r1, #CRUNCH_MVAX0H] + cfmv32al mvfx0, mvax1 + cfstr32 mvfx0, [r1, #CRUNCH_MVAX1L] + cfmv32am mvfx0, mvax1 + cfstr32 mvfx0, [r1, #CRUNCH_MVAX1M] + cfmv32ah mvfx0, mvax1 + cfstr32 mvfx0, [r1, #CRUNCH_MVAX1H] + cfmv32al mvfx0, mvax2 + cfstr32 mvfx0, [r1, #CRUNCH_MVAX2L] + cfmv32am mvfx0, mvax2 + cfstr32 mvfx0, [r1, #CRUNCH_MVAX2M] + cfmv32ah mvfx0, mvax2 + cfstr32 mvfx0, [r1, #CRUNCH_MVAX2H] + cfmv32al mvfx0, mvax3 + cfstr32 mvfx0, [r1, #CRUNCH_MVAX3L] + cfmv32am mvfx0, mvax3 + cfstr32 mvfx0, [r1, #CRUNCH_MVAX3M] + cfmv32ah mvfx0, mvax3 + cfstr32 mvfx0, [r1, #CRUNCH_MVAX3H] + + cfmv32sc mvdx0, dspsc @ save status word + cfstr64 mvdx0, [r1, #CRUNCH_DSPSC] + + teq r0, #0 @ anything to load? + cfldr64eq mvdx0, [r1, #CRUNCH_MVDX0] @ mvdx0 was clobbered + moveq pc, lr + +crunch_load: + cfldr64 mvdx0, [r0, #CRUNCH_DSPSC] @ load status word + cfmvsc32 dspsc, mvdx0 + + cfldr32 mvfx0, [r0, #CRUNCH_MVAX0L] @ load 72b accumulators + cfmval32 mvax0, mvfx0 + cfldr32 mvfx0, [r0, #CRUNCH_MVAX0M] + cfmvam32 mvax0, mvfx0 + cfldr32 mvfx0, [r0, #CRUNCH_MVAX0H] + cfmvah32 mvax0, mvfx0 + cfldr32 mvfx0, [r0, #CRUNCH_MVAX1L] + cfmval32 mvax1, mvfx0 + cfldr32 mvfx0, [r0, #CRUNCH_MVAX1M] + cfmvam32 mvax1, mvfx0 + cfldr32 mvfx0, [r0, #CRUNCH_MVAX1H] + cfmvah32 mvax1, mvfx0 + cfldr32 mvfx0, [r0, #CRUNCH_MVAX2L] + cfmval32 mvax2, mvfx0 + cfldr32 mvfx0, [r0, #CRUNCH_MVAX2M] + cfmvam32 mvax2, mvfx0 + cfldr32 mvfx0, [r0, #CRUNCH_MVAX2H] + cfmvah32 mvax2, mvfx0 + cfldr32 mvfx0, [r0, #CRUNCH_MVAX3L] + cfmval32 mvax3, mvfx0 + cfldr32 mvfx0, [r0, #CRUNCH_MVAX3M] + cfmvam32 mvax3, mvfx0 + cfldr32 mvfx0, [r0, #CRUNCH_MVAX3H] + cfmvah32 mvax3, mvfx0 + + cfldr64 mvdx0, [r0, #CRUNCH_MVDX0] @ load 64b registers + cfldr64 mvdx1, [r0, #CRUNCH_MVDX1] + cfldr64 mvdx2, [r0, #CRUNCH_MVDX2] + cfldr64 mvdx3, [r0, #CRUNCH_MVDX3] + cfldr64 mvdx4, [r0, #CRUNCH_MVDX4] + cfldr64 mvdx5, [r0, #CRUNCH_MVDX5] + cfldr64 mvdx6, [r0, #CRUNCH_MVDX6] + cfldr64 mvdx7, [r0, #CRUNCH_MVDX7] + cfldr64 mvdx8, [r0, #CRUNCH_MVDX8] + cfldr64 mvdx9, [r0, #CRUNCH_MVDX9] + cfldr64 mvdx10, [r0, #CRUNCH_MVDX10] + cfldr64 mvdx11, [r0, #CRUNCH_MVDX11] + cfldr64 mvdx12, [r0, #CRUNCH_MVDX12] + cfldr64 mvdx13, [r0, #CRUNCH_MVDX13] + cfldr64 mvdx14, [r0, #CRUNCH_MVDX14] + cfldr64 mvdx15, [r0, #CRUNCH_MVDX15] + + mov pc, lr + +/* + * Back up crunch regs to save area and disable access to them + * (mainly for gdb or sleep mode usage) + * + * r0 = struct thread_info pointer of target task or NULL for any + */ +ENTRY(crunch_task_disable) + stmfd sp!, {r4, r5, lr} + + mrs ip, cpsr + orr r2, ip, #PSR_I_BIT @ disable interrupts + msr cpsr_c, r2 + + ldr r4, =(EP93XX_APB_VIRT_BASE + 0x00130000) @ syscon addr + + ldr r3, =crunch_owner + add r2, r0, #TI_CRUNCH_STATE @ get task crunch save area + ldr r1, [r3] @ get current crunch owner + teq r1, #0 @ any current owner? + beq 1f @ no: quit + teq r0, #0 @ any owner? + teqne r1, r2 @ or specified one? + bne 1f @ no: quit + + ldr r5, [r4, #0x80] @ enable access to crunch + mov r2, #0xaa + str r2, [r4, #0xc0] + orr r5, r5, #0x00800000 + str r5, [r4, #0x80] + + mov r0, #0 @ nothing to load + str r0, [r3] @ no more current owner + ldr r2, [r4, #0x80] @ flush out enable (@@@) + mov r2, r2 + bl crunch_save + + mov r2, #0xaa @ disable access to crunch + str r2, [r4, #0xc0] + bic r5, r5, #0x00800000 + str r5, [r4, #0x80] + ldr r5, [r4, #0x80] @ flush out enable (@@@) + mov r5, r5 + +1: msr cpsr_c, ip @ restore interrupt mode + ldmfd sp!, {r4, r5, pc} + +/* + * Copy crunch state to given memory address + * + * r0 = struct thread_info pointer of target task + * r1 = memory address where to store crunch state + * + * this is called mainly in the creation of signal stack frames + */ +ENTRY(crunch_task_copy) + mrs ip, cpsr + orr r2, ip, #PSR_I_BIT @ disable interrupts + msr cpsr_c, r2 + + ldr r3, =crunch_owner + add r2, r0, #TI_CRUNCH_STATE @ get task crunch save area + ldr r3, [r3] @ get current crunch owner + teq r2, r3 @ does this task own it... + beq 1f + + @ current crunch values are in the task save area + msr cpsr_c, ip @ restore interrupt mode + mov r0, r1 + mov r1, r2 + mov r2, #CRUNCH_SIZE + b memcpy + +1: @ this task owns crunch regs -- grab a copy from there + mov r0, #0 @ nothing to load + mov r3, lr @ preserve return address + bl crunch_save + msr cpsr_c, ip @ restore interrupt mode + mov pc, r3 + +/* + * Restore crunch state from given memory address + * + * r0 = struct thread_info pointer of target task + * r1 = memory address where to get crunch state from + * + * this is used to restore crunch state when unwinding a signal stack frame + */ +ENTRY(crunch_task_restore) + mrs ip, cpsr + orr r2, ip, #PSR_I_BIT @ disable interrupts + msr cpsr_c, r2 + + ldr r3, =crunch_owner + add r2, r0, #TI_CRUNCH_STATE @ get task crunch save area + ldr r3, [r3] @ get current crunch owner + teq r2, r3 @ does this task own it... + beq 1f + + @ this task doesn't own crunch regs -- use its save area + msr cpsr_c, ip @ restore interrupt mode + mov r0, r2 + mov r2, #CRUNCH_SIZE + b memcpy + +1: @ this task owns crunch regs -- load them directly + mov r0, r1 + mov r1, #0 @ nothing to save + mov r3, lr @ preserve return address + bl crunch_load + msr cpsr_c, ip @ restore interrupt mode + mov pc, r3 diff --git a/trunk/arch/arm/kernel/crunch.c b/trunk/arch/arm/kernel/crunch.c new file mode 100644 index 000000000000..748175921f9b --- /dev/null +++ b/trunk/arch/arm/kernel/crunch.c @@ -0,0 +1,83 @@ +/* + * arch/arm/kernel/crunch.c + * Cirrus MaverickCrunch context switching and handling + * + * Copyright (C) 2006 Lennert Buytenhek + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct crunch_state *crunch_owner; + +void crunch_task_release(struct thread_info *thread) +{ + local_irq_disable(); + if (crunch_owner == &thread->crunchstate) + crunch_owner = NULL; + local_irq_enable(); +} + +static int crunch_enabled(u32 devcfg) +{ + return !!(devcfg & EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE); +} + +static int crunch_do(struct notifier_block *self, unsigned long cmd, void *t) +{ + struct thread_info *thread = (struct thread_info *)t; + struct crunch_state *crunch_state; + u32 devcfg; + + crunch_state = &thread->crunchstate; + + switch (cmd) { + case THREAD_NOTIFY_FLUSH: + memset(crunch_state, 0, sizeof(*crunch_state)); + + /* + * FALLTHROUGH: Ensure we don't try to overwrite our newly + * initialised state information on the first fault. + */ + + case THREAD_NOTIFY_RELEASE: + crunch_task_release(thread); + break; + + case THREAD_NOTIFY_SWITCH: + devcfg = __raw_readl(EP93XX_SYSCON_DEVICE_CONFIG); + if (crunch_enabled(devcfg) || crunch_owner == crunch_state) { + devcfg ^= EP93XX_SYSCON_DEVICE_CONFIG_CRUNCH_ENABLE; + __raw_writel(0xaa, EP93XX_SYSCON_SWLOCK); + __raw_writel(devcfg, EP93XX_SYSCON_DEVICE_CONFIG); + } + break; + } + + return NOTIFY_DONE; +} + +static struct notifier_block crunch_notifier_block = { + .notifier_call = crunch_do, +}; + +static int __init crunch_init(void) +{ + thread_register_notifier(&crunch_notifier_block); + + return 0; +} + +late_initcall(crunch_init); diff --git a/trunk/arch/arm/kernel/entry-armv.S b/trunk/arch/arm/kernel/entry-armv.S index 86c92523a346..6423a38839b8 100644 --- a/trunk/arch/arm/kernel/entry-armv.S +++ b/trunk/arch/arm/kernel/entry-armv.S @@ -492,9 +492,15 @@ call_fpe: b do_fpe @ CP#1 (FPE) b do_fpe @ CP#2 (FPE) mov pc, lr @ CP#3 +#ifdef CONFIG_CRUNCH + b crunch_task_enable @ CP#4 (MaverickCrunch) + b crunch_task_enable @ CP#5 (MaverickCrunch) + b crunch_task_enable @ CP#6 (MaverickCrunch) +#else mov pc, lr @ CP#4 mov pc, lr @ CP#5 mov pc, lr @ CP#6 +#endif mov pc, lr @ CP#7 mov pc, lr @ CP#8 mov pc, lr @ CP#9 diff --git a/trunk/arch/arm/kernel/ptrace.c b/trunk/arch/arm/kernel/ptrace.c index a1d1b2906e8d..c40bdc770054 100644 --- a/trunk/arch/arm/kernel/ptrace.c +++ b/trunk/arch/arm/kernel/ptrace.c @@ -634,6 +634,32 @@ static int ptrace_setwmmxregs(struct task_struct *tsk, void __user *ufp) #endif +#ifdef CONFIG_CRUNCH +/* + * Get the child Crunch state. + */ +static int ptrace_getcrunchregs(struct task_struct *tsk, void __user *ufp) +{ + struct thread_info *thread = task_thread_info(tsk); + + crunch_task_disable(thread); /* force it to ram */ + return copy_to_user(ufp, &thread->crunchstate, CRUNCH_SIZE) + ? -EFAULT : 0; +} + +/* + * Set the child Crunch state. + */ +static int ptrace_setcrunchregs(struct task_struct *tsk, void __user *ufp) +{ + struct thread_info *thread = task_thread_info(tsk); + + crunch_task_release(thread); /* force a reload */ + return copy_from_user(&thread->crunchstate, ufp, CRUNCH_SIZE) + ? -EFAULT : 0; +} +#endif + long arch_ptrace(struct task_struct *child, long request, long addr, long data) { unsigned long tmp; @@ -765,6 +791,16 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) child->ptrace_message = data; break; +#ifdef CONFIG_CRUNCH + case PTRACE_GETCRUNCHREGS: + ret = ptrace_getcrunchregs(child, (void __user *)data); + break; + + case PTRACE_SETCRUNCHREGS: + ret = ptrace_setcrunchregs(child, (void __user *)data); + break; +#endif + default: ret = ptrace_request(child, request, addr, data); break; diff --git a/trunk/arch/arm/kernel/setup.c b/trunk/arch/arm/kernel/setup.c index 093ccba0503c..6bdf70def01f 100644 --- a/trunk/arch/arm/kernel/setup.c +++ b/trunk/arch/arm/kernel/setup.c @@ -119,9 +119,24 @@ DEFINE_PER_CPU(struct cpuinfo_arm, cpu_data); * Standard memory resources */ static struct resource mem_res[] = { - { "Video RAM", 0, 0, IORESOURCE_MEM }, - { "Kernel text", 0, 0, IORESOURCE_MEM }, - { "Kernel data", 0, 0, IORESOURCE_MEM } + { + .name = "Video RAM", + .start = 0, + .end = 0, + .flags = IORESOURCE_MEM + }, + { + .name = "Kernel text", + .start = 0, + .end = 0, + .flags = IORESOURCE_MEM + }, + { + .name = "Kernel data", + .start = 0, + .end = 0, + .flags = IORESOURCE_MEM + } }; #define video_ram mem_res[0] @@ -129,9 +144,24 @@ static struct resource mem_res[] = { #define kernel_data mem_res[2] static struct resource io_res[] = { - { "reserved", 0x3bc, 0x3be, IORESOURCE_IO | IORESOURCE_BUSY }, - { "reserved", 0x378, 0x37f, IORESOURCE_IO | IORESOURCE_BUSY }, - { "reserved", 0x278, 0x27f, IORESOURCE_IO | IORESOURCE_BUSY } + { + .name = "reserved", + .start = 0x3bc, + .end = 0x3be, + .flags = IORESOURCE_IO | IORESOURCE_BUSY + }, + { + .name = "reserved", + .start = 0x378, + .end = 0x37f, + .flags = IORESOURCE_IO | IORESOURCE_BUSY + }, + { + .name = "reserved", + .start = 0x278, + .end = 0x27f, + .flags = IORESOURCE_IO | IORESOURCE_BUSY + } }; #define lp0 io_res[0] diff --git a/trunk/arch/arm/kernel/signal.c b/trunk/arch/arm/kernel/signal.c index 1ce05ec086c6..83a8d3c95eb3 100644 --- a/trunk/arch/arm/kernel/signal.c +++ b/trunk/arch/arm/kernel/signal.c @@ -132,6 +132,37 @@ sys_sigaction(int sig, const struct old_sigaction __user *act, return ret; } +#ifdef CONFIG_CRUNCH +static int preserve_crunch_context(struct crunch_sigframe *frame) +{ + char kbuf[sizeof(*frame) + 8]; + struct crunch_sigframe *kframe; + + /* the crunch context must be 64 bit aligned */ + kframe = (struct crunch_sigframe *)((unsigned long)(kbuf + 8) & ~7); + kframe->magic = CRUNCH_MAGIC; + kframe->size = CRUNCH_STORAGE_SIZE; + crunch_task_copy(current_thread_info(), &kframe->storage); + return __copy_to_user(frame, kframe, sizeof(*frame)); +} + +static int restore_crunch_context(struct crunch_sigframe *frame) +{ + char kbuf[sizeof(*frame) + 8]; + struct crunch_sigframe *kframe; + + /* the crunch context must be 64 bit aligned */ + kframe = (struct crunch_sigframe *)((unsigned long)(kbuf + 8) & ~7); + if (__copy_from_user(kframe, frame, sizeof(*frame))) + return -1; + if (kframe->magic != CRUNCH_MAGIC || + kframe->size != CRUNCH_STORAGE_SIZE) + return -1; + crunch_task_restore(current_thread_info(), &kframe->storage); + return 0; +} +#endif + #ifdef CONFIG_IWMMXT static int preserve_iwmmxt_context(struct iwmmxt_sigframe *frame) @@ -214,6 +245,10 @@ static int restore_sigframe(struct pt_regs *regs, struct sigframe __user *sf) err |= !valid_user_regs(regs); aux = (struct aux_sigframe __user *) sf->uc.uc_regspace; +#ifdef CONFIG_CRUNCH + if (err == 0) + err |= restore_crunch_context(&aux->crunch); +#endif #ifdef CONFIG_IWMMXT if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) err |= restore_iwmmxt_context(&aux->iwmmxt); @@ -333,6 +368,10 @@ setup_sigframe(struct sigframe __user *sf, struct pt_regs *regs, sigset_t *set) err |= __copy_to_user(&sf->uc.uc_sigmask, set, sizeof(*set)); aux = (struct aux_sigframe __user *) sf->uc.uc_regspace; +#ifdef CONFIG_CRUNCH + if (err == 0) + err |= preserve_crunch_context(&aux->crunch); +#endif #ifdef CONFIG_IWMMXT if (err == 0 && test_thread_flag(TIF_USING_IWMMXT)) err |= preserve_iwmmxt_context(&aux->iwmmxt); diff --git a/trunk/arch/arm/kernel/vmlinux.lds.S b/trunk/arch/arm/kernel/vmlinux.lds.S index 2b254e88595c..2df9688a7028 100644 --- a/trunk/arch/arm/kernel/vmlinux.lds.S +++ b/trunk/arch/arm/kernel/vmlinux.lds.S @@ -80,6 +80,10 @@ SECTIONS *(.exit.text) *(.exit.data) *(.exitcall.exit) +#ifndef CONFIG_MMU + *(.fixup) + *(__ex_table) +#endif } .text : { /* Real text segment */ @@ -87,7 +91,9 @@ SECTIONS *(.text) SCHED_TEXT LOCK_TEXT +#ifdef CONFIG_MMU *(.fixup) +#endif *(.gnu.warning) *(.rodata) *(.rodata.*) @@ -142,7 +148,9 @@ SECTIONS */ . = ALIGN(32); __start___ex_table = .; +#ifdef CONFIG_MMU *(__ex_table) +#endif __stop___ex_table = .; /* diff --git a/trunk/arch/arm/lib/Makefile b/trunk/arch/arm/lib/Makefile index 7b726b627ea5..30351cd4560d 100644 --- a/trunk/arch/arm/lib/Makefile +++ b/trunk/arch/arm/lib/Makefile @@ -6,28 +6,31 @@ lib-y := backtrace.o changebit.o csumipv6.o csumpartial.o \ csumpartialcopy.o csumpartialcopyuser.o clearbit.o \ - copy_page.o delay.o findbit.o memchr.o memcpy.o \ + delay.o findbit.o memchr.o memcpy.o \ memmove.o memset.o memzero.o setbit.o \ strncpy_from_user.o strnlen_user.o \ strchr.o strrchr.o \ testchangebit.o testclearbit.o testsetbit.o \ - getuser.o putuser.o clear_user.o \ ashldi3.o ashrdi3.o lshrdi3.o muldi3.o \ ucmpdi2.o lib1funcs.o div64.o sha1.o \ io-readsb.o io-writesb.o io-readsl.o io-writesl.o +mmu-y := clear_user.o copy_page.o getuser.o putuser.o + # the code in uaccess.S is not preemption safe and # probably faster on ARMv3 only ifeq ($(CONFIG_PREEMPT),y) - lib-y += copy_from_user.o copy_to_user.o + mmu-y += copy_from_user.o copy_to_user.o else ifneq ($(CONFIG_CPU_32v3),y) - lib-y += copy_from_user.o copy_to_user.o + mmu-y += copy_from_user.o copy_to_user.o else - lib-y += uaccess.o + mmu-y += uaccess.o endif endif +lib-$(CONFIG_MMU) += $(mmu-y) + ifeq ($(CONFIG_CPU_32v3),y) lib-y += io-readsw-armv3.o io-writesw-armv3.o else diff --git a/trunk/arch/arm/lib/backtrace.S b/trunk/arch/arm/lib/backtrace.S index 058b80d72aa1..91f993f2e9db 100644 --- a/trunk/arch/arm/lib/backtrace.S +++ b/trunk/arch/arm/lib/backtrace.S @@ -97,16 +97,13 @@ ENTRY(c_backtrace) b 1007f /* - * Fixup for LDMDB + * Fixup for LDMDB. Note that this must not be in the fixup section. */ - .section .fixup,"ax" - .align 0 1007: ldr r0, =.Lbad mov r1, frame bl printk ldmfd sp!, {r4 - r8, pc} .ltorg - .previous .section __ex_table,"a" .align 3 diff --git a/trunk/arch/arm/lib/clear_user.S b/trunk/arch/arm/lib/clear_user.S index ea435ae2e4a5..ecb28dcdaf7b 100644 --- a/trunk/arch/arm/lib/clear_user.S +++ b/trunk/arch/arm/lib/clear_user.S @@ -12,13 +12,13 @@ .text -/* Prototype: int __arch_clear_user(void *addr, size_t sz) +/* Prototype: int __clear_user(void *addr, size_t sz) * Purpose : clear some user memory * Params : addr - user memory address to clear * : sz - number of bytes to clear * Returns : number of bytes NOT cleared */ -ENTRY(__arch_clear_user) +ENTRY(__clear_user) stmfd sp!, {r1, lr} mov r2, #0 cmp r1, #4 diff --git a/trunk/arch/arm/lib/copy_from_user.S b/trunk/arch/arm/lib/copy_from_user.S index 7497393a0e81..6b7363ce749c 100644 --- a/trunk/arch/arm/lib/copy_from_user.S +++ b/trunk/arch/arm/lib/copy_from_user.S @@ -16,7 +16,7 @@ /* * Prototype: * - * size_t __arch_copy_from_user(void *to, const void *from, size_t n) + * size_t __copy_from_user(void *to, const void *from, size_t n) * * Purpose: * @@ -83,7 +83,7 @@ .text -ENTRY(__arch_copy_from_user) +ENTRY(__copy_from_user) #include "copy_template.S" diff --git a/trunk/arch/arm/lib/copy_to_user.S b/trunk/arch/arm/lib/copy_to_user.S index 4a6d8ea14022..5224d94688d9 100644 --- a/trunk/arch/arm/lib/copy_to_user.S +++ b/trunk/arch/arm/lib/copy_to_user.S @@ -16,7 +16,7 @@ /* * Prototype: * - * size_t __arch_copy_to_user(void *to, const void *from, size_t n) + * size_t __copy_to_user(void *to, const void *from, size_t n) * * Purpose: * @@ -86,7 +86,7 @@ .text -ENTRY(__arch_copy_to_user) +ENTRY(__copy_to_user) #include "copy_template.S" diff --git a/trunk/arch/arm/lib/strncpy_from_user.S b/trunk/arch/arm/lib/strncpy_from_user.S index 35649f04fcac..36e3741a3772 100644 --- a/trunk/arch/arm/lib/strncpy_from_user.S +++ b/trunk/arch/arm/lib/strncpy_from_user.S @@ -20,7 +20,7 @@ * returns the number of characters copied (strlen of copied string), * -EFAULT on exception, or "len" if we fill the whole buffer */ -ENTRY(__arch_strncpy_from_user) +ENTRY(__strncpy_from_user) mov ip, r1 1: subs r2, r2, #1 USER( ldrplbt r3, [r1], #1) diff --git a/trunk/arch/arm/lib/strnlen_user.S b/trunk/arch/arm/lib/strnlen_user.S index 3668a15991ef..18d8fa4f925a 100644 --- a/trunk/arch/arm/lib/strnlen_user.S +++ b/trunk/arch/arm/lib/strnlen_user.S @@ -14,13 +14,13 @@ .text .align 5 -/* Prototype: unsigned long __arch_strnlen_user(const char *str, long n) +/* Prototype: unsigned long __strnlen_user(const char *str, long n) * Purpose : get length of a string in user memory * Params : str - address of string in user memory * Returns : length of string *including terminator* * or zero on exception, or n + 1 if too long */ -ENTRY(__arch_strnlen_user) +ENTRY(__strnlen_user) mov r2, r0 1: USER( ldrbt r3, [r0], #1) diff --git a/trunk/arch/arm/lib/uaccess.S b/trunk/arch/arm/lib/uaccess.S index 1f1545d737be..b48bd6d5fd83 100644 --- a/trunk/arch/arm/lib/uaccess.S +++ b/trunk/arch/arm/lib/uaccess.S @@ -19,7 +19,7 @@ #define PAGE_SHIFT 12 -/* Prototype: int __arch_copy_to_user(void *to, const char *from, size_t n) +/* Prototype: int __copy_to_user(void *to, const char *from, size_t n) * Purpose : copy a block to user memory from kernel memory * Params : to - user memory * : from - kernel memory @@ -39,7 +39,7 @@ USER( strgtbt r3, [r0], #1) @ May fault sub r2, r2, ip b .Lc2u_dest_aligned -ENTRY(__arch_copy_to_user) +ENTRY(__copy_to_user) stmfd sp!, {r2, r4 - r7, lr} cmp r2, #4 blt .Lc2u_not_enough @@ -283,7 +283,7 @@ USER( strgtbt r3, [r0], #1) @ May fault 9001: ldmfd sp!, {r0, r4 - r7, pc} .previous -/* Prototype: unsigned long __arch_copy_from_user(void *to,const void *from,unsigned long n); +/* Prototype: unsigned long __copy_from_user(void *to,const void *from,unsigned long n); * Purpose : copy a block from user memory to kernel memory * Params : to - kernel memory * : from - user memory @@ -302,7 +302,7 @@ USER( ldrgtbt r3, [r1], #1) @ May fault sub r2, r2, ip b .Lcfu_dest_aligned -ENTRY(__arch_copy_from_user) +ENTRY(__copy_from_user) stmfd sp!, {r0, r2, r4 - r7, lr} cmp r2, #4 blt .Lcfu_not_enough diff --git a/trunk/arch/arm/mach-ep93xx/Kconfig b/trunk/arch/arm/mach-ep93xx/Kconfig index cec5a21ca4e3..e15e4c54a253 100644 --- a/trunk/arch/arm/mach-ep93xx/Kconfig +++ b/trunk/arch/arm/mach-ep93xx/Kconfig @@ -2,8 +2,19 @@ if ARCH_EP93XX menu "Cirrus EP93xx Implementation Options" +config CRUNCH + bool "Support for MaverickCrunch" + help + Enable kernel support for MaverickCrunch. + comment "EP93xx Platforms" +config MACH_EDB9315 + bool "Support Cirrus Logic EDB9315" + help + Say 'Y' here if you want your kernel to support the Cirrus + Logic EDB9315 Evaluation Board. + config MACH_GESBC9312 bool "Support Glomation GESBC-9312-sx" help diff --git a/trunk/arch/arm/mach-ep93xx/Makefile b/trunk/arch/arm/mach-ep93xx/Makefile index 05a48a21038e..dfa7e2e8a18b 100644 --- a/trunk/arch/arm/mach-ep93xx/Makefile +++ b/trunk/arch/arm/mach-ep93xx/Makefile @@ -6,5 +6,6 @@ obj-m := obj-n := obj- := +obj-$(CONFIG_MACH_EDB9315) += edb9315.o obj-$(CONFIG_MACH_GESBC9312) += gesbc9312.o obj-$(CONFIG_MACH_TS72XX) += ts72xx.o diff --git a/trunk/arch/arm/mach-ep93xx/edb9315.c b/trunk/arch/arm/mach-ep93xx/edb9315.c new file mode 100644 index 000000000000..ef7482faad81 --- /dev/null +++ b/trunk/arch/arm/mach-ep93xx/edb9315.c @@ -0,0 +1,62 @@ +/* + * arch/arm/mach-ep93xx/edb9315.c + * Cirrus Logic EDB9315 support. + * + * Copyright (C) 2006 Lennert Buytenhek + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or (at + * your option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static struct physmap_flash_data edb9315_flash_data = { + .width = 4, +}; + +static struct resource edb9315_flash_resource = { + .start = 0x60000000, + .end = 0x61ffffff, + .flags = IORESOURCE_MEM, +}; + +static struct platform_device edb9315_flash = { + .name = "physmap-flash", + .id = 0, + .dev = { + .platform_data = &edb9315_flash_data, + }, + .num_resources = 1, + .resource = &edb9315_flash_resource, +}; + +static void __init edb9315_init_machine(void) +{ + ep93xx_init_devices(); + platform_device_register(&edb9315_flash); +} + +MACHINE_START(EDB9315, "Cirrus Logic EDB9315 Evaluation Board") + /* Maintainer: Lennert Buytenhek */ + .phys_io = EP93XX_APB_PHYS_BASE, + .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc, + .boot_params = 0x00000100, + .map_io = ep93xx_map_io, + .init_irq = ep93xx_init_irq, + .timer = &ep93xx_timer, + .init_machine = edb9315_init_machine, +MACHINE_END diff --git a/trunk/arch/arm/mach-ep93xx/gesbc9312.c b/trunk/arch/arm/mach-ep93xx/gesbc9312.c index 47cc6c8b7c79..2c28d66d260e 100644 --- a/trunk/arch/arm/mach-ep93xx/gesbc9312.c +++ b/trunk/arch/arm/mach-ep93xx/gesbc9312.c @@ -30,7 +30,7 @@ static struct physmap_flash_data gesbc9312_flash_data = { static struct resource gesbc9312_flash_resource = { .start = 0x60000000, - .end = 0x60800000, + .end = 0x607fffff, .flags = IORESOURCE_MEM, }; diff --git a/trunk/arch/arm/mach-ep93xx/ts72xx.c b/trunk/arch/arm/mach-ep93xx/ts72xx.c index 6e5a56cd5ae8..0b3b875b1875 100644 --- a/trunk/arch/arm/mach-ep93xx/ts72xx.c +++ b/trunk/arch/arm/mach-ep93xx/ts72xx.c @@ -118,7 +118,7 @@ static struct physmap_flash_data ts72xx_flash_data = { static struct resource ts72xx_flash_resource = { .start = TS72XX_NOR_PHYS_BASE, - .end = TS72XX_NOR_PHYS_BASE + 0x01000000, + .end = TS72XX_NOR_PHYS_BASE + 0x00ffffff, .flags = IORESOURCE_MEM, }; diff --git a/trunk/arch/arm/mach-ixp23xx/espresso.c b/trunk/arch/arm/mach-ixp23xx/espresso.c index dc5e489c70bc..357351fbb1e2 100644 --- a/trunk/arch/arm/mach-ixp23xx/espresso.c +++ b/trunk/arch/arm/mach-ixp23xx/espresso.c @@ -59,7 +59,7 @@ static struct physmap_flash_data espresso_flash_data = { static struct resource espresso_flash_resource = { .start = 0x90000000, - .end = 0x92000000, + .end = 0x91ffffff, .flags = IORESOURCE_MEM, }; diff --git a/trunk/arch/arm/mach-ixp23xx/ixdp2351.c b/trunk/arch/arm/mach-ixp23xx/ixdp2351.c index 535b334ee045..e0886871cc77 100644 --- a/trunk/arch/arm/mach-ixp23xx/ixdp2351.c +++ b/trunk/arch/arm/mach-ixp23xx/ixdp2351.c @@ -304,7 +304,7 @@ static struct physmap_flash_data ixdp2351_flash_data = { static struct resource ixdp2351_flash_resource = { .start = 0x90000000, - .end = 0x94000000, + .end = 0x93ffffff, .flags = IORESOURCE_MEM, }; diff --git a/trunk/arch/arm/mach-ixp23xx/roadrunner.c b/trunk/arch/arm/mach-ixp23xx/roadrunner.c index b9f5d13fcfe1..92ad18f41251 100644 --- a/trunk/arch/arm/mach-ixp23xx/roadrunner.c +++ b/trunk/arch/arm/mach-ixp23xx/roadrunner.c @@ -143,7 +143,7 @@ static struct physmap_flash_data roadrunner_flash_data = { static struct resource roadrunner_flash_resource = { .start = 0x90000000, - .end = 0x94000000, + .end = 0x93ffffff, .flags = IORESOURCE_MEM, }; diff --git a/trunk/arch/arm/mach-pxa/irq.c b/trunk/arch/arm/mach-pxa/irq.c index 539b596005fc..d9635ff4b10c 100644 --- a/trunk/arch/arm/mach-pxa/irq.c +++ b/trunk/arch/arm/mach-pxa/irq.c @@ -88,8 +88,8 @@ static int pxa_gpio_irq_type(unsigned int irq, unsigned int type) if (type == IRQT_PROBE) { /* Don't mess with enabled GPIOs using preconfigured edges or - GPIOs set to alternate function during probe */ - if ((GPIO_IRQ_rising_edge[idx] | GPIO_IRQ_falling_edge[idx]) & + GPIOs set to alternate function or to output during probe */ + if ((GPIO_IRQ_rising_edge[idx] | GPIO_IRQ_falling_edge[idx] | GPDR(gpio)) & GPIO_bit(gpio)) return 0; if (GAFR(gpio) & (0x3 << (((gpio) & 0xf)*2))) diff --git a/trunk/arch/arm/mach-s3c2410/s3c244x.c b/trunk/arch/arm/mach-s3c2410/s3c244x.c index 838bc525e836..9a2258270de9 100644 --- a/trunk/arch/arm/mach-s3c2410/s3c244x.c +++ b/trunk/arch/arm/mach-s3c2410/s3c244x.c @@ -69,6 +69,7 @@ void __init s3c244x_map_io(struct map_desc *mach_desc, int size) s3c_device_i2c.name = "s3c2440-i2c"; s3c_device_nand.name = "s3c2440-nand"; + s3c_device_usbgadget.name = "s3c2440-usbgadget"; } void __init s3c244x_init_clocks(int xtal) diff --git a/trunk/arch/arm/mm/Kconfig b/trunk/arch/arm/mm/Kconfig index ecf5e232a6fc..c4bca753165b 100644 --- a/trunk/arch/arm/mm/Kconfig +++ b/trunk/arch/arm/mm/Kconfig @@ -15,8 +15,8 @@ config CPU_ARM610 select CPU_32v3 select CPU_CACHE_V3 select CPU_CACHE_VIVT - select CPU_COPY_V3 - select CPU_TLB_V3 + select CPU_COPY_V3 if MMU + select CPU_TLB_V3 if MMU help The ARM610 is the successor to the ARM3 processor and was produced by VLSI Technology Inc. @@ -31,8 +31,8 @@ config CPU_ARM710 select CPU_32v3 select CPU_CACHE_V3 select CPU_CACHE_VIVT - select CPU_COPY_V3 - select CPU_TLB_V3 + select CPU_COPY_V3 if MMU + select CPU_TLB_V3 if MMU help A 32-bit RISC microprocessor based on the ARM7 processor core designed by Advanced RISC Machines Ltd. The ARM710 is the @@ -50,8 +50,8 @@ config CPU_ARM720T select CPU_ABRT_LV4T select CPU_CACHE_V4 select CPU_CACHE_VIVT - select CPU_COPY_V4WT - select CPU_TLB_V4WT + select CPU_COPY_V4WT if MMU + select CPU_TLB_V4WT if MMU help A 32-bit RISC processor with 8kByte Cache, Write Buffer and MMU built around an ARM7TDMI core. @@ -68,8 +68,8 @@ config CPU_ARM920T select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT - select CPU_COPY_V4WB - select CPU_TLB_V4WBI + select CPU_COPY_V4WB if MMU + select CPU_TLB_V4WBI if MMU help The ARM920T is licensed to be produced by numerous vendors, and is used in the Maverick EP9312 and the Samsung S3C2410. @@ -89,8 +89,8 @@ config CPU_ARM922T select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT - select CPU_COPY_V4WB - select CPU_TLB_V4WBI + select CPU_COPY_V4WB if MMU + select CPU_TLB_V4WBI if MMU help The ARM922T is a version of the ARM920T, but with smaller instruction and data caches. It is used in Altera's @@ -108,8 +108,8 @@ config CPU_ARM925T select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT - select CPU_COPY_V4WB - select CPU_TLB_V4WBI + select CPU_COPY_V4WB if MMU + select CPU_TLB_V4WBI if MMU help The ARM925T is a mix between the ARM920T and ARM926T, but with different instruction and data caches. It is used in TI's OMAP @@ -126,8 +126,8 @@ config CPU_ARM926T select CPU_32v5 select CPU_ABRT_EV5TJ select CPU_CACHE_VIVT - select CPU_COPY_V4WB - select CPU_TLB_V4WBI + select CPU_COPY_V4WB if MMU + select CPU_TLB_V4WBI if MMU help This is a variant of the ARM920. It has slightly different instruction sequences for cache and TLB operations. Curiously, @@ -144,8 +144,8 @@ config CPU_ARM1020 select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT - select CPU_COPY_V4WB - select CPU_TLB_V4WBI + select CPU_COPY_V4WB if MMU + select CPU_TLB_V4WBI if MMU help The ARM1020 is the 32K cached version of the ARM10 processor, with an addition of a floating-point unit. @@ -161,8 +161,8 @@ config CPU_ARM1020E select CPU_ABRT_EV4T select CPU_CACHE_V4WT select CPU_CACHE_VIVT - select CPU_COPY_V4WB - select CPU_TLB_V4WBI + select CPU_COPY_V4WB if MMU + select CPU_TLB_V4WBI if MMU depends on n # ARM1022E @@ -172,8 +172,8 @@ config CPU_ARM1022 select CPU_32v5 select CPU_ABRT_EV4T select CPU_CACHE_VIVT - select CPU_COPY_V4WB # can probably do better - select CPU_TLB_V4WBI + select CPU_COPY_V4WB if MMU # can probably do better + select CPU_TLB_V4WBI if MMU help The ARM1022E is an implementation of the ARMv5TE architecture based upon the ARM10 integer core with a 16KiB L1 Harvard cache, @@ -189,8 +189,8 @@ config CPU_ARM1026 select CPU_32v5 select CPU_ABRT_EV5T # But need Jazelle, but EV5TJ ignores bit 10 select CPU_CACHE_VIVT - select CPU_COPY_V4WB # can probably do better - select CPU_TLB_V4WBI + select CPU_COPY_V4WB if MMU # can probably do better + select CPU_TLB_V4WBI if MMU help The ARM1026EJ-S is an implementation of the ARMv5TEJ architecture based upon the ARM10 integer core. @@ -207,8 +207,8 @@ config CPU_SA110 select CPU_ABRT_EV4 select CPU_CACHE_V4WB select CPU_CACHE_VIVT - select CPU_COPY_V4WB - select CPU_TLB_V4WB + select CPU_COPY_V4WB if MMU + select CPU_TLB_V4WB if MMU help The Intel StrongARM(R) SA-110 is a 32-bit microprocessor and is available at five speeds ranging from 100 MHz to 233 MHz. @@ -227,7 +227,7 @@ config CPU_SA1100 select CPU_ABRT_EV4 select CPU_CACHE_V4WB select CPU_CACHE_VIVT - select CPU_TLB_V4WB + select CPU_TLB_V4WB if MMU # XScale config CPU_XSCALE @@ -237,7 +237,7 @@ config CPU_XSCALE select CPU_32v5 select CPU_ABRT_EV5T select CPU_CACHE_VIVT - select CPU_TLB_V4WBI + select CPU_TLB_V4WBI if MMU # XScale Core Version 3 config CPU_XSC3 @@ -247,7 +247,7 @@ config CPU_XSC3 select CPU_32v5 select CPU_ABRT_EV5T select CPU_CACHE_VIVT - select CPU_TLB_V4WBI + select CPU_TLB_V4WBI if MMU select IO_36 # ARMv6 @@ -258,8 +258,8 @@ config CPU_V6 select CPU_ABRT_EV6 select CPU_CACHE_V6 select CPU_CACHE_VIPT - select CPU_COPY_V6 - select CPU_TLB_V6 + select CPU_COPY_V6 if MMU + select CPU_TLB_V6 if MMU # ARMv6k config CPU_32v6K @@ -277,17 +277,17 @@ config CPU_32v6K # This defines the compiler instruction set which depends on the machine type. config CPU_32v3 bool - select TLS_REG_EMUL if SMP + select TLS_REG_EMUL if SMP || !MMU select NEEDS_SYSCALL_FOR_CMPXCHG if SMP config CPU_32v4 bool - select TLS_REG_EMUL if SMP + select TLS_REG_EMUL if SMP || !MMU select NEEDS_SYSCALL_FOR_CMPXCHG if SMP config CPU_32v5 bool - select TLS_REG_EMUL if SMP + select TLS_REG_EMUL if SMP || !MMU select NEEDS_SYSCALL_FOR_CMPXCHG if SMP config CPU_32v6 @@ -334,6 +334,7 @@ config CPU_CACHE_VIVT config CPU_CACHE_VIPT bool +if MMU # The copy-page model config CPU_COPY_V3 bool @@ -372,6 +373,8 @@ config CPU_TLB_V4WBI config CPU_TLB_V6 bool +endif + # # CPU supports 36-bit I/O # diff --git a/trunk/arch/arm/mm/Makefile b/trunk/arch/arm/mm/Makefile index 07a538505784..21a2770226ee 100644 --- a/trunk/arch/arm/mm/Makefile +++ b/trunk/arch/arm/mm/Makefile @@ -2,10 +2,16 @@ # Makefile for the linux arm-specific parts of the memory manager. # -obj-y := consistent.o extable.o fault-armv.o \ - fault.o flush.o init.o ioremap.o mmap.o \ +obj-y := consistent.o extable.o fault.o init.o \ + iomap.o + +obj-$(CONFIG_MMU) += fault-armv.o flush.o ioremap.o mmap.o \ mm-armv.o +ifneq ($(CONFIG_MMU),y) +obj-y += nommu.o +endif + obj-$(CONFIG_MODULES) += proc-syms.o obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o diff --git a/trunk/arch/arm/mm/init.c b/trunk/arch/arm/mm/init.c index 9ea1f87a7079..989fd681c822 100644 --- a/trunk/arch/arm/mm/init.c +++ b/trunk/arch/arm/mm/init.c @@ -26,8 +26,6 @@ #include #include -#define TABLE_SIZE (2 * PTRS_PER_PTE * sizeof(pte_t)) - DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; diff --git a/trunk/arch/arm/mm/iomap.c b/trunk/arch/arm/mm/iomap.c new file mode 100644 index 000000000000..62066f3020c8 --- /dev/null +++ b/trunk/arch/arm/mm/iomap.c @@ -0,0 +1,55 @@ +/* + * linux/arch/arm/mm/iomap.c + * + * Map IO port and PCI memory spaces so that {read,write}[bwl] can + * be used to access this memory. + */ +#include +#include +#include + +#include + +#ifdef __io +void __iomem *ioport_map(unsigned long port, unsigned int nr) +{ + return __io(port); +} +EXPORT_SYMBOL(ioport_map); + +void ioport_unmap(void __iomem *addr) +{ +} +EXPORT_SYMBOL(ioport_unmap); +#endif + +#ifdef CONFIG_PCI +void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) +{ + unsigned long start = pci_resource_start(dev, bar); + unsigned long len = pci_resource_len(dev, bar); + unsigned long flags = pci_resource_flags(dev, bar); + + if (!len || !start) + return NULL; + if (maxlen && len > maxlen) + len = maxlen; + if (flags & IORESOURCE_IO) + return ioport_map(start, len); + if (flags & IORESOURCE_MEM) { + if (flags & IORESOURCE_CACHEABLE) + return ioremap(start, len); + return ioremap_nocache(start, len); + } + return NULL; +} +EXPORT_SYMBOL(pci_iomap); + +void pci_iounmap(struct pci_dev *dev, void __iomem *addr) +{ + if ((unsigned long)addr >= VMALLOC_START && + (unsigned long)addr < VMALLOC_END) + iounmap(addr); +} +EXPORT_SYMBOL(pci_iounmap); +#endif diff --git a/trunk/arch/arm/mm/ioremap.c b/trunk/arch/arm/mm/ioremap.c index c1f7180c7bed..7691cfdba567 100644 --- a/trunk/arch/arm/mm/ioremap.c +++ b/trunk/arch/arm/mm/ioremap.c @@ -176,50 +176,3 @@ void __iounmap(void __iomem *addr) vunmap((void *)(PAGE_MASK & (unsigned long)addr)); } EXPORT_SYMBOL(__iounmap); - -#ifdef __io -void __iomem *ioport_map(unsigned long port, unsigned int nr) -{ - return __io(port); -} -EXPORT_SYMBOL(ioport_map); - -void ioport_unmap(void __iomem *addr) -{ -} -EXPORT_SYMBOL(ioport_unmap); -#endif - -#ifdef CONFIG_PCI -#include -#include - -void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) -{ - unsigned long start = pci_resource_start(dev, bar); - unsigned long len = pci_resource_len(dev, bar); - unsigned long flags = pci_resource_flags(dev, bar); - - if (!len || !start) - return NULL; - if (maxlen && len > maxlen) - len = maxlen; - if (flags & IORESOURCE_IO) - return ioport_map(start, len); - if (flags & IORESOURCE_MEM) { - if (flags & IORESOURCE_CACHEABLE) - return ioremap(start, len); - return ioremap_nocache(start, len); - } - return NULL; -} -EXPORT_SYMBOL(pci_iomap); - -void pci_iounmap(struct pci_dev *dev, void __iomem *addr) -{ - if ((unsigned long)addr >= VMALLOC_START && - (unsigned long)addr < VMALLOC_END) - iounmap(addr); -} -EXPORT_SYMBOL(pci_iounmap); -#endif diff --git a/trunk/arch/arm/mm/nommu.c b/trunk/arch/arm/mm/nommu.c new file mode 100644 index 000000000000..1464ed817b5d --- /dev/null +++ b/trunk/arch/arm/mm/nommu.c @@ -0,0 +1,39 @@ +/* + * linux/arch/arm/mm/nommu.c + * + * ARM uCLinux supporting functions. + */ +#include +#include +#include + +#include +#include +#include + +void flush_dcache_page(struct page *page) +{ + __cpuc_flush_dcache_page(page_address(page)); +} +EXPORT_SYMBOL(flush_dcache_page); + +void __iomem *__ioremap_pfn(unsigned long pfn, unsigned long offset, + size_t size, unsigned long flags) +{ + if (pfn >= (0x100000000ULL >> PAGE_SHIFT)) + return NULL; + return (void __iomem *) (offset + (pfn << PAGE_SHIFT)); +} +EXPORT_SYMBOL(__ioremap_pfn); + +void __iomem *__ioremap(unsigned long phys_addr, size_t size, + unsigned long flags) +{ + return (void __iomem *)phys_addr; +} +EXPORT_SYMBOL(__ioremap); + +void __iounmap(void __iomem *addr) +{ +} +EXPORT_SYMBOL(__iounmap); diff --git a/trunk/arch/arm/mm/proc-arm1020.S b/trunk/arch/arm/mm/proc-arm1020.S index 959588884fa5..b9abbafca812 100644 --- a/trunk/arch/arm/mm/proc-arm1020.S +++ b/trunk/arch/arm/mm/proc-arm1020.S @@ -3,6 +3,7 @@ * * Copyright (C) 2000 ARM Limited * Copyright (C) 2000 Deep Blue Solutions Ltd. + * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -101,7 +102,9 @@ ENTRY(cpu_arm1020_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB +#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -359,6 +362,7 @@ ENTRY(cpu_arm1020_dcache_clean_area) */ .align 5 ENTRY(cpu_arm1020_switch_mm) +#ifdef CONFIG_MMU #ifndef CONFIG_CPU_DCACHE_DISABLE mcr p15, 0, r3, c7, c10, 4 mov r1, #0xF @ 16 segments @@ -383,6 +387,7 @@ ENTRY(cpu_arm1020_switch_mm) mcr p15, 0, r1, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs +#endif /* CONFIG_MMU */ mov pc, lr /* @@ -392,6 +397,7 @@ ENTRY(cpu_arm1020_switch_mm) */ .align 5 ENTRY(cpu_arm1020_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -421,6 +427,7 @@ ENTRY(cpu_arm1020_set_pte) mcr p15, 0, r0, c7, c10, 1 @ clean D entry #endif mcr p15, 0, r0, c7, c10, 4 @ drain WB +#endif /* CONFIG_MMU */ mov pc, lr __INIT @@ -430,7 +437,9 @@ __arm1020_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 +#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 +#endif mrc p15, 0, r0, c1, c0 @ get control register v4 ldr r5, arm1020_cr1_clear bic r0, r0, r5 diff --git a/trunk/arch/arm/mm/proc-arm1020e.S b/trunk/arch/arm/mm/proc-arm1020e.S index be6d081ff2b7..bcd5ee022e00 100644 --- a/trunk/arch/arm/mm/proc-arm1020e.S +++ b/trunk/arch/arm/mm/proc-arm1020e.S @@ -3,6 +3,7 @@ * * Copyright (C) 2000 ARM Limited * Copyright (C) 2000 Deep Blue Solutions Ltd. + * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -101,7 +102,9 @@ ENTRY(cpu_arm1020e_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB +#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -344,6 +347,7 @@ ENTRY(cpu_arm1020e_dcache_clean_area) */ .align 5 ENTRY(cpu_arm1020e_switch_mm) +#ifdef CONFIG_MMU #ifndef CONFIG_CPU_DCACHE_DISABLE mcr p15, 0, r3, c7, c10, 4 mov r1, #0xF @ 16 segments @@ -367,6 +371,7 @@ ENTRY(cpu_arm1020e_switch_mm) mcr p15, 0, r1, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs +#endif mov pc, lr /* @@ -376,6 +381,7 @@ ENTRY(cpu_arm1020e_switch_mm) */ .align 5 ENTRY(cpu_arm1020e_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -403,6 +409,7 @@ ENTRY(cpu_arm1020e_set_pte) #ifndef CONFIG_CPU_DCACHE_DISABLE mcr p15, 0, r0, c7, c10, 1 @ clean D entry #endif +#endif /* CONFIG_MMU */ mov pc, lr __INIT @@ -412,7 +419,9 @@ __arm1020e_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 +#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 +#endif mrc p15, 0, r0, c1, c0 @ get control register v4 ldr r5, arm1020e_cr1_clear bic r0, r0, r5 diff --git a/trunk/arch/arm/mm/proc-arm1022.S b/trunk/arch/arm/mm/proc-arm1022.S index f778545d57a2..b0ccff4fadd2 100644 --- a/trunk/arch/arm/mm/proc-arm1022.S +++ b/trunk/arch/arm/mm/proc-arm1022.S @@ -3,6 +3,7 @@ * * Copyright (C) 2000 ARM Limited * Copyright (C) 2000 Deep Blue Solutions Ltd. + * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -90,7 +91,9 @@ ENTRY(cpu_arm1022_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB +#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -333,6 +336,7 @@ ENTRY(cpu_arm1022_dcache_clean_area) */ .align 5 ENTRY(cpu_arm1022_switch_mm) +#ifdef CONFIG_MMU #ifndef CONFIG_CPU_DCACHE_DISABLE mov r1, #(CACHE_DSEGMENTS - 1) << 5 @ 16 segments 1: orr r3, r1, #(CACHE_DENTRIES - 1) << 26 @ 64 entries @@ -349,6 +353,7 @@ ENTRY(cpu_arm1022_switch_mm) mcr p15, 0, r1, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs +#endif mov pc, lr /* @@ -358,6 +363,7 @@ ENTRY(cpu_arm1022_switch_mm) */ .align 5 ENTRY(cpu_arm1022_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -385,6 +391,7 @@ ENTRY(cpu_arm1022_set_pte) #ifndef CONFIG_CPU_DCACHE_DISABLE mcr p15, 0, r0, c7, c10, 1 @ clean D entry #endif +#endif /* CONFIG_MMU */ mov pc, lr __INIT @@ -394,7 +401,9 @@ __arm1022_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 +#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 +#endif mrc p15, 0, r0, c1, c0 @ get control register v4 ldr r5, arm1022_cr1_clear bic r0, r0, r5 diff --git a/trunk/arch/arm/mm/proc-arm1026.S b/trunk/arch/arm/mm/proc-arm1026.S index 148c111fde73..abe850c9a641 100644 --- a/trunk/arch/arm/mm/proc-arm1026.S +++ b/trunk/arch/arm/mm/proc-arm1026.S @@ -3,6 +3,7 @@ * * Copyright (C) 2000 ARM Limited * Copyright (C) 2000 Deep Blue Solutions Ltd. + * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -90,7 +91,9 @@ ENTRY(cpu_arm1026_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB +#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -327,6 +330,7 @@ ENTRY(cpu_arm1026_dcache_clean_area) */ .align 5 ENTRY(cpu_arm1026_switch_mm) +#ifdef CONFIG_MMU mov r1, #0 #ifndef CONFIG_CPU_DCACHE_DISABLE 1: mrc p15, 0, r15, c7, c14, 3 @ test, clean, invalidate @@ -338,6 +342,7 @@ ENTRY(cpu_arm1026_switch_mm) mcr p15, 0, r1, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, r1, c8, c7, 0 @ invalidate I & D TLBs +#endif mov pc, lr /* @@ -347,6 +352,7 @@ ENTRY(cpu_arm1026_switch_mm) */ .align 5 ENTRY(cpu_arm1026_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -374,6 +380,7 @@ ENTRY(cpu_arm1026_set_pte) #ifndef CONFIG_CPU_DCACHE_DISABLE mcr p15, 0, r0, c7, c10, 1 @ clean D entry #endif +#endif /* CONFIG_MMU */ mov pc, lr @@ -384,8 +391,10 @@ __arm1026_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 +#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 mcr p15, 0, r4, c2, c0 @ load page table pointer +#endif #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mov r0, #4 @ explicitly disable writeback mcr p15, 7, r0, c15, c0, 0 diff --git a/trunk/arch/arm/mm/proc-arm6_7.S b/trunk/arch/arm/mm/proc-arm6_7.S index 540359b475d0..7a705edfa4b2 100644 --- a/trunk/arch/arm/mm/proc-arm6_7.S +++ b/trunk/arch/arm/mm/proc-arm6_7.S @@ -2,6 +2,7 @@ * linux/arch/arm/mm/proc-arm6,7.S * * Copyright (C) 1997-2000 Russell King + * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -199,10 +200,12 @@ ENTRY(cpu_arm7_do_idle) */ ENTRY(cpu_arm6_switch_mm) ENTRY(cpu_arm7_switch_mm) +#ifdef CONFIG_MMU mov r1, #0 mcr p15, 0, r1, c7, c0, 0 @ flush cache mcr p15, 0, r0, c2, c0, 0 @ update page table ptr mcr p15, 0, r1, c5, c0, 0 @ flush TLBs +#endif mov pc, lr /* @@ -214,6 +217,7 @@ ENTRY(cpu_arm7_switch_mm) .align 5 ENTRY(cpu_arm6_set_pte) ENTRY(cpu_arm7_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -232,6 +236,7 @@ ENTRY(cpu_arm7_set_pte) movne r2, #0 str r2, [r0] @ hardware version +#endif /* CONFIG_MMU */ mov pc, lr /* @@ -243,7 +248,9 @@ ENTRY(cpu_arm6_reset) ENTRY(cpu_arm7_reset) mov r1, #0 mcr p15, 0, r1, c7, c0, 0 @ flush cache +#ifdef CONFIG_MMU mcr p15, 0, r1, c5, c0, 0 @ flush TLB +#endif mov r1, #0x30 mcr p15, 0, r1, c1, c0, 0 @ turn off MMU etc mov pc, r0 @@ -253,19 +260,27 @@ ENTRY(cpu_arm7_reset) .type __arm6_setup, #function __arm6_setup: mov r0, #0 mcr p15, 0, r0, c7, c0 @ flush caches on v3 +#ifdef CONFIG_MMU mcr p15, 0, r0, c5, c0 @ flush TLBs on v3 mov r0, #0x3d @ . ..RS BLDP WCAM orr r0, r0, #0x100 @ . ..01 0011 1101 +#else + mov r0, #0x3c @ . ..RS BLDP WCA. +#endif mov pc, lr .size __arm6_setup, . - __arm6_setup .type __arm7_setup, #function __arm7_setup: mov r0, #0 mcr p15, 0, r0, c7, c0 @ flush caches on v3 +#ifdef CONFIG_MMU mcr p15, 0, r0, c5, c0 @ flush TLBs on v3 mcr p15, 0, r0, c3, c0 @ load domain access register mov r0, #0x7d @ . ..RS BLDP WCAM orr r0, r0, #0x100 @ . ..01 0111 1101 +#else + mov r0, #0x7c @ . ..RS BLDP WCA. +#endif mov pc, lr .size __arm7_setup, . - __arm7_setup diff --git a/trunk/arch/arm/mm/proc-arm720.S b/trunk/arch/arm/mm/proc-arm720.S index 26f00ee2ad9a..86102467d37f 100644 --- a/trunk/arch/arm/mm/proc-arm720.S +++ b/trunk/arch/arm/mm/proc-arm720.S @@ -4,6 +4,7 @@ * Copyright (C) 2000 Steve Hill (sjhill@cotw.com) * Rob Scott (rscott@mtrob.fdns.net) * Copyright (C) 2000 ARM Limited, Deep Blue Solutions Ltd. + * hacked for non-paged-MM by Hyok S. Choi, 2004. * * 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 @@ -29,6 +30,7 @@ * out of 'proc-arm6,7.S' per RMK discussion * 07-25-2000 SJH Added idle function. * 08-25-2000 DBS Updated for integration of ARM Ltd version. + * 04-20-2004 HSC modified for non-paged memory management mode. */ #include #include @@ -75,10 +77,12 @@ ENTRY(cpu_arm720_do_idle) * the new. */ ENTRY(cpu_arm720_switch_mm) +#ifdef CONFIG_MMU mov r1, #0 mcr p15, 0, r1, c7, c7, 0 @ invalidate cache mcr p15, 0, r0, c2, c0, 0 @ update page table ptr mcr p15, 0, r1, c8, c7, 0 @ flush TLB (v4) +#endif mov pc, lr /* @@ -89,6 +93,7 @@ ENTRY(cpu_arm720_switch_mm) */ .align 5 ENTRY(cpu_arm720_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -107,6 +112,7 @@ ENTRY(cpu_arm720_set_pte) movne r2, #0 str r2, [r0] @ hardware version +#endif mov pc, lr /* @@ -117,7 +123,9 @@ ENTRY(cpu_arm720_set_pte) ENTRY(cpu_arm720_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate cache +#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ flush TLB (v4) +#endif mrc p15, 0, ip, c1, c0, 0 @ get ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x2100 @ ..v....s........ @@ -130,7 +138,9 @@ ENTRY(cpu_arm720_reset) __arm710_setup: mov r0, #0 mcr p15, 0, r0, c7, c7, 0 @ invalidate caches +#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4) +#endif mrc p15, 0, r0, c1, c0 @ get control register ldr r5, arm710_cr1_clear bic r0, r0, r5 @@ -156,7 +166,9 @@ arm710_cr1_set: __arm720_setup: mov r0, #0 mcr p15, 0, r0, c7, c7, 0 @ invalidate caches +#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7, 0 @ flush TLB (v4) +#endif mrc p15, 0, r0, c1, c0 @ get control register ldr r5, arm720_cr1_clear bic r0, r0, r5 diff --git a/trunk/arch/arm/mm/proc-arm920.S b/trunk/arch/arm/mm/proc-arm920.S index a17f79e0199c..31dc839ba07c 100644 --- a/trunk/arch/arm/mm/proc-arm920.S +++ b/trunk/arch/arm/mm/proc-arm920.S @@ -3,6 +3,7 @@ * * Copyright (C) 1999,2000 ARM Limited * Copyright (C) 2000 Deep Blue Solutions Ltd. + * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -97,7 +98,9 @@ ENTRY(cpu_arm920_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB +#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -317,6 +320,7 @@ ENTRY(cpu_arm920_dcache_clean_area) */ .align 5 ENTRY(cpu_arm920_switch_mm) +#ifdef CONFIG_MMU mov ip, #0 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache @@ -337,6 +341,7 @@ ENTRY(cpu_arm920_switch_mm) mcr p15, 0, ip, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mov pc, lr /* @@ -346,6 +351,7 @@ ENTRY(cpu_arm920_switch_mm) */ .align 5 ENTRY(cpu_arm920_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -372,6 +378,7 @@ ENTRY(cpu_arm920_set_pte) mov r0, r0 mcr p15, 0, r0, c7, c10, 1 @ clean D entry mcr p15, 0, r0, c7, c10, 4 @ drain WB +#endif /* CONFIG_MMU */ mov pc, lr __INIT @@ -381,7 +388,9 @@ __arm920_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 +#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 +#endif mrc p15, 0, r0, c1, c0 @ get control register v4 ldr r5, arm920_cr1_clear bic r0, r0, r5 diff --git a/trunk/arch/arm/mm/proc-arm922.S b/trunk/arch/arm/mm/proc-arm922.S index bbde4a024a48..9e57c34f5c09 100644 --- a/trunk/arch/arm/mm/proc-arm922.S +++ b/trunk/arch/arm/mm/proc-arm922.S @@ -4,6 +4,7 @@ * Copyright (C) 1999,2000 ARM Limited * Copyright (C) 2000 Deep Blue Solutions Ltd. * Copyright (C) 2001 Altera Corporation + * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -99,7 +100,9 @@ ENTRY(cpu_arm922_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB +#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -321,6 +324,7 @@ ENTRY(cpu_arm922_dcache_clean_area) */ .align 5 ENTRY(cpu_arm922_switch_mm) +#ifdef CONFIG_MMU mov ip, #0 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache @@ -341,6 +345,7 @@ ENTRY(cpu_arm922_switch_mm) mcr p15, 0, ip, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mov pc, lr /* @@ -350,6 +355,7 @@ ENTRY(cpu_arm922_switch_mm) */ .align 5 ENTRY(cpu_arm922_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -376,6 +382,7 @@ ENTRY(cpu_arm922_set_pte) mov r0, r0 mcr p15, 0, r0, c7, c10, 1 @ clean D entry mcr p15, 0, r0, c7, c10, 4 @ drain WB +#endif /* CONFIG_MMU */ mov pc, lr __INIT @@ -385,7 +392,9 @@ __arm922_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 +#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 +#endif mrc p15, 0, r0, c1, c0 @ get control register v4 ldr r5, arm922_cr1_clear bic r0, r0, r5 diff --git a/trunk/arch/arm/mm/proc-arm925.S b/trunk/arch/arm/mm/proc-arm925.S index 224ce226a01b..8d47c9f3f931 100644 --- a/trunk/arch/arm/mm/proc-arm925.S +++ b/trunk/arch/arm/mm/proc-arm925.S @@ -9,6 +9,8 @@ * Update for Linux-2.6 and cache flush improvements * Copyright (C) 2004 Nokia Corporation by Tony Lindgren * + * hacked for non-paged-MM by Hyok S. Choi, 2004. + * * 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 @@ -122,7 +124,9 @@ ENTRY(cpu_arm925_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB +#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -369,6 +373,7 @@ ENTRY(cpu_arm925_dcache_clean_area) */ .align 5 ENTRY(cpu_arm925_switch_mm) +#ifdef CONFIG_MMU mov ip, #0 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache @@ -383,6 +388,7 @@ ENTRY(cpu_arm925_switch_mm) mcr p15, 0, ip, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mov pc, lr /* @@ -392,6 +398,7 @@ ENTRY(cpu_arm925_switch_mm) */ .align 5 ENTRY(cpu_arm925_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -420,6 +427,7 @@ ENTRY(cpu_arm925_set_pte) mcr p15, 0, r0, c7, c10, 1 @ clean D entry #endif mcr p15, 0, r0, c7, c10, 4 @ drain WB +#endif /* CONFIG_MMU */ mov pc, lr __INIT @@ -438,7 +446,9 @@ __arm925_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 +#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 +#endif #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mov r0, #4 @ disable write-back on caches explicitly diff --git a/trunk/arch/arm/mm/proc-arm926.S b/trunk/arch/arm/mm/proc-arm926.S index 4e2a087cf388..cb4d8f33d2a3 100644 --- a/trunk/arch/arm/mm/proc-arm926.S +++ b/trunk/arch/arm/mm/proc-arm926.S @@ -3,6 +3,7 @@ * * Copyright (C) 1999-2001 ARM Limited * Copyright (C) 2000 Deep Blue Solutions Ltd. + * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -85,7 +86,9 @@ ENTRY(cpu_arm926_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB +#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -329,6 +332,7 @@ ENTRY(cpu_arm926_dcache_clean_area) */ .align 5 ENTRY(cpu_arm926_switch_mm) +#ifdef CONFIG_MMU mov ip, #0 #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH mcr p15, 0, ip, c7, c6, 0 @ invalidate D cache @@ -341,6 +345,7 @@ ENTRY(cpu_arm926_switch_mm) mcr p15, 0, ip, c7, c10, 4 @ drain WB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mov pc, lr /* @@ -350,6 +355,7 @@ ENTRY(cpu_arm926_switch_mm) */ .align 5 ENTRY(cpu_arm926_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -378,6 +384,7 @@ ENTRY(cpu_arm926_set_pte) mcr p15, 0, r0, c7, c10, 1 @ clean D entry #endif mcr p15, 0, r0, c7, c10, 4 @ drain WB +#endif mov pc, lr __INIT @@ -387,7 +394,9 @@ __arm926_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 +#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 +#endif #ifdef CONFIG_CPU_DCACHE_WRITETHROUGH diff --git a/trunk/arch/arm/mm/proc-sa110.S b/trunk/arch/arm/mm/proc-sa110.S index a2dd5ae1077d..5a760a2c629c 100644 --- a/trunk/arch/arm/mm/proc-sa110.S +++ b/trunk/arch/arm/mm/proc-sa110.S @@ -2,6 +2,7 @@ * linux/arch/arm/mm/proc-sa110.S * * Copyright (C) 1997-2002 Russell King + * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -67,7 +68,9 @@ ENTRY(cpu_sa110_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB +#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -130,11 +133,15 @@ ENTRY(cpu_sa110_dcache_clean_area) */ .align 5 ENTRY(cpu_sa110_switch_mm) +#ifdef CONFIG_MMU str lr, [sp, #-4]! bl v4wb_flush_kern_cache_all @ clears IP mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs ldr pc, [sp], #4 +#else + mov pc, lr +#endif /* * cpu_sa110_set_pte(ptep, pte) @@ -143,6 +150,7 @@ ENTRY(cpu_sa110_switch_mm) */ .align 5 ENTRY(cpu_sa110_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -164,6 +172,7 @@ ENTRY(cpu_sa110_set_pte) mov r0, r0 mcr p15, 0, r0, c7, c10, 1 @ clean D entry mcr p15, 0, r0, c7, c10, 4 @ drain WB +#endif mov pc, lr __INIT @@ -173,7 +182,9 @@ __sa110_setup: mov r10, #0 mcr p15, 0, r10, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r10, c7, c10, 4 @ drain write buffer on v4 +#ifdef CONFIG_MMU mcr p15, 0, r10, c8, c7 @ invalidate I,D TLBs on v4 +#endif mrc p15, 0, r0, c1, c0 @ get control register v4 ldr r5, sa110_cr1_clear bic r0, r0, r5 diff --git a/trunk/arch/arm/mm/proc-sa1100.S b/trunk/arch/arm/mm/proc-sa1100.S index 777ad99c1439..0a2107ad4c32 100644 --- a/trunk/arch/arm/mm/proc-sa1100.S +++ b/trunk/arch/arm/mm/proc-sa1100.S @@ -2,6 +2,7 @@ * linux/arch/arm/mm/proc-sa1100.S * * Copyright (C) 1997-2002 Russell King + * hacked for non-paged-MM by Hyok S. Choi, 2003. * * 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 @@ -77,7 +78,9 @@ ENTRY(cpu_sa1100_reset) mov ip, #0 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches mcr p15, 0, ip, c7, c10, 4 @ drain WB +#ifdef CONFIG_MMU mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs +#endif mrc p15, 0, ip, c1, c0, 0 @ ctrl register bic ip, ip, #0x000f @ ............wcam bic ip, ip, #0x1100 @ ...i...s........ @@ -142,12 +145,16 @@ ENTRY(cpu_sa1100_dcache_clean_area) */ .align 5 ENTRY(cpu_sa1100_switch_mm) +#ifdef CONFIG_MMU str lr, [sp, #-4]! bl v4wb_flush_kern_cache_all @ clears IP mcr p15, 0, ip, c9, c0, 0 @ invalidate RB mcr p15, 0, r0, c2, c0, 0 @ load page table pointer mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs ldr pc, [sp], #4 +#else + mov pc, lr +#endif /* * cpu_sa1100_set_pte(ptep, pte) @@ -156,6 +163,7 @@ ENTRY(cpu_sa1100_switch_mm) */ .align 5 ENTRY(cpu_sa1100_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version eor r1, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY @@ -177,6 +185,7 @@ ENTRY(cpu_sa1100_set_pte) mov r0, r0 mcr p15, 0, r0, c7, c10, 1 @ clean D entry mcr p15, 0, r0, c7, c10, 4 @ drain WB +#endif mov pc, lr __INIT @@ -186,7 +195,9 @@ __sa1100_setup: mov r0, #0 mcr p15, 0, r0, c7, c7 @ invalidate I,D caches on v4 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer on v4 +#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7 @ invalidate I,D TLBs on v4 +#endif mrc p15, 0, r0, c1, c0 @ get control register v4 ldr r5, sa1100_cr1_clear bic r0, r0, r5 diff --git a/trunk/arch/arm/mm/proc-v6.S b/trunk/arch/arm/mm/proc-v6.S index 09b1a41a6de8..ca13d4d05f65 100644 --- a/trunk/arch/arm/mm/proc-v6.S +++ b/trunk/arch/arm/mm/proc-v6.S @@ -2,6 +2,7 @@ * linux/arch/arm/mm/proc-v6.S * * Copyright (C) 2001 Deep Blue Solutions Ltd. + * Modified by Catalin Marinas for noMMU support * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -88,6 +89,7 @@ ENTRY(cpu_v6_dcache_clean_area) * - we are not using split page tables */ ENTRY(cpu_v6_switch_mm) +#ifdef CONFIG_MMU mov r2, #0 ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id #ifdef CONFIG_SMP @@ -97,6 +99,7 @@ ENTRY(cpu_v6_switch_mm) mcr p15, 0, r2, c7, c10, 4 @ drain write buffer mcr p15, 0, r0, c2, c0, 0 @ set TTB 0 mcr p15, 0, r1, c13, c0, 1 @ set context ID +#endif mov pc, lr /* @@ -119,6 +122,7 @@ ENTRY(cpu_v6_switch_mm) * 1111 0 1 1 r/w r/w */ ENTRY(cpu_v6_set_pte) +#ifdef CONFIG_MMU str r1, [r0], #-2048 @ linux version bic r2, r1, #0x000003f0 @@ -145,6 +149,7 @@ ENTRY(cpu_v6_set_pte) str r2, [r0] mcr p15, 0, r0, c7, c10, 1 @ flush_pte +#endif mov pc, lr @@ -194,12 +199,14 @@ __v6_setup: mcr p15, 0, r0, c7, c5, 0 @ invalidate I cache mcr p15, 0, r0, c7, c15, 0 @ clean+invalidate cache mcr p15, 0, r0, c7, c10, 4 @ drain write buffer +#ifdef CONFIG_MMU mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs mcr p15, 0, r0, c2, c0, 2 @ TTB control register #ifdef CONFIG_SMP orr r4, r4, #TTB_RGN_WBWA|TTB_S @ mark PTWs shared, outer cacheable #endif mcr p15, 0, r4, c2, c0, 1 @ load TTB1 +#endif /* CONFIG_MMU */ #ifdef CONFIG_VFP mrc p15, 0, r0, c1, c0, 2 orr r0, r0, #(0xf << 20) diff --git a/trunk/arch/cris/Kconfig b/trunk/arch/cris/Kconfig index 856b665020e7..6a1238a29d6c 100644 --- a/trunk/arch/cris/Kconfig +++ b/trunk/arch/cris/Kconfig @@ -28,6 +28,10 @@ config GENERIC_CALIBRATE_DELAY bool default y +config IRQ_PER_CPU + bool + default y + config CRIS bool default y diff --git a/trunk/arch/cris/arch-v10/kernel/irq.c b/trunk/arch/cris/arch-v10/kernel/irq.c index 4b368a122015..2d5be93b5197 100644 --- a/trunk/arch/cris/arch-v10/kernel/irq.c +++ b/trunk/arch/cris/arch-v10/kernel/irq.c @@ -172,7 +172,7 @@ init_IRQ(void) /* Initialize IRQ handler descriptiors. */ for(i = 2; i < NR_IRQS; i++) { - irq_desc[i].handler = &crisv10_irq_type; + irq_desc[i].chip = &crisv10_irq_type; set_int_vector(i, interrupt[i]); } diff --git a/trunk/arch/cris/arch-v32/drivers/pci/bios.c b/trunk/arch/cris/arch-v32/drivers/pci/bios.c index 1e9d062103ae..a2b9c60c2777 100644 --- a/trunk/arch/cris/arch-v32/drivers/pci/bios.c +++ b/trunk/arch/cris/arch-v32/drivers/pci/bios.c @@ -43,10 +43,10 @@ int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; + resource_size_t start = res->start; if (start & 0x300) { start = (start + 0x3ff) & ~0x3ff; diff --git a/trunk/arch/cris/arch-v32/kernel/irq.c b/trunk/arch/cris/arch-v32/kernel/irq.c index c78cc2685133..06260874f018 100644 --- a/trunk/arch/cris/arch-v32/kernel/irq.c +++ b/trunk/arch/cris/arch-v32/kernel/irq.c @@ -369,7 +369,7 @@ init_IRQ(void) /* Point all IRQ's to bad handlers. */ for (i = FIRST_IRQ, j = 0; j < NR_IRQS; i++, j++) { - irq_desc[j].handler = &crisv32_irq_type; + irq_desc[j].chip = &crisv32_irq_type; set_exception_vector(i, interrupt[j]); } diff --git a/trunk/arch/cris/kernel/irq.c b/trunk/arch/cris/kernel/irq.c index b504def3e346..6547bb646364 100644 --- a/trunk/arch/cris/kernel/irq.c +++ b/trunk/arch/cris/kernel/irq.c @@ -69,7 +69,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %14s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) diff --git a/trunk/arch/frv/mb93090-mb00/pci-frv.c b/trunk/arch/frv/mb93090-mb00/pci-frv.c index 0a26bf6f1cd4..4f165c93be42 100644 --- a/trunk/arch/frv/mb93090-mb00/pci-frv.c +++ b/trunk/arch/frv/mb93090-mb00/pci-frv.c @@ -64,10 +64,10 @@ pcibios_update_resource(struct pci_dev *dev, struct resource *root, */ void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; + resource_size_t start = res->start; if (start & 0x300) { start = (start + 0x3ff) & ~0x3ff; diff --git a/trunk/arch/i386/Kconfig b/trunk/arch/i386/Kconfig index 3bb221db164a..0463f6335905 100644 --- a/trunk/arch/i386/Kconfig +++ b/trunk/arch/i386/Kconfig @@ -529,6 +529,7 @@ config X86_PAE bool depends on HIGHMEM64G default y + select RESOURCES_64BIT # Common NUMA Features config NUMA @@ -794,6 +795,9 @@ config COMPAT_VDSO endmenu +config ARCH_ENABLE_MEMORY_HOTPLUG + def_bool y + depends on HIGHMEM menu "Power management options (ACPI, APM)" depends on !X86_VOYAGER diff --git a/trunk/arch/i386/kernel/efi.c b/trunk/arch/i386/kernel/efi.c index 9202b67c4b2e..8beb0f07d999 100644 --- a/trunk/arch/i386/kernel/efi.c +++ b/trunk/arch/i386/kernel/efi.c @@ -601,8 +601,10 @@ efi_initialize_iomem_resources(struct resource *code_resource, res->end = res->start + ((md->num_pages << EFI_PAGE_SHIFT) - 1); res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; if (request_resource(&iomem_resource, res) < 0) - printk(KERN_ERR PFX "Failed to allocate res %s : 0x%lx-0x%lx\n", - res->name, res->start, res->end); + printk(KERN_ERR PFX "Failed to allocate res %s : " + "0x%llx-0x%llx\n", res->name, + (unsigned long long)res->start, + (unsigned long long)res->end); /* * We don't know which region contains kernel data so we try * it repeatedly and let the resource manager test it. diff --git a/trunk/arch/i386/kernel/i8259.c b/trunk/arch/i386/kernel/i8259.c index c1a42feba286..3c6063671a9f 100644 --- a/trunk/arch/i386/kernel/i8259.c +++ b/trunk/arch/i386/kernel/i8259.c @@ -132,7 +132,7 @@ void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); io_apic_irqs &= ~(1<= NR_IRQS)) { + printk(KERN_EMERG "%s: cannot handle IRQ %d\n", + __FUNCTION__, irq); + BUG(); + } + irq_enter(); #ifdef CONFIG_DEBUG_STACKOVERFLOW /* Debugging check for stack overflow: is there less than 1KB free? */ @@ -76,6 +82,10 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs) } #endif + if (!irq_desc[irq].handle_irq) { + __do_IRQ(irq, regs); + goto out_exit; + } #ifdef CONFIG_4KSTACKS curctx = (union irq_ctx *) current_thread_info(); @@ -115,6 +125,7 @@ fastcall unsigned int do_IRQ(struct pt_regs *regs) #endif __do_IRQ(irq, regs); +out_exit: irq_exit(); return 1; @@ -243,7 +254,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %14s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -285,13 +296,13 @@ void fixup_irqs(cpumask_t map) if (irq == 2) continue; - cpus_and(mask, irq_affinity[irq], map); + cpus_and(mask, irq_desc[irq].affinity, map); if (any_online_cpu(mask) == NR_CPUS) { printk("Breaking affinity for irq %i\n", irq); mask = map; } - if (irq_desc[irq].handler->set_affinity) - irq_desc[irq].handler->set_affinity(irq, mask); + if (irq_desc[irq].chip->set_affinity) + irq_desc[irq].chip->set_affinity(irq, mask); else if (irq_desc[irq].action && !(warned++)) printk("Cannot set affinity for irq %i\n", irq); } diff --git a/trunk/arch/i386/kernel/setup.c b/trunk/arch/i386/kernel/setup.c index 4a65040cc624..6712f0d2eb37 100644 --- a/trunk/arch/i386/kernel/setup.c +++ b/trunk/arch/i386/kernel/setup.c @@ -1314,8 +1314,10 @@ legacy_init_iomem_resources(struct resource *code_resource, struct resource *dat probe_roms(); for (i = 0; i < e820.nr_map; i++) { struct resource *res; +#ifndef CONFIG_RESOURCES_64BIT if (e820.map[i].addr + e820.map[i].size > 0x100000000ULL) continue; +#endif res = kzalloc(sizeof(struct resource), GFP_ATOMIC); switch (e820.map[i].type) { case E820_RAM: res->name = "System RAM"; break; diff --git a/trunk/arch/i386/kernel/sysenter.c b/trunk/arch/i386/kernel/sysenter.c index c60419dee018..713ba39d32c6 100644 --- a/trunk/arch/i386/kernel/sysenter.c +++ b/trunk/arch/i386/kernel/sysenter.c @@ -148,8 +148,10 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack) vma->vm_mm = mm; ret = insert_vm_struct(mm, vma); - if (ret) - goto free_vma; + if (unlikely(ret)) { + kmem_cache_free(vm_area_cachep, vma); + goto up_fail; + } current->mm->context.vdso = (void *)addr; current_thread_info()->sysenter_return = @@ -158,10 +160,6 @@ int arch_setup_additional_pages(struct linux_binprm *bprm, int exstack) up_fail: up_write(&mm->mmap_sem); return ret; - -free_vma: - kmem_cache_free(vm_area_cachep, vma); - return ret; } const char *arch_vma_name(struct vm_area_struct *vma) diff --git a/trunk/arch/i386/mach-visws/setup.c b/trunk/arch/i386/mach-visws/setup.c index 8a9e1a6f745d..1f84cdb24779 100644 --- a/trunk/arch/i386/mach-visws/setup.c +++ b/trunk/arch/i386/mach-visws/setup.c @@ -140,8 +140,8 @@ void __init time_init_hook(void) #define MB (1024 * 1024) -static unsigned long sgivwfb_mem_phys; -static unsigned long sgivwfb_mem_size; +unsigned long sgivwfb_mem_phys; +unsigned long sgivwfb_mem_size; long long mem_size __initdata = 0; @@ -177,8 +177,4 @@ char * __init machine_specific_memory_setup(void) add_memory_region(sgivwfb_mem_phys, sgivwfb_mem_size, E820_RESERVED); return "PROM"; - - /* Remove gcc warnings */ - (void) sanitize_e820_map(NULL, NULL); - (void) copy_e820_map(NULL, 0); } diff --git a/trunk/arch/i386/mach-visws/visws_apic.c b/trunk/arch/i386/mach-visws/visws_apic.c index 3e64fb721291..c418521dd554 100644 --- a/trunk/arch/i386/mach-visws/visws_apic.c +++ b/trunk/arch/i386/mach-visws/visws_apic.c @@ -278,22 +278,22 @@ void init_VISWS_APIC_irqs(void) irq_desc[i].depth = 1; if (i == 0) { - irq_desc[i].handler = &cobalt_irq_type; + irq_desc[i].chip = &cobalt_irq_type; } else if (i == CO_IRQ_IDE0) { - irq_desc[i].handler = &cobalt_irq_type; + irq_desc[i].chip = &cobalt_irq_type; } else if (i == CO_IRQ_IDE1) { - irq_desc[i].handler = &cobalt_irq_type; + irq_desc[i].chip = &cobalt_irq_type; } else if (i == CO_IRQ_8259) { - irq_desc[i].handler = &piix4_master_irq_type; + irq_desc[i].chip = &piix4_master_irq_type; } else if (i < CO_IRQ_APIC0) { - irq_desc[i].handler = &piix4_virtual_irq_type; + irq_desc[i].chip = &piix4_virtual_irq_type; } else if (IS_CO_APIC(i)) { - irq_desc[i].handler = &cobalt_irq_type; + irq_desc[i].chip = &cobalt_irq_type; } } diff --git a/trunk/arch/i386/mach-voyager/voyager_smp.c b/trunk/arch/i386/mach-voyager/voyager_smp.c index 8242af9ebc6f..5b8b579a079f 100644 --- a/trunk/arch/i386/mach-voyager/voyager_smp.c +++ b/trunk/arch/i386/mach-voyager/voyager_smp.c @@ -1419,7 +1419,7 @@ smp_intr_init(void) * This is for later: first 16 correspond to PC IRQs; next 16 * are Primary MC IRQs and final 16 are Secondary MC IRQs */ for(i = 0; i < 48; i++) - irq_desc[i].handler = &vic_irq_type; + irq_desc[i].chip = &vic_irq_type; } /* send a CPI at level cpi to a set of cpus in cpuset (set 1 bit per diff --git a/trunk/arch/i386/pci/i386.c b/trunk/arch/i386/pci/i386.c index a151f7a99f5e..10154a2cac68 100644 --- a/trunk/arch/i386/pci/i386.c +++ b/trunk/arch/i386/pci/i386.c @@ -48,10 +48,10 @@ */ void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; + resource_size_t start = res->start; if (start & 0x300) { start = (start + 0x3ff) & ~0x3ff; diff --git a/trunk/arch/ia64/Kconfig b/trunk/arch/ia64/Kconfig index a56df7bf022d..b487e227a1f7 100644 --- a/trunk/arch/ia64/Kconfig +++ b/trunk/arch/ia64/Kconfig @@ -271,6 +271,9 @@ config HOTPLUG_CPU can be controlled through /sys/devices/system/cpu/cpu#. Say N if you want to disable CPU hotplug. +config ARCH_ENABLE_MEMORY_HOTPLUG + def_bool y + config SCHED_SMT bool "SMT scheduler support" depends on SMP @@ -489,6 +492,10 @@ config GENERIC_PENDING_IRQ depends on GENERIC_HARDIRQS && SMP default y +config IRQ_PER_CPU + bool + default y + source "arch/ia64/hp/sim/Kconfig" menu "Instrumentation Support" diff --git a/trunk/arch/ia64/configs/tiger_defconfig b/trunk/arch/ia64/configs/tiger_defconfig index 766bf4955432..9d1cffb57cde 100644 --- a/trunk/arch/ia64/configs/tiger_defconfig +++ b/trunk/arch/ia64/configs/tiger_defconfig @@ -114,7 +114,7 @@ CONFIG_IA64_CYCLONE=y CONFIG_IOSAPIC=y CONFIG_FORCE_MAX_ZONEORDER=17 CONFIG_SMP=y -CONFIG_NR_CPUS=4 +CONFIG_NR_CPUS=16 CONFIG_HOTPLUG_CPU=y CONFIG_PERMIT_BSP_REMOVE=y CONFIG_FORCE_CPEI_RETARGET=y diff --git a/trunk/arch/ia64/hp/sim/hpsim_irq.c b/trunk/arch/ia64/hp/sim/hpsim_irq.c index c0d25a2a3e9c..8145547bb52d 100644 --- a/trunk/arch/ia64/hp/sim/hpsim_irq.c +++ b/trunk/arch/ia64/hp/sim/hpsim_irq.c @@ -44,8 +44,8 @@ hpsim_irq_init (void) int i; for (i = 0; i < NR_IRQS; ++i) { - idesc = irq_descp(i); - if (idesc->handler == &no_irq_type) - idesc->handler = &irq_type_hp_sim; + idesc = irq_desc + i; + if (idesc->chip == &no_irq_type) + idesc->chip = &irq_type_hp_sim; } } diff --git a/trunk/arch/ia64/kernel/iosapic.c b/trunk/arch/ia64/kernel/iosapic.c index d58c1c5c903a..efc7df4b0fd2 100644 --- a/trunk/arch/ia64/kernel/iosapic.c +++ b/trunk/arch/ia64/kernel/iosapic.c @@ -456,7 +456,7 @@ iosapic_startup_edge_irq (unsigned int irq) static void iosapic_ack_edge_irq (unsigned int irq) { - irq_desc_t *idesc = irq_descp(irq); + irq_desc_t *idesc = irq_desc + irq; move_native_irq(irq); /* @@ -659,14 +659,14 @@ register_intr (unsigned int gsi, int vector, unsigned char delivery, else irq_type = &irq_type_iosapic_level; - idesc = irq_descp(vector); - if (idesc->handler != irq_type) { - if (idesc->handler != &no_irq_type) + idesc = irq_desc + vector; + if (idesc->chip != irq_type) { + if (idesc->chip != &no_irq_type) printk(KERN_WARNING "%s: changing vector %d from %s to %s\n", __FUNCTION__, vector, - idesc->handler->typename, irq_type->typename); - idesc->handler = irq_type; + idesc->chip->typename, irq_type->typename); + idesc->chip = irq_type; } return 0; } @@ -793,14 +793,14 @@ iosapic_register_intr (unsigned int gsi, return -ENOSPC; } - spin_lock_irqsave(&irq_descp(vector)->lock, flags); + spin_lock_irqsave(&irq_desc[vector].lock, flags); spin_lock(&iosapic_lock); { if (gsi_to_vector(gsi) > 0) { if (list_empty(&iosapic_intr_info[vector].rtes)) free_irq_vector(vector); spin_unlock(&iosapic_lock); - spin_unlock_irqrestore(&irq_descp(vector)->lock, + spin_unlock_irqrestore(&irq_desc[vector].lock, flags); goto again; } @@ -810,7 +810,7 @@ iosapic_register_intr (unsigned int gsi, polarity, trigger); if (err < 0) { spin_unlock(&iosapic_lock); - spin_unlock_irqrestore(&irq_descp(vector)->lock, + spin_unlock_irqrestore(&irq_desc[vector].lock, flags); return err; } @@ -825,7 +825,7 @@ iosapic_register_intr (unsigned int gsi, set_rte(gsi, vector, dest, mask); } spin_unlock(&iosapic_lock); - spin_unlock_irqrestore(&irq_descp(vector)->lock, flags); + spin_unlock_irqrestore(&irq_desc[vector].lock, flags); printk(KERN_INFO "GSI %u (%s, %s) -> CPU %d (0x%04x) vector %d\n", gsi, (trigger == IOSAPIC_EDGE ? "edge" : "level"), @@ -860,7 +860,7 @@ iosapic_unregister_intr (unsigned int gsi) } vector = irq_to_vector(irq); - idesc = irq_descp(irq); + idesc = irq_desc + irq; spin_lock_irqsave(&idesc->lock, flags); spin_lock(&iosapic_lock); { @@ -903,7 +903,7 @@ iosapic_unregister_intr (unsigned int gsi) BUG_ON(iosapic_intr_info[vector].count); /* Clear the interrupt controller descriptor */ - idesc->handler = &no_irq_type; + idesc->chip = &no_irq_type; /* Clear the interrupt information */ memset(&iosapic_intr_info[vector], 0, diff --git a/trunk/arch/ia64/kernel/irq.c b/trunk/arch/ia64/kernel/irq.c index 9c72ea3f6432..7852382de2fa 100644 --- a/trunk/arch/ia64/kernel/irq.c +++ b/trunk/arch/ia64/kernel/irq.c @@ -76,7 +76,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); } #endif - seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %14s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -100,7 +100,7 @@ void set_irq_affinity_info (unsigned int irq, int hwid, int redir) cpu_set(cpu_logical_id(hwid), mask); if (irq < NR_IRQS) { - irq_affinity[irq] = mask; + irq_desc[irq].affinity = mask; irq_redir[irq] = (char) (redir & 0xff); } } @@ -120,7 +120,7 @@ static void migrate_irqs(void) int irq, new_cpu; for (irq=0; irq < NR_IRQS; irq++) { - desc = irq_descp(irq); + desc = irq_desc + irq; /* * No handling for now. @@ -131,7 +131,7 @@ static void migrate_irqs(void) if (desc->status == IRQ_PER_CPU) continue; - cpus_and(mask, irq_affinity[irq], cpu_online_map); + cpus_and(mask, irq_desc[irq].affinity, cpu_online_map); if (any_online_cpu(mask) == NR_CPUS) { /* * Save it for phase 2 processing @@ -144,15 +144,15 @@ static void migrate_irqs(void) /* * Al three are essential, currently WARN_ON.. maybe panic? */ - if (desc->handler && desc->handler->disable && - desc->handler->enable && desc->handler->set_affinity) { - desc->handler->disable(irq); - desc->handler->set_affinity(irq, mask); - desc->handler->enable(irq); + if (desc->chip && desc->chip->disable && + desc->chip->enable && desc->chip->set_affinity) { + desc->chip->disable(irq); + desc->chip->set_affinity(irq, mask); + desc->chip->enable(irq); } else { - WARN_ON((!(desc->handler) || !(desc->handler->disable) || - !(desc->handler->enable) || - !(desc->handler->set_affinity))); + WARN_ON((!(desc->chip) || !(desc->chip->disable) || + !(desc->chip->enable) || + !(desc->chip->set_affinity))); } } } diff --git a/trunk/arch/ia64/kernel/irq_ia64.c b/trunk/arch/ia64/kernel/irq_ia64.c index ef9a2b49307a..f5035304594e 100644 --- a/trunk/arch/ia64/kernel/irq_ia64.c +++ b/trunk/arch/ia64/kernel/irq_ia64.c @@ -249,9 +249,9 @@ register_percpu_irq (ia64_vector vec, struct irqaction *action) for (irq = 0; irq < NR_IRQS; ++irq) if (irq_to_vector(irq) == vec) { - desc = irq_descp(irq); + desc = irq_desc + irq; desc->status |= IRQ_PER_CPU; - desc->handler = &irq_type_ia64_lsapic; + desc->chip = &irq_type_ia64_lsapic; if (action) setup_irq(irq, action); } diff --git a/trunk/arch/ia64/kernel/irq_lsapic.c b/trunk/arch/ia64/kernel/irq_lsapic.c index ea14e6a04409..1ab58b09f3d7 100644 --- a/trunk/arch/ia64/kernel/irq_lsapic.c +++ b/trunk/arch/ia64/kernel/irq_lsapic.c @@ -26,6 +26,13 @@ lsapic_noop (unsigned int irq) /* nuthing to do... */ } +static int lsapic_retrigger(unsigned int irq) +{ + ia64_resend_irq(irq); + + return 1; +} + struct hw_interrupt_type irq_type_ia64_lsapic = { .typename = "LSAPIC", .startup = lsapic_noop_startup, @@ -33,5 +40,6 @@ struct hw_interrupt_type irq_type_ia64_lsapic = { .enable = lsapic_noop, .disable = lsapic_noop, .ack = lsapic_noop, - .end = lsapic_noop + .end = lsapic_noop, + .retrigger = lsapic_retrigger, }; diff --git a/trunk/arch/ia64/kernel/mca.c b/trunk/arch/ia64/kernel/mca.c index 6a0880639bc9..d7dc5e63de63 100644 --- a/trunk/arch/ia64/kernel/mca.c +++ b/trunk/arch/ia64/kernel/mca.c @@ -1788,7 +1788,7 @@ ia64_mca_late_init(void) cpe_poll_enabled = 0; for (irq = 0; irq < NR_IRQS; ++irq) if (irq_to_vector(irq) == cpe_vector) { - desc = irq_descp(irq); + desc = irq_desc + irq; desc->status |= IRQ_PER_CPU; setup_irq(irq, &mca_cpe_irqaction); ia64_cpe_irq = irq; diff --git a/trunk/arch/ia64/kernel/palinfo.c b/trunk/arch/ia64/kernel/palinfo.c index 303a9afcf2a1..8a1208419138 100644 --- a/trunk/arch/ia64/kernel/palinfo.c +++ b/trunk/arch/ia64/kernel/palinfo.c @@ -998,7 +998,7 @@ palinfo_init(void) } /* Register for future delivery via notify registration */ - register_cpu_notifier(&palinfo_cpu_notifier); + register_hotcpu_notifier(&palinfo_cpu_notifier); return 0; } diff --git a/trunk/arch/ia64/kernel/perfmon.c b/trunk/arch/ia64/kernel/perfmon.c index 6d7bc8ff7b3a..a0055d3d695c 100644 --- a/trunk/arch/ia64/kernel/perfmon.c +++ b/trunk/arch/ia64/kernel/perfmon.c @@ -6165,7 +6165,7 @@ pfm_load_regs (struct task_struct *task) /* * will replay the PMU interrupt */ - if (need_irq_resend) hw_resend_irq(NULL, IA64_PERFMON_VECTOR); + if (need_irq_resend) ia64_resend_irq(IA64_PERFMON_VECTOR); pfm_stats[smp_processor_id()].pfm_replay_ovfl_intr_count++; } @@ -6305,7 +6305,7 @@ pfm_load_regs (struct task_struct *task) /* * will replay the PMU interrupt */ - if (need_irq_resend) hw_resend_irq(NULL, IA64_PERFMON_VECTOR); + if (need_irq_resend) ia64_resend_irq(IA64_PERFMON_VECTOR); pfm_stats[smp_processor_id()].pfm_replay_ovfl_intr_count++; } diff --git a/trunk/arch/ia64/kernel/smpboot.c b/trunk/arch/ia64/kernel/smpboot.c index 44e9547878ac..5203df78f150 100644 --- a/trunk/arch/ia64/kernel/smpboot.c +++ b/trunk/arch/ia64/kernel/smpboot.c @@ -677,16 +677,16 @@ int migrate_platform_irqs(unsigned int cpu) new_cpei_cpu = any_online_cpu(cpu_online_map); mask = cpumask_of_cpu(new_cpei_cpu); set_cpei_target_cpu(new_cpei_cpu); - desc = irq_descp(ia64_cpe_irq); + desc = irq_desc + ia64_cpe_irq; /* * Switch for now, immediatly, we need to do fake intr * as other interrupts, but need to study CPEI behaviour with * polling before making changes. */ if (desc) { - desc->handler->disable(ia64_cpe_irq); - desc->handler->set_affinity(ia64_cpe_irq, mask); - desc->handler->enable(ia64_cpe_irq); + desc->chip->disable(ia64_cpe_irq); + desc->chip->set_affinity(ia64_cpe_irq, mask); + desc->chip->enable(ia64_cpe_irq); printk ("Re-targetting CPEI to cpu %d\n", new_cpei_cpu); } } diff --git a/trunk/arch/ia64/pci/pci.c b/trunk/arch/ia64/pci/pci.c index 77375a55da31..5bef0e3603f2 100644 --- a/trunk/arch/ia64/pci/pci.c +++ b/trunk/arch/ia64/pci/pci.c @@ -568,7 +568,7 @@ pcibios_disable_device (struct pci_dev *dev) void pcibios_align_resource (void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { } diff --git a/trunk/arch/ia64/sn/kernel/irq.c b/trunk/arch/ia64/sn/kernel/irq.c index 677c6c0fd661..7bb6ad188ba3 100644 --- a/trunk/arch/ia64/sn/kernel/irq.c +++ b/trunk/arch/ia64/sn/kernel/irq.c @@ -225,8 +225,8 @@ void sn_irq_init(void) ia64_last_device_vector = IA64_SN2_LAST_DEVICE_VECTOR; for (i = 0; i < NR_IRQS; i++) { - if (base_desc[i].handler == &no_irq_type) { - base_desc[i].handler = &irq_type_sn; + if (base_desc[i].chip == &no_irq_type) { + base_desc[i].chip = &irq_type_sn; } } } diff --git a/trunk/arch/ia64/sn/kernel/setup.c b/trunk/arch/ia64/sn/kernel/setup.c index 93577abae36d..3bfccf354343 100644 --- a/trunk/arch/ia64/sn/kernel/setup.c +++ b/trunk/arch/ia64/sn/kernel/setup.c @@ -458,7 +458,7 @@ void __init sn_setup(char **cmdline_p) * support here so we don't have to listen to failed keyboard probe * messages. */ - if (version <= 0x0209 && acpi_kbd_controller_present) { + if (is_shub1() && version <= 0x0209 && acpi_kbd_controller_present) { printk(KERN_INFO "Disabling legacy keyboard support as prom " "is too old and doesn't provide FADT\n"); acpi_kbd_controller_present = 0; @@ -577,7 +577,8 @@ void __init sn_cpu_init(void) int i; static int wars_have_been_checked; - if (smp_processor_id() == 0 && IS_MEDUSA()) { + cpuid = smp_processor_id(); + if (cpuid == 0 && IS_MEDUSA()) { if (ia64_sn_is_fake_prom()) sn_prom_type = 2; else @@ -596,6 +597,12 @@ void __init sn_cpu_init(void) BUG(); sn_hub_info->as_shift = sn_hub_info->nasid_shift - 2; + /* + * Don't check status. The SAL call is not supported on all PROMs + * but a failure is harmless. + */ + (void) ia64_sn_set_cpu_number(cpuid); + /* * The boot cpu makes this call again after platform initialization is * complete. @@ -607,7 +614,6 @@ void __init sn_cpu_init(void) if (ia64_sn_get_prom_feature_set(i, &sn_prom_features[i]) != 0) break; - cpuid = smp_processor_id(); cpuphyid = get_sapicid(); if (ia64_sn_get_sapic_info(cpuphyid, &nasid, &subnode, &slice)) diff --git a/trunk/arch/ia64/sn/pci/tioca_provider.c b/trunk/arch/ia64/sn/pci/tioca_provider.c index 20de72791b97..e4aa839d0189 100644 --- a/trunk/arch/ia64/sn/pci/tioca_provider.c +++ b/trunk/arch/ia64/sn/pci/tioca_provider.c @@ -595,7 +595,7 @@ tioca_bus_fixup(struct pcibus_bussoft *prom_bussoft, struct pci_controller *cont /* sanity check prom rev */ - if (sn_sal_rev() < 0x0406) { + if (is_shub1() && sn_sal_rev() < 0x0406) { printk (KERN_ERR "%s: SGI prom rev 4.06 or greater required " "for tioca support\n", __FUNCTION__); diff --git a/trunk/arch/m32r/kernel/irq.c b/trunk/arch/m32r/kernel/irq.c index a4634b06f675..3841861df6a2 100644 --- a/trunk/arch/m32r/kernel/irq.c +++ b/trunk/arch/m32r/kernel/irq.c @@ -54,7 +54,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %14s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) diff --git a/trunk/arch/m32r/kernel/setup_m32104ut.c b/trunk/arch/m32r/kernel/setup_m32104ut.c index 6328e1357a80..f9f56c270195 100644 --- a/trunk/arch/m32r/kernel/setup_m32104ut.c +++ b/trunk/arch/m32r/kernel/setup_m32104ut.c @@ -87,7 +87,7 @@ void __init init_IRQ(void) #if defined(CONFIG_SMC91X) /* INT#0: LAN controller on M32104UT-LAN (SMC91C111)*/ irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT0].handler = &m32104ut_irq_type; + irq_desc[M32R_IRQ_INT0].chip = &m32104ut_irq_type; irq_desc[M32R_IRQ_INT0].action = 0; irq_desc[M32R_IRQ_INT0].depth = 1; icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD11; /* "H" level sense */ @@ -96,7 +96,7 @@ void __init init_IRQ(void) /* MFT2 : system timer */ irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_MFT2].handler = &m32104ut_irq_type; + irq_desc[M32R_IRQ_MFT2].chip = &m32104ut_irq_type; irq_desc[M32R_IRQ_MFT2].action = 0; irq_desc[M32R_IRQ_MFT2].depth = 1; icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; @@ -105,7 +105,7 @@ void __init init_IRQ(void) #ifdef CONFIG_SERIAL_M32R_SIO /* SIO0_R : uart receive data */ irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_R].handler = &m32104ut_irq_type; + irq_desc[M32R_IRQ_SIO0_R].chip = &m32104ut_irq_type; irq_desc[M32R_IRQ_SIO0_R].action = 0; irq_desc[M32R_IRQ_SIO0_R].depth = 1; icu_data[M32R_IRQ_SIO0_R].icucr = M32R_ICUCR_IEN; @@ -113,7 +113,7 @@ void __init init_IRQ(void) /* SIO0_S : uart send data */ irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_S].handler = &m32104ut_irq_type; + irq_desc[M32R_IRQ_SIO0_S].chip = &m32104ut_irq_type; irq_desc[M32R_IRQ_SIO0_S].action = 0; irq_desc[M32R_IRQ_SIO0_S].depth = 1; icu_data[M32R_IRQ_SIO0_S].icucr = M32R_ICUCR_IEN; diff --git a/trunk/arch/m32r/kernel/setup_m32700ut.c b/trunk/arch/m32r/kernel/setup_m32700ut.c index fad1fc99bb27..b6ab00eff580 100644 --- a/trunk/arch/m32r/kernel/setup_m32700ut.c +++ b/trunk/arch/m32r/kernel/setup_m32700ut.c @@ -301,7 +301,7 @@ void __init init_IRQ(void) #if defined(CONFIG_SMC91X) /* INT#0: LAN controller on M32700UT-LAN (SMC91C111)*/ irq_desc[M32700UT_LAN_IRQ_LAN].status = IRQ_DISABLED; - irq_desc[M32700UT_LAN_IRQ_LAN].handler = &m32700ut_lanpld_irq_type; + irq_desc[M32700UT_LAN_IRQ_LAN].chip = &m32700ut_lanpld_irq_type; irq_desc[M32700UT_LAN_IRQ_LAN].action = 0; irq_desc[M32700UT_LAN_IRQ_LAN].depth = 1; /* disable nested irq */ lanpld_icu_data[irq2lanpldirq(M32700UT_LAN_IRQ_LAN)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* "H" edge sense */ @@ -310,7 +310,7 @@ void __init init_IRQ(void) /* MFT2 : system timer */ irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_MFT2].handler = &m32700ut_irq_type; + irq_desc[M32R_IRQ_MFT2].chip = &m32700ut_irq_type; irq_desc[M32R_IRQ_MFT2].action = 0; irq_desc[M32R_IRQ_MFT2].depth = 1; icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; @@ -318,7 +318,7 @@ void __init init_IRQ(void) /* SIO0 : receive */ irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_R].handler = &m32700ut_irq_type; + irq_desc[M32R_IRQ_SIO0_R].chip = &m32700ut_irq_type; irq_desc[M32R_IRQ_SIO0_R].action = 0; irq_desc[M32R_IRQ_SIO0_R].depth = 1; icu_data[M32R_IRQ_SIO0_R].icucr = 0; @@ -326,7 +326,7 @@ void __init init_IRQ(void) /* SIO0 : send */ irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_S].handler = &m32700ut_irq_type; + irq_desc[M32R_IRQ_SIO0_S].chip = &m32700ut_irq_type; irq_desc[M32R_IRQ_SIO0_S].action = 0; irq_desc[M32R_IRQ_SIO0_S].depth = 1; icu_data[M32R_IRQ_SIO0_S].icucr = 0; @@ -334,7 +334,7 @@ void __init init_IRQ(void) /* SIO1 : receive */ irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_R].handler = &m32700ut_irq_type; + irq_desc[M32R_IRQ_SIO1_R].chip = &m32700ut_irq_type; irq_desc[M32R_IRQ_SIO1_R].action = 0; irq_desc[M32R_IRQ_SIO1_R].depth = 1; icu_data[M32R_IRQ_SIO1_R].icucr = 0; @@ -342,7 +342,7 @@ void __init init_IRQ(void) /* SIO1 : send */ irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_S].handler = &m32700ut_irq_type; + irq_desc[M32R_IRQ_SIO1_S].chip = &m32700ut_irq_type; irq_desc[M32R_IRQ_SIO1_S].action = 0; irq_desc[M32R_IRQ_SIO1_S].depth = 1; icu_data[M32R_IRQ_SIO1_S].icucr = 0; @@ -350,7 +350,7 @@ void __init init_IRQ(void) /* DMA1 : */ irq_desc[M32R_IRQ_DMA1].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_DMA1].handler = &m32700ut_irq_type; + irq_desc[M32R_IRQ_DMA1].chip = &m32700ut_irq_type; irq_desc[M32R_IRQ_DMA1].action = 0; irq_desc[M32R_IRQ_DMA1].depth = 1; icu_data[M32R_IRQ_DMA1].icucr = 0; @@ -359,7 +359,7 @@ void __init init_IRQ(void) #ifdef CONFIG_SERIAL_M32R_PLDSIO /* INT#1: SIO0 Receive on PLD */ irq_desc[PLD_IRQ_SIO0_RCV].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_SIO0_RCV].handler = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_SIO0_RCV].chip = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_SIO0_RCV].action = 0; irq_desc[PLD_IRQ_SIO0_RCV].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_RCV)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; @@ -367,7 +367,7 @@ void __init init_IRQ(void) /* INT#1: SIO0 Send on PLD */ irq_desc[PLD_IRQ_SIO0_SND].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_SIO0_SND].handler = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_SIO0_SND].chip = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_SIO0_SND].action = 0; irq_desc[PLD_IRQ_SIO0_SND].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_SND)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; @@ -376,7 +376,7 @@ void __init init_IRQ(void) /* INT#1: CFC IREQ on PLD */ irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFIREQ].handler = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_CFIREQ].chip = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_CFIREQ].action = 0; irq_desc[PLD_IRQ_CFIREQ].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_CFIREQ)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* 'L' level sense */ @@ -384,7 +384,7 @@ void __init init_IRQ(void) /* INT#1: CFC Insert on PLD */ irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFC_INSERT].handler = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_CFC_INSERT].chip = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_CFC_INSERT].action = 0; irq_desc[PLD_IRQ_CFC_INSERT].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_CFC_INSERT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD00; /* 'L' edge sense */ @@ -392,7 +392,7 @@ void __init init_IRQ(void) /* INT#1: CFC Eject on PLD */ irq_desc[PLD_IRQ_CFC_EJECT].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFC_EJECT].handler = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_CFC_EJECT].chip = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_CFC_EJECT].action = 0; irq_desc[PLD_IRQ_CFC_EJECT].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_CFC_EJECT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* 'H' edge sense */ @@ -416,7 +416,7 @@ void __init init_IRQ(void) outw(USBCR_OTGS, USBCR); /* USBCR: non-OTG */ irq_desc[M32700UT_LCD_IRQ_USB_INT1].status = IRQ_DISABLED; - irq_desc[M32700UT_LCD_IRQ_USB_INT1].handler = &m32700ut_lcdpld_irq_type; + irq_desc[M32700UT_LCD_IRQ_USB_INT1].chip = &m32700ut_lcdpld_irq_type; irq_desc[M32700UT_LCD_IRQ_USB_INT1].action = 0; irq_desc[M32700UT_LCD_IRQ_USB_INT1].depth = 1; lcdpld_icu_data[irq2lcdpldirq(M32700UT_LCD_IRQ_USB_INT1)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* "L" level sense */ @@ -434,7 +434,7 @@ void __init init_IRQ(void) * INT3# is used for AR */ irq_desc[M32R_IRQ_INT3].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT3].handler = &m32700ut_irq_type; + irq_desc[M32R_IRQ_INT3].chip = &m32700ut_irq_type; irq_desc[M32R_IRQ_INT3].action = 0; irq_desc[M32R_IRQ_INT3].depth = 1; icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; diff --git a/trunk/arch/m32r/kernel/setup_mappi.c b/trunk/arch/m32r/kernel/setup_mappi.c index 00f253209cb3..c268044185f5 100644 --- a/trunk/arch/m32r/kernel/setup_mappi.c +++ b/trunk/arch/m32r/kernel/setup_mappi.c @@ -86,7 +86,7 @@ void __init init_IRQ(void) #ifdef CONFIG_NE2000 /* INT0 : LAN controller (RTL8019AS) */ irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT0].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_INT0].chip = &mappi_irq_type; irq_desc[M32R_IRQ_INT0].action = 0; irq_desc[M32R_IRQ_INT0].depth = 1; icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; @@ -95,7 +95,7 @@ void __init init_IRQ(void) /* MFT2 : system timer */ irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_MFT2].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_MFT2].chip = &mappi_irq_type; irq_desc[M32R_IRQ_MFT2].action = 0; irq_desc[M32R_IRQ_MFT2].depth = 1; icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; @@ -104,7 +104,7 @@ void __init init_IRQ(void) #ifdef CONFIG_SERIAL_M32R_SIO /* SIO0_R : uart receive data */ irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_R].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_SIO0_R].chip = &mappi_irq_type; irq_desc[M32R_IRQ_SIO0_R].action = 0; irq_desc[M32R_IRQ_SIO0_R].depth = 1; icu_data[M32R_IRQ_SIO0_R].icucr = 0; @@ -112,7 +112,7 @@ void __init init_IRQ(void) /* SIO0_S : uart send data */ irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_S].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_SIO0_S].chip = &mappi_irq_type; irq_desc[M32R_IRQ_SIO0_S].action = 0; irq_desc[M32R_IRQ_SIO0_S].depth = 1; icu_data[M32R_IRQ_SIO0_S].icucr = 0; @@ -120,7 +120,7 @@ void __init init_IRQ(void) /* SIO1_R : uart receive data */ irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_R].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_SIO1_R].chip = &mappi_irq_type; irq_desc[M32R_IRQ_SIO1_R].action = 0; irq_desc[M32R_IRQ_SIO1_R].depth = 1; icu_data[M32R_IRQ_SIO1_R].icucr = 0; @@ -128,7 +128,7 @@ void __init init_IRQ(void) /* SIO1_S : uart send data */ irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_S].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_SIO1_S].chip = &mappi_irq_type; irq_desc[M32R_IRQ_SIO1_S].action = 0; irq_desc[M32R_IRQ_SIO1_S].depth = 1; icu_data[M32R_IRQ_SIO1_S].icucr = 0; @@ -138,7 +138,7 @@ void __init init_IRQ(void) #if defined(CONFIG_M32R_PCC) /* INT1 : pccard0 interrupt */ irq_desc[M32R_IRQ_INT1].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT1].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_INT1].chip = &mappi_irq_type; irq_desc[M32R_IRQ_INT1].action = 0; irq_desc[M32R_IRQ_INT1].depth = 1; icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD00; @@ -146,7 +146,7 @@ void __init init_IRQ(void) /* INT2 : pccard1 interrupt */ irq_desc[M32R_IRQ_INT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT2].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_INT2].chip = &mappi_irq_type; irq_desc[M32R_IRQ_INT2].action = 0; irq_desc[M32R_IRQ_INT2].depth = 1; icu_data[M32R_IRQ_INT2].icucr = M32R_ICUCR_IEN | M32R_ICUCR_ISMOD00; diff --git a/trunk/arch/m32r/kernel/setup_mappi2.c b/trunk/arch/m32r/kernel/setup_mappi2.c index eebc9d8b4e72..bd2327d5cca2 100644 --- a/trunk/arch/m32r/kernel/setup_mappi2.c +++ b/trunk/arch/m32r/kernel/setup_mappi2.c @@ -87,7 +87,7 @@ void __init init_IRQ(void) #if defined(CONFIG_SMC91X) /* INT0 : LAN controller (SMC91111) */ irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT0].handler = &mappi2_irq_type; + irq_desc[M32R_IRQ_INT0].chip = &mappi2_irq_type; irq_desc[M32R_IRQ_INT0].action = 0; irq_desc[M32R_IRQ_INT0].depth = 1; icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; @@ -96,7 +96,7 @@ void __init init_IRQ(void) /* MFT2 : system timer */ irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_MFT2].handler = &mappi2_irq_type; + irq_desc[M32R_IRQ_MFT2].chip = &mappi2_irq_type; irq_desc[M32R_IRQ_MFT2].action = 0; irq_desc[M32R_IRQ_MFT2].depth = 1; icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; @@ -105,7 +105,7 @@ void __init init_IRQ(void) #ifdef CONFIG_SERIAL_M32R_SIO /* SIO0_R : uart receive data */ irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_R].handler = &mappi2_irq_type; + irq_desc[M32R_IRQ_SIO0_R].chip = &mappi2_irq_type; irq_desc[M32R_IRQ_SIO0_R].action = 0; irq_desc[M32R_IRQ_SIO0_R].depth = 1; icu_data[M32R_IRQ_SIO0_R].icucr = 0; @@ -113,14 +113,14 @@ void __init init_IRQ(void) /* SIO0_S : uart send data */ irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_S].handler = &mappi2_irq_type; + irq_desc[M32R_IRQ_SIO0_S].chip = &mappi2_irq_type; irq_desc[M32R_IRQ_SIO0_S].action = 0; irq_desc[M32R_IRQ_SIO0_S].depth = 1; icu_data[M32R_IRQ_SIO0_S].icucr = 0; disable_mappi2_irq(M32R_IRQ_SIO0_S); /* SIO1_R : uart receive data */ irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_R].handler = &mappi2_irq_type; + irq_desc[M32R_IRQ_SIO1_R].chip = &mappi2_irq_type; irq_desc[M32R_IRQ_SIO1_R].action = 0; irq_desc[M32R_IRQ_SIO1_R].depth = 1; icu_data[M32R_IRQ_SIO1_R].icucr = 0; @@ -128,7 +128,7 @@ void __init init_IRQ(void) /* SIO1_S : uart send data */ irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_S].handler = &mappi2_irq_type; + irq_desc[M32R_IRQ_SIO1_S].chip = &mappi2_irq_type; irq_desc[M32R_IRQ_SIO1_S].action = 0; irq_desc[M32R_IRQ_SIO1_S].depth = 1; icu_data[M32R_IRQ_SIO1_S].icucr = 0; @@ -138,7 +138,7 @@ void __init init_IRQ(void) #if defined(CONFIG_USB) /* INT1 : USB Host controller interrupt */ irq_desc[M32R_IRQ_INT1].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT1].handler = &mappi2_irq_type; + irq_desc[M32R_IRQ_INT1].chip = &mappi2_irq_type; irq_desc[M32R_IRQ_INT1].action = 0; irq_desc[M32R_IRQ_INT1].depth = 1; icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_ISMOD01; @@ -147,7 +147,7 @@ void __init init_IRQ(void) /* ICUCR40: CFC IREQ */ irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFIREQ].handler = &mappi2_irq_type; + irq_desc[PLD_IRQ_CFIREQ].chip = &mappi2_irq_type; irq_desc[PLD_IRQ_CFIREQ].action = 0; irq_desc[PLD_IRQ_CFIREQ].depth = 1; /* disable nested irq */ icu_data[PLD_IRQ_CFIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01; @@ -156,7 +156,7 @@ void __init init_IRQ(void) #if defined(CONFIG_M32R_CFC) /* ICUCR41: CFC Insert */ irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFC_INSERT].handler = &mappi2_irq_type; + irq_desc[PLD_IRQ_CFC_INSERT].chip = &mappi2_irq_type; irq_desc[PLD_IRQ_CFC_INSERT].action = 0; irq_desc[PLD_IRQ_CFC_INSERT].depth = 1; /* disable nested irq */ icu_data[PLD_IRQ_CFC_INSERT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD00; @@ -164,7 +164,7 @@ void __init init_IRQ(void) /* ICUCR42: CFC Eject */ irq_desc[PLD_IRQ_CFC_EJECT].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFC_EJECT].handler = &mappi2_irq_type; + irq_desc[PLD_IRQ_CFC_EJECT].chip = &mappi2_irq_type; irq_desc[PLD_IRQ_CFC_EJECT].action = 0; irq_desc[PLD_IRQ_CFC_EJECT].depth = 1; /* disable nested irq */ icu_data[PLD_IRQ_CFC_EJECT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; diff --git a/trunk/arch/m32r/kernel/setup_mappi3.c b/trunk/arch/m32r/kernel/setup_mappi3.c index d2ff021e2d3d..014b51d17505 100644 --- a/trunk/arch/m32r/kernel/setup_mappi3.c +++ b/trunk/arch/m32r/kernel/setup_mappi3.c @@ -87,7 +87,7 @@ void __init init_IRQ(void) #if defined(CONFIG_SMC91X) /* INT0 : LAN controller (SMC91111) */ irq_desc[M32R_IRQ_INT0].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT0].handler = &mappi3_irq_type; + irq_desc[M32R_IRQ_INT0].chip = &mappi3_irq_type; irq_desc[M32R_IRQ_INT0].action = 0; irq_desc[M32R_IRQ_INT0].depth = 1; icu_data[M32R_IRQ_INT0].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; @@ -96,7 +96,7 @@ void __init init_IRQ(void) /* MFT2 : system timer */ irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_MFT2].handler = &mappi3_irq_type; + irq_desc[M32R_IRQ_MFT2].chip = &mappi3_irq_type; irq_desc[M32R_IRQ_MFT2].action = 0; irq_desc[M32R_IRQ_MFT2].depth = 1; icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; @@ -105,7 +105,7 @@ void __init init_IRQ(void) #ifdef CONFIG_SERIAL_M32R_SIO /* SIO0_R : uart receive data */ irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_R].handler = &mappi3_irq_type; + irq_desc[M32R_IRQ_SIO0_R].chip = &mappi3_irq_type; irq_desc[M32R_IRQ_SIO0_R].action = 0; irq_desc[M32R_IRQ_SIO0_R].depth = 1; icu_data[M32R_IRQ_SIO0_R].icucr = 0; @@ -113,14 +113,14 @@ void __init init_IRQ(void) /* SIO0_S : uart send data */ irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_S].handler = &mappi3_irq_type; + irq_desc[M32R_IRQ_SIO0_S].chip = &mappi3_irq_type; irq_desc[M32R_IRQ_SIO0_S].action = 0; irq_desc[M32R_IRQ_SIO0_S].depth = 1; icu_data[M32R_IRQ_SIO0_S].icucr = 0; disable_mappi3_irq(M32R_IRQ_SIO0_S); /* SIO1_R : uart receive data */ irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_R].handler = &mappi3_irq_type; + irq_desc[M32R_IRQ_SIO1_R].chip = &mappi3_irq_type; irq_desc[M32R_IRQ_SIO1_R].action = 0; irq_desc[M32R_IRQ_SIO1_R].depth = 1; icu_data[M32R_IRQ_SIO1_R].icucr = 0; @@ -128,7 +128,7 @@ void __init init_IRQ(void) /* SIO1_S : uart send data */ irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_S].handler = &mappi3_irq_type; + irq_desc[M32R_IRQ_SIO1_S].chip = &mappi3_irq_type; irq_desc[M32R_IRQ_SIO1_S].action = 0; irq_desc[M32R_IRQ_SIO1_S].depth = 1; icu_data[M32R_IRQ_SIO1_S].icucr = 0; @@ -138,7 +138,7 @@ void __init init_IRQ(void) #if defined(CONFIG_USB) /* INT1 : USB Host controller interrupt */ irq_desc[M32R_IRQ_INT1].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT1].handler = &mappi3_irq_type; + irq_desc[M32R_IRQ_INT1].chip = &mappi3_irq_type; irq_desc[M32R_IRQ_INT1].action = 0; irq_desc[M32R_IRQ_INT1].depth = 1; icu_data[M32R_IRQ_INT1].icucr = M32R_ICUCR_ISMOD01; @@ -147,7 +147,7 @@ void __init init_IRQ(void) /* CFC IREQ */ irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFIREQ].handler = &mappi3_irq_type; + irq_desc[PLD_IRQ_CFIREQ].chip = &mappi3_irq_type; irq_desc[PLD_IRQ_CFIREQ].action = 0; irq_desc[PLD_IRQ_CFIREQ].depth = 1; /* disable nested irq */ icu_data[PLD_IRQ_CFIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD01; @@ -156,7 +156,7 @@ void __init init_IRQ(void) #if defined(CONFIG_M32R_CFC) /* ICUCR41: CFC Insert & eject */ irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFC_INSERT].handler = &mappi3_irq_type; + irq_desc[PLD_IRQ_CFC_INSERT].chip = &mappi3_irq_type; irq_desc[PLD_IRQ_CFC_INSERT].action = 0; irq_desc[PLD_IRQ_CFC_INSERT].depth = 1; /* disable nested irq */ icu_data[PLD_IRQ_CFC_INSERT].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD00; @@ -166,7 +166,7 @@ void __init init_IRQ(void) /* IDE IREQ */ irq_desc[PLD_IRQ_IDEIREQ].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_IDEIREQ].handler = &mappi3_irq_type; + irq_desc[PLD_IRQ_IDEIREQ].chip = &mappi3_irq_type; irq_desc[PLD_IRQ_IDEIREQ].action = 0; irq_desc[PLD_IRQ_IDEIREQ].depth = 1; /* disable nested irq */ icu_data[PLD_IRQ_IDEIREQ].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; diff --git a/trunk/arch/m32r/kernel/setup_oaks32r.c b/trunk/arch/m32r/kernel/setup_oaks32r.c index 0e9e63538c0f..ea64831aef7a 100644 --- a/trunk/arch/m32r/kernel/setup_oaks32r.c +++ b/trunk/arch/m32r/kernel/setup_oaks32r.c @@ -85,7 +85,7 @@ void __init init_IRQ(void) #ifdef CONFIG_NE2000 /* INT3 : LAN controller (RTL8019AS) */ irq_desc[M32R_IRQ_INT3].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT3].handler = &oaks32r_irq_type; + irq_desc[M32R_IRQ_INT3].chip = &oaks32r_irq_type; irq_desc[M32R_IRQ_INT3].action = 0; irq_desc[M32R_IRQ_INT3].depth = 1; icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; @@ -94,7 +94,7 @@ void __init init_IRQ(void) /* MFT2 : system timer */ irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_MFT2].handler = &oaks32r_irq_type; + irq_desc[M32R_IRQ_MFT2].chip = &oaks32r_irq_type; irq_desc[M32R_IRQ_MFT2].action = 0; irq_desc[M32R_IRQ_MFT2].depth = 1; icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; @@ -103,7 +103,7 @@ void __init init_IRQ(void) #ifdef CONFIG_SERIAL_M32R_SIO /* SIO0_R : uart receive data */ irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_R].handler = &oaks32r_irq_type; + irq_desc[M32R_IRQ_SIO0_R].chip = &oaks32r_irq_type; irq_desc[M32R_IRQ_SIO0_R].action = 0; irq_desc[M32R_IRQ_SIO0_R].depth = 1; icu_data[M32R_IRQ_SIO0_R].icucr = 0; @@ -111,7 +111,7 @@ void __init init_IRQ(void) /* SIO0_S : uart send data */ irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_S].handler = &oaks32r_irq_type; + irq_desc[M32R_IRQ_SIO0_S].chip = &oaks32r_irq_type; irq_desc[M32R_IRQ_SIO0_S].action = 0; irq_desc[M32R_IRQ_SIO0_S].depth = 1; icu_data[M32R_IRQ_SIO0_S].icucr = 0; @@ -119,7 +119,7 @@ void __init init_IRQ(void) /* SIO1_R : uart receive data */ irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_R].handler = &oaks32r_irq_type; + irq_desc[M32R_IRQ_SIO1_R].chip = &oaks32r_irq_type; irq_desc[M32R_IRQ_SIO1_R].action = 0; irq_desc[M32R_IRQ_SIO1_R].depth = 1; icu_data[M32R_IRQ_SIO1_R].icucr = 0; @@ -127,7 +127,7 @@ void __init init_IRQ(void) /* SIO1_S : uart send data */ irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_S].handler = &oaks32r_irq_type; + irq_desc[M32R_IRQ_SIO1_S].chip = &oaks32r_irq_type; irq_desc[M32R_IRQ_SIO1_S].action = 0; irq_desc[M32R_IRQ_SIO1_S].depth = 1; icu_data[M32R_IRQ_SIO1_S].icucr = 0; diff --git a/trunk/arch/m32r/kernel/setup_opsput.c b/trunk/arch/m32r/kernel/setup_opsput.c index 548e8fc7949b..55e8972d455a 100644 --- a/trunk/arch/m32r/kernel/setup_opsput.c +++ b/trunk/arch/m32r/kernel/setup_opsput.c @@ -302,7 +302,7 @@ void __init init_IRQ(void) #if defined(CONFIG_SMC91X) /* INT#0: LAN controller on OPSPUT-LAN (SMC91C111)*/ irq_desc[OPSPUT_LAN_IRQ_LAN].status = IRQ_DISABLED; - irq_desc[OPSPUT_LAN_IRQ_LAN].handler = &opsput_lanpld_irq_type; + irq_desc[OPSPUT_LAN_IRQ_LAN].chip = &opsput_lanpld_irq_type; irq_desc[OPSPUT_LAN_IRQ_LAN].action = 0; irq_desc[OPSPUT_LAN_IRQ_LAN].depth = 1; /* disable nested irq */ lanpld_icu_data[irq2lanpldirq(OPSPUT_LAN_IRQ_LAN)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* "H" edge sense */ @@ -311,7 +311,7 @@ void __init init_IRQ(void) /* MFT2 : system timer */ irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_MFT2].handler = &opsput_irq_type; + irq_desc[M32R_IRQ_MFT2].chip = &opsput_irq_type; irq_desc[M32R_IRQ_MFT2].action = 0; irq_desc[M32R_IRQ_MFT2].depth = 1; icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; @@ -319,7 +319,7 @@ void __init init_IRQ(void) /* SIO0 : receive */ irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_R].handler = &opsput_irq_type; + irq_desc[M32R_IRQ_SIO0_R].chip = &opsput_irq_type; irq_desc[M32R_IRQ_SIO0_R].action = 0; irq_desc[M32R_IRQ_SIO0_R].depth = 1; icu_data[M32R_IRQ_SIO0_R].icucr = 0; @@ -327,7 +327,7 @@ void __init init_IRQ(void) /* SIO0 : send */ irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_S].handler = &opsput_irq_type; + irq_desc[M32R_IRQ_SIO0_S].chip = &opsput_irq_type; irq_desc[M32R_IRQ_SIO0_S].action = 0; irq_desc[M32R_IRQ_SIO0_S].depth = 1; icu_data[M32R_IRQ_SIO0_S].icucr = 0; @@ -335,7 +335,7 @@ void __init init_IRQ(void) /* SIO1 : receive */ irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_R].handler = &opsput_irq_type; + irq_desc[M32R_IRQ_SIO1_R].chip = &opsput_irq_type; irq_desc[M32R_IRQ_SIO1_R].action = 0; irq_desc[M32R_IRQ_SIO1_R].depth = 1; icu_data[M32R_IRQ_SIO1_R].icucr = 0; @@ -343,7 +343,7 @@ void __init init_IRQ(void) /* SIO1 : send */ irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_S].handler = &opsput_irq_type; + irq_desc[M32R_IRQ_SIO1_S].chip = &opsput_irq_type; irq_desc[M32R_IRQ_SIO1_S].action = 0; irq_desc[M32R_IRQ_SIO1_S].depth = 1; icu_data[M32R_IRQ_SIO1_S].icucr = 0; @@ -351,7 +351,7 @@ void __init init_IRQ(void) /* DMA1 : */ irq_desc[M32R_IRQ_DMA1].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_DMA1].handler = &opsput_irq_type; + irq_desc[M32R_IRQ_DMA1].chip = &opsput_irq_type; irq_desc[M32R_IRQ_DMA1].action = 0; irq_desc[M32R_IRQ_DMA1].depth = 1; icu_data[M32R_IRQ_DMA1].icucr = 0; @@ -360,7 +360,7 @@ void __init init_IRQ(void) #ifdef CONFIG_SERIAL_M32R_PLDSIO /* INT#1: SIO0 Receive on PLD */ irq_desc[PLD_IRQ_SIO0_RCV].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_SIO0_RCV].handler = &opsput_pld_irq_type; + irq_desc[PLD_IRQ_SIO0_RCV].chip = &opsput_pld_irq_type; irq_desc[PLD_IRQ_SIO0_RCV].action = 0; irq_desc[PLD_IRQ_SIO0_RCV].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_RCV)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; @@ -368,7 +368,7 @@ void __init init_IRQ(void) /* INT#1: SIO0 Send on PLD */ irq_desc[PLD_IRQ_SIO0_SND].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_SIO0_SND].handler = &opsput_pld_irq_type; + irq_desc[PLD_IRQ_SIO0_SND].chip = &opsput_pld_irq_type; irq_desc[PLD_IRQ_SIO0_SND].action = 0; irq_desc[PLD_IRQ_SIO0_SND].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_SIO0_SND)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD03; @@ -378,7 +378,7 @@ void __init init_IRQ(void) #if defined(CONFIG_M32R_CFC) /* INT#1: CFC IREQ on PLD */ irq_desc[PLD_IRQ_CFIREQ].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFIREQ].handler = &opsput_pld_irq_type; + irq_desc[PLD_IRQ_CFIREQ].chip = &opsput_pld_irq_type; irq_desc[PLD_IRQ_CFIREQ].action = 0; irq_desc[PLD_IRQ_CFIREQ].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_CFIREQ)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* 'L' level sense */ @@ -386,7 +386,7 @@ void __init init_IRQ(void) /* INT#1: CFC Insert on PLD */ irq_desc[PLD_IRQ_CFC_INSERT].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFC_INSERT].handler = &opsput_pld_irq_type; + irq_desc[PLD_IRQ_CFC_INSERT].chip = &opsput_pld_irq_type; irq_desc[PLD_IRQ_CFC_INSERT].action = 0; irq_desc[PLD_IRQ_CFC_INSERT].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_CFC_INSERT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD00; /* 'L' edge sense */ @@ -394,7 +394,7 @@ void __init init_IRQ(void) /* INT#1: CFC Eject on PLD */ irq_desc[PLD_IRQ_CFC_EJECT].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CFC_EJECT].handler = &opsput_pld_irq_type; + irq_desc[PLD_IRQ_CFC_EJECT].chip = &opsput_pld_irq_type; irq_desc[PLD_IRQ_CFC_EJECT].action = 0; irq_desc[PLD_IRQ_CFC_EJECT].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_CFC_EJECT)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD02; /* 'H' edge sense */ @@ -420,7 +420,7 @@ void __init init_IRQ(void) outw(USBCR_OTGS, USBCR); /* USBCR: non-OTG */ irq_desc[OPSPUT_LCD_IRQ_USB_INT1].status = IRQ_DISABLED; - irq_desc[OPSPUT_LCD_IRQ_USB_INT1].handler = &opsput_lcdpld_irq_type; + irq_desc[OPSPUT_LCD_IRQ_USB_INT1].chip = &opsput_lcdpld_irq_type; irq_desc[OPSPUT_LCD_IRQ_USB_INT1].action = 0; irq_desc[OPSPUT_LCD_IRQ_USB_INT1].depth = 1; lcdpld_icu_data[irq2lcdpldirq(OPSPUT_LCD_IRQ_USB_INT1)].icucr = PLD_ICUCR_IEN|PLD_ICUCR_ISMOD01; /* "L" level sense */ @@ -438,7 +438,7 @@ void __init init_IRQ(void) * INT3# is used for AR */ irq_desc[M32R_IRQ_INT3].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_INT3].handler = &opsput_irq_type; + irq_desc[M32R_IRQ_INT3].chip = &opsput_irq_type; irq_desc[M32R_IRQ_INT3].action = 0; irq_desc[M32R_IRQ_INT3].depth = 1; icu_data[M32R_IRQ_INT3].icucr = M32R_ICUCR_IEN|M32R_ICUCR_ISMOD10; diff --git a/trunk/arch/m32r/kernel/setup_usrv.c b/trunk/arch/m32r/kernel/setup_usrv.c index 64be659a23e7..7fa12d8f66b4 100644 --- a/trunk/arch/m32r/kernel/setup_usrv.c +++ b/trunk/arch/m32r/kernel/setup_usrv.c @@ -158,7 +158,7 @@ void __init init_IRQ(void) /* MFT2 : system timer */ irq_desc[M32R_IRQ_MFT2].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_MFT2].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_MFT2].chip = &mappi_irq_type; irq_desc[M32R_IRQ_MFT2].action = 0; irq_desc[M32R_IRQ_MFT2].depth = 1; icu_data[M32R_IRQ_MFT2].icucr = M32R_ICUCR_IEN; @@ -167,7 +167,7 @@ void __init init_IRQ(void) #if defined(CONFIG_SERIAL_M32R_SIO) /* SIO0_R : uart receive data */ irq_desc[M32R_IRQ_SIO0_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_R].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_SIO0_R].chip = &mappi_irq_type; irq_desc[M32R_IRQ_SIO0_R].action = 0; irq_desc[M32R_IRQ_SIO0_R].depth = 1; icu_data[M32R_IRQ_SIO0_R].icucr = 0; @@ -175,7 +175,7 @@ void __init init_IRQ(void) /* SIO0_S : uart send data */ irq_desc[M32R_IRQ_SIO0_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO0_S].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_SIO0_S].chip = &mappi_irq_type; irq_desc[M32R_IRQ_SIO0_S].action = 0; irq_desc[M32R_IRQ_SIO0_S].depth = 1; icu_data[M32R_IRQ_SIO0_S].icucr = 0; @@ -183,7 +183,7 @@ void __init init_IRQ(void) /* SIO1_R : uart receive data */ irq_desc[M32R_IRQ_SIO1_R].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_R].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_SIO1_R].chip = &mappi_irq_type; irq_desc[M32R_IRQ_SIO1_R].action = 0; irq_desc[M32R_IRQ_SIO1_R].depth = 1; icu_data[M32R_IRQ_SIO1_R].icucr = 0; @@ -191,7 +191,7 @@ void __init init_IRQ(void) /* SIO1_S : uart send data */ irq_desc[M32R_IRQ_SIO1_S].status = IRQ_DISABLED; - irq_desc[M32R_IRQ_SIO1_S].handler = &mappi_irq_type; + irq_desc[M32R_IRQ_SIO1_S].chip = &mappi_irq_type; irq_desc[M32R_IRQ_SIO1_S].action = 0; irq_desc[M32R_IRQ_SIO1_S].depth = 1; icu_data[M32R_IRQ_SIO1_S].icucr = 0; @@ -201,7 +201,7 @@ void __init init_IRQ(void) /* INT#67-#71: CFC#0 IREQ on PLD */ for (i = 0 ; i < CONFIG_CFC_NUM ; i++ ) { irq_desc[PLD_IRQ_CF0 + i].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_CF0 + i].handler = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_CF0 + i].chip = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_CF0 + i].action = 0; irq_desc[PLD_IRQ_CF0 + i].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_CF0 + i)].icucr @@ -212,7 +212,7 @@ void __init init_IRQ(void) #if defined(CONFIG_SERIAL_8250) || defined(CONFIG_SERIAL_8250_MODULE) /* INT#76: 16552D#0 IREQ on PLD */ irq_desc[PLD_IRQ_UART0].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_UART0].handler = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_UART0].chip = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_UART0].action = 0; irq_desc[PLD_IRQ_UART0].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_UART0)].icucr @@ -221,7 +221,7 @@ void __init init_IRQ(void) /* INT#77: 16552D#1 IREQ on PLD */ irq_desc[PLD_IRQ_UART1].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_UART1].handler = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_UART1].chip = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_UART1].action = 0; irq_desc[PLD_IRQ_UART1].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_UART1)].icucr @@ -232,7 +232,7 @@ void __init init_IRQ(void) #if defined(CONFIG_IDC_AK4524) || defined(CONFIG_IDC_AK4524_MODULE) /* INT#80: AK4524 IREQ on PLD */ irq_desc[PLD_IRQ_SNDINT].status = IRQ_DISABLED; - irq_desc[PLD_IRQ_SNDINT].handler = &m32700ut_pld_irq_type; + irq_desc[PLD_IRQ_SNDINT].chip = &m32700ut_pld_irq_type; irq_desc[PLD_IRQ_SNDINT].action = 0; irq_desc[PLD_IRQ_SNDINT].depth = 1; /* disable nested irq */ pld_icu_data[irq2pldirq(PLD_IRQ_SNDINT)].icucr diff --git a/trunk/arch/m68knommu/Kconfig b/trunk/arch/m68knommu/Kconfig index 8b6e723eb82b..e767f2ddae72 100644 --- a/trunk/arch/m68knommu/Kconfig +++ b/trunk/arch/m68knommu/Kconfig @@ -540,6 +540,59 @@ config RAM32BIT endchoice +comment "ROM configuration" + +config ROM + bool "Specify ROM linker regions" + default n + help + Define a ROM region for the linker script. This creates a kernel + that can be stored in flash, with possibly the text, and data + regions being copied out to RAM at startup. + +config ROMBASE + hex "Address of the base of ROM device" + default "0" + depends on ROM + help + Define the address that the ROM region starts at. Some platforms + use this to set their chip select region accordingly for the boot + device. + +config ROMVEC + hex "Address of the base of the ROM vectors" + default "0" + depends on ROM + help + This is almost always the same as the base of the ROM. Since on all + 68000 type varients the vectors are at the base of the boot device + on system startup. + +config ROMVECSIZE + hex "Size of ROM vector region (in bytes)" + default "0x400" + depends on ROM + help + Define the size of the vector region in ROM. For most 68000 + varients this would be 0x400 bytes in size. Set to 0 if you do + not want a vector region at the start of the ROM. + +config ROMSTART + hex "Address of the base of system image in ROM" + default "0x400" + depends on ROM + help + Define the start address of the system image in ROM. Commonly this + is strait after the ROM vectors. + +config ROMSIZE + hex "Size of the ROM device" + default "0x100000" + depends on ROM + help + Size of the ROM device. On some platforms this is used to setup + the chip select that controls the boot ROM device. + choice prompt "Kernel executes from" ---help--- diff --git a/trunk/arch/m68knommu/kernel/comempci.c b/trunk/arch/m68knommu/kernel/comempci.c index 8670938f1107..db7a0c1cebae 100644 --- a/trunk/arch/m68knommu/kernel/comempci.c +++ b/trunk/arch/m68knommu/kernel/comempci.c @@ -357,7 +357,8 @@ void pcibios_fixup_bus(struct pci_bus *b) /*****************************************************************************/ -void pcibios_align_resource(void *data, struct resource *res, unsigned long size, unsigned long align) +void pcibios_align_resource(void *data, struct resource *res, + resource_size_t size, resource_size_t align) { } diff --git a/trunk/arch/m68knommu/kernel/vmlinux.lds.S b/trunk/arch/m68knommu/kernel/vmlinux.lds.S index 6a2f0c693254..59ced831b792 100644 --- a/trunk/arch/m68knommu/kernel/vmlinux.lds.S +++ b/trunk/arch/m68knommu/kernel/vmlinux.lds.S @@ -3,63 +3,13 @@ * * (C) Copyright 2002-2006, Greg Ungerer * - * This ends up looking compilcated, because of the number of - * address variations for ram and rom/flash layouts. The real - * work of the linker script is all at the end, and reasonably - * strait forward. + * This linker script is equiped to build either ROM loaded or RAM + * run kernels. */ #include #include -/* - * Original Palm pilot (same for Xcopilot). - * There is really only a rom target for this. - */ -#ifdef CONFIG_PILOT3 -#define ROMVEC_START 0x10c00000 -#define ROMVEC_LENGTH 0x10400 -#define ROM_START 0x10c10400 -#define ROM_LENGTH 0xfec00 -#define ROM_END 0x10d00000 -#define DATA_ADDR CONFIG_KERNELBASE -#endif - -/* - * Same setup on both the uCsimm and uCdimm. - */ -#if defined(CONFIG_UCSIMM) || defined(CONFIG_UCDIMM) -#ifdef CONFIG_RAMKERNEL -#define ROMVEC_START 0x10c10000 -#define ROMVEC_LENGTH 0x400 -#define ROM_START 0x10c10400 -#define ROM_LENGTH 0x1efc00 -#define ROM_END 0x10e00000 -#endif -#ifdef CONFIG_ROMKERNEL -#define ROMVEC_START 0x10c10000 -#define ROMVEC_LENGTH 0x400 -#define ROM_START 0x10c10400 -#define ROM_LENGTH 0x1efc00 -#define ROM_END 0x10e00000 -#endif -#ifdef CONFIG_HIMEMKERNEL -#define ROMVEC_START 0x00600000 -#define ROMVEC_LENGTH 0x400 -#define ROM_START 0x00600400 -#define ROM_LENGTH 0x1efc00 -#define ROM_END 0x007f0000 -#endif -#endif - -#ifdef CONFIG_UCQUICC -#define ROMVEC_START 0x00000000 -#define ROMVEC_LENGTH 0x404 -#define ROM_START 0x00000404 -#define ROM_LENGTH 0x1ff6fc -#define ROM_END 0x00200000 -#endif - #if defined(CONFIG_RAMKERNEL) #define RAM_START CONFIG_KERNELBASE #define RAM_LENGTH (CONFIG_RAMBASE + CONFIG_RAMSIZE - CONFIG_KERNELBASE) @@ -71,6 +21,10 @@ #if defined(CONFIG_ROMKERNEL) || defined(CONFIG_HIMEMKERNEL) #define RAM_START CONFIG_RAMBASE #define RAM_LENGTH CONFIG_RAMSIZE +#define ROMVEC_START CONFIG_ROMVEC +#define ROMVEC_LENGTH CONFIG_ROMVECSIZE +#define ROM_START CONFIG_ROMSTART +#define ROM_LENGTH CONFIG_ROMSIZE #define TEXT rom #define DATA ram #define INIT ram @@ -90,7 +44,6 @@ MEMORY { #ifdef ROM_START romvec : ORIGIN = ROMVEC_START, LENGTH = ROMVEC_LENGTH rom : ORIGIN = ROM_START, LENGTH = ROM_LENGTH - erom : ORIGIN = ROM_END, LENGTH = 0 #endif } @@ -167,13 +120,6 @@ SECTIONS { _etext = . ; } > TEXT -#ifdef ROM_END - . = ROM_END ; - .erom : { - __rom_end = . ; - } > erom -#endif - .data DATA_ADDR : { . = ALIGN(4); _sdata = . ; diff --git a/trunk/arch/m68knommu/platform/68328/Makefile b/trunk/arch/m68knommu/platform/68328/Makefile index 1b3b719e4479..5e5435552d56 100644 --- a/trunk/arch/m68knommu/platform/68328/Makefile +++ b/trunk/arch/m68knommu/platform/68328/Makefile @@ -8,6 +8,7 @@ head-$(CONFIG_DRAGEN2) = head-de2.o obj-y += entry.o ints.o timers.o obj-$(CONFIG_M68328) += config.o +obj-$(CONFIG_ROM) += romvec.o extra-y := head.o extra-$(CONFIG_M68328) += bootlogo.rh head.o diff --git a/trunk/arch/m68knommu/platform/68328/ints.c b/trunk/arch/m68knommu/platform/68328/ints.c index 7437217813d2..2dda7339aae5 100644 --- a/trunk/arch/m68knommu/platform/68328/ints.c +++ b/trunk/arch/m68knommu/platform/68328/ints.c @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -82,25 +83,6 @@ unsigned int local_irq_count[NR_CPUS]; /* irq node variables for the 32 (potential) on chip sources */ static irq_node_t int_irq_list[NR_IRQS]; -#if !defined(CONFIG_DRAGEN2) -asm (".global _start, __ramend/n/t" - ".section .romvec/n" - "e_vectors:\n\t" - ".long __ramend-4, _start, buserr, trap, trap, trap, trap, trap\n\t" - ".long trap, trap, trap, trap, trap, trap, trap, trap\n\t" - ".long trap, trap, trap, trap, trap, trap, trap, trap\n\t" - ".long trap, trap, trap, trap\n\t" - ".long trap, trap, trap, trap\n\t" - /*.long inthandler, inthandler, inthandler, inthandler - .long inthandler4, inthandler, inthandler, inthandler */ - /* TRAP #0-15 */ - ".long system_call, trap, trap, trap, trap, trap, trap, trap\n\t" - ".long trap, trap, trap, trap, trap, trap, trap, trap\n\t" - ".long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0\n\t" - ".text\n" - "ignore: rte"); -#endif - /* * This function should be called during kernel startup to initialize * the IRQ handling routines. diff --git a/trunk/arch/m68knommu/platform/68328/romvec.S b/trunk/arch/m68knommu/platform/68328/romvec.S new file mode 100644 index 000000000000..3e7fe1e14913 --- /dev/null +++ b/trunk/arch/m68knommu/platform/68328/romvec.S @@ -0,0 +1,37 @@ +/* + * linux/arch/m68knommu/platform/68328/romvec.S + * + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file COPYING in the main directory of this archive + * for more details. + * + * Copyright 1996 Roman Zippel + * Copyright 1999 D. Jeff Dionne + * Copyright 2006 Greg Ungerer + */ + +#include + +.global _start +.global _buserr +.global trap +.global system_call + +.section .romvec + +e_vectors: +.long CONFIG_RAMBASE+CONFIG_RAMSIZE-4, _start, buserr, trap +.long trap, trap, trap, trap +.long trap, trap, trap, trap +.long trap, trap, trap, trap +.long trap, trap, trap, trap +.long trap, trap, trap, trap +.long trap, trap, trap, trap +.long trap, trap, trap, trap +/* TRAP #0-15 */ +.long system_call, trap, trap, trap +.long trap, trap, trap, trap +.long trap, trap, trap, trap +.long trap, trap, trap, trap +.long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 + diff --git a/trunk/arch/m68knommu/platform/68360/config.c b/trunk/arch/m68knommu/platform/68360/config.c index 3db244625f0f..69c670dfd62b 100644 --- a/trunk/arch/m68knommu/platform/68360/config.c +++ b/trunk/arch/m68knommu/platform/68360/config.c @@ -141,13 +141,13 @@ int BSP_set_clock_mmss (unsigned long nowtime) void BSP_reset (void) { local_irq_disable(); - asm volatile (" - moveal #_start, %a0; - moveb #0, 0xFFFFF300; - moveal 0(%a0), %sp; - moveal 4(%a0), %a0; - jmp (%a0); - "); + asm volatile ( + "moveal #_start, %a0;\n" + "moveb #0, 0xFFFFF300;\n" + "moveal 0(%a0), %sp;\n" + "moveal 4(%a0), %a0;\n" + "jmp (%a0);\n" + ); } unsigned char *scc1_hwaddr; diff --git a/trunk/arch/m68knommu/platform/68360/ints.c b/trunk/arch/m68knommu/platform/68360/ints.c index ba184db1651b..0245fc4a4781 100644 --- a/trunk/arch/m68knommu/platform/68360/ints.c +++ b/trunk/arch/m68knommu/platform/68360/ints.c @@ -20,6 +20,7 @@ #include #include +#include #include #include #include diff --git a/trunk/arch/m68knommu/platform/68EZ328/config.c b/trunk/arch/m68knommu/platform/68EZ328/config.c index d8d56e5de310..15a14a67c2bf 100644 --- a/trunk/arch/m68knommu/platform/68EZ328/config.c +++ b/trunk/arch/m68knommu/platform/68EZ328/config.c @@ -42,13 +42,13 @@ void m68328_timer_gettod(int *year, int *mon, int *day, int *hour, int *min, int void m68ez328_reset(void) { local_irq_disable(); - asm volatile (" - moveal #0x10c00000, %a0; - moveb #0, 0xFFFFF300; - moveal 0(%a0), %sp; - moveal 4(%a0), %a0; - jmp (%a0); - "); + asm volatile ( + "moveal #0x10c00000, %a0;\n" + "moveb #0, 0xFFFFF300;\n" + "moveal 0(%a0), %sp;\n" + "moveal 4(%a0), %a0;\n" + "jmp (%a0);\n" + ); } /***************************************************************************/ diff --git a/trunk/arch/m68knommu/platform/68VZ328/config.c b/trunk/arch/m68knommu/platform/68VZ328/config.c index d926524cdf82..4058de5c8fa2 100644 --- a/trunk/arch/m68knommu/platform/68VZ328/config.c +++ b/trunk/arch/m68knommu/platform/68VZ328/config.c @@ -141,13 +141,13 @@ static void init_hardware(char *command, int size) static void m68vz328_reset(void) { local_irq_disable(); - asm volatile (" - moveal #0x10c00000, %a0; - moveb #0, 0xFFFFF300; - moveal 0(%a0), %sp; - moveal 4(%a0), %a0; - jmp (%a0); - "); + asm volatile ( + "moveal #0x10c00000, %a0;\n\t" + "moveb #0, 0xFFFFF300;\n\t" + "moveal 0(%a0), %sp;\n\t" + "moveal 4(%a0), %a0;\n\t" + "jmp (%a0);\n" + ); } unsigned char *cs8900a_hwaddr; diff --git a/trunk/arch/mips/Kconfig b/trunk/arch/mips/Kconfig index 35e038a974c6..08c2ece4ae40 100644 --- a/trunk/arch/mips/Kconfig +++ b/trunk/arch/mips/Kconfig @@ -1618,6 +1618,11 @@ config GENERIC_IRQ_PROBE bool default y +config IRQ_PER_CPU + depends on SMP + bool + default y + # # - Highmem only makes sense for the 32-bit kernel. # - The current highmem code will only work properly on physically indexed diff --git a/trunk/arch/mips/au1000/common/irq.c b/trunk/arch/mips/au1000/common/irq.c index afe05ec12c27..da74ac21954b 100644 --- a/trunk/arch/mips/au1000/common/irq.c +++ b/trunk/arch/mips/au1000/common/irq.c @@ -333,31 +333,31 @@ static void setup_local_irq(unsigned int irq_nr, int type, int int_req) au_writel(1<<(irq_nr-32), IC1_CFG2CLR); au_writel(1<<(irq_nr-32), IC1_CFG1CLR); au_writel(1<<(irq_nr-32), IC1_CFG0SET); - irq_desc[irq_nr].handler = &rise_edge_irq_type; + irq_desc[irq_nr].chip = &rise_edge_irq_type; break; case INTC_INT_FALL_EDGE: /* 0:1:0 */ au_writel(1<<(irq_nr-32), IC1_CFG2CLR); au_writel(1<<(irq_nr-32), IC1_CFG1SET); au_writel(1<<(irq_nr-32), IC1_CFG0CLR); - irq_desc[irq_nr].handler = &fall_edge_irq_type; + irq_desc[irq_nr].chip = &fall_edge_irq_type; break; case INTC_INT_RISE_AND_FALL_EDGE: /* 0:1:1 */ au_writel(1<<(irq_nr-32), IC1_CFG2CLR); au_writel(1<<(irq_nr-32), IC1_CFG1SET); au_writel(1<<(irq_nr-32), IC1_CFG0SET); - irq_desc[irq_nr].handler = &either_edge_irq_type; + irq_desc[irq_nr].chip = &either_edge_irq_type; break; case INTC_INT_HIGH_LEVEL: /* 1:0:1 */ au_writel(1<<(irq_nr-32), IC1_CFG2SET); au_writel(1<<(irq_nr-32), IC1_CFG1CLR); au_writel(1<<(irq_nr-32), IC1_CFG0SET); - irq_desc[irq_nr].handler = &level_irq_type; + irq_desc[irq_nr].chip = &level_irq_type; break; case INTC_INT_LOW_LEVEL: /* 1:1:0 */ au_writel(1<<(irq_nr-32), IC1_CFG2SET); au_writel(1<<(irq_nr-32), IC1_CFG1SET); au_writel(1<<(irq_nr-32), IC1_CFG0CLR); - irq_desc[irq_nr].handler = &level_irq_type; + irq_desc[irq_nr].chip = &level_irq_type; break; case INTC_INT_DISABLED: /* 0:0:0 */ au_writel(1<<(irq_nr-32), IC1_CFG0CLR); @@ -385,31 +385,31 @@ static void setup_local_irq(unsigned int irq_nr, int type, int int_req) au_writel(1<im_type) { case MSC01_IRQ_EDGE: - irq_desc[base+n].handler = &msc_edgeirq_type; + irq_desc[base+n].chip = &msc_edgeirq_type; if (cpu_has_veic) MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT); else MSCIC_WRITE(MSC01_IC_SUP+n*8, MSC01_IC_SUP_EDGE_BIT | imp->im_lvl); break; case MSC01_IRQ_LEVEL: - irq_desc[base+n].handler = &msc_levelirq_type; + irq_desc[base+n].chip = &msc_levelirq_type; if (cpu_has_veic) MSCIC_WRITE(MSC01_IC_SUP+n*8, 0); else diff --git a/trunk/arch/mips/kernel/irq-mv6434x.c b/trunk/arch/mips/kernel/irq-mv6434x.c index 0613f1f36b1b..f9c763a65547 100644 --- a/trunk/arch/mips/kernel/irq-mv6434x.c +++ b/trunk/arch/mips/kernel/irq-mv6434x.c @@ -155,7 +155,7 @@ void __init mv64340_irq_init(unsigned int base) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 2; - irq_desc[i].handler = &mv64340_irq_type; + irq_desc[i].chip = &mv64340_irq_type; } irq_base = base; diff --git a/trunk/arch/mips/kernel/irq-rm7000.c b/trunk/arch/mips/kernel/irq-rm7000.c index 0b130c5ac5d9..121da385a94d 100644 --- a/trunk/arch/mips/kernel/irq-rm7000.c +++ b/trunk/arch/mips/kernel/irq-rm7000.c @@ -91,7 +91,7 @@ void __init rm7k_cpu_irq_init(int base) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; - irq_desc[i].handler = &rm7k_irq_controller; + irq_desc[i].chip = &rm7k_irq_controller; } irq_base = base; diff --git a/trunk/arch/mips/kernel/irq-rm9000.c b/trunk/arch/mips/kernel/irq-rm9000.c index 9b5f20c32acb..25109c103e44 100644 --- a/trunk/arch/mips/kernel/irq-rm9000.c +++ b/trunk/arch/mips/kernel/irq-rm9000.c @@ -139,11 +139,11 @@ void __init rm9k_cpu_irq_init(int base) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; - irq_desc[i].handler = &rm9k_irq_controller; + irq_desc[i].chip = &rm9k_irq_controller; } rm9000_perfcount_irq = base + 1; - irq_desc[rm9000_perfcount_irq].handler = &rm9k_perfcounter_irq; + irq_desc[rm9000_perfcount_irq].chip = &rm9k_perfcounter_irq; irq_base = base; } diff --git a/trunk/arch/mips/kernel/irq.c b/trunk/arch/mips/kernel/irq.c index 3dce742e716f..5c9dcd5eed59 100644 --- a/trunk/arch/mips/kernel/irq.c +++ b/trunk/arch/mips/kernel/irq.c @@ -95,7 +95,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %14s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -137,7 +137,7 @@ void __init init_IRQ(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; - irq_desc[i].handler = &no_irq_type; + irq_desc[i].chip = &no_irq_type; spin_lock_init(&irq_desc[i].lock); #ifdef CONFIG_MIPS_MT_SMTC irq_hwmask[i] = 0; diff --git a/trunk/arch/mips/kernel/irq_cpu.c b/trunk/arch/mips/kernel/irq_cpu.c index 5db67e31ec1a..0e455a8ad860 100644 --- a/trunk/arch/mips/kernel/irq_cpu.c +++ b/trunk/arch/mips/kernel/irq_cpu.c @@ -167,14 +167,14 @@ void __init mips_cpu_irq_init(int irq_base) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; - irq_desc[i].handler = &mips_mt_cpu_irq_controller; + irq_desc[i].chip = &mips_mt_cpu_irq_controller; } for (i = irq_base + 2; i < irq_base + 8; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; - irq_desc[i].handler = &mips_cpu_irq_controller; + irq_desc[i].chip = &mips_cpu_irq_controller; } mips_cpu_irq_base = irq_base; diff --git a/trunk/arch/mips/lasat/interrupt.c b/trunk/arch/mips/lasat/interrupt.c index 2d3472b21ebb..9316a024a818 100644 --- a/trunk/arch/mips/lasat/interrupt.c +++ b/trunk/arch/mips/lasat/interrupt.c @@ -156,6 +156,6 @@ void __init arch_init_irq(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 1; - irq_desc[i].handler = &lasat_irq_type; + irq_desc[i].chip = &lasat_irq_type; } } diff --git a/trunk/arch/mips/mips-boards/atlas/atlas_int.c b/trunk/arch/mips/mips-boards/atlas/atlas_int.c index db53950b7cfb..9dd6b8925581 100644 --- a/trunk/arch/mips/mips-boards/atlas/atlas_int.c +++ b/trunk/arch/mips/mips-boards/atlas/atlas_int.c @@ -215,7 +215,7 @@ void __init arch_init_irq(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 1; - irq_desc[i].handler = &atlas_irq_type; + irq_desc[i].chip = &atlas_irq_type; spin_lock_init(&irq_desc[i].lock); } } diff --git a/trunk/arch/mips/momentum/ocelot_c/cpci-irq.c b/trunk/arch/mips/momentum/ocelot_c/cpci-irq.c index bd885785e2f9..31d179c4673f 100644 --- a/trunk/arch/mips/momentum/ocelot_c/cpci-irq.c +++ b/trunk/arch/mips/momentum/ocelot_c/cpci-irq.c @@ -147,6 +147,6 @@ void cpci_irq_init(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 2; - irq_desc[i].handler = &cpci_irq_type; + irq_desc[i].chip = &cpci_irq_type; } } diff --git a/trunk/arch/mips/momentum/ocelot_c/uart-irq.c b/trunk/arch/mips/momentum/ocelot_c/uart-irq.c index 755bde5146be..852265026fd1 100644 --- a/trunk/arch/mips/momentum/ocelot_c/uart-irq.c +++ b/trunk/arch/mips/momentum/ocelot_c/uart-irq.c @@ -137,10 +137,10 @@ void uart_irq_init(void) irq_desc[80].status = IRQ_DISABLED; irq_desc[80].action = 0; irq_desc[80].depth = 2; - irq_desc[80].handler = &uart_irq_type; + irq_desc[80].chip = &uart_irq_type; irq_desc[81].status = IRQ_DISABLED; irq_desc[81].action = 0; irq_desc[81].depth = 2; - irq_desc[81].handler = &uart_irq_type; + irq_desc[81].chip = &uart_irq_type; } diff --git a/trunk/arch/mips/pci/pci.c b/trunk/arch/mips/pci/pci.c index 4dfce154d4af..ba66f8c9bd4e 100644 --- a/trunk/arch/mips/pci/pci.c +++ b/trunk/arch/mips/pci/pci.c @@ -51,11 +51,11 @@ unsigned long PCIBIOS_MIN_MEM = 0; */ void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; struct pci_controller *hose = dev->sysdata; - unsigned long start = res->start; + resource_size_t start = res->start; if (res->flags & IORESOURCE_IO) { /* Make sure we start at our min on all hoses */ diff --git a/trunk/arch/mips/philips/pnx8550/common/int.c b/trunk/arch/mips/philips/pnx8550/common/int.c index 39ee6314f627..8f18764a2359 100644 --- a/trunk/arch/mips/philips/pnx8550/common/int.c +++ b/trunk/arch/mips/philips/pnx8550/common/int.c @@ -236,7 +236,7 @@ void __init arch_init_irq(void) int configPR; for (i = 0; i < PNX8550_INT_CP0_TOTINT; i++) { - irq_desc[i].handler = &level_irq_type; + irq_desc[i].chip = &level_irq_type; pnx8550_ack(i); /* mask the irq just in case */ } @@ -273,7 +273,7 @@ void __init arch_init_irq(void) /* mask/priority is still 0 so we will not get any * interrupts until it is unmasked */ - irq_desc[i].handler = &level_irq_type; + irq_desc[i].chip = &level_irq_type; } /* Priority level 0 */ @@ -282,12 +282,12 @@ void __init arch_init_irq(void) /* Set int vector table address */ PNX8550_GIC_VECTOR_0 = PNX8550_GIC_VECTOR_1 = 0; - irq_desc[MIPS_CPU_GIC_IRQ].handler = &level_irq_type; + irq_desc[MIPS_CPU_GIC_IRQ].chip = &level_irq_type; setup_irq(MIPS_CPU_GIC_IRQ, &gic_action); /* init of Timer interrupts */ for (i = PNX8550_INT_TIMER_MIN; i <= PNX8550_INT_TIMER_MAX; i++) { - irq_desc[i].handler = &level_irq_type; + irq_desc[i].chip = &level_irq_type; } /* Stop Timer 1-3 */ @@ -295,7 +295,7 @@ void __init arch_init_irq(void) configPR |= 0x00000038; write_c0_config7(configPR); - irq_desc[MIPS_CPU_TIMER_IRQ].handler = &level_irq_type; + irq_desc[MIPS_CPU_TIMER_IRQ].chip = &level_irq_type; setup_irq(MIPS_CPU_TIMER_IRQ, &timer_action); } diff --git a/trunk/arch/mips/pmc-sierra/yosemite/ht.c b/trunk/arch/mips/pmc-sierra/yosemite/ht.c index 54b65a80abf5..fb523ebcafa8 100644 --- a/trunk/arch/mips/pmc-sierra/yosemite/ht.c +++ b/trunk/arch/mips/pmc-sierra/yosemite/ht.c @@ -383,12 +383,12 @@ void pcibios_update_resource(struct pci_dev *dev, struct resource *root, void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; + resource_size_t start = res->start; /* We need to avoid collisions with `mirrored' VGA ports and other strange ISA hardware, so we always want the diff --git a/trunk/arch/mips/sgi-ip22/ip22-eisa.c b/trunk/arch/mips/sgi-ip22/ip22-eisa.c index b19820110aa3..989167b49ce9 100644 --- a/trunk/arch/mips/sgi-ip22/ip22-eisa.c +++ b/trunk/arch/mips/sgi-ip22/ip22-eisa.c @@ -279,9 +279,9 @@ int __init ip22_eisa_init(void) irq_desc[i].action = 0; irq_desc[i].depth = 1; if (i < (SGINT_EISA + 8)) - irq_desc[i].handler = &ip22_eisa1_irq_type; + irq_desc[i].chip = &ip22_eisa1_irq_type; else - irq_desc[i].handler = &ip22_eisa2_irq_type; + irq_desc[i].chip = &ip22_eisa2_irq_type; } /* Cannot use request_irq because of kmalloc not being ready at such diff --git a/trunk/arch/mips/sgi-ip22/ip22-int.c b/trunk/arch/mips/sgi-ip22/ip22-int.c index fc6a7e2b189c..18906af69691 100644 --- a/trunk/arch/mips/sgi-ip22/ip22-int.c +++ b/trunk/arch/mips/sgi-ip22/ip22-int.c @@ -436,7 +436,7 @@ void __init arch_init_irq(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 1; - irq_desc[i].handler = handler; + irq_desc[i].chip = handler; } /* vector handler. this register the IRQ as non-sharable */ diff --git a/trunk/arch/mips/sgi-ip27/ip27-irq.c b/trunk/arch/mips/sgi-ip27/ip27-irq.c index 0b61a39ce2bb..869566c360ae 100644 --- a/trunk/arch/mips/sgi-ip27/ip27-irq.c +++ b/trunk/arch/mips/sgi-ip27/ip27-irq.c @@ -386,7 +386,7 @@ void __devinit register_bridge_irq(unsigned int irq) irq_desc[irq].status = IRQ_DISABLED; irq_desc[irq].action = 0; irq_desc[irq].depth = 1; - irq_desc[irq].handler = &bridge_irq_type; + irq_desc[irq].chip = &bridge_irq_type; } int __devinit request_bridge_irq(struct bridge_controller *bc) diff --git a/trunk/arch/mips/sgi-ip32/ip32-irq.c b/trunk/arch/mips/sgi-ip32/ip32-irq.c index 8ba08047d164..00b94aaf6371 100644 --- a/trunk/arch/mips/sgi-ip32/ip32-irq.c +++ b/trunk/arch/mips/sgi-ip32/ip32-irq.c @@ -591,7 +591,7 @@ void __init arch_init_irq(void) irq_desc[irq].status = IRQ_DISABLED; irq_desc[irq].action = 0; irq_desc[irq].depth = 0; - irq_desc[irq].handler = controller; + irq_desc[irq].chip = controller; } setup_irq(CRIME_MEMERR_IRQ, &memerr_irq); setup_irq(CRIME_CPUERR_IRQ, &cpuerr_irq); diff --git a/trunk/arch/mips/sibyte/bcm1480/irq.c b/trunk/arch/mips/sibyte/bcm1480/irq.c index e61760b14d99..610df40cb820 100644 --- a/trunk/arch/mips/sibyte/bcm1480/irq.c +++ b/trunk/arch/mips/sibyte/bcm1480/irq.c @@ -276,10 +276,10 @@ void __init init_bcm1480_irqs(void) irq_desc[i].action = 0; irq_desc[i].depth = 1; if (i < BCM1480_NR_IRQS) { - irq_desc[i].handler = &bcm1480_irq_type; + irq_desc[i].chip = &bcm1480_irq_type; bcm1480_irq_owner[i] = 0; } else { - irq_desc[i].handler = &no_irq_type; + irq_desc[i].chip = &no_irq_type; } } } diff --git a/trunk/arch/mips/sibyte/sb1250/irq.c b/trunk/arch/mips/sibyte/sb1250/irq.c index f853c32f60a0..fcc61940f1ff 100644 --- a/trunk/arch/mips/sibyte/sb1250/irq.c +++ b/trunk/arch/mips/sibyte/sb1250/irq.c @@ -246,10 +246,10 @@ void __init init_sb1250_irqs(void) irq_desc[i].action = 0; irq_desc[i].depth = 1; if (i < SB1250_NR_IRQS) { - irq_desc[i].handler = &sb1250_irq_type; + irq_desc[i].chip = &sb1250_irq_type; sb1250_irq_owner[i] = 0; } else { - irq_desc[i].handler = &no_irq_type; + irq_desc[i].chip = &no_irq_type; } } } diff --git a/trunk/arch/mips/sni/irq.c b/trunk/arch/mips/sni/irq.c index 7365b4853ddb..c19e158ec402 100644 --- a/trunk/arch/mips/sni/irq.c +++ b/trunk/arch/mips/sni/irq.c @@ -203,7 +203,7 @@ void __init arch_init_irq(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 1; - irq_desc[i].handler = &pciasic_irq_type; + irq_desc[i].chip = &pciasic_irq_type; } change_c0_status(ST0_IM, IE_IRQ1|IE_IRQ2|IE_IRQ3|IE_IRQ4); diff --git a/trunk/arch/mips/tx4927/common/tx4927_irq.c b/trunk/arch/mips/tx4927/common/tx4927_irq.c index 8ca68015cf40..a42be00483e6 100644 --- a/trunk/arch/mips/tx4927/common/tx4927_irq.c +++ b/trunk/arch/mips/tx4927/common/tx4927_irq.c @@ -227,7 +227,7 @@ static void __init tx4927_irq_cp0_init(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 1; - irq_desc[i].handler = &tx4927_irq_cp0_type; + irq_desc[i].chip = &tx4927_irq_cp0_type; } return; @@ -435,7 +435,7 @@ static void __init tx4927_irq_pic_init(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 2; - irq_desc[i].handler = &tx4927_irq_pic_type; + irq_desc[i].chip = &tx4927_irq_pic_type; } setup_irq(TX4927_IRQ_NEST_PIC_ON_CP0, &tx4927_irq_pic_action); diff --git a/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c b/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c index aee07ff2212a..c67978b6dae4 100644 --- a/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c +++ b/trunk/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_irq.c @@ -368,7 +368,7 @@ static void __init toshiba_rbtx4927_irq_ioc_init(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 3; - irq_desc[i].handler = &toshiba_rbtx4927_irq_ioc_type; + irq_desc[i].chip = &toshiba_rbtx4927_irq_ioc_type; } setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_IOC_ON_PIC, @@ -526,7 +526,7 @@ static void __init toshiba_rbtx4927_irq_isa_init(void) irq_desc[i].action = 0; irq_desc[i].depth = ((i < TOSHIBA_RBTX4927_IRQ_ISA_MID) ? (4) : (5)); - irq_desc[i].handler = &toshiba_rbtx4927_irq_isa_type; + irq_desc[i].chip = &toshiba_rbtx4927_irq_isa_type; } setup_irq(TOSHIBA_RBTX4927_IRQ_NEST_ISA_ON_IOC, @@ -692,13 +692,13 @@ void toshiba_rbtx4927_irq_dump(char *key) { u32 i, j = 0; for (i = 0; i < NR_IRQS; i++) { - if (strcmp(irq_desc[i].handler->typename, "none") + if (strcmp(irq_desc[i].chip->typename, "none") == 0) continue; if ((i >= 1) - && (irq_desc[i - 1].handler->typename == - irq_desc[i].handler->typename)) { + && (irq_desc[i - 1].chip->typename == + irq_desc[i].chip->typename)) { j++; } else { j = 0; @@ -707,12 +707,12 @@ void toshiba_rbtx4927_irq_dump(char *key) (TOSHIBA_RBTX4927_IRQ_INFO, "%s irq=0x%02x/%3d s=0x%08x h=0x%08x a=0x%08x ah=0x%08x d=%1d n=%s/%02d\n", key, i, i, irq_desc[i].status, - (u32) irq_desc[i].handler, + (u32) irq_desc[i].chip, (u32) irq_desc[i].action, (u32) (irq_desc[i].action ? irq_desc[i]. action->handler : 0), irq_desc[i].depth, - irq_desc[i].handler->typename, j); + irq_desc[i].chip->typename, j); } } #endif diff --git a/trunk/arch/mips/tx4938/common/irq.c b/trunk/arch/mips/tx4938/common/irq.c index 873805178d8e..0b2f8c849218 100644 --- a/trunk/arch/mips/tx4938/common/irq.c +++ b/trunk/arch/mips/tx4938/common/irq.c @@ -102,7 +102,7 @@ tx4938_irq_cp0_init(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 1; - irq_desc[i].handler = &tx4938_irq_cp0_type; + irq_desc[i].chip = &tx4938_irq_cp0_type; } return; @@ -306,7 +306,7 @@ tx4938_irq_pic_init(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 2; - irq_desc[i].handler = &tx4938_irq_pic_type; + irq_desc[i].chip = &tx4938_irq_pic_type; } setup_irq(TX4938_IRQ_NEST_PIC_ON_CP0, &tx4938_irq_pic_action); diff --git a/trunk/arch/mips/tx4938/toshiba_rbtx4938/irq.c b/trunk/arch/mips/tx4938/toshiba_rbtx4938/irq.c index 9cd9c0fe2265..3b8245dc5bd3 100644 --- a/trunk/arch/mips/tx4938/toshiba_rbtx4938/irq.c +++ b/trunk/arch/mips/tx4938/toshiba_rbtx4938/irq.c @@ -146,7 +146,7 @@ toshiba_rbtx4938_irq_ioc_init(void) irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = 0; irq_desc[i].depth = 3; - irq_desc[i].handler = &toshiba_rbtx4938_irq_ioc_type; + irq_desc[i].chip = &toshiba_rbtx4938_irq_ioc_type; } setup_irq(RBTX4938_IRQ_IOCINT, diff --git a/trunk/arch/mips/vr41xx/common/icu.c b/trunk/arch/mips/vr41xx/common/icu.c index 07ae19cf0c29..b9323302cc4e 100644 --- a/trunk/arch/mips/vr41xx/common/icu.c +++ b/trunk/arch/mips/vr41xx/common/icu.c @@ -722,10 +722,10 @@ static int __init vr41xx_icu_init(void) icu2_write(MGIUINTHREG, 0xffff); for (i = SYSINT1_IRQ_BASE; i <= SYSINT1_IRQ_LAST; i++) - irq_desc[i].handler = &sysint1_irq_type; + irq_desc[i].chip = &sysint1_irq_type; for (i = SYSINT2_IRQ_BASE; i <= SYSINT2_IRQ_LAST; i++) - irq_desc[i].handler = &sysint2_irq_type; + irq_desc[i].chip = &sysint2_irq_type; cascade_irq(INT0_IRQ, icu_get_irq); cascade_irq(INT1_IRQ, icu_get_irq); diff --git a/trunk/arch/mips/vr41xx/common/irq.c b/trunk/arch/mips/vr41xx/common/irq.c index 86796bb63c3c..66aa50802deb 100644 --- a/trunk/arch/mips/vr41xx/common/irq.c +++ b/trunk/arch/mips/vr41xx/common/irq.c @@ -73,13 +73,13 @@ static void irq_dispatch(unsigned int irq, struct pt_regs *regs) if (cascade->get_irq != NULL) { unsigned int source_irq = irq; desc = irq_desc + source_irq; - desc->handler->ack(source_irq); + desc->chip->ack(source_irq); irq = cascade->get_irq(irq, regs); if (irq < 0) atomic_inc(&irq_err_count); else irq_dispatch(irq, regs); - desc->handler->end(source_irq); + desc->chip->end(source_irq); } else do_IRQ(irq, regs); } diff --git a/trunk/arch/mips/vr41xx/common/vrc4173.c b/trunk/arch/mips/vr41xx/common/vrc4173.c index 3e31f8193d21..2d287b8893d9 100644 --- a/trunk/arch/mips/vr41xx/common/vrc4173.c +++ b/trunk/arch/mips/vr41xx/common/vrc4173.c @@ -483,7 +483,7 @@ static inline int vrc4173_icu_init(int cascade_irq) vr41xx_set_irq_level(GIU_IRQ_TO_PIN(cascade_irq), LEVEL_LOW); for (i = VRC4173_IRQ_BASE; i <= VRC4173_IRQ_LAST; i++) - irq_desc[i].handler = &vrc4173_irq_type; + irq_desc[i].chip = &vrc4173_irq_type; return 0; } diff --git a/trunk/arch/mips/vr41xx/nec-cmbvr4133/irq.c b/trunk/arch/mips/vr41xx/nec-cmbvr4133/irq.c index 31db6b61a39e..7b2511ca0a61 100644 --- a/trunk/arch/mips/vr41xx/nec-cmbvr4133/irq.c +++ b/trunk/arch/mips/vr41xx/nec-cmbvr4133/irq.c @@ -104,7 +104,7 @@ void __init rockhopper_init_irq(void) } for (i = I8259_IRQ_BASE; i <= I8259_IRQ_LAST; i++) - irq_desc[i].handler = &i8259_irq_type; + irq_desc[i].chip = &i8259_irq_type; setup_irq(I8259_SLAVE_IRQ, &i8259_slave_cascade); diff --git a/trunk/arch/parisc/Kconfig b/trunk/arch/parisc/Kconfig index 910fb3afc0b5..6dd0ea8f88e0 100644 --- a/trunk/arch/parisc/Kconfig +++ b/trunk/arch/parisc/Kconfig @@ -51,6 +51,10 @@ config GENERIC_HARDIRQS config GENERIC_IRQ_PROBE def_bool y +config IRQ_PER_CPU + bool + default y + # unless you want to implement ACPI on PA-RISC ... ;-) config PM bool diff --git a/trunk/arch/parisc/kernel/cache.c b/trunk/arch/parisc/kernel/cache.c index c057ad7605ba..bc7c4a4e26a1 100644 --- a/trunk/arch/parisc/kernel/cache.c +++ b/trunk/arch/parisc/kernel/cache.c @@ -97,15 +97,17 @@ update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte) void show_cache_info(struct seq_file *m) { + char buf[32]; + seq_printf(m, "I-cache\t\t: %ld KB\n", cache_info.ic_size/1024 ); - seq_printf(m, "D-cache\t\t: %ld KB (%s%s, %d-way associative)\n", + if (cache_info.dc_loop == 1) + snprintf(buf, 32, "%lu-way associative", cache_info.dc_loop); + seq_printf(m, "D-cache\t\t: %ld KB (%s%s, %s)\n", cache_info.dc_size/1024, (cache_info.dc_conf.cc_wt ? "WT":"WB"), (cache_info.dc_conf.cc_sh ? ", shared I/D":""), - (cache_info.dc_conf.cc_assoc) - ); - + ((cache_info.dc_loop == 1) ? "direct mapped" : buf)); seq_printf(m, "ITLB entries\t: %ld\n" "DTLB entries\t: %ld%s\n", cache_info.it_size, cache_info.dt_size, @@ -158,11 +160,11 @@ parisc_cache_init(void) cache_info.dc_conf.cc_block, cache_info.dc_conf.cc_line, cache_info.dc_conf.cc_shift); - printk(" wt %d sh %d cst %d assoc %d\n", + printk(" wt %d sh %d cst %d hv %d\n", cache_info.dc_conf.cc_wt, cache_info.dc_conf.cc_sh, cache_info.dc_conf.cc_cst, - cache_info.dc_conf.cc_assoc); + cache_info.dc_conf.cc_hv); printk("IC base 0x%lx stride 0x%lx count 0x%lx loop 0x%lx\n", cache_info.ic_base, @@ -176,11 +178,11 @@ parisc_cache_init(void) cache_info.ic_conf.cc_block, cache_info.ic_conf.cc_line, cache_info.ic_conf.cc_shift); - printk(" wt %d sh %d cst %d assoc %d\n", + printk(" wt %d sh %d cst %d hv %d\n", cache_info.ic_conf.cc_wt, cache_info.ic_conf.cc_sh, cache_info.ic_conf.cc_cst, - cache_info.ic_conf.cc_assoc); + cache_info.ic_conf.cc_hv); printk("D-TLB conf: sh %d page %d cst %d aid %d pad1 %d \n", cache_info.dt_conf.tc_sh, @@ -234,7 +236,8 @@ parisc_cache_init(void) void disable_sr_hashing(void) { - int srhash_type; + int srhash_type, retval; + unsigned long space_bits; switch (boot_cpu_data.cpu_type) { case pcx: /* We shouldn't get this far. setup.c should prevent it. */ @@ -260,6 +263,13 @@ void disable_sr_hashing(void) } disable_sr_hashing_asm(srhash_type); + + retval = pdc_spaceid_bits(&space_bits); + /* If this procedure isn't implemented, don't panic. */ + if (retval < 0 && retval != PDC_BAD_OPTION) + panic("pdc_spaceid_bits call failed.\n"); + if (space_bits != 0) + panic("SpaceID hashing is still on!\n"); } void flush_dcache_page(struct page *page) diff --git a/trunk/arch/parisc/kernel/entry.S b/trunk/arch/parisc/kernel/entry.S index d9e53cf0372b..630730c32a5a 100644 --- a/trunk/arch/parisc/kernel/entry.S +++ b/trunk/arch/parisc/kernel/entry.S @@ -1638,7 +1638,7 @@ dbit_trap_20w: load32 PA(pa_dbit_lock),t0 dbit_spin_20w: - ldcw 0(t0),t1 + LDCW 0(t0),t1 cmpib,= 0,t1,dbit_spin_20w nop @@ -1674,7 +1674,7 @@ dbit_trap_11: load32 PA(pa_dbit_lock),t0 dbit_spin_11: - ldcw 0(t0),t1 + LDCW 0(t0),t1 cmpib,= 0,t1,dbit_spin_11 nop @@ -1714,7 +1714,7 @@ dbit_trap_20: load32 PA(pa_dbit_lock),t0 dbit_spin_20: - ldcw 0(t0),t1 + LDCW 0(t0),t1 cmpib,= 0,t1,dbit_spin_20 nop diff --git a/trunk/arch/parisc/kernel/firmware.c b/trunk/arch/parisc/kernel/firmware.c index 2dc06b8e1817..4398d2a95789 100644 --- a/trunk/arch/parisc/kernel/firmware.c +++ b/trunk/arch/parisc/kernel/firmware.c @@ -11,7 +11,7 @@ * Copyright 1999 The Puffin Group, (Alex deVries, David Kennedy) * Copyright 2003 Grant Grundler * Copyright 2003,2004 Ryan Bradetich - * Copyright 2004 Thibaut VARENE + * Copyright 2004,2006 Thibaut VARENE * * 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 @@ -252,10 +252,8 @@ int pdc_pat_chassis_send_log(unsigned long state, unsigned long data) #endif /** - * pdc_chassis_disp - Updates display + * pdc_chassis_disp - Updates chassis code * @retval: -1 on error, 0 on success - * - * Works on old PDC only (E class, others?) */ int pdc_chassis_disp(unsigned long disp) { @@ -268,6 +266,22 @@ int pdc_chassis_disp(unsigned long disp) return retval; } +/** + * pdc_chassis_warn - Fetches chassis warnings + * @retval: -1 on error, 0 on success + */ +int pdc_chassis_warn(unsigned long *warn) +{ + int retval = 0; + + spin_lock_irq(&pdc_lock); + retval = mem_pdc_call(PDC_CHASSIS, PDC_CHASSIS_WARN, __pa(pdc_result)); + *warn = pdc_result[0]; + spin_unlock_irq(&pdc_lock); + + return retval; +} + /** * pdc_coproc_cfg - To identify coprocessors attached to the processor. * @pdc_coproc_info: Return buffer address. @@ -393,7 +407,9 @@ int pdc_model_info(struct pdc_model *model) * pdc_model_sysmodel - Get the system model name. * @name: A char array of at least 81 characters. * - * Get system model name from PDC ROM (e.g. 9000/715 or 9000/778/B160L) + * Get system model name from PDC ROM (e.g. 9000/715 or 9000/778/B160L). + * Using OS_ID_HPUX will return the equivalent of the 'modelname' command + * on HP/UX. */ int pdc_model_sysmodel(char *name) { @@ -498,6 +514,26 @@ int pdc_cache_info(struct pdc_cache_info *cache_info) return retval; } +/** + * pdc_spaceid_bits - Return whether Space ID hashing is turned on. + * @space_bits: Should be 0, if not, bad mojo! + * + * Returns information about Space ID hashing. + */ +int pdc_spaceid_bits(unsigned long *space_bits) +{ + int retval; + + spin_lock_irq(&pdc_lock); + pdc_result[0] = 0; + retval = mem_pdc_call(PDC_CACHE, PDC_CACHE_RET_SPID, __pa(pdc_result), 0); + convert_to_wide(pdc_result); + *space_bits = pdc_result[0]; + spin_unlock_irq(&pdc_lock); + + return retval; +} + #ifndef CONFIG_PA20 /** * pdc_btlb_info - Return block TLB information. diff --git a/trunk/arch/parisc/kernel/irq.c b/trunk/arch/parisc/kernel/irq.c index 197936d9359a..82fe6ba29727 100644 --- a/trunk/arch/parisc/kernel/irq.c +++ b/trunk/arch/parisc/kernel/irq.c @@ -94,7 +94,7 @@ int cpu_check_affinity(unsigned int irq, cpumask_t *dest) if (irq == TIMER_IRQ || irq == IPI_IRQ) { /* Bad linux design decision. The mask has already * been set; we must reset it */ - irq_affinity[irq] = CPU_MASK_ALL; + irq_desc[irq].affinity = CPU_MASK_ALL; return -EINVAL; } @@ -110,7 +110,7 @@ static void cpu_set_affinity_irq(unsigned int irq, cpumask_t dest) if (cpu_check_affinity(irq, &dest)) return; - irq_affinity[irq] = dest; + irq_desc[irq].affinity = dest; } #endif @@ -125,6 +125,10 @@ static struct hw_interrupt_type cpu_interrupt_type = { #ifdef CONFIG_SMP .set_affinity = cpu_set_affinity_irq, #endif + /* XXX: Needs to be written. We managed without it so far, but + * we really ought to write it. + */ + .retrigger = NULL, }; int show_interrupts(struct seq_file *p, void *v) @@ -158,7 +162,7 @@ int show_interrupts(struct seq_file *p, void *v) seq_printf(p, "%10u ", kstat_irqs(i)); #endif - seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %14s", irq_desc[i].chip->typename); #ifndef PARISC_IRQ_CR16_COUNTS seq_printf(p, " %s", action->name); @@ -210,12 +214,12 @@ int cpu_claim_irq(unsigned int irq, struct hw_interrupt_type *type, void *data) { if (irq_desc[irq].action) return -EBUSY; - if (irq_desc[irq].handler != &cpu_interrupt_type) + if (irq_desc[irq].chip != &cpu_interrupt_type) return -EBUSY; if (type) { - irq_desc[irq].handler = type; - irq_desc[irq].handler_data = data; + irq_desc[irq].chip = type; + irq_desc[irq].chip_data = data; cpu_interrupt_type.enable(irq); } return 0; @@ -265,7 +269,7 @@ int txn_alloc_irq(unsigned int bits_wide) unsigned long txn_affinity_addr(unsigned int irq, int cpu) { #ifdef CONFIG_SMP - irq_affinity[irq] = cpumask_of_cpu(cpu); + irq_desc[irq].affinity = cpumask_of_cpu(cpu); #endif return cpu_data[cpu].txn_addr; @@ -326,7 +330,7 @@ void do_cpu_irq_mask(struct pt_regs *regs) /* Work our way from MSb to LSb...same order we alloc EIRs */ for (irq = TIMER_IRQ; eirr_val && bit; bit>>=1, irq++) { #ifdef CONFIG_SMP - cpumask_t dest = irq_affinity[irq]; + cpumask_t dest = irq_desc[irq].affinity; #endif if (!(bit & eirr_val)) continue; @@ -378,7 +382,7 @@ static void claim_cpu_irqs(void) { int i; for (i = CPU_IRQ_BASE; i <= CPU_IRQ_MAX; i++) { - irq_desc[i].handler = &cpu_interrupt_type; + irq_desc[i].chip = &cpu_interrupt_type; } irq_desc[TIMER_IRQ].action = &timer_action; @@ -404,13 +408,6 @@ void __init init_IRQ(void) } -void hw_resend_irq(struct hw_interrupt_type *type, unsigned int irq) -{ - /* XXX: Needs to be written. We managed without it so far, but - * we really ought to write it. - */ -} - void ack_bad_irq(unsigned int irq) { printk("unexpected IRQ %d\n", irq); diff --git a/trunk/arch/parisc/kernel/module.c b/trunk/arch/parisc/kernel/module.c index f27cfe4771b8..aee311884f3f 100644 --- a/trunk/arch/parisc/kernel/module.c +++ b/trunk/arch/parisc/kernel/module.c @@ -89,6 +89,12 @@ static inline int is_local(struct module *me, void *loc) return is_init(me, loc) || is_core(me, loc); } +static inline int is_local_section(struct module *me, void *loc, void *dot) +{ + return (is_init(me, loc) && is_init(me, dot)) || + (is_core(me, loc) && is_core(me, dot)); +} + #ifndef __LP64__ struct got_entry { @@ -364,8 +370,14 @@ static Elf_Addr get_fdesc(struct module *me, unsigned long value) } #endif /* __LP64__ */ +enum elf_stub_type { + ELF_STUB_GOT, + ELF_STUB_MILLI, + ELF_STUB_DIRECT, +}; + static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, - int millicode, int init_section) + enum elf_stub_type stub_type, int init_section) { unsigned long i; struct stub_entry *stub; @@ -396,7 +408,7 @@ static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, stub->insns[1] |= reassemble_17(rrsel(value, addend) / 4); #else -/* for 64-bit we have two kinds of stubs: +/* for 64-bit we have three kinds of stubs: * for normal function calls: * ldd 0(%dp),%dp * ldd 10(%dp), %r1 @@ -408,18 +420,23 @@ static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, * ldo 0(%r1), %r1 * ldd 10(%r1), %r1 * bve,n (%r1) + * + * for direct branches (jumps between different section of the + * same module): + * ldil 0, %r1 + * ldo 0(%r1), %r1 + * bve,n (%r1) */ - if (!millicode) - { + switch (stub_type) { + case ELF_STUB_GOT: stub->insns[0] = 0x537b0000; /* ldd 0(%dp),%dp */ stub->insns[1] = 0x53610020; /* ldd 10(%dp),%r1 */ stub->insns[2] = 0xe820d000; /* bve (%r1) */ stub->insns[3] = 0x537b0030; /* ldd 18(%dp),%dp */ stub->insns[0] |= reassemble_14(get_got(me, value, addend) & 0x3fff); - } - else - { + break; + case ELF_STUB_MILLI: stub->insns[0] = 0x20200000; /* ldil 0,%r1 */ stub->insns[1] = 0x34210000; /* ldo 0(%r1), %r1 */ stub->insns[2] = 0x50210020; /* ldd 10(%r1),%r1 */ @@ -427,7 +444,17 @@ static Elf_Addr get_stub(struct module *me, unsigned long value, long addend, stub->insns[0] |= reassemble_21(lrsel(value, addend)); stub->insns[1] |= reassemble_14(rrsel(value, addend)); + break; + case ELF_STUB_DIRECT: + stub->insns[0] = 0x20200000; /* ldil 0,%r1 */ + stub->insns[1] = 0x34210000; /* ldo 0(%r1), %r1 */ + stub->insns[2] = 0xe820d002; /* bve,n (%r1) */ + + stub->insns[0] |= reassemble_21(lrsel(value, addend)); + stub->insns[1] |= reassemble_14(rrsel(value, addend)); + break; } + #endif return (Elf_Addr)stub; @@ -539,14 +566,14 @@ int apply_relocate_add(Elf_Shdr *sechdrs, break; case R_PARISC_PCREL17F: /* 17-bit PC relative address */ - val = get_stub(me, val, addend, 0, is_init(me, loc)); + val = get_stub(me, val, addend, ELF_STUB_GOT, is_init(me, loc)); val = (val - dot - 8)/4; CHECK_RELOC(val, 17) *loc = (*loc & ~0x1f1ffd) | reassemble_17(val); break; case R_PARISC_PCREL22F: /* 22-bit PC relative address; only defined for pa20 */ - val = get_stub(me, val, addend, 0, is_init(me, loc)); + val = get_stub(me, val, addend, ELF_STUB_GOT, is_init(me, loc)); DEBUGP("STUB FOR %s loc %lx+%lx at %lx\n", strtab + sym->st_name, (unsigned long)loc, addend, val) @@ -643,13 +670,23 @@ int apply_relocate_add(Elf_Shdr *sechdrs, strtab + sym->st_name, loc, val); /* can we reach it locally? */ - if(!is_local(me, (void *)val)) { - if (strncmp(strtab + sym->st_name, "$$", 2) + if(!is_local_section(me, (void *)val, (void *)dot)) { + + if (is_local(me, (void *)val)) + /* this is the case where the + * symbol is local to the + * module, but in a different + * section, so stub the jump + * in case it's more than 22 + * bits away */ + val = get_stub(me, val, addend, ELF_STUB_DIRECT, + is_init(me, loc)); + else if (strncmp(strtab + sym->st_name, "$$", 2) == 0) - val = get_stub(me, val, addend, 1, + val = get_stub(me, val, addend, ELF_STUB_MILLI, is_init(me, loc)); else - val = get_stub(me, val, addend, 0, + val = get_stub(me, val, addend, ELF_STUB_GOT, is_init(me, loc)); } DEBUGP("STUB FOR %s loc %lx, val %lx+%lx at %lx\n", diff --git a/trunk/arch/parisc/kernel/pci.c b/trunk/arch/parisc/kernel/pci.c index 79c7db2705fd..7d6967ee367c 100644 --- a/trunk/arch/parisc/kernel/pci.c +++ b/trunk/arch/parisc/kernel/pci.c @@ -289,7 +289,7 @@ EXPORT_SYMBOL(pcibios_bus_to_resource); * than res->start. */ void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long alignment) + resource_size_t size, resource_size_t alignment) { unsigned long mask, align; diff --git a/trunk/arch/parisc/kernel/pdc_chassis.c b/trunk/arch/parisc/kernel/pdc_chassis.c index a45e2e2ffd9f..d47ba1aa8253 100644 --- a/trunk/arch/parisc/kernel/pdc_chassis.c +++ b/trunk/arch/parisc/kernel/pdc_chassis.c @@ -1,8 +1,8 @@ /* - * interfaces to log Chassis Codes via PDC (firmware) + * interfaces to Chassis Codes via PDC (firmware) * * Copyright (C) 2002 Laurent Canet - * Copyright (C) 2002-2004 Thibaut VARENE + * Copyright (C) 2002-2006 Thibaut VARENE * * 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 @@ -16,6 +16,10 @@ * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * TODO: poll chassis warns, trigger (configurable) machine shutdown when + * needed. + * Find out how to get Chassis warnings out of PAT boxes? */ #undef PDC_CHASSIS_DEBUG @@ -30,15 +34,16 @@ #include #include #include +#include #include #include #include #include +#define PDC_CHASSIS_VER "0.05" #ifdef CONFIG_PDC_CHASSIS -static int pdc_chassis_old __read_mostly = 0; static unsigned int pdc_chassis_enabled __read_mostly = 1; @@ -64,7 +69,7 @@ __setup("pdcchassis=", pdc_chassis_setup); * Currently, only E class and A180 are known to work with this. * Inspired by Christoph Plattner */ - +#if 0 static void __init pdc_chassis_checkold(void) { switch(CPU_HVERSION) { @@ -73,7 +78,6 @@ static void __init pdc_chassis_checkold(void) case 0x482: /* E45 */ case 0x483: /* E55 */ case 0x516: /* A180 */ - pdc_chassis_old = 1; break; default: @@ -81,7 +85,7 @@ static void __init pdc_chassis_checkold(void) } DPRINTK(KERN_DEBUG "%s: pdc_chassis_checkold(); pdc_chassis_old = %d\n", __FILE__, pdc_chassis_old); } - +#endif /** * pdc_chassis_panic_event() - Called by the panic handler. @@ -131,30 +135,20 @@ static struct notifier_block pdc_chassis_reboot_block = { void __init parisc_pdc_chassis_init(void) { #ifdef CONFIG_PDC_CHASSIS - int handle = 0; if (likely(pdc_chassis_enabled)) { DPRINTK(KERN_DEBUG "%s: parisc_pdc_chassis_init()\n", __FILE__); /* Let see if we have something to handle... */ - /* Check for PDC_PAT or old LED Panel */ - pdc_chassis_checkold(); - if (is_pdc_pat()) { - printk(KERN_INFO "Enabling PDC_PAT chassis codes support.\n"); - handle = 1; - } - else if (unlikely(pdc_chassis_old)) { - printk(KERN_INFO "Enabling old style chassis LED panel support.\n"); - handle = 1; - } - - if (handle) { - /* initialize panic notifier chain */ - atomic_notifier_chain_register(&panic_notifier_list, - &pdc_chassis_panic_block); - - /* initialize reboot notifier chain */ - register_reboot_notifier(&pdc_chassis_reboot_block); - } + printk(KERN_INFO "Enabling %s chassis codes support v%s\n", + is_pdc_pat() ? "PDC_PAT" : "regular", + PDC_CHASSIS_VER); + + /* initialize panic notifier chain */ + atomic_notifier_chain_register(&panic_notifier_list, + &pdc_chassis_panic_block); + + /* initialize reboot notifier chain */ + register_reboot_notifier(&pdc_chassis_reboot_block); } #endif /* CONFIG_PDC_CHASSIS */ } @@ -215,9 +209,12 @@ int pdc_chassis_send_status(int message) } } else retval = -1; #else - if (unlikely(pdc_chassis_old)) { + if (1) { switch (message) { case PDC_CHASSIS_DIRECT_BSTART: + retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_INIT)); + break; + case PDC_CHASSIS_DIRECT_BCOMPLETE: retval = pdc_chassis_disp(PDC_CHASSIS_DISP_DATA(OSTAT_RUN)); break; @@ -244,3 +241,61 @@ int pdc_chassis_send_status(int message) #endif /* CONFIG_PDC_CHASSIS */ return retval; } + +#ifdef CONFIG_PDC_CHASSIS_WARN +#ifdef CONFIG_PROC_FS +static int pdc_chassis_warn_pread(char *page, char **start, off_t off, + int count, int *eof, void *data) +{ + char *out = page; + int len, ret; + unsigned long warn; + u32 warnreg; + + ret = pdc_chassis_warn(&warn); + if (ret != PDC_OK) + return -EIO; + + warnreg = (warn & 0xFFFFFFFF); + + if ((warnreg >> 24) & 0xFF) + out += sprintf(out, "Chassis component failure! (eg fan or PSU): 0x%.2x\n", ((warnreg >> 24) & 0xFF)); + + out += sprintf(out, "Battery: %s\n", (warnreg & 0x04) ? "Low!" : "OK"); + out += sprintf(out, "Temp low: %s\n", (warnreg & 0x02) ? "Exceeded!" : "OK"); + out += sprintf(out, "Temp mid: %s\n", (warnreg & 0x01) ? "Exceeded!" : "OK"); + + len = out - page - off; + if (len < count) { + *eof = 1; + if (len <= 0) return 0; + } else { + len = count; + } + *start = page + off; + return len; +} + +static int __init pdc_chassis_create_procfs(void) +{ + unsigned long test; + int ret; + + ret = pdc_chassis_warn(&test); + if ((ret == PDC_BAD_PROC) || (ret == PDC_BAD_OPTION)) { + /* seems that some boxes (eg L1000) do not implement this */ + printk(KERN_INFO "Chassis warnings not supported.\n"); + return 0; + } + + printk(KERN_INFO "Enabling PDC chassis warnings support v%s\n", + PDC_CHASSIS_VER); + create_proc_read_entry("chassis", 0400, NULL, pdc_chassis_warn_pread, + NULL); + return 0; +} + +__initcall(pdc_chassis_create_procfs); + +#endif /* CONFIG_PROC_FS */ +#endif /* CONFIG_PDC_CHASSIS_WARN */ diff --git a/trunk/arch/parisc/kernel/ptrace.c b/trunk/arch/parisc/kernel/ptrace.c index 413292f1a4a3..3f28de974556 100644 --- a/trunk/arch/parisc/kernel/ptrace.c +++ b/trunk/arch/parisc/kernel/ptrace.c @@ -91,7 +91,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) int copied; #ifdef __LP64__ - if (personality(child->personality) == PER_LINUX32) { + if (__is_compat_task(child)) { unsigned int tmp; addr &= 0xffffffffL; @@ -123,7 +123,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) case PTRACE_POKEDATA: ret = 0; #ifdef __LP64__ - if (personality(child->personality) == PER_LINUX32) { + if (__is_compat_task(child)) { unsigned int tmp = (unsigned int)data; DBG("sys_ptrace(POKE%s, %d, %lx, %lx)\n", request == PTRACE_POKETEXT ? "TEXT" : "DATA", @@ -146,7 +146,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) case PTRACE_PEEKUSR: { ret = -EIO; #ifdef __LP64__ - if (personality(child->personality) == PER_LINUX32) { + if (__is_compat_task(child)) { unsigned int tmp; if (addr & (sizeof(int)-1)) @@ -205,7 +205,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data) goto out_tsk; } #ifdef __LP64__ - if (personality(child->personality) == PER_LINUX32) { + if (__is_compat_task(child)) { if (addr & (sizeof(int)-1)) goto out_tsk; if ((addr = translate_usr_offset(addr)) < 0) diff --git a/trunk/arch/parisc/kernel/real2.S b/trunk/arch/parisc/kernel/real2.S index 8c2859cca77e..453d01a9f971 100644 --- a/trunk/arch/parisc/kernel/real2.S +++ b/trunk/arch/parisc/kernel/real2.S @@ -276,15 +276,6 @@ r64_ret: #endif - .export pc_in_user_space - .text - /* Doesn't belong here but I couldn't find a nicer spot. */ - /* Should never get called, only used by profile stuff in time.c */ -pc_in_user_space: - bv,n 0(%rp) - nop - - .export __canonicalize_funcptr_for_compare .text /* http://lists.parisc-linux.org/hypermail/parisc-linux/10916.html diff --git a/trunk/arch/parisc/kernel/setup.c b/trunk/arch/parisc/kernel/setup.c index 4a36ec3f6ac1..278f4b9f6a38 100644 --- a/trunk/arch/parisc/kernel/setup.c +++ b/trunk/arch/parisc/kernel/setup.c @@ -303,6 +303,8 @@ extern void eisa_init(void); static int __init parisc_init(void) { + u32 osid = (OS_ID_LINUX << 16); + parisc_proc_mkdir(); parisc_init_resources(); do_device_inventory(); /* probe for hardware */ @@ -311,6 +313,9 @@ static int __init parisc_init(void) /* set up a new led state on systems shipped LED State panel */ pdc_chassis_send_status(PDC_CHASSIS_DIRECT_BSTART); + + /* tell PDC we're Linux. Nevermind failure. */ + pdc_stable_write(0x40, &osid, sizeof(osid)); processor_init(); printk(KERN_INFO "CPU(s): %d x %s at %d.%06d MHz\n", diff --git a/trunk/arch/parisc/kernel/signal.c b/trunk/arch/parisc/kernel/signal.c index cc38edfd90c5..bb83880c5ee3 100644 --- a/trunk/arch/parisc/kernel/signal.c +++ b/trunk/arch/parisc/kernel/signal.c @@ -76,7 +76,7 @@ sys_rt_sigsuspend(sigset_t __user *unewset, size_t sigsetsize, struct pt_regs *r #ifdef __LP64__ compat_sigset_t newset32; - if(personality(current->personality) == PER_LINUX32){ + if (is_compat_task()) { /* XXX: Don't preclude handling different sized sigset_t's. */ if (sigsetsize != sizeof(compat_sigset_t)) return -EINVAL; @@ -153,7 +153,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) compat_sigset_t compat_set; struct compat_rt_sigframe __user * compat_frame; - if(personality(current->personality) == PER_LINUX32) + if (is_compat_task()) sigframe_size = PARISC_RT_SIGFRAME_SIZE32; #endif @@ -166,7 +166,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) #ifdef __LP64__ compat_frame = (struct compat_rt_sigframe __user *)frame; - if(personality(current->personality) == PER_LINUX32){ + if (is_compat_task()) { DBG(2,"sys_rt_sigreturn: ELF32 process.\n"); if (__copy_from_user(&compat_set, &compat_frame->uc.uc_sigmask, sizeof(compat_set))) goto give_sigsegv; @@ -186,7 +186,7 @@ sys_rt_sigreturn(struct pt_regs *regs, int in_syscall) /* Good thing we saved the old gr[30], eh? */ #ifdef __LP64__ - if(personality(current->personality) == PER_LINUX32){ + if (is_compat_task()) { DBG(1,"sys_rt_sigreturn: compat_frame->uc.uc_mcontext 0x%p\n", &compat_frame->uc.uc_mcontext); // FIXME: Load upper half from register file @@ -315,7 +315,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, compat_frame = (struct compat_rt_sigframe __user *)frame; - if(personality(current->personality) == PER_LINUX32) { + if (is_compat_task()) { DBG(1,"setup_rt_frame: frame->info = 0x%p\n", &compat_frame->info); err |= copy_siginfo_to_user32(&compat_frame->info, info); DBG(1,"SETUP_RT_FRAME: 1\n"); @@ -392,7 +392,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, haddr = A(ka->sa.sa_handler); /* The sa_handler may be a pointer to a function descriptor */ #ifdef __LP64__ - if(personality(current->personality) == PER_LINUX32) { + if (is_compat_task()) { #endif if (haddr & PA_PLABEL_FDESC) { Elf32_Fdesc fdesc; @@ -427,19 +427,19 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, */ sigframe_size = PARISC_RT_SIGFRAME_SIZE; #ifdef __LP64__ - if(personality(current->personality) == PER_LINUX32) + if (is_compat_task()) sigframe_size = PARISC_RT_SIGFRAME_SIZE32; #endif if (in_syscall) { regs->gr[31] = haddr; #ifdef __LP64__ - if(personality(current->personality) == PER_LINUX) + if (personality(current->personality) == PER_LINUX) sigframe_size |= 1; #endif } else { unsigned long psw = USER_PSW; #ifdef __LP64__ - if(personality(current->personality) == PER_LINUX) + if (personality(current->personality) == PER_LINUX) psw |= PSW_W; #endif @@ -464,7 +464,7 @@ setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, regs->gr[26] = sig; /* signal number */ #ifdef __LP64__ - if(personality(current->personality) == PER_LINUX32){ + if (is_compat_task()) { regs->gr[25] = A(&compat_frame->info); /* siginfo pointer */ regs->gr[24] = A(&compat_frame->uc); /* ucontext pointer */ } else diff --git a/trunk/arch/parisc/kernel/syscall.S b/trunk/arch/parisc/kernel/syscall.S index 479d9a017cd1..9670a89c77fe 100644 --- a/trunk/arch/parisc/kernel/syscall.S +++ b/trunk/arch/parisc/kernel/syscall.S @@ -29,18 +29,6 @@ .level 1.1 #endif -#ifndef CONFIG_64BIT - .macro fixup_branch,lbl - b \lbl - .endm -#else - .macro fixup_branch,lbl - ldil L%\lbl, %r1 - ldo R%\lbl(%r1), %r1 - bv,n %r0(%r1) - .endm -#endif - .text .import syscall_exit,code @@ -541,7 +529,7 @@ cas_nocontend: # endif /* ENABLE_LWS_DEBUG */ - ldcw 0(%sr2,%r20), %r28 /* Try to acquire the lock */ + LDCW 0(%sr2,%r20), %r28 /* Try to acquire the lock */ cmpb,<>,n %r0, %r28, cas_action /* Did we get it? */ cas_wouldblock: ldo 2(%r0), %r28 /* 2nd case */ diff --git a/trunk/arch/parisc/kernel/time.c b/trunk/arch/parisc/kernel/time.c index 594930bc4bcf..eb35e1c0bb53 100644 --- a/trunk/arch/parisc/kernel/time.c +++ b/trunk/arch/parisc/kernel/time.c @@ -157,8 +157,22 @@ do_gettimeofday (struct timeval *tv) usec += (xtime.tv_nsec / 1000); } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - while (usec >= 1000000) { - usec -= 1000000; + if (unlikely(usec > LONG_MAX)) { + /* This can happen if the gettimeoffset adjustment is + * negative and xtime.tv_nsec is smaller than the + * adjustment */ + printk(KERN_ERR "do_gettimeofday() spurious xtime.tv_nsec of %ld\n", usec); + usec += USEC_PER_SEC; + --sec; + /* This should never happen, it means the negative + * time adjustment was more than a second, so there's + * something seriously wrong */ + BUG_ON(usec > LONG_MAX); + } + + + while (usec >= USEC_PER_SEC) { + usec -= USEC_PER_SEC; ++sec; } diff --git a/trunk/arch/parisc/kernel/traps.c b/trunk/arch/parisc/kernel/traps.c index ff200608c851..348344a84bf7 100644 --- a/trunk/arch/parisc/kernel/traps.c +++ b/trunk/arch/parisc/kernel/traps.c @@ -66,57 +66,42 @@ int printbinary(char *buf, unsigned long x, int nbits) #else #define RFMT "%08lx" #endif +#define FFMT "%016llx" /* fpregs are 64-bit always */ -void show_regs(struct pt_regs *regs) +#define PRINTREGS(lvl,r,f,fmt,x) \ + printk("%s%s%02d-%02d " fmt " " fmt " " fmt " " fmt "\n", \ + lvl, f, (x), (x+3), (r)[(x)+0], (r)[(x)+1], \ + (r)[(x)+2], (r)[(x)+3]) + +static void print_gr(char *level, struct pt_regs *regs) { int i; - char buf[128], *p; - char *level; - unsigned long cr30; - unsigned long cr31; - /* carlos says that gcc understands better memory in a struct, - * and it makes our life easier with fpregs -- T-Bone */ - struct { u32 sw[2]; } s; - - level = user_mode(regs) ? KERN_DEBUG : KERN_CRIT; - - printk("%s\n", level); /* don't want to have that pretty register dump messed up */ + char buf[64]; + printk("%s\n", level); printk("%s YZrvWESTHLNXBCVMcbcbcbcbOGFRQPDI\n", level); printbinary(buf, regs->gr[0], 32); printk("%sPSW: %s %s\n", level, buf, print_tainted()); - for (i = 0; i < 32; i += 4) { - int j; - p = buf; - p += sprintf(p, "%sr%02d-%02d ", level, i, i + 3); - for (j = 0; j < 4; j++) { - p += sprintf(p, " " RFMT, (i+j) == 0 ? 0 : regs->gr[i + j]); - } - printk("%s\n", buf); - } + for (i = 0; i < 32; i += 4) + PRINTREGS(level, regs->gr, "r", RFMT, i); +} - for (i = 0; i < 8; i += 4) { - int j; - p = buf; - p += sprintf(p, "%ssr%d-%d ", level, i, i + 3); - for (j = 0; j < 4; j++) { - p += sprintf(p, " " RFMT, regs->sr[i + j]); - } - printk("%s\n", buf); - } +static void print_fr(char *level, struct pt_regs *regs) +{ + int i; + char buf[64]; + struct { u32 sw[2]; } s; /* FR are 64bit everywhere. Need to use asm to get the content * of fpsr/fper1, and we assume that we won't have a FP Identify * in our way, otherwise we're screwed. * The fldd is used to restore the T-bit if there was one, as the * store clears it anyway. - * BTW, PA2.0 book says "thou shall not use fstw on FPSR/FPERs". */ - __asm__ ( - "fstd %%fr0,0(%1) \n\t" - "fldd 0(%1),%%fr0 \n\t" - : "=m" (s) : "r" (&s) : "%r0" - ); + * PA2.0 book says "thou shall not use fstw on FPSR/FPERs" - T-Bone */ + asm volatile ("fstd %%fr0,0(%1) \n\t" + "fldd 0(%1),%%fr0 \n\t" + : "=m" (s) : "r" (&s) : "r0"); printk("%s\n", level); printk("%s VZOUICununcqcqcqcqcqcrmunTDVZOUI\n", level); @@ -125,14 +110,25 @@ void show_regs(struct pt_regs *regs) printk("%sFPER1: %08x\n", level, s.sw[1]); /* here we'll print fr0 again, tho it'll be meaningless */ - for (i = 0; i < 32; i += 4) { - int j; - p = buf; - p += sprintf(p, "%sfr%02d-%02d ", level, i, i + 3); - for (j = 0; j < 4; j++) - p += sprintf(p, " %016llx", (i+j) == 0 ? 0 : regs->fr[i+j]); - printk("%s\n", buf); - } + for (i = 0; i < 32; i += 4) + PRINTREGS(level, regs->fr, "fr", FFMT, i); +} + +void show_regs(struct pt_regs *regs) +{ + int i; + char *level; + unsigned long cr30, cr31; + + level = user_mode(regs) ? KERN_DEBUG : KERN_CRIT; + + print_gr(level, regs); + + for (i = 0; i < 8; i += 4) + PRINTREGS(level, regs->sr, "sr", RFMT, i); + + if (user_mode(regs)) + print_fr(level, regs); cr30 = mfctl(30); cr31 = mfctl(31); diff --git a/trunk/arch/parisc/kernel/unaligned.c b/trunk/arch/parisc/kernel/unaligned.c index de0a1b21cb40..92328fbddb3e 100644 --- a/trunk/arch/parisc/kernel/unaligned.c +++ b/trunk/arch/parisc/kernel/unaligned.c @@ -43,6 +43,8 @@ "\tldil L%%" #lbl ", %%r1\n" \ "\tldo R%%" #lbl "(%%r1), %%r1\n" \ "\tbv,n %%r0(%%r1)\n" +/* If you use FIXUP_BRANCH, then you must list this clobber */ +#define FIXUP_BRANCH_CLOBBER "r1" /* 1111 1100 0000 0000 0001 0011 1100 0000 */ #define OPCODE1(a,b,c) ((a)<<26|(b)<<12|(c)<<6) @@ -157,7 +159,7 @@ static int emulate_ldh(struct pt_regs *regs, int toreg) " .previous\n" : "=r" (val), "=r" (ret) : "0" (val), "r" (saddr), "r" (regs->isr) - : "r20" ); + : "r20", FIXUP_BRANCH_CLOBBER ); DPRINTF("val = 0x" RFMT "\n", val); @@ -202,7 +204,7 @@ static int emulate_ldw(struct pt_regs *regs, int toreg, int flop) " .previous\n" : "=r" (val), "=r" (ret) : "0" (val), "r" (saddr), "r" (regs->isr) - : "r19", "r20" ); + : "r19", "r20", FIXUP_BRANCH_CLOBBER ); DPRINTF("val = 0x" RFMT "\n", val); @@ -253,7 +255,7 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop) " .previous\n" : "=r" (val), "=r" (ret) : "0" (val), "r" (saddr), "r" (regs->isr) - : "r19", "r20" ); + : "r19", "r20", FIXUP_BRANCH_CLOBBER ); #else { unsigned long valh=0,vall=0; @@ -287,7 +289,7 @@ static int emulate_ldd(struct pt_regs *regs, int toreg, int flop) " .previous\n" : "=r" (valh), "=r" (vall), "=r" (ret) : "0" (valh), "1" (vall), "r" (saddr), "r" (regs->isr) - : "r19", "r20" ); + : "r19", "r20", FIXUP_BRANCH_CLOBBER ); val=((__u64)valh<<32)|(__u64)vall; } #endif @@ -335,7 +337,7 @@ static int emulate_sth(struct pt_regs *regs, int frreg) " .previous\n" : "=r" (ret) : "r" (val), "r" (regs->ior), "r" (regs->isr) - : "r19" ); + : "r19", FIXUP_BRANCH_CLOBBER ); return ret; } @@ -389,7 +391,7 @@ static int emulate_stw(struct pt_regs *regs, int frreg, int flop) " .previous\n" : "=r" (ret) : "r" (val), "r" (regs->ior), "r" (regs->isr) - : "r19", "r20", "r21", "r22", "r1" ); + : "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER ); return 0; } @@ -450,7 +452,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop) " .previous\n" : "=r" (ret) : "r" (val), "r" (regs->ior), "r" (regs->isr) - : "r19", "r20", "r21", "r22", "r1" ); + : "r19", "r20", "r21", "r22", "r1", FIXUP_BRANCH_CLOBBER ); #else { unsigned long valh=(val>>32),vall=(val&0xffffffffl); @@ -495,7 +497,7 @@ static int emulate_std(struct pt_regs *regs, int frreg, int flop) " .previous\n" : "=r" (ret) : "r" (valh), "r" (vall), "r" (regs->ior), "r" (regs->isr) - : "r19", "r20", "r21", "r1" ); + : "r19", "r20", "r21", "r1", FIXUP_BRANCH_CLOBBER ); } #endif diff --git a/trunk/arch/powerpc/Kconfig b/trunk/arch/powerpc/Kconfig index e922a88b2bad..b9a40a35a9ed 100644 --- a/trunk/arch/powerpc/Kconfig +++ b/trunk/arch/powerpc/Kconfig @@ -30,6 +30,10 @@ config GENERIC_HARDIRQS bool default y +config IRQ_PER_CPU + bool + default y + config RWSEM_GENERIC_SPINLOCK bool @@ -336,7 +340,7 @@ config PPC_ISERIES config EMBEDDED6xx bool "Embedded 6xx/7xx/7xxx-based board" - depends on PPC32 && BROKEN + depends on PPC32 && (BROKEN||BROKEN_ON_SMP) config APUS bool "Amiga-APUS" @@ -413,12 +417,17 @@ config PPC_CELL_NATIVE default n config PPC_IBM_CELL_BLADE - bool " IBM Cell Blade" + bool "IBM Cell Blade" depends on PPC_MULTIPLATFORM && PPC64 select PPC_CELL_NATIVE select PPC_RTAS select MMIO_NVRAM select PPC_UDBG_16550 + select UDBG_RTAS_CONSOLE + +config UDBG_RTAS_CONSOLE + bool + default n config XICS depends on PPC_PSERIES @@ -431,7 +440,8 @@ config U3_DART default n config MPIC - depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP + depends on PPC_PSERIES || PPC_PMAC || PPC_MAPLE || PPC_CHRP \ + || MPC7448HPC2 bool default y @@ -557,6 +567,13 @@ config TAU_AVERAGE /proc/cpuinfo. If in doubt, say N here. + +config PPC_TODC + depends on EMBEDDED6xx + bool "Generic Time-of-day Clock (TODC) support" + ---help--- + This adds support for many TODC/RTC chips. + endmenu source arch/powerpc/platforms/embedded6xx/Kconfig @@ -618,6 +635,9 @@ config HOTPLUG_CPU Say N if you are unsure. +config ARCH_ENABLE_MEMORY_HOTPLUG + def_bool y + config KEXEC bool "kexec system call (EXPERIMENTAL)" depends on PPC_MULTIPLATFORM && EXPERIMENTAL @@ -794,7 +814,6 @@ config GENERIC_ISA_DMA config PPC_I8259 bool - default y if MPC8641_HPCN default n config PPC_INDIRECT_PCI @@ -817,7 +836,8 @@ config MCA bool config PCI - bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx || PPC_MPC52xx || (EMBEDDED && PPC_ISERIES) + bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_MPC52xx || (EMBEDDED && PPC_ISERIES) \ + || MPC7448HPC2 default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx && !PPC_85xx && !PPC_86xx default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS default PCI_QSPAN if !4xx && !CPM2 && 8xx diff --git a/trunk/arch/powerpc/Kconfig.debug b/trunk/arch/powerpc/Kconfig.debug index c69006ae8246..e29ef77d3b00 100644 --- a/trunk/arch/powerpc/Kconfig.debug +++ b/trunk/arch/powerpc/Kconfig.debug @@ -134,12 +134,19 @@ config PPC_EARLY_DEBUG_G5 help Select this to enable early debugging for Apple G5 machines. -config PPC_EARLY_DEBUG_RTAS +config PPC_EARLY_DEBUG_RTAS_PANEL bool "RTAS Panel" depends on PPC_RTAS help Select this to enable early debugging via the RTAS panel. +config PPC_EARLY_DEBUG_RTAS_CONSOLE + bool "RTAS Console" + depends on PPC_RTAS + select UDBG_RTAS_CONSOLE + help + Select this to enable early debugging via the RTAS console. + config PPC_EARLY_DEBUG_MAPLE bool "Maple real mode" depends on PPC_MAPLE diff --git a/trunk/arch/powerpc/configs/cell_defconfig b/trunk/arch/powerpc/configs/cell_defconfig index b8b8d4675dc0..e028a2ecb8a3 100644 --- a/trunk/arch/powerpc/configs/cell_defconfig +++ b/trunk/arch/powerpc/configs/cell_defconfig @@ -1,7 +1,7 @@ # # Automatically generated make config: don't edit -# Linux kernel version: 2.6.17 -# Mon Jun 19 17:23:03 2006 +# Linux kernel version: 2.6.17-rc6 +# Thu Jun 22 15:28:36 2006 # CONFIG_PPC64=y CONFIG_64BIT=y @@ -1063,7 +1063,8 @@ CONFIG_DEBUG_FS=y # CONFIG_DEBUG_STACKOVERFLOW is not set # CONFIG_DEBUG_STACK_USAGE is not set CONFIG_DEBUGGER=y -# CONFIG_XMON is not set +CONFIG_XMON=y +CONFIG_XMON_DEFAULT=y CONFIG_IRQSTACKS=y # CONFIG_BOOTX_TEXT is not set # CONFIG_PPC_EARLY_DEBUG is not set diff --git a/trunk/arch/powerpc/configs/mpc7448_hpc2_defconfig b/trunk/arch/powerpc/configs/mpc7448_hpc2_defconfig new file mode 100644 index 000000000000..15a50f4ceb1f --- /dev/null +++ b/trunk/arch/powerpc/configs/mpc7448_hpc2_defconfig @@ -0,0 +1,923 @@ +# +# Automatically generated make config: don't edit +# Linux kernel version: 2.6.17-rc4 +# Sat May 27 18:45:55 2006 +# +# CONFIG_PPC64 is not set +CONFIG_PPC32=y +CONFIG_PPC_MERGE=y +CONFIG_MMU=y +CONFIG_GENERIC_HARDIRQS=y +CONFIG_RWSEM_XCHGADD_ALGORITHM=y +CONFIG_GENERIC_HWEIGHT=y +CONFIG_GENERIC_CALIBRATE_DELAY=y +CONFIG_PPC=y +CONFIG_EARLY_PRINTK=y +CONFIG_GENERIC_NVRAM=y +CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y +CONFIG_ARCH_MAY_HAVE_PC_FDC=y +CONFIG_PPC_OF=y +CONFIG_PPC_UDBG_16550=y +# CONFIG_GENERIC_TBSYNC is not set +CONFIG_DEFAULT_UIMAGE=y + +# +# Processor support +# +CONFIG_CLASSIC32=y +# CONFIG_PPC_52xx is not set +# CONFIG_PPC_82xx is not set +# CONFIG_PPC_83xx is not set +# CONFIG_PPC_85xx is not set +# CONFIG_40x is not set +# CONFIG_44x is not set +# CONFIG_8xx is not set +# CONFIG_E200 is not set +CONFIG_6xx=y +CONFIG_PPC_FPU=y +# CONFIG_ALTIVEC is not set +CONFIG_PPC_STD_MMU=y +CONFIG_PPC_STD_MMU_32=y +# CONFIG_SMP is not set + +# +# Code maturity level options +# +CONFIG_EXPERIMENTAL=y +CONFIG_BROKEN_ON_SMP=y +CONFIG_INIT_ENV_ARG_LIMIT=32 + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_SWAP=y +CONFIG_SYSVIPC=y +# CONFIG_POSIX_MQUEUE is not set +# CONFIG_BSD_PROCESS_ACCT is not set +CONFIG_SYSCTL=y +# CONFIG_AUDIT is not set +# CONFIG_IKCONFIG is not set +# CONFIG_RELAY is not set +CONFIG_INITRAMFS_SOURCE="" +# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set +CONFIG_EMBEDDED=y +CONFIG_KALLSYMS=y +# CONFIG_KALLSYMS_EXTRA_PASS is not set +CONFIG_HOTPLUG=y +CONFIG_PRINTK=y +CONFIG_BUG=y +CONFIG_ELF_CORE=y +CONFIG_BASE_FULL=y +CONFIG_FUTEX=y +CONFIG_EPOLL=y +CONFIG_SHMEM=y +CONFIG_SLAB=y +# CONFIG_TINY_SHMEM is not set +CONFIG_BASE_SMALL=0 +# CONFIG_SLOB is not set + +# +# Loadable module support +# +# CONFIG_MODULES is not set + +# +# Block layer +# +CONFIG_LBD=y +# CONFIG_BLK_DEV_IO_TRACE is not set +# CONFIG_LSF is not set + +# +# 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_MULTIPLATFORM is not set +# CONFIG_PPC_ISERIES is not set +CONFIG_EMBEDDED6xx=y +# CONFIG_APUS is not set +CONFIG_MPIC=y +# CONFIG_PPC_RTAS is not set +# CONFIG_MMIO_NVRAM is not set +# CONFIG_PPC_MPC106 is not set +# CONFIG_PPC_970_NAP is not set +# CONFIG_CPU_FREQ is not set +# CONFIG_TAU is not set +# CONFIG_KATANA is not set +# CONFIG_WILLOW is not set +# CONFIG_CPCI690 is not set +# CONFIG_POWERPMC250 is not set +# CONFIG_CHESTNUT is not set +# CONFIG_SPRUCE is not set +# CONFIG_HDPU is not set +# CONFIG_EV64260 is not set +# CONFIG_LOPEC is not set +# CONFIG_MVME5100 is not set +# CONFIG_PPLUS is not set +# CONFIG_PRPMC750 is not set +# CONFIG_PRPMC800 is not set +# CONFIG_SANDPOINT is not set +CONFIG_MPC7448HPC2=y +# CONFIG_RADSTONE_PPC7D is not set +# CONFIG_PAL4 is not set +# CONFIG_GEMINI is not set +# CONFIG_EST8260 is not set +# CONFIG_SBC82xx is not set +# CONFIG_SBS8260 is not set +# CONFIG_RPX8260 is not set +# CONFIG_TQM8260 is not set +# CONFIG_ADS8272 is not set +# CONFIG_PQ2FADS is not set +# CONFIG_LITE5200 is not set +# CONFIG_EV64360 is not set +CONFIG_TSI108_BRIDGE=y +# CONFIG_WANT_EARLY_SERIAL is not set + +# +# Kernel options +# +# CONFIG_HIGHMEM is not set +# 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_BINFMT_ELF=y +CONFIG_BINFMT_MISC=y +CONFIG_ARCH_FLATMEM_ENABLE=y +CONFIG_SELECT_MEMORY_MODEL=y +CONFIG_FLATMEM_MANUAL=y +# CONFIG_DISCONTIGMEM_MANUAL is not set +# CONFIG_SPARSEMEM_MANUAL is not set +CONFIG_FLATMEM=y +CONFIG_FLAT_NODE_MEM_MAP=y +# CONFIG_SPARSEMEM_STATIC is not set +CONFIG_SPLIT_PTLOCK_CPUS=4 +CONFIG_PROC_DEVICETREE=y +# CONFIG_CMDLINE_BOOL is not set +# CONFIG_PM is not set +# CONFIG_SOFTWARE_SUSPEND is not set +# CONFIG_SECCOMP is not set +CONFIG_ISA_DMA_API=y + +# +# Bus options +# +CONFIG_GENERIC_ISA_DMA=y +# CONFIG_PPC_I8259 is not set +# CONFIG_PPC_INDIRECT_PCI is not set +CONFIG_PCI=y +CONFIG_PCI_DOMAINS=y + +# +# PCCARD (PCMCIA/CardBus) support +# +# CONFIG_PCCARD is not set + +# +# PCI Hotplug Support +# +# CONFIG_HOTPLUG_PCI is not set + +# +# Advanced setup +# +# CONFIG_ADVANCED_OPTIONS is not set + +# +# Default settings for advanced configuration options are used +# +CONFIG_HIGHMEM_START=0xfe000000 +CONFIG_LOWMEM_SIZE=0x30000000 +CONFIG_KERNEL_START=0xc0000000 +CONFIG_TASK_SIZE=0x80000000 +CONFIG_BOOT_LOAD=0x00800000 + +# +# Networking +# +CONFIG_NET=y + +# +# Networking options +# +# CONFIG_NETDEBUG is not set +CONFIG_PACKET=y +# CONFIG_PACKET_MMAP is not set +CONFIG_UNIX=y +# CONFIG_NET_KEY is not set +CONFIG_INET=y +CONFIG_IP_MULTICAST=y +# CONFIG_IP_ADVANCED_ROUTER is not set +CONFIG_IP_FIB_HASH=y +CONFIG_IP_PNP=y +CONFIG_IP_PNP_DHCP=y +CONFIG_IP_PNP_BOOTP=y +# CONFIG_IP_PNP_RARP is not set +# CONFIG_NET_IPIP is not set +# CONFIG_NET_IPGRE is not set +# CONFIG_IP_MROUTE is not set +# CONFIG_ARPD is not set +CONFIG_SYN_COOKIES=y +# CONFIG_INET_AH is not set +# CONFIG_INET_ESP is not set +# CONFIG_INET_IPCOMP is not set +# CONFIG_INET_XFRM_TUNNEL is not set +# CONFIG_INET_TUNNEL is not set +CONFIG_INET_DIAG=y +CONFIG_INET_TCP_DIAG=y +# CONFIG_TCP_CONG_ADVANCED is not set +CONFIG_TCP_CONG_BIC=y +# CONFIG_IPV6 is not set +# CONFIG_INET6_XFRM_TUNNEL is not set +# CONFIG_INET6_TUNNEL is not set +# CONFIG_NETFILTER is not set + +# +# DCCP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_DCCP is not set + +# +# SCTP Configuration (EXPERIMENTAL) +# +# CONFIG_IP_SCTP is not set + +# +# TIPC Configuration (EXPERIMENTAL) +# +# CONFIG_TIPC is not set +# CONFIG_ATM is not set +# CONFIG_BRIDGE is not set +# CONFIG_VLAN_8021Q is not set +# CONFIG_DECNET is not set +# CONFIG_LLC2 is not set +# CONFIG_IPX is not set +# CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# 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 + +# +# Network testing +# +# CONFIG_NET_PKTGEN is not set +# CONFIG_HAMRADIO is not set +# CONFIG_IRDA is not set +# CONFIG_BT is not set +# CONFIG_IEEE80211 is not set + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_STANDALONE=y +CONFIG_PREVENT_FIRMWARE_BUILD=y +# CONFIG_FW_LOADER is not set + +# +# Connector - unified userspace <-> kernelspace linker +# +# CONFIG_CONNECTOR is not set + +# +# Memory Technology Devices (MTD) +# +# CONFIG_MTD is not set + +# +# Parallel port support +# +# CONFIG_PARPORT is not set + +# +# Plug and Play support +# + +# +# Block devices +# +# CONFIG_BLK_DEV_FD is not set +# CONFIG_BLK_CPQ_DA is not set +# CONFIG_BLK_CPQ_CISS_DA is not set +# CONFIG_BLK_DEV_DAC960 is not set +# CONFIG_BLK_DEV_UMEM is not set +# CONFIG_BLK_DEV_COW_COMMON is not set +CONFIG_BLK_DEV_LOOP=y +# CONFIG_BLK_DEV_CRYPTOLOOP is not set +# CONFIG_BLK_DEV_NBD is not set +# CONFIG_BLK_DEV_SX8 is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=131072 +CONFIG_BLK_DEV_INITRD=y +# CONFIG_CDROM_PKTCDVD is not set +# CONFIG_ATA_OVER_ETH is not set + +# +# ATA/ATAPI/MFM/RLL support +# +# CONFIG_IDE is not set + +# +# SCSI device support +# +# CONFIG_RAID_ATTRS is not set +CONFIG_SCSI=y +CONFIG_SCSI_PROC_FS=y + +# +# SCSI support type (disk, tape, CD-ROM) +# +CONFIG_BLK_DEV_SD=y +# CONFIG_CHR_DEV_ST is not set +# CONFIG_CHR_DEV_OSST is not set +# CONFIG_BLK_DEV_SR is not set +# CONFIG_CHR_DEV_SG is not set +# CONFIG_CHR_DEV_SCH is not set + +# +# Some SCSI devices (e.g. CD jukebox) support multiple LUNs +# +# CONFIG_SCSI_MULTI_LUN is not set +# CONFIG_SCSI_CONSTANTS is not set +# CONFIG_SCSI_LOGGING is not set + +# +# SCSI Transport Attributes +# +# CONFIG_SCSI_SPI_ATTRS is not set +# CONFIG_SCSI_FC_ATTRS is not set +# CONFIG_SCSI_ISCSI_ATTRS is not set +# CONFIG_SCSI_SAS_ATTRS is not set + +# +# 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 +# CONFIG_SCSI_AACRAID is not set +# CONFIG_SCSI_AIC7XXX is not set +# CONFIG_SCSI_AIC7XXX_OLD is not set +# CONFIG_SCSI_AIC79XX is not set +# CONFIG_SCSI_DPT_I2O is not set +# CONFIG_MEGARAID_NEWGEN is not set +# CONFIG_MEGARAID_LEGACY is not set +# CONFIG_MEGARAID_SAS is not set +CONFIG_SCSI_SATA=y +# CONFIG_SCSI_SATA_AHCI is not set +# CONFIG_SCSI_SATA_SVW is not set +# CONFIG_SCSI_ATA_PIIX is not set +CONFIG_SCSI_SATA_MV=y +# CONFIG_SCSI_SATA_NV is not set +# CONFIG_SCSI_PDC_ADMA is not set +# CONFIG_SCSI_SATA_QSTOR is not set +# CONFIG_SCSI_SATA_PROMISE is not set +# CONFIG_SCSI_SATA_SX4 is not set +# CONFIG_SCSI_SATA_SIL is not set +# CONFIG_SCSI_SATA_SIL24 is not set +# CONFIG_SCSI_SATA_SIS is not set +# CONFIG_SCSI_SATA_ULI is not set +# CONFIG_SCSI_SATA_VIA is not set +# CONFIG_SCSI_SATA_VITESSE is not set +# CONFIG_SCSI_BUSLOGIC is not set +# CONFIG_SCSI_DMX3191D is not set +# CONFIG_SCSI_EATA is not set +# CONFIG_SCSI_FUTURE_DOMAIN is not set +# CONFIG_SCSI_GDTH is not set +# CONFIG_SCSI_IPS is not set +# CONFIG_SCSI_INITIO is not set +# CONFIG_SCSI_INIA100 is not set +# CONFIG_SCSI_SYM53C8XX_2 is not set +# CONFIG_SCSI_IPR is not set +# CONFIG_SCSI_QLOGIC_1280 is not set +# CONFIG_SCSI_QLA_FC is not set +# CONFIG_SCSI_LPFC is not set +# CONFIG_SCSI_DC395x is not set +# CONFIG_SCSI_DC390T is not set +# CONFIG_SCSI_NSP32 is not set +# CONFIG_SCSI_DEBUG is not set + +# +# Multi-device support (RAID and LVM) +# +# CONFIG_MD is not set + +# +# Fusion MPT device support +# +# CONFIG_FUSION is not set +# CONFIG_FUSION_SPI is not set +# CONFIG_FUSION_FC is not set +# CONFIG_FUSION_SAS is not set + +# +# IEEE 1394 (FireWire) support +# +# CONFIG_IEEE1394 is not set + +# +# I2O device support +# +# CONFIG_I2O is not set + +# +# Macintosh device drivers +# +# CONFIG_WINDFARM is not set + +# +# Network device support +# +CONFIG_NETDEVICES=y +# CONFIG_DUMMY is not set +# CONFIG_BONDING is not set +# CONFIG_EQUALIZER is not set +# CONFIG_TUN is not set + +# +# ARCnet devices +# +# CONFIG_ARCNET is not set + +# +# PHY device support +# +CONFIG_PHYLIB=y + +# +# MII PHY device drivers +# +# CONFIG_MARVELL_PHY is not set +# CONFIG_DAVICOM_PHY is not set +# CONFIG_QSEMI_PHY is not set +# CONFIG_LXT_PHY is not set +# CONFIG_CICADA_PHY is not set + +# +# Ethernet (10 or 100Mbit) +# +CONFIG_NET_ETHERNET=y +CONFIG_MII=y +# CONFIG_HAPPYMEAL is not set +# CONFIG_SUNGEM is not set +# CONFIG_CASSINI is not set +# CONFIG_NET_VENDOR_3COM is not set + +# +# Tulip family network device support +# +# CONFIG_NET_TULIP is not set +# CONFIG_HP100 is not set +CONFIG_NET_PCI=y +# CONFIG_PCNET32 is not set +# CONFIG_AMD8111_ETH is not set +# CONFIG_ADAPTEC_STARFIRE is not set +# CONFIG_B44 is not set +# CONFIG_FORCEDETH is not set +# CONFIG_DGRS is not set +# CONFIG_EEPRO100 is not set +CONFIG_E100=y +# CONFIG_FEALNX is not set +# CONFIG_NATSEMI is not set +# CONFIG_NE2K_PCI is not set +# CONFIG_8139CP is not set +CONFIG_8139TOO=y +# CONFIG_8139TOO_PIO is not set +# CONFIG_8139TOO_TUNE_TWISTER is not set +# CONFIG_8139TOO_8129 is not set +# CONFIG_8139_OLD_RX_RESET is not set +# CONFIG_SIS900 is not set +# CONFIG_EPIC100 is not set +# CONFIG_SUNDANCE is not set +# CONFIG_TLAN is not set +# CONFIG_VIA_RHINE is not set + +# +# Ethernet (1000 Mbit) +# +# CONFIG_ACENIC is not set +# CONFIG_DL2K is not set +# CONFIG_E1000 is not set +# CONFIG_NS83820 is not set +# CONFIG_HAMACHI is not set +# CONFIG_YELLOWFIN is not set +# CONFIG_R8169 is not set +# CONFIG_SIS190 is not set +# CONFIG_SKGE is not set +# CONFIG_SKY2 is not set +# CONFIG_SK98LIN is not set +# CONFIG_VIA_VELOCITY is not set +# CONFIG_TIGON3 is not set +# CONFIG_BNX2 is not set +CONFIG_TSI108_ETH=y + +# +# Ethernet (10000 Mbit) +# +# CONFIG_CHELSIO_T1 is not set +# CONFIG_IXGB is not set +# CONFIG_S2IO is not set + +# +# Token Ring devices +# +# CONFIG_TR is not set + +# +# Wireless LAN (non-hamradio) +# +# CONFIG_NET_RADIO is not set + +# +# Wan interfaces +# +# CONFIG_WAN is not set +# CONFIG_FDDI is not set +# CONFIG_HIPPI is not set +# CONFIG_PPP is not set +# CONFIG_SLIP is not set +# CONFIG_NET_FC is not set +# CONFIG_SHAPER is not set +# CONFIG_NETCONSOLE is not set +# CONFIG_NETPOLL is not set +# CONFIG_NET_POLL_CONTROLLER is not set + +# +# ISDN subsystem +# +# CONFIG_ISDN is not set + +# +# Telephony Support +# +# CONFIG_PHONE is not set + +# +# Input device support +# +CONFIG_INPUT=y + +# +# Userland interfaces +# +# CONFIG_INPUT_MOUSEDEV is not set +# CONFIG_INPUT_JOYDEV is not set +# CONFIG_INPUT_TSDEV is not set +# CONFIG_INPUT_EVDEV is not set +# CONFIG_INPUT_EVBUG is not set + +# +# Input Device Drivers +# +# CONFIG_INPUT_KEYBOARD is not set +# CONFIG_INPUT_MOUSE is not set +# CONFIG_INPUT_JOYSTICK is not set +# CONFIG_INPUT_TOUCHSCREEN is not set +# CONFIG_INPUT_MISC is not set + +# +# Hardware I/O ports +# +# CONFIG_SERIO is not set +# CONFIG_GAMEPORT is not set + +# +# Character devices +# +# CONFIG_VT is not set +# CONFIG_SERIAL_NONSTANDARD is not set + +# +# Serial drivers +# +CONFIG_SERIAL_8250=y +CONFIG_SERIAL_8250_CONSOLE=y +CONFIG_SERIAL_8250_PCI=y +CONFIG_SERIAL_8250_NR_UARTS=4 +CONFIG_SERIAL_8250_RUNTIME_UARTS=4 +# CONFIG_SERIAL_8250_EXTENDED is not set + +# +# Non-8250 serial port support +# +CONFIG_SERIAL_CORE=y +CONFIG_SERIAL_CORE_CONSOLE=y +# CONFIG_SERIAL_JSM is not set +CONFIG_UNIX98_PTYS=y +CONFIG_LEGACY_PTYS=y +CONFIG_LEGACY_PTY_COUNT=256 + +# +# IPMI +# +# CONFIG_IPMI_HANDLER is not set + +# +# Watchdog Cards +# +# CONFIG_WATCHDOG is not set +# CONFIG_NVRAM 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 + +# +# Ftape, the floppy tape device driver +# +# CONFIG_AGP is not set +# CONFIG_DRM is not set +# CONFIG_RAW_DRIVER is not set + +# +# TPM devices +# +# CONFIG_TCG_TPM is not set +# CONFIG_TELCLOCK is not set + +# +# I2C support +# +# CONFIG_I2C is not set + +# +# SPI support +# +# CONFIG_SPI is not set +# CONFIG_SPI_MASTER is not set + +# +# Dallas's 1-wire bus +# +# CONFIG_W1 is not set + +# +# Hardware Monitoring support +# +CONFIG_HWMON=y +# CONFIG_HWMON_VID is not set +# CONFIG_SENSORS_F71805F is not set +# CONFIG_HWMON_DEBUG_CHIP is not set + +# +# Misc devices +# + +# +# Multimedia devices +# +# CONFIG_VIDEO_DEV is not set + +# +# Digital Video Broadcasting Devices +# +# CONFIG_DVB is not set + +# +# Graphics support +# +# CONFIG_FB is not set + +# +# Sound +# +# CONFIG_SOUND is not set + +# +# USB support +# +CONFIG_USB_ARCH_HAS_HCD=y +CONFIG_USB_ARCH_HAS_OHCI=y +CONFIG_USB_ARCH_HAS_EHCI=y +# CONFIG_USB is not set + +# +# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support' +# + +# +# USB Gadget Support +# +# CONFIG_USB_GADGET is not set + +# +# MMC/SD Card support +# +# CONFIG_MMC is not set + +# +# LED devices +# +# CONFIG_NEW_LEDS is not set + +# +# LED drivers +# + +# +# LED Triggers +# + +# +# InfiniBand support +# +# CONFIG_INFINIBAND is not set + +# +# EDAC - error detection and reporting (RAS) (EXPERIMENTAL) +# + +# +# Real Time Clock +# +# CONFIG_RTC_CLASS is not set + +# +# File systems +# +CONFIG_EXT2_FS=y +# CONFIG_EXT2_FS_XATTR is not set +# CONFIG_EXT2_FS_XIP is not set +CONFIG_EXT3_FS=y +CONFIG_EXT3_FS_XATTR=y +# CONFIG_EXT3_FS_POSIX_ACL is not set +# CONFIG_EXT3_FS_SECURITY is not set +CONFIG_JBD=y +# CONFIG_JBD_DEBUG is not set +CONFIG_FS_MBCACHE=y +# CONFIG_REISERFS_FS is not set +# CONFIG_JFS_FS is not set +# CONFIG_FS_POSIX_ACL is not set +# CONFIG_XFS_FS is not set +# CONFIG_OCFS2_FS is not set +# CONFIG_MINIX_FS is not set +# CONFIG_ROMFS_FS is not set +CONFIG_INOTIFY=y +# CONFIG_QUOTA is not set +CONFIG_DNOTIFY=y +# CONFIG_AUTOFS_FS is not set +# CONFIG_AUTOFS4_FS is not set +# CONFIG_FUSE_FS is not set + +# +# CD-ROM/DVD Filesystems +# +# CONFIG_ISO9660_FS is not set +# CONFIG_UDF_FS is not set + +# +# DOS/FAT/NT Filesystems +# +# CONFIG_MSDOS_FS is not set +# CONFIG_VFAT_FS is not set +# CONFIG_NTFS_FS is not set + +# +# Pseudo filesystems +# +CONFIG_PROC_FS=y +CONFIG_PROC_KCORE=y +CONFIG_SYSFS=y +CONFIG_TMPFS=y +# CONFIG_HUGETLB_PAGE is not set +CONFIG_RAMFS=y +# CONFIG_CONFIGFS_FS is not set + +# +# Miscellaneous filesystems +# +# CONFIG_ADFS_FS is not set +# CONFIG_AFFS_FS is not set +# CONFIG_HFS_FS is not set +# CONFIG_HFSPLUS_FS is not set +# CONFIG_BEFS_FS is not set +# CONFIG_BFS_FS is not set +# CONFIG_EFS_FS is not set +# CONFIG_CRAMFS is not set +# CONFIG_VXFS_FS is not set +# CONFIG_HPFS_FS is not set +# CONFIG_QNX4FS_FS is not set +# CONFIG_SYSV_FS is not set +# CONFIG_UFS_FS is not set + +# +# Network File Systems +# +CONFIG_NFS_FS=y +# CONFIG_NFS_V3 is not set +# CONFIG_NFS_V4 is not set +# CONFIG_NFS_DIRECTIO is not set +# CONFIG_NFSD is not set +CONFIG_ROOT_NFS=y +CONFIG_LOCKD=y +CONFIG_NFS_COMMON=y +CONFIG_SUNRPC=y +# CONFIG_RPCSEC_GSS_KRB5 is not set +# CONFIG_RPCSEC_GSS_SPKM3 is not set +# CONFIG_SMB_FS is not set +# CONFIG_CIFS is not set +# CONFIG_NCP_FS is not set +# CONFIG_CODA_FS is not set +# CONFIG_AFS_FS is not set +# CONFIG_9P_FS is not set + +# +# Partition Types +# +CONFIG_PARTITION_ADVANCED=y +# CONFIG_ACORN_PARTITION is not set +# CONFIG_OSF_PARTITION is not set +# CONFIG_AMIGA_PARTITION is not set +# CONFIG_ATARI_PARTITION is not set +# CONFIG_MAC_PARTITION is not set +CONFIG_MSDOS_PARTITION=y +# CONFIG_BSD_DISKLABEL is not set +# CONFIG_MINIX_SUBPARTITION is not set +# CONFIG_SOLARIS_X86_PARTITION is not set +# CONFIG_UNIXWARE_DISKLABEL is not set +# CONFIG_LDM_PARTITION is not set +# CONFIG_SGI_PARTITION is not set +# CONFIG_ULTRIX_PARTITION is not set +# CONFIG_SUN_PARTITION is not set +# CONFIG_KARMA_PARTITION is not set +# CONFIG_EFI_PARTITION is not set + +# +# Native Language Support +# +# CONFIG_NLS is not set + +# +# Library routines +# +# CONFIG_CRC_CCITT is not set +# CONFIG_CRC16 is not set +CONFIG_CRC32=y +# CONFIG_LIBCRC32C is not set + +# +# Instrumentation Support +# +# CONFIG_PROFILING is not set + +# +# Kernel hacking +# +# CONFIG_PRINTK_TIME is not set +# CONFIG_MAGIC_SYSRQ is not set +# CONFIG_DEBUG_KERNEL is not set +CONFIG_LOG_BUF_SHIFT=14 +# CONFIG_DEBUG_FS is not set +# CONFIG_UNWIND_INFO is not set +# CONFIG_BOOTX_TEXT is not set +# CONFIG_SERIAL_TEXT_DEBUG is not set +# CONFIG_PPC_EARLY_DEBUG_LPAR is not set +# CONFIG_PPC_EARLY_DEBUG_G5 is not set +# CONFIG_PPC_EARLY_DEBUG_RTAS is not set +# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set +# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set + +# +# Security options +# +# CONFIG_KEYS is not set +# CONFIG_SECURITY is not set + +# +# Cryptographic options +# +# CONFIG_CRYPTO is not set + +# +# Hardware crypto devices +# diff --git a/trunk/arch/powerpc/kernel/Makefile b/trunk/arch/powerpc/kernel/Makefile index 803858e86160..814f242aeb8c 100644 --- a/trunk/arch/powerpc/kernel/Makefile +++ b/trunk/arch/powerpc/kernel/Makefile @@ -50,7 +50,8 @@ extra-$(CONFIG_FSL_BOOKE) := head_fsl_booke.o extra-$(CONFIG_8xx) := head_8xx.o extra-y += vmlinux.lds -obj-y += time.o prom.o traps.o setup-common.o udbg.o +obj-y += time.o prom.o traps.o setup-common.o \ + udbg.o misc.o obj-$(CONFIG_PPC32) += entry_32.o setup_32.o misc_32.o obj-$(CONFIG_PPC64) += misc_64.o dma_64.o iommu.o obj-$(CONFIG_PPC_MULTIPLATFORM) += prom_init.o diff --git a/trunk/arch/powerpc/kernel/cpu_setup_power4.S b/trunk/arch/powerpc/kernel/cpu_setup_power4.S index 271418308d53..1fc863261003 100644 --- a/trunk/arch/powerpc/kernel/cpu_setup_power4.S +++ b/trunk/arch/powerpc/kernel/cpu_setup_power4.S @@ -125,7 +125,12 @@ _GLOBAL(__save_cpu_setup) cmpwi r0,0x44 bne 2f -1: /* Save HID0,1,4 and 5 */ +1: /* skip if not running in HV mode */ + mfmsr r0 + rldicl. r0,r0,4,63 + beq 2f + + /* Save HID0,1,4 and 5 */ mfspr r3,SPRN_HID0 std r3,CS_HID0(r5) mfspr r3,SPRN_HID1 @@ -159,7 +164,12 @@ _GLOBAL(__restore_cpu_setup) cmpwi r0,0x44 bnelr -1: /* Before accessing memory, we make sure rm_ci is clear */ +1: /* skip if not running in HV mode */ + mfmsr r0 + rldicl. r0,r0,4,63 + beqlr + + /* Before accessing memory, we make sure rm_ci is clear */ li r0,0 mfspr r3,SPRN_HID4 rldimi r3,r0,40,23 /* clear bit 23 (rm_ci) */ diff --git a/trunk/arch/powerpc/kernel/cputable.c b/trunk/arch/powerpc/kernel/cputable.c index 1c114880dc05..abf7d42a8b07 100644 --- a/trunk/arch/powerpc/kernel/cputable.c +++ b/trunk/arch/powerpc/kernel/cputable.c @@ -722,18 +722,6 @@ struct cpu_spec cpu_specs[] = { .oprofile_type = PPC_OPROFILE_G4, .platform = "ppc7450", }, - { /* 8641 */ - .pvr_mask = 0xffffffff, - .pvr_value = 0x80040010, - .cpu_name = "8641", - .cpu_features = CPU_FTRS_7447A, - .cpu_user_features = COMMON_USER | PPC_FEATURE_HAS_ALTIVEC_COMP, - .icache_bsize = 32, - .dcache_bsize = 32, - .num_pmcs = 6, - .cpu_setup = __setup_cpu_745x - }, - { /* 82xx (8240, 8245, 8260 are all 603e cores) */ .pvr_mask = 0x7fff0000, .pvr_value = 0x00810000, diff --git a/trunk/arch/powerpc/kernel/crash.c b/trunk/arch/powerpc/kernel/crash.c index e253a45dcf10..358cecdc6aef 100644 --- a/trunk/arch/powerpc/kernel/crash.c +++ b/trunk/arch/powerpc/kernel/crash.c @@ -24,9 +24,11 @@ #include #include #include +#include #include #include +#include #include #include #include @@ -41,6 +43,7 @@ /* This keeps a track of which one is crashing cpu. */ int crashing_cpu = -1; +static cpumask_t cpus_in_crash = CPU_MASK_NONE; static u32 *append_elf_note(u32 *buf, char *name, unsigned type, void *data, size_t data_len) @@ -98,34 +101,66 @@ static void crash_save_this_cpu(struct pt_regs *regs, int cpu) } #ifdef CONFIG_SMP -static atomic_t waiting_for_crash_ipi; +static atomic_t enter_on_soft_reset = ATOMIC_INIT(0); void crash_ipi_callback(struct pt_regs *regs) { int cpu = smp_processor_id(); - if (cpu == crashing_cpu) - return; - if (!cpu_online(cpu)) return; - if (ppc_md.kexec_cpu_down) - ppc_md.kexec_cpu_down(1, 1); - local_irq_disable(); + if (!cpu_isset(cpu, cpus_in_crash)) + crash_save_this_cpu(regs, cpu); + cpu_set(cpu, cpus_in_crash); - crash_save_this_cpu(regs, cpu); - atomic_dec(&waiting_for_crash_ipi); + /* + * Entered via soft-reset - could be the kdump + * process is invoked using soft-reset or user activated + * it if some CPU did not respond to an IPI. + * For soft-reset, the secondary CPU can enter this func + * twice. 1 - using IPI, and 2. soft-reset. + * Tell the kexec CPU that entered via soft-reset and ready + * to go down. + */ + if (cpu_isset(cpu, cpus_in_sr)) { + cpu_clear(cpu, cpus_in_sr); + atomic_inc(&enter_on_soft_reset); + } + + /* + * Starting the kdump boot. + * This barrier is needed to make sure that all CPUs are stopped. + * If not, soft-reset will be invoked to bring other CPUs. + */ + while (!cpu_isset(crashing_cpu, cpus_in_crash)) + cpu_relax(); + + if (ppc_md.kexec_cpu_down) + ppc_md.kexec_cpu_down(1, 1); kexec_smp_wait(); /* NOTREACHED */ } -static void crash_kexec_prepare_cpus(void) +/* + * Wait until all CPUs are entered via soft-reset. + */ +static void crash_soft_reset_check(int cpu) +{ + unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */ + + cpu_clear(cpu, cpus_in_sr); + while (atomic_read(&enter_on_soft_reset) != ncpus) + cpu_relax(); +} + + +static void crash_kexec_prepare_cpus(int cpu) { unsigned int msecs; - atomic_set(&waiting_for_crash_ipi, num_online_cpus() - 1); + unsigned int ncpus = num_online_cpus() - 1;/* Excluding the panic cpu */ crash_send_ipi(crash_ipi_callback); smp_wmb(); @@ -133,14 +168,13 @@ static void crash_kexec_prepare_cpus(void) /* * FIXME: Until we will have the way to stop other CPUSs reliabally, * the crash CPU will send an IPI and wait for other CPUs to - * respond. If not, proceed the kexec boot even though we failed to - * capture other CPU states. + * respond. * Delay of at least 10 seconds. */ - printk(KERN_ALERT "Sending IPI to other cpus...\n"); + printk(KERN_EMERG "Sending IPI to other cpus...\n"); msecs = 10000; - while ((atomic_read(&waiting_for_crash_ipi) > 0) && (--msecs > 0)) { - barrier(); + while ((cpus_weight(cpus_in_crash) < ncpus) && (--msecs > 0)) { + cpu_relax(); mdelay(1); } @@ -149,18 +183,71 @@ static void crash_kexec_prepare_cpus(void) /* * FIXME: In case if we do not get all CPUs, one possibility: ask the * user to do soft reset such that we get all. - * IPI handler is already set by the panic cpu initially. Therefore, - * all cpus could invoke this handler from die() and the panic CPU - * will call machine_kexec() directly from this handler to do - * kexec boot. + * Soft-reset will be used until better mechanism is implemented. + */ + if (cpus_weight(cpus_in_crash) < ncpus) { + printk(KERN_EMERG "done waiting: %d cpu(s) not responding\n", + ncpus - cpus_weight(cpus_in_crash)); + printk(KERN_EMERG "Activate soft-reset to stop other cpu(s)\n"); + cpus_in_sr = CPU_MASK_NONE; + atomic_set(&enter_on_soft_reset, 0); + while (cpus_weight(cpus_in_crash) < ncpus) + cpu_relax(); + } + /* + * Make sure all CPUs are entered via soft-reset if the kdump is + * invoked using soft-reset. */ - if (atomic_read(&waiting_for_crash_ipi)) - printk(KERN_ALERT "done waiting: %d cpus not responding\n", - atomic_read(&waiting_for_crash_ipi)); + if (cpu_isset(cpu, cpus_in_sr)) + crash_soft_reset_check(cpu); /* Leave the IPI callback set */ } + +/* + * This function will be called by secondary cpus or by kexec cpu + * if soft-reset is activated to stop some CPUs. + */ +void crash_kexec_secondary(struct pt_regs *regs) +{ + int cpu = smp_processor_id(); + unsigned long flags; + int msecs = 5; + + local_irq_save(flags); + /* Wait 5ms if the kexec CPU is not entered yet. */ + while (crashing_cpu < 0) { + if (--msecs < 0) { + /* + * Either kdump image is not loaded or + * kdump process is not started - Probably xmon + * exited using 'x'(exit and recover) or + * kexec_should_crash() failed for all running tasks. + */ + cpu_clear(cpu, cpus_in_sr); + local_irq_restore(flags); + return; + } + mdelay(1); + cpu_relax(); + } + if (cpu == crashing_cpu) { + /* + * Panic CPU will enter this func only via soft-reset. + * Wait until all secondary CPUs entered and + * then start kexec boot. + */ + crash_soft_reset_check(cpu); + cpu_set(crashing_cpu, cpus_in_crash); + if (ppc_md.kexec_cpu_down) + ppc_md.kexec_cpu_down(1, 0); + machine_kexec(kexec_crash_image); + /* NOTREACHED */ + } + crash_ipi_callback(regs); +} + #else -static void crash_kexec_prepare_cpus(void) +static void crash_kexec_prepare_cpus(int cpu) { /* * move the secondarys to us so that we can copy @@ -171,6 +258,10 @@ static void crash_kexec_prepare_cpus(void) smp_release_cpus(); } +void crash_kexec_secondary(struct pt_regs *regs) +{ + cpus_in_sr = CPU_MASK_NONE; +} #endif void default_machine_crash_shutdown(struct pt_regs *regs) @@ -190,23 +281,23 @@ void default_machine_crash_shutdown(struct pt_regs *regs) local_irq_disable(); for_each_irq(irq) { - struct irq_desc *desc = irq_descp(irq); + struct irq_desc *desc = irq_desc + irq; if (desc->status & IRQ_INPROGRESS) - desc->handler->end(irq); + desc->chip->end(irq); if (!(desc->status & IRQ_DISABLED)) - desc->handler->disable(irq); + desc->chip->disable(irq); } - if (ppc_md.kexec_cpu_down) - ppc_md.kexec_cpu_down(1, 0); - /* * Make a note of crashing cpu. Will be used in machine_kexec * such that another IPI will not be sent. */ crashing_cpu = smp_processor_id(); - crash_kexec_prepare_cpus(); crash_save_this_cpu(regs, crashing_cpu); + crash_kexec_prepare_cpus(crashing_cpu); + cpu_set(crashing_cpu, cpus_in_crash); + if (ppc_md.kexec_cpu_down) + ppc_md.kexec_cpu_down(1, 0); } diff --git a/trunk/arch/powerpc/kernel/head_64.S b/trunk/arch/powerpc/kernel/head_64.S index 831acbdf2592..8cfd040d1f50 100644 --- a/trunk/arch/powerpc/kernel/head_64.S +++ b/trunk/arch/powerpc/kernel/head_64.S @@ -85,34 +85,6 @@ END_FTR_SECTION(0, 1) /* Catch branch to 0 in real mode */ trap -#ifdef CONFIG_PPC_ISERIES - /* - * At offset 0x20, there is a pointer to iSeries LPAR data. - * This is required by the hypervisor - */ - . = 0x20 - .llong hvReleaseData-KERNELBASE - - /* - * At offset 0x28 and 0x30 are offsets to the mschunks_map - * array (used by the iSeries LPAR debugger to do translation - * between physical addresses and absolute addresses) and - * to the pidhash table (also used by the debugger) - */ - .llong mschunks_map-KERNELBASE - .llong 0 /* pidhash-KERNELBASE SFRXXX */ - - /* Offset 0x38 - Pointer to start of embedded System.map */ - .globl embedded_sysmap_start -embedded_sysmap_start: - .llong 0 - /* Offset 0x40 - Pointer to end of embedded System.map */ - .globl embedded_sysmap_end -embedded_sysmap_end: - .llong 0 - -#endif /* CONFIG_PPC_ISERIES */ - /* Secondary processors spin on this value until it goes to 1. */ .globl __secondary_hold_spinloop __secondary_hold_spinloop: @@ -124,6 +96,15 @@ __secondary_hold_spinloop: __secondary_hold_acknowledge: .llong 0x0 +#ifdef CONFIG_PPC_ISERIES + /* + * At offset 0x20, there is a pointer to iSeries LPAR data. + * This is required by the hypervisor + */ + . = 0x20 + .llong hvReleaseData-KERNELBASE +#endif /* CONFIG_PPC_ISERIES */ + . = 0x60 /* * The following code is used on pSeries to hold secondary processors @@ -1602,9 +1583,6 @@ _GLOBAL(__start_initialization_multiplatform) /* Setup some critical 970 SPRs before switching MMU off */ bl .__970_cpu_preinit - /* cpu # */ - li r24,0 - /* Switch off MMU if not already */ LOAD_REG_IMMEDIATE(r4, .__after_prom_start - KERNELBASE) add r4,r4,r30 @@ -1683,6 +1661,9 @@ _STATIC(__after_prom_start) /* i.e. where we are running */ /* the source addr */ + cmpdi r4,0 /* In some cases the loader may */ + beq .start_here_multiplatform /* have already put us at zero */ + /* so we can skip the copy. */ LOAD_REG_IMMEDIATE(r5,copy_to_here) /* # bytes of memory to copy */ sub r5,r5,r27 @@ -1962,14 +1943,6 @@ _STATIC(start_here_common) li r3,0 bl .do_cpu_ftr_fixups - LOAD_REG_IMMEDIATE(r26, boot_cpuid) - lwz r26,0(r26) - - LOAD_REG_IMMEDIATE(r24, paca) /* Get base vaddr of paca array */ - mulli r13,r26,PACA_SIZE /* Calculate vaddr of right paca */ - add r13,r13,r24 /* for this processor. */ - mtspr SPRN_SPRG3,r13 - /* ptr to current */ LOAD_REG_IMMEDIATE(r4, init_task) std r4,PACACURRENT(r13) @@ -1995,17 +1968,6 @@ _STATIC(start_here_common) /* Not reached */ BUG_OPCODE -/* Put the paca pointer into r13 and SPRG3 */ -_GLOBAL(setup_boot_paca) - LOAD_REG_IMMEDIATE(r3, boot_cpuid) - lwz r3,0(r3) - LOAD_REG_IMMEDIATE(r4, paca) /* Get base vaddr of paca array */ - mulli r3,r3,PACA_SIZE /* Calculate vaddr of right paca */ - add r13,r3,r4 /* for this processor. */ - mtspr SPRN_SPRG3,r13 - - blr - /* * We put a few things here that have to be page-aligned. * This stuff goes at the beginning of the bss, which is page-aligned. diff --git a/trunk/arch/powerpc/kernel/iommu.c b/trunk/arch/powerpc/kernel/iommu.c index 7cb77c20fc5d..3d677ac99659 100644 --- a/trunk/arch/powerpc/kernel/iommu.c +++ b/trunk/arch/powerpc/kernel/iommu.c @@ -38,6 +38,7 @@ #include #include #include +#include #define DBG(...) @@ -440,8 +441,37 @@ struct iommu_table *iommu_init_table(struct iommu_table *tbl, int nid) tbl->it_largehint = tbl->it_halfpoint; spin_lock_init(&tbl->it_lock); +#ifdef CONFIG_CRASH_DUMP + if (ppc_md.tce_get) { + unsigned long index, tceval; + unsigned long tcecount = 0; + + /* + * Reserve the existing mappings left by the first kernel. + */ + for (index = 0; index < tbl->it_size; index++) { + tceval = ppc_md.tce_get(tbl, index + tbl->it_offset); + /* + * Freed TCE entry contains 0x7fffffffffffffff on JS20 + */ + if (tceval && (tceval != 0x7fffffffffffffffUL)) { + __set_bit(index, tbl->it_map); + tcecount++; + } + } + if ((tbl->it_size - tcecount) < KDUMP_MIN_TCE_ENTRIES) { + printk(KERN_WARNING "TCE table is full; "); + printk(KERN_WARNING "freeing %d entries for the kdump boot\n", + KDUMP_MIN_TCE_ENTRIES); + for (index = tbl->it_size - KDUMP_MIN_TCE_ENTRIES; + index < tbl->it_size; index++) + __clear_bit(index, tbl->it_map); + } + } +#else /* Clear the hardware table in case firmware left allocations in it */ ppc_md.tce_free(tbl, tbl->it_offset, tbl->it_size); +#endif if (!welcomed) { printk(KERN_INFO "IOMMU table initialized, virtual merging %s\n", diff --git a/trunk/arch/powerpc/kernel/irq.c b/trunk/arch/powerpc/kernel/irq.c index 40d4c14fde8f..24f6050aa4ab 100644 --- a/trunk/arch/powerpc/kernel/irq.c +++ b/trunk/arch/powerpc/kernel/irq.c @@ -120,8 +120,8 @@ int show_interrupts(struct seq_file *p, void *v) #else seq_printf(p, "%10u ", kstat_irqs(i)); #endif /* CONFIG_SMP */ - if (desc->handler) - seq_printf(p, " %s ", desc->handler->typename); + if (desc->chip) + seq_printf(p, " %s ", desc->chip->typename); else seq_puts(p, " None "); seq_printf(p, "%s", (desc->status & IRQ_LEVEL) ? "Level " : "Edge "); @@ -164,13 +164,13 @@ void fixup_irqs(cpumask_t map) if (irq_desc[irq].status & IRQ_PER_CPU) continue; - cpus_and(mask, irq_affinity[irq], map); + cpus_and(mask, irq_desc[irq].affinity, map); if (any_online_cpu(mask) == NR_CPUS) { printk("Breaking affinity for irq %i\n", irq); mask = map; } - if (irq_desc[irq].handler->set_affinity) - irq_desc[irq].handler->set_affinity(irq, mask); + if (irq_desc[irq].chip->set_affinity) + irq_desc[irq].chip->set_affinity(irq, mask); else if (irq_desc[irq].action && !(warned++)) printk("Cannot set affinity for irq %i\n", irq); } diff --git a/trunk/arch/powerpc/kernel/legacy_serial.c b/trunk/arch/powerpc/kernel/legacy_serial.c index 6e67b5b49ba1..3a9b78d03542 100644 --- a/trunk/arch/powerpc/kernel/legacy_serial.c +++ b/trunk/arch/powerpc/kernel/legacy_serial.c @@ -302,6 +302,17 @@ void __init find_legacy_serial_ports(void) of_node_put(isa); } + /* First fill our array with tsi-bridge ports */ + for (np = NULL; (np = of_find_compatible_node(np, "serial", "ns16550")) != NULL;) { + struct device_node *tsi = of_get_parent(np); + if (tsi && !strcmp(tsi->type, "tsi-bridge")) { + index = add_legacy_soc_port(np, np); + if (index >= 0 && np == stdout) + legacy_serial_console = index; + } + of_node_put(tsi); + } + #ifdef CONFIG_PCI /* Next, try to locate PCI ports */ for (np = NULL; (np = of_find_all_nodes(np));) { diff --git a/trunk/arch/powerpc/kernel/lparcfg.c b/trunk/arch/powerpc/kernel/lparcfg.c index c02deaab26c7..73edc3c16137 100644 --- a/trunk/arch/powerpc/kernel/lparcfg.c +++ b/trunk/arch/powerpc/kernel/lparcfg.c @@ -45,11 +45,9 @@ static struct proc_dir_entry *proc_ppc64_lparcfg; #define LPARCFG_BUFF_SIZE 4096 -#ifdef CONFIG_PPC_ISERIES - /* - * For iSeries legacy systems, the PPA purr function is available from the - * emulated_time_base field in the paca. + * Track sum of all purrs across all processors. This is used to further + * calculate usage values by different applications */ static unsigned long get_purr(void) { @@ -57,48 +55,31 @@ static unsigned long get_purr(void) int cpu; for_each_possible_cpu(cpu) { - sum_purr += lppaca[cpu].emulated_time_base; + if (firmware_has_feature(FW_FEATURE_ISERIES)) + sum_purr += lppaca[cpu].emulated_time_base; + else { + struct cpu_usage *cu; -#ifdef PURR_DEBUG - printk(KERN_INFO "get_purr for cpu (%d) has value (%ld) \n", - cpu, lppaca[cpu].emulated_time_base); -#endif + cu = &per_cpu(cpu_usage_array, cpu); + sum_purr += cu->current_tb; + } } return sum_purr; } -#define lparcfg_write NULL +#ifdef CONFIG_PPC_ISERIES /* * Methods used to fetch LPAR data when running on an iSeries platform. */ -static int lparcfg_data(struct seq_file *m, void *v) +static int iseries_lparcfg_data(struct seq_file *m, void *v) { - unsigned long pool_id, lp_index; + unsigned long pool_id; int shared, entitled_capacity, max_entitled_capacity; int processors, max_processors; unsigned long purr = get_purr(); - seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); - shared = (int)(get_lppaca()->shared_proc); - seq_printf(m, "serial_number=%c%c%c%c%c%c%c\n", - e2a(xItExtVpdPanel.mfgID[2]), - e2a(xItExtVpdPanel.mfgID[3]), - e2a(xItExtVpdPanel.systemSerial[1]), - e2a(xItExtVpdPanel.systemSerial[2]), - e2a(xItExtVpdPanel.systemSerial[3]), - e2a(xItExtVpdPanel.systemSerial[4]), - e2a(xItExtVpdPanel.systemSerial[5])); - - seq_printf(m, "system_type=%c%c%c%c\n", - e2a(xItExtVpdPanel.machineType[0]), - e2a(xItExtVpdPanel.machineType[1]), - e2a(xItExtVpdPanel.machineType[2]), - e2a(xItExtVpdPanel.machineType[3])); - - lp_index = HvLpConfig_getLpIndex(); - seq_printf(m, "partition_id=%d\n", (int)lp_index); seq_printf(m, "system_active_processors=%d\n", (int)HvLpConfig_getSystemPhysicalProcessors()); @@ -137,6 +118,14 @@ static int lparcfg_data(struct seq_file *m, void *v) return 0; } + +#else /* CONFIG_PPC_ISERIES */ + +static int iseries_lparcfg_data(struct seq_file *m, void *v) +{ + return 0; +} + #endif /* CONFIG_PPC_ISERIES */ #ifdef CONFIG_PPC_PSERIES @@ -213,22 +202,6 @@ static void h_pic(unsigned long *pool_idle_time, unsigned long *num_procs) log_plpar_hcall_return(rc, "H_PIC"); } -/* Track sum of all purrs across all processors. This is used to further */ -/* calculate usage values by different applications */ - -static unsigned long get_purr(void) -{ - unsigned long sum_purr = 0; - int cpu; - struct cpu_usage *cu; - - for_each_possible_cpu(cpu) { - cu = &per_cpu(cpu_usage_array, cpu); - sum_purr += cu->current_tb; - } - return sum_purr; -} - #define SPLPAR_CHARACTERISTICS_TOKEN 20 #define SPLPAR_MAXLENGTH 1026*(sizeof(char)) @@ -333,35 +306,13 @@ static int lparcfg_count_active_processors(void) return count; } -static int lparcfg_data(struct seq_file *m, void *v) +static int pseries_lparcfg_data(struct seq_file *m, void *v) { int partition_potential_processors; int partition_active_processors; - struct device_node *rootdn; - const char *model = ""; - const char *system_id = ""; - unsigned int *lp_index_ptr, lp_index = 0; struct device_node *rtas_node; int *lrdrp = NULL; - rootdn = find_path_device("/"); - if (rootdn) { - model = get_property(rootdn, "model", NULL); - system_id = get_property(rootdn, "system-id", NULL); - lp_index_ptr = (unsigned int *) - get_property(rootdn, "ibm,partition-no", NULL); - if (lp_index_ptr) - lp_index = *lp_index_ptr; - } - - seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); - - seq_printf(m, "serial_number=%s\n", system_id); - - seq_printf(m, "system_type=%s\n", model); - - seq_printf(m, "partition_id=%d\n", (int)lp_index); - rtas_node = find_path_device("/rtas"); if (rtas_node) lrdrp = (int *)get_property(rtas_node, "ibm,lrdr-capacity", @@ -549,8 +500,61 @@ static ssize_t lparcfg_write(struct file *file, const char __user * buf, return retval; } +#else /* CONFIG_PPC_PSERIES */ + +static int pseries_lparcfg_data(struct seq_file *m, void *v) +{ + return 0; +} + +static ssize_t lparcfg_write(struct file *file, const char __user * buf, + size_t count, loff_t * off) +{ + return count; +} + #endif /* CONFIG_PPC_PSERIES */ +static int lparcfg_data(struct seq_file *m, void *v) +{ + struct device_node *rootdn; + const char *model = ""; + const char *system_id = ""; + const char *tmp; + unsigned int *lp_index_ptr, lp_index = 0; + + seq_printf(m, "%s %s \n", MODULE_NAME, MODULE_VERS); + + rootdn = find_path_device("/"); + if (rootdn) { + tmp = get_property(rootdn, "model", NULL); + if (tmp) { + model = tmp; + /* Skip "IBM," - see platforms/iseries/dt.c */ + if (firmware_has_feature(FW_FEATURE_ISERIES)) + model += 4; + } + tmp = get_property(rootdn, "system-id", NULL); + if (tmp) { + system_id = tmp; + /* Skip "IBM," - see platforms/iseries/dt.c */ + if (firmware_has_feature(FW_FEATURE_ISERIES)) + system_id += 4; + } + lp_index_ptr = (unsigned int *) + get_property(rootdn, "ibm,partition-no", NULL); + if (lp_index_ptr) + lp_index = *lp_index_ptr; + } + seq_printf(m, "serial_number=%s\n", system_id); + seq_printf(m, "system_type=%s\n", model); + seq_printf(m, "partition_id=%d\n", (int)lp_index); + + if (firmware_has_feature(FW_FEATURE_ISERIES)) + return iseries_lparcfg_data(m, v); + return pseries_lparcfg_data(m, v); +} + static int lparcfg_open(struct inode *inode, struct file *file) { return single_open(file, lparcfg_data, NULL); @@ -569,7 +573,8 @@ int __init lparcfg_init(void) mode_t mode = S_IRUSR | S_IRGRP | S_IROTH; /* Allow writing if we have FW_FEATURE_SPLPAR */ - if (firmware_has_feature(FW_FEATURE_SPLPAR)) { + if (firmware_has_feature(FW_FEATURE_SPLPAR) && + !firmware_has_feature(FW_FEATURE_ISERIES)) { lparcfg_fops.write = lparcfg_write; mode |= S_IWUSR; } diff --git a/trunk/arch/powerpc/kernel/machine_kexec_64.c b/trunk/arch/powerpc/kernel/machine_kexec_64.c index a8fa04ef27cd..b438d45a068c 100644 --- a/trunk/arch/powerpc/kernel/machine_kexec_64.c +++ b/trunk/arch/powerpc/kernel/machine_kexec_64.c @@ -378,11 +378,13 @@ static void __init export_crashk_values(void) of_node_put(node); } -void __init kexec_setup(void) +static int __init kexec_setup(void) { export_htab_values(); export_crashk_values(); + return 0; } +__initcall(kexec_setup); static int __init early_parse_crashk(char *p) { diff --git a/trunk/arch/powerpc/kernel/misc.S b/trunk/arch/powerpc/kernel/misc.S new file mode 100644 index 000000000000..fc23040d5a26 --- /dev/null +++ b/trunk/arch/powerpc/kernel/misc.S @@ -0,0 +1,203 @@ +/* + * This file contains miscellaneous low-level functions. + * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) + * + * Largely rewritten by Cort Dougan (cort@cs.nmt.edu) + * and Paul Mackerras. + * + * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com) + * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com) + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + */ +#include + + .text + +#ifdef CONFIG_PPC64 +#define IN_SYNC twi 0,r5,0; isync +#define EIEIO_32 +#define SYNC_64 sync +#else /* CONFIG_PPC32 */ +#define IN_SYNC +#define EIEIO_32 eieio +#define SYNC_64 +#endif +/* + * Returns (address we are running at) - (address we were linked at) + * for use before the text and data are mapped to KERNELBASE. + */ + +_GLOBAL(reloc_offset) + mflr r0 + bl 1f +1: mflr r3 + LOAD_REG_IMMEDIATE(r4,1b) + subf r3,r4,r3 + mtlr r0 + blr + +/* + * add_reloc_offset(x) returns x + reloc_offset(). + */ +_GLOBAL(add_reloc_offset) + mflr r0 + bl 1f +1: mflr r5 + LOAD_REG_IMMEDIATE(r4,1b) + subf r5,r4,r5 + add r3,r3,r5 + mtlr r0 + blr + +/* + * I/O string operations + * + * insb(port, buf, len) + * outsb(port, buf, len) + * insw(port, buf, len) + * outsw(port, buf, len) + * insl(port, buf, len) + * outsl(port, buf, len) + * insw_ns(port, buf, len) + * outsw_ns(port, buf, len) + * insl_ns(port, buf, len) + * outsl_ns(port, buf, len) + * + * The *_ns versions don't do byte-swapping. + */ +_GLOBAL(_insb) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,1 + blelr- +00: lbz r5,0(r3) + eieio + stbu r5,1(r4) + bdnz 00b + IN_SYNC + blr + +_GLOBAL(_outsb) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,1 + blelr- +00: lbzu r5,1(r4) + stb r5,0(r3) + EIEIO_32 + bdnz 00b + SYNC_64 + blr + +_GLOBAL(_insw) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,2 + blelr- +00: lhbrx r5,0,r3 + eieio + sthu r5,2(r4) + bdnz 00b + IN_SYNC + blr + +_GLOBAL(_outsw) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,2 + blelr- +00: lhzu r5,2(r4) + EIEIO_32 + sthbrx r5,0,r3 + bdnz 00b + SYNC_64 + blr + +_GLOBAL(_insl) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,4 + blelr- +00: lwbrx r5,0,r3 + eieio + stwu r5,4(r4) + bdnz 00b + IN_SYNC + blr + +_GLOBAL(_outsl) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,4 + blelr- +00: lwzu r5,4(r4) + stwbrx r5,0,r3 + EIEIO_32 + bdnz 00b + SYNC_64 + blr + +#ifdef CONFIG_PPC32 +_GLOBAL(__ide_mm_insw) +#endif +_GLOBAL(_insw_ns) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,2 + blelr- +00: lhz r5,0(r3) + eieio + sthu r5,2(r4) + bdnz 00b + IN_SYNC + blr + +#ifdef CONFIG_PPC32 +_GLOBAL(__ide_mm_outsw) +#endif +_GLOBAL(_outsw_ns) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,2 + blelr- +00: lhzu r5,2(r4) + sth r5,0(r3) + EIEIO_32 + bdnz 00b + SYNC_64 + blr + +#ifdef CONFIG_PPC32 +_GLOBAL(__ide_mm_insl) +#endif +_GLOBAL(_insl_ns) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,4 + blelr- +00: lwz r5,0(r3) + eieio + stwu r5,4(r4) + bdnz 00b + IN_SYNC + blr + +#ifdef CONFIG_PPC32 +_GLOBAL(__ide_mm_outsl) +#endif +_GLOBAL(_outsl_ns) + cmpwi 0,r5,0 + mtctr r5 + subi r4,r4,4 + blelr- +00: lwzu r5,4(r4) + stw r5,0(r3) + EIEIO_32 + bdnz 00b + SYNC_64 + blr + diff --git a/trunk/arch/powerpc/kernel/misc_32.S b/trunk/arch/powerpc/kernel/misc_32.S index 01d3916c4cb1..c74774e2175d 100644 --- a/trunk/arch/powerpc/kernel/misc_32.S +++ b/trunk/arch/powerpc/kernel/misc_32.S @@ -60,32 +60,6 @@ _GLOBAL(mulhdu) addze r3,r3 blr -/* - * Returns (address we're running at) - (address we were linked at) - * for use before the text and data are mapped to KERNELBASE. - */ -_GLOBAL(reloc_offset) - mflr r0 - bl 1f -1: mflr r3 - LOAD_REG_IMMEDIATE(r4,1b) - subf r3,r4,r3 - mtlr r0 - blr - -/* - * add_reloc_offset(x) returns x + reloc_offset(). - */ -_GLOBAL(add_reloc_offset) - mflr r0 - bl 1f -1: mflr r5 - LOAD_REG_IMMEDIATE(r4,1b) - subf r5,r4,r5 - add r3,r3,r5 - mtlr r0 - blr - /* * sub_reloc_offset(x) returns x - reloc_offset(). */ @@ -780,136 +754,6 @@ _GLOBAL(atomic_set_mask) bne- 10b blr -/* - * I/O string operations - * - * insb(port, buf, len) - * outsb(port, buf, len) - * insw(port, buf, len) - * outsw(port, buf, len) - * insl(port, buf, len) - * outsl(port, buf, len) - * insw_ns(port, buf, len) - * outsw_ns(port, buf, len) - * insl_ns(port, buf, len) - * outsl_ns(port, buf, len) - * - * The *_ns versions don't do byte-swapping. - */ -_GLOBAL(_insb) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,1 - blelr- -00: lbz r5,0(r3) - eieio - stbu r5,1(r4) - bdnz 00b - blr - -_GLOBAL(_outsb) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,1 - blelr- -00: lbzu r5,1(r4) - stb r5,0(r3) - eieio - bdnz 00b - blr - -_GLOBAL(_insw) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,2 - blelr- -00: lhbrx r5,0,r3 - eieio - sthu r5,2(r4) - bdnz 00b - blr - -_GLOBAL(_outsw) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,2 - blelr- -00: lhzu r5,2(r4) - eieio - sthbrx r5,0,r3 - bdnz 00b - blr - -_GLOBAL(_insl) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,4 - blelr- -00: lwbrx r5,0,r3 - eieio - stwu r5,4(r4) - bdnz 00b - blr - -_GLOBAL(_outsl) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,4 - blelr- -00: lwzu r5,4(r4) - stwbrx r5,0,r3 - eieio - bdnz 00b - blr - -_GLOBAL(__ide_mm_insw) -_GLOBAL(_insw_ns) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,2 - blelr- -00: lhz r5,0(r3) - eieio - sthu r5,2(r4) - bdnz 00b - blr - -_GLOBAL(__ide_mm_outsw) -_GLOBAL(_outsw_ns) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,2 - blelr- -00: lhzu r5,2(r4) - sth r5,0(r3) - eieio - bdnz 00b - blr - -_GLOBAL(__ide_mm_insl) -_GLOBAL(_insl_ns) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,4 - blelr- -00: lwz r5,0(r3) - eieio - stwu r5,4(r4) - bdnz 00b - blr - -_GLOBAL(__ide_mm_outsl) -_GLOBAL(_outsl_ns) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,4 - blelr- -00: lwzu r5,4(r4) - stw r5,0(r3) - eieio - bdnz 00b - blr - /* * Extended precision shifts. * diff --git a/trunk/arch/powerpc/kernel/misc_64.S b/trunk/arch/powerpc/kernel/misc_64.S index e8883d42c43c..580891cb8ccb 100644 --- a/trunk/arch/powerpc/kernel/misc_64.S +++ b/trunk/arch/powerpc/kernel/misc_64.S @@ -1,14 +1,12 @@ /* - * arch/powerpc/kernel/misc64.S - * * This file contains miscellaneous low-level functions. * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * * Largely rewritten by Cort Dougan (cort@cs.nmt.edu) * and Paul Mackerras. * Adapted for iSeries by Mike Corrigan (mikejc@us.ibm.com) - * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com) - * + * PPC64 updates by Dave Engebretsen (engebret@us.ibm.com) + * * 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 @@ -30,41 +28,10 @@ .text -/* - * Returns (address we are running at) - (address we were linked at) - * for use before the text and data are mapped to KERNELBASE. - */ - -_GLOBAL(reloc_offset) - mflr r0 - bl 1f -1: mflr r3 - LOAD_REG_IMMEDIATE(r4,1b) - subf r3,r4,r3 - mtlr r0 - blr - -/* - * add_reloc_offset(x) returns x + reloc_offset(). - */ -_GLOBAL(add_reloc_offset) - mflr r0 - bl 1f -1: mflr r5 - LOAD_REG_IMMEDIATE(r4,1b) - subf r5,r4,r5 - add r3,r3,r5 - mtlr r0 - blr - _GLOBAL(get_msr) mfmsr r3 blr -_GLOBAL(get_dar) - mfdar r3 - blr - _GLOBAL(get_srr0) mfsrr0 r3 blr @@ -72,10 +39,6 @@ _GLOBAL(get_srr0) _GLOBAL(get_srr1) mfsrr1 r3 blr - -_GLOBAL(get_sp) - mr r3,r1 - blr #ifdef CONFIG_IRQSTACKS _GLOBAL(call_do_softirq) @@ -101,48 +64,6 @@ _GLOBAL(call___do_IRQ) blr #endif /* CONFIG_IRQSTACKS */ - /* - * To be called by C code which needs to do some operations with MMU - * disabled. Note that interrupts have to be disabled by the caller - * prior to calling us. The code called _MUST_ be in the RMO of course - * and part of the linear mapping as we don't attempt to translate the - * stack pointer at all. The function is called with the stack switched - * to this CPU emergency stack - * - * prototype is void *call_with_mmu_off(void *func, void *data); - * - * the called function is expected to be of the form - * - * void *called(void *data); - */ -_GLOBAL(call_with_mmu_off) - mflr r0 /* get link, save it on stackframe */ - std r0,16(r1) - mr r1,r5 /* save old stack ptr */ - ld r1,PACAEMERGSP(r13) /* get emerg. stack */ - subi r1,r1,STACK_FRAME_OVERHEAD - std r0,16(r1) /* save link on emerg. stack */ - std r5,0(r1) /* save old stack ptr in backchain */ - ld r3,0(r3) /* get to real function ptr (assume same TOC) */ - bl 2f /* we need LR to return, continue at label 2 */ - - ld r0,16(r1) /* we return here from the call, get LR and */ - ld r1,0(r1) /* .. old stack ptr */ - mtspr SPRN_SRR0,r0 /* and get back to virtual mode with these */ - mfmsr r4 - ori r4,r4,MSR_IR|MSR_DR - mtspr SPRN_SRR1,r4 - rfid - -2: mtspr SPRN_SRR0,r3 /* coming from above, enter real mode */ - mr r3,r4 /* get parameter */ - mfmsr r0 - ori r0,r0,MSR_IR|MSR_DR - xori r0,r0,MSR_IR|MSR_DR - mtspr SPRN_SRR1,r0 - rfid - - .section ".toc","aw" PPC64_CACHES: .tc ppc64_caches[TC],ppc64_caches @@ -323,144 +244,6 @@ _GLOBAL(__flush_dcache_icache) bdnz 1b isync blr - -/* - * I/O string operations - * - * insb(port, buf, len) - * outsb(port, buf, len) - * insw(port, buf, len) - * outsw(port, buf, len) - * insl(port, buf, len) - * outsl(port, buf, len) - * insw_ns(port, buf, len) - * outsw_ns(port, buf, len) - * insl_ns(port, buf, len) - * outsl_ns(port, buf, len) - * - * The *_ns versions don't do byte-swapping. - */ -_GLOBAL(_insb) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,1 - blelr- -00: lbz r5,0(r3) - eieio - stbu r5,1(r4) - bdnz 00b - twi 0,r5,0 - isync - blr - -_GLOBAL(_outsb) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,1 - blelr- -00: lbzu r5,1(r4) - stb r5,0(r3) - bdnz 00b - sync - blr - -_GLOBAL(_insw) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,2 - blelr- -00: lhbrx r5,0,r3 - eieio - sthu r5,2(r4) - bdnz 00b - twi 0,r5,0 - isync - blr - -_GLOBAL(_outsw) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,2 - blelr- -00: lhzu r5,2(r4) - sthbrx r5,0,r3 - bdnz 00b - sync - blr - -_GLOBAL(_insl) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,4 - blelr- -00: lwbrx r5,0,r3 - eieio - stwu r5,4(r4) - bdnz 00b - twi 0,r5,0 - isync - blr - -_GLOBAL(_outsl) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,4 - blelr- -00: lwzu r5,4(r4) - stwbrx r5,0,r3 - bdnz 00b - sync - blr - -/* _GLOBAL(ide_insw) now in drivers/ide/ide-iops.c */ -_GLOBAL(_insw_ns) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,2 - blelr- -00: lhz r5,0(r3) - eieio - sthu r5,2(r4) - bdnz 00b - twi 0,r5,0 - isync - blr - -/* _GLOBAL(ide_outsw) now in drivers/ide/ide-iops.c */ -_GLOBAL(_outsw_ns) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,2 - blelr- -00: lhzu r5,2(r4) - sth r5,0(r3) - bdnz 00b - sync - blr - -_GLOBAL(_insl_ns) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,4 - blelr- -00: lwz r5,0(r3) - eieio - stwu r5,4(r4) - bdnz 00b - twi 0,r5,0 - isync - blr - -_GLOBAL(_outsl_ns) - cmpwi 0,r5,0 - mtctr r5 - subi r4,r4,4 - blelr- -00: lwzu r5,4(r4) - stw r5,0(r3) - bdnz 00b - sync - blr /* * identify_cpu and calls setup_cpu @@ -605,6 +388,7 @@ _GLOBAL(real_writeb) blr #endif /* defined(CONFIG_PPC_PMAC) || defined(CONFIG_PPC_MAPLE) */ +#ifdef CONFIG_CPU_FREQ_PMAC64 /* * SCOM access functions for 970 (FX only for now) * @@ -673,6 +457,7 @@ _GLOBAL(scom970_write) /* restore interrupts */ mtmsrd r5,1 blr +#endif /* CONFIG_CPU_FREQ_PMAC64 */ /* diff --git a/trunk/arch/powerpc/kernel/paca.c b/trunk/arch/powerpc/kernel/paca.c index f505a8827e3e..a0bb354c1c08 100644 --- a/trunk/arch/powerpc/kernel/paca.c +++ b/trunk/arch/powerpc/kernel/paca.c @@ -16,7 +16,6 @@ #include #include #include -#include #include #include diff --git a/trunk/arch/powerpc/kernel/pci_32.c b/trunk/arch/powerpc/kernel/pci_32.c index b5431ccf1147..8474355a1a4f 100644 --- a/trunk/arch/powerpc/kernel/pci_32.c +++ b/trunk/arch/powerpc/kernel/pci_32.c @@ -99,7 +99,7 @@ pcibios_fixup_resources(struct pci_dev *dev) if (!res->flags) continue; if (res->end == 0xffffffff) { - DBG("PCI:%s Resource %d [%08lx-%08lx] is unassigned\n", + DBG("PCI:%s Resource %d [%016llx-%016llx] is unassigned\n", pci_name(dev), i, res->start, res->end); res->end -= res->start; res->start = 0; @@ -117,7 +117,7 @@ pcibios_fixup_resources(struct pci_dev *dev) res->start += offset; res->end += offset; #ifdef DEBUG - printk("Fixup res %d (%lx) of dev %s: %lx -> %lx\n", + printk("Fixup res %d (%lx) of dev %s: %llx -> %llx\n", i, res->flags, pci_name(dev), res->start - offset, res->start); #endif @@ -173,18 +173,18 @@ EXPORT_SYMBOL(pcibios_bus_to_resource); * but we want to try to avoid allocating at 0x2900-0x2bff * which might have be mirrored at 0x0100-0x03ff.. */ -void pcibios_align_resource(void *data, struct resource *res, unsigned long size, - unsigned long align) +void pcibios_align_resource(void *data, struct resource *res, + resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; + resource_size_t start = res->start; if (size > 0x100) { printk(KERN_ERR "PCI: I/O Region %s/%d too large" - " (%ld bytes)\n", pci_name(dev), - dev->resource - res, size); + " (%lld bytes)\n", pci_name(dev), + dev->resource - res, (unsigned long long)size); } if (start & 0x300) { @@ -255,8 +255,8 @@ pcibios_allocate_bus_resources(struct list_head *bus_list) } } - DBG("PCI: bridge rsrc %lx..%lx (%lx), parent %p\n", - res->start, res->end, res->flags, pr); + DBG("PCI: bridge rsrc %llx..%llx (%lx), parent %p\n", + res->start, res->end, res->flags, pr); if (pr) { if (request_resource(pr, res) == 0) continue; @@ -306,7 +306,7 @@ reparent_resources(struct resource *parent, struct resource *res) *pp = NULL; for (p = res->child; p != NULL; p = p->sibling) { p->parent = res; - DBG(KERN_INFO "PCI: reparented %s [%lx..%lx] under %s\n", + DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n", p->name, p->start, p->end, res->name); } return 0; @@ -362,13 +362,14 @@ pci_relocate_bridge_resource(struct pci_bus *bus, int i) try = conflict->start - 1; } if (request_resource(pr, res)) { - DBG(KERN_ERR "PCI: huh? couldn't move to %lx..%lx\n", + DBG(KERN_ERR "PCI: huh? couldn't move to %llx..%llx\n", res->start, res->end); return -1; /* "can't happen" */ } update_bridge_base(bus, i); - printk(KERN_INFO "PCI: bridge %d resource %d moved to %lx..%lx\n", - bus->number, i, res->start, res->end); + printk(KERN_INFO "PCI: bridge %d resource %d moved to %llx..%llx\n", + bus->number, i, (unsigned long long)res->start, + (unsigned long long)res->end); return 0; } @@ -479,14 +480,14 @@ static inline void alloc_resource(struct pci_dev *dev, int idx) { struct resource *pr, *r = &dev->resource[idx]; - DBG("PCI:%s: Resource %d: %08lx-%08lx (f=%lx)\n", + DBG("PCI:%s: Resource %d: %016llx-%016llx (f=%lx)\n", pci_name(dev), idx, r->start, r->end, r->flags); pr = pci_find_parent_resource(dev, r); if (!pr || request_resource(pr, r) < 0) { printk(KERN_ERR "PCI: Cannot allocate resource region %d" " of device %s\n", idx, pci_name(dev)); if (pr) - DBG("PCI: parent is %p: %08lx-%08lx (f=%lx)\n", + DBG("PCI: parent is %p: %016llx-%016llx (f=%lx)\n", pr, pr->start, pr->end, pr->flags); /* We'll assign a new address later */ r->flags |= IORESOURCE_UNSET; @@ -956,7 +957,7 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose, res = &hose->io_resource; res->flags = IORESOURCE_IO; res->start = ranges[2]; - DBG("PCI: IO 0x%lx -> 0x%lx\n", + DBG("PCI: IO 0x%llx -> 0x%llx\n", res->start, res->start + size - 1); break; case 2: /* memory space */ @@ -978,7 +979,7 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose, if(ranges[0] & 0x40000000) res->flags |= IORESOURCE_PREFETCH; res->start = ranges[na+2]; - DBG("PCI: MEM[%d] 0x%lx -> 0x%lx\n", memno, + DBG("PCI: MEM[%d] 0x%llx -> 0x%llx\n", memno, res->start, res->start + size - 1); } break; @@ -1074,7 +1075,7 @@ do_update_p2p_io_resource(struct pci_bus *bus, int enable_vga) DBG("Remapping Bus %d, bridge: %s\n", bus->number, pci_name(bridge)); res.start -= ((unsigned long) hose->io_base_virt - isa_io_base); res.end -= ((unsigned long) hose->io_base_virt - isa_io_base); - DBG(" IO window: %08lx-%08lx\n", res.start, res.end); + DBG(" IO window: %016llx-%016llx\n", res.start, res.end); /* Set up the top and bottom of the PCI I/O segment for this bus. */ pci_read_config_dword(bridge, PCI_IO_BASE, &l); @@ -1223,8 +1224,8 @@ do_fixup_p2p_level(struct pci_bus *bus) continue; if ((r->flags & IORESOURCE_IO) == 0) continue; - DBG("Trying to allocate from %08lx, size %08lx from parent" - " res %d: %08lx -> %08lx\n", + DBG("Trying to allocate from %016llx, size %016llx from parent" + " res %d: %016llx -> %016llx\n", res->start, res->end, i, r->start, r->end); if (allocate_resource(r, res, res->end + 1, res->start, max, @@ -1574,8 +1575,8 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, else prot |= _PAGE_GUARDED; - printk("PCI map for %s:%lx, prot: %lx\n", pci_name(dev), rp->start, - prot); + printk("PCI map for %s:%llx, prot: %lx\n", pci_name(dev), + (unsigned long long)rp->start, prot); return __pgprot(prot); } @@ -1755,7 +1756,7 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) void pci_resource_to_user(const struct pci_dev *dev, int bar, const struct resource *rsrc, - u64 *start, u64 *end) + resource_size_t *start, resource_size_t *end) { struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); unsigned long offset = 0; diff --git a/trunk/arch/powerpc/kernel/pci_64.c b/trunk/arch/powerpc/kernel/pci_64.c index 247937dd8b73..286aa52aae33 100644 --- a/trunk/arch/powerpc/kernel/pci_64.c +++ b/trunk/arch/powerpc/kernel/pci_64.c @@ -138,11 +138,11 @@ EXPORT_SYMBOL(pcibios_bus_to_resource); * which might have be mirrored at 0x0100-0x03ff.. */ void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; struct pci_controller *hose = pci_bus_to_host(dev->bus); - unsigned long start = res->start; + resource_size_t start = res->start; unsigned long alignto; if (res->flags & IORESOURCE_IO) { diff --git a/trunk/arch/powerpc/kernel/prom.c b/trunk/arch/powerpc/kernel/prom.c index 483455c5bb02..320c913435cd 100644 --- a/trunk/arch/powerpc/kernel/prom.c +++ b/trunk/arch/powerpc/kernel/prom.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include @@ -952,6 +953,7 @@ static struct ibm_pa_feature { /* put this back once we know how to test if firmware does 64k IO */ {CPU_FTR_CI_LARGE_PAGE, 0, 1, 2, 0}, #endif + {CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0}, }; static void __init check_cpu_pa_features(unsigned long node) @@ -1124,24 +1126,6 @@ static int __init early_init_dt_scan_chosen(unsigned long node, tce_alloc_end = *lprop; #endif -#ifdef CONFIG_PPC_RTAS - /* To help early debugging via the front panel, we retrieve a minimal - * set of RTAS infos now if available - */ - { - u64 *basep, *entryp, *sizep; - - basep = of_get_flat_dt_prop(node, "linux,rtas-base", NULL); - entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL); - sizep = of_get_flat_dt_prop(node, "linux,rtas-size", NULL); - if (basep && entryp && sizep) { - rtas.base = *basep; - rtas.entry = *entryp; - rtas.size = *sizep; - } - } -#endif /* CONFIG_PPC_RTAS */ - #ifdef CONFIG_KEXEC lprop = (u64*)of_get_flat_dt_prop(node, "linux,crashkernel-base", NULL); if (lprop) @@ -1326,6 +1310,11 @@ void __init early_init_devtree(void *params) /* Setup flat device-tree pointer */ initial_boot_params = params; +#ifdef CONFIG_PPC_RTAS + /* Some machines might need RTAS info for debugging, grab it now. */ + of_scan_flat_dt(early_init_dt_scan_rtas, NULL); +#endif + /* Retrieve various informations from the /chosen node of the * device-tree, including the platform type, initrd location and * size, TCE reserve, and more ... @@ -2148,3 +2137,27 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) } return NULL; } + +#ifdef DEBUG +static struct debugfs_blob_wrapper flat_dt_blob; + +static int __init export_flat_device_tree(void) +{ + struct dentry *d; + + d = debugfs_create_dir("powerpc", NULL); + if (!d) + return 1; + + flat_dt_blob.data = initial_boot_params; + flat_dt_blob.size = initial_boot_params->totalsize; + + d = debugfs_create_blob("flat-device-tree", S_IFREG | S_IRUSR, + d, &flat_dt_blob); + if (!d) + return 1; + + return 0; +} +__initcall(export_flat_device_tree); +#endif diff --git a/trunk/arch/powerpc/kernel/rtas.c b/trunk/arch/powerpc/kernel/rtas.c index 17dc79198515..4a4cb5598402 100644 --- a/trunk/arch/powerpc/kernel/rtas.c +++ b/trunk/arch/powerpc/kernel/rtas.c @@ -38,16 +38,19 @@ struct rtas_t rtas = { .lock = SPIN_LOCK_UNLOCKED }; +EXPORT_SYMBOL(rtas); struct rtas_suspend_me_data { long waiting; struct rtas_args *args; }; -EXPORT_SYMBOL(rtas); - DEFINE_SPINLOCK(rtas_data_buf_lock); +EXPORT_SYMBOL(rtas_data_buf_lock); + char rtas_data_buf[RTAS_DATA_BUF_SIZE] __cacheline_aligned; +EXPORT_SYMBOL(rtas_data_buf); + unsigned long rtas_rmo_buf; /* @@ -106,11 +109,71 @@ static void call_rtas_display_status_delay(char c) } } -void __init udbg_init_rtas(void) +void __init udbg_init_rtas_panel(void) { udbg_putc = call_rtas_display_status_delay; } +#ifdef CONFIG_UDBG_RTAS_CONSOLE + +/* If you think you're dying before early_init_dt_scan_rtas() does its + * work, you can hard code the token values for your firmware here and + * hardcode rtas.base/entry etc. + */ +static unsigned int rtas_putchar_token = RTAS_UNKNOWN_SERVICE; +static unsigned int rtas_getchar_token = RTAS_UNKNOWN_SERVICE; + +static void udbg_rtascon_putc(char c) +{ + int tries; + + if (!rtas.base) + return; + + /* Add CRs before LFs */ + if (c == '\n') + udbg_rtascon_putc('\r'); + + /* if there is more than one character to be displayed, wait a bit */ + for (tries = 0; tries < 16; tries++) { + if (rtas_call(rtas_putchar_token, 1, 1, NULL, c) == 0) + break; + udelay(1000); + } +} + +static int udbg_rtascon_getc_poll(void) +{ + int c; + + if (!rtas.base) + return -1; + + if (rtas_call(rtas_getchar_token, 0, 2, &c)) + return -1; + + return c; +} + +static int udbg_rtascon_getc(void) +{ + int c; + + while ((c = udbg_rtascon_getc_poll()) == -1) + ; + + return c; +} + + +void __init udbg_init_rtas_console(void) +{ + udbg_putc = udbg_rtascon_putc; + udbg_getc = udbg_rtascon_getc; + udbg_getc_poll = udbg_rtascon_getc_poll; +} +#endif /* CONFIG_UDBG_RTAS_CONSOLE */ + void rtas_progress(char *s, unsigned short hex) { struct device_node *root; @@ -236,6 +299,7 @@ int rtas_token(const char *service) tokp = (int *) get_property(rtas.dev, service, NULL); return tokp ? *tokp : RTAS_UNKNOWN_SERVICE; } +EXPORT_SYMBOL(rtas_token); #ifdef CONFIG_RTAS_ERROR_LOGGING /* @@ -328,7 +392,7 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...) char *buff_copy = NULL; int ret; - if (token == RTAS_UNKNOWN_SERVICE) + if (!rtas.entry || token == RTAS_UNKNOWN_SERVICE) return -1; /* Gotta do something different here, use global lock for now... */ @@ -369,6 +433,7 @@ int rtas_call(int token, int nargs, int nret, int *outputs, ...) } return ret; } +EXPORT_SYMBOL(rtas_call); /* For RTAS_BUSY (-2), delay for 1 millisecond. For an extended busy status * code of 990n, perform the hinted delay of 10^n (last digit) milliseconds. @@ -388,6 +453,7 @@ unsigned int rtas_busy_delay_time(int status) return ms; } +EXPORT_SYMBOL(rtas_busy_delay_time); /* For an RTAS busy status code, perform the hinted delay. */ unsigned int rtas_busy_delay(int status) @@ -401,6 +467,7 @@ unsigned int rtas_busy_delay(int status) return ms; } +EXPORT_SYMBOL(rtas_busy_delay); int rtas_error_rc(int rtas_rc) { @@ -446,6 +513,7 @@ int rtas_get_power_level(int powerdomain, int *level) return rtas_error_rc(rc); return rc; } +EXPORT_SYMBOL(rtas_get_power_level); int rtas_set_power_level(int powerdomain, int level, int *setlevel) { @@ -463,6 +531,7 @@ int rtas_set_power_level(int powerdomain, int level, int *setlevel) return rtas_error_rc(rc); return rc; } +EXPORT_SYMBOL(rtas_set_power_level); int rtas_get_sensor(int sensor, int index, int *state) { @@ -480,6 +549,7 @@ int rtas_get_sensor(int sensor, int index, int *state) return rtas_error_rc(rc); return rc; } +EXPORT_SYMBOL(rtas_get_sensor); int rtas_set_indicator(int indicator, int index, int new_value) { @@ -497,6 +567,7 @@ int rtas_set_indicator(int indicator, int index, int new_value) return rtas_error_rc(rc); return rc; } +EXPORT_SYMBOL(rtas_set_indicator); void rtas_restart(char *cmd) { @@ -791,14 +862,34 @@ void __init rtas_initialize(void) #endif } +int __init early_init_dt_scan_rtas(unsigned long node, + const char *uname, int depth, void *data) +{ + u32 *basep, *entryp, *sizep; -EXPORT_SYMBOL(rtas_token); -EXPORT_SYMBOL(rtas_call); -EXPORT_SYMBOL(rtas_data_buf); -EXPORT_SYMBOL(rtas_data_buf_lock); -EXPORT_SYMBOL(rtas_busy_delay_time); -EXPORT_SYMBOL(rtas_busy_delay); -EXPORT_SYMBOL(rtas_get_sensor); -EXPORT_SYMBOL(rtas_get_power_level); -EXPORT_SYMBOL(rtas_set_power_level); -EXPORT_SYMBOL(rtas_set_indicator); + if (depth != 1 || strcmp(uname, "rtas") != 0) + return 0; + + basep = of_get_flat_dt_prop(node, "linux,rtas-base", NULL); + entryp = of_get_flat_dt_prop(node, "linux,rtas-entry", NULL); + sizep = of_get_flat_dt_prop(node, "rtas-size", NULL); + + if (basep && entryp && sizep) { + rtas.base = *basep; + rtas.entry = *entryp; + rtas.size = *sizep; + } + +#ifdef CONFIG_UDBG_RTAS_CONSOLE + basep = of_get_flat_dt_prop(node, "put-term-char", NULL); + if (basep) + rtas_putchar_token = *basep; + + basep = of_get_flat_dt_prop(node, "get-term-char", NULL); + if (basep) + rtas_getchar_token = *basep; +#endif + + /* break now */ + return 1; +} diff --git a/trunk/arch/powerpc/kernel/setup_64.c b/trunk/arch/powerpc/kernel/setup_64.c index 78f3a5fd43f6..175539c9afa0 100644 --- a/trunk/arch/powerpc/kernel/setup_64.c +++ b/trunk/arch/powerpc/kernel/setup_64.c @@ -149,6 +149,13 @@ early_param("smt-enabled", early_smt_enabled); #define check_smt_enabled() #endif /* CONFIG_SMP */ +/* Put the paca pointer into r13 and SPRG3 */ +void __init setup_paca(int cpu) +{ + local_paca = &paca[cpu]; + mtspr(SPRN_SPRG3, local_paca); +} + /* * Early initialization entry point. This is called by head.S * with MMU translation disabled. We rely on the "feature" of @@ -170,6 +177,9 @@ early_param("smt-enabled", early_smt_enabled); void __init early_setup(unsigned long dt_ptr) { + /* Assume we're on cpu 0 for now. Don't write to the paca yet! */ + setup_paca(0); + /* Enable early debugging if any specified (see udbg.h) */ udbg_early_init(); @@ -183,7 +193,7 @@ void __init early_setup(unsigned long dt_ptr) early_init_devtree(__va(dt_ptr)); /* Now we know the logical id of our boot cpu, setup the paca. */ - setup_boot_paca(); + setup_paca(boot_cpuid); /* Fix up paca fields required for the boot cpu */ get_paca()->cpu_start = 1; @@ -350,19 +360,11 @@ 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 * retrieved from the device-tree. Need to be called before * finish_device_tree() since the later requires some of the - * informations filled up here to properly parse the interrupt - * tree. - * It also sets up the cache line sizes which allows to call - * routines like flush_icache_range (used by the hash init - * later on). + * informations filled up here to properly parse the interrupt tree. */ initialize_cache_info(); diff --git a/trunk/arch/powerpc/kernel/traps.c b/trunk/arch/powerpc/kernel/traps.c index 52f5659534f4..fa6bd97b6b9d 100644 --- a/trunk/arch/powerpc/kernel/traps.c +++ b/trunk/arch/powerpc/kernel/traps.c @@ -52,9 +52,13 @@ #include #include #endif +#include #ifdef CONFIG_PPC64 /* XXX */ #define _IO_BASE pci_io_base +#ifdef CONFIG_KEXEC +cpumask_t cpus_in_sr = CPU_MASK_NONE; +#endif #endif #ifdef CONFIG_DEBUGGER @@ -97,7 +101,7 @@ static DEFINE_SPINLOCK(die_lock); int die(const char *str, struct pt_regs *regs, long err) { - static int die_counter, crash_dump_start = 0; + static int die_counter; if (debugger(regs)) return 1; @@ -137,21 +141,12 @@ int die(const char *str, struct pt_regs *regs, long err) print_modules(); show_regs(regs); bust_spinlocks(0); + spin_unlock_irq(&die_lock); - if (!crash_dump_start && kexec_should_crash(current)) { - crash_dump_start = 1; - spin_unlock_irq(&die_lock); + if (kexec_should_crash(current) || + kexec_sr_activated(smp_processor_id())) crash_kexec(regs); - /* NOTREACHED */ - } - spin_unlock_irq(&die_lock); - if (crash_dump_start) - /* - * Only for soft-reset: Other CPUs will be responded to an IPI - * sent by first kexec CPU. - */ - for(;;) - ; + crash_kexec_secondary(regs); if (in_interrupt()) panic("Fatal exception in interrupt"); @@ -215,6 +210,10 @@ void system_reset_exception(struct pt_regs *regs) return; } +#ifdef CONFIG_KEXEC + cpu_set(smp_processor_id(), cpus_in_sr); +#endif + die("System Reset", regs, SIGABRT); /* Must die if the interrupt is not recoverable */ diff --git a/trunk/arch/powerpc/kernel/udbg.c b/trunk/arch/powerpc/kernel/udbg.c index 67d9fd9ae2b5..759afd5e0d8a 100644 --- a/trunk/arch/powerpc/kernel/udbg.c +++ b/trunk/arch/powerpc/kernel/udbg.c @@ -34,9 +34,12 @@ void __init udbg_early_init(void) #elif defined(CONFIG_PPC_EARLY_DEBUG_G5) /* For use on Apple G5 machines */ udbg_init_pmac_realmode(); -#elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS) +#elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL) /* RTAS panel debug */ - udbg_init_rtas(); + udbg_init_rtas_panel(); +#elif defined(CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE) + /* RTAS console debug */ + udbg_init_rtas_console(); #elif defined(CONFIG_PPC_EARLY_DEBUG_MAPLE) /* Maple real mode debug */ udbg_init_maple_realmode(); diff --git a/trunk/arch/powerpc/mm/hash_native_64.c b/trunk/arch/powerpc/mm/hash_native_64.c index a0f3cbd00d39..c90f124f3c71 100644 --- a/trunk/arch/powerpc/mm/hash_native_64.c +++ b/trunk/arch/powerpc/mm/hash_native_64.c @@ -520,7 +520,7 @@ static inline int tlb_batching_enabled(void) } #endif -void hpte_init_native(void) +void __init hpte_init_native(void) { ppc_md.hpte_invalidate = native_hpte_invalidate; ppc_md.hpte_updatepp = native_hpte_updatepp; @@ -530,5 +530,4 @@ void hpte_init_native(void) ppc_md.hpte_clear_all = native_hpte_clear; if (tlb_batching_enabled()) ppc_md.flush_hash_range = native_flush_hash_range; - htab_finish_init(); } diff --git a/trunk/arch/powerpc/mm/hash_utils_64.c b/trunk/arch/powerpc/mm/hash_utils_64.c index d03fd2b4445e..3cc6d68f7117 100644 --- a/trunk/arch/powerpc/mm/hash_utils_64.c +++ b/trunk/arch/powerpc/mm/hash_utils_64.c @@ -167,34 +167,12 @@ int htab_bolt_mapping(unsigned long vstart, unsigned long vend, hash = hpt_hash(va, shift); hpteg = ((hash & htab_hash_mask) * HPTES_PER_GROUP); - /* The crap below can be cleaned once ppd_md.probe() can - * set up the hash callbacks, thus we can just used the - * normal insert callback here. - */ -#ifdef CONFIG_PPC_ISERIES - if (machine_is(iseries)) - ret = iSeries_hpte_insert(hpteg, va, - paddr, - tmp_mode, - HPTE_V_BOLTED, - psize); - else -#endif -#ifdef CONFIG_PPC_PSERIES - if (machine_is(pseries) && firmware_has_feature(FW_FEATURE_LPAR)) - ret = pSeries_lpar_hpte_insert(hpteg, va, - paddr, - tmp_mode, - HPTE_V_BOLTED, - psize); - else -#endif -#ifdef CONFIG_PPC_MULTIPLATFORM - ret = native_hpte_insert(hpteg, va, - paddr, - tmp_mode, HPTE_V_BOLTED, - psize); -#endif + DBG("htab_bolt_mapping: calling %p\n", ppc_md.hpte_insert); + + BUG_ON(!ppc_md.hpte_insert); + ret = ppc_md.hpte_insert(hpteg, va, paddr, + tmp_mode, HPTE_V_BOLTED, psize); + if (ret < 0) break; } @@ -413,6 +391,41 @@ void create_section_mapping(unsigned long start, unsigned long end) } #endif /* CONFIG_MEMORY_HOTPLUG */ +static inline void make_bl(unsigned int *insn_addr, void *func) +{ + unsigned long funcp = *((unsigned long *)func); + int offset = funcp - (unsigned long)insn_addr; + + *insn_addr = (unsigned int)(0x48000001 | (offset & 0x03fffffc)); + flush_icache_range((unsigned long)insn_addr, 4+ + (unsigned long)insn_addr); +} + +static void __init htab_finish_init(void) +{ + extern unsigned int *htab_call_hpte_insert1; + extern unsigned int *htab_call_hpte_insert2; + extern unsigned int *htab_call_hpte_remove; + extern unsigned int *htab_call_hpte_updatepp; + +#ifdef CONFIG_PPC_64K_PAGES + extern unsigned int *ht64_call_hpte_insert1; + extern unsigned int *ht64_call_hpte_insert2; + extern unsigned int *ht64_call_hpte_remove; + extern unsigned int *ht64_call_hpte_updatepp; + + make_bl(ht64_call_hpte_insert1, ppc_md.hpte_insert); + make_bl(ht64_call_hpte_insert2, ppc_md.hpte_insert); + make_bl(ht64_call_hpte_remove, ppc_md.hpte_remove); + make_bl(ht64_call_hpte_updatepp, ppc_md.hpte_updatepp); +#endif /* CONFIG_PPC_64K_PAGES */ + + make_bl(htab_call_hpte_insert1, ppc_md.hpte_insert); + make_bl(htab_call_hpte_insert2, ppc_md.hpte_insert); + make_bl(htab_call_hpte_remove, ppc_md.hpte_remove); + make_bl(htab_call_hpte_updatepp, ppc_md.hpte_updatepp); +} + void __init htab_initialize(void) { unsigned long table; @@ -525,6 +538,8 @@ void __init htab_initialize(void) mmu_linear_psize)); } + htab_finish_init(); + DBG(" <- htab_initialize()\n"); } #undef KB @@ -787,16 +802,6 @@ void flush_hash_range(unsigned long number, int local) } } -static inline void make_bl(unsigned int *insn_addr, void *func) -{ - unsigned long funcp = *((unsigned long *)func); - int offset = funcp - (unsigned long)insn_addr; - - *insn_addr = (unsigned int)(0x48000001 | (offset & 0x03fffffc)); - flush_icache_range((unsigned long)insn_addr, 4+ - (unsigned long)insn_addr); -} - /* * low_hash_fault is called when we the low level hash code failed * to instert a PTE due to an hypervisor error @@ -815,28 +820,3 @@ void low_hash_fault(struct pt_regs *regs, unsigned long address) } bad_page_fault(regs, address, SIGBUS); } - -void __init htab_finish_init(void) -{ - extern unsigned int *htab_call_hpte_insert1; - extern unsigned int *htab_call_hpte_insert2; - extern unsigned int *htab_call_hpte_remove; - extern unsigned int *htab_call_hpte_updatepp; - -#ifdef CONFIG_PPC_64K_PAGES - extern unsigned int *ht64_call_hpte_insert1; - extern unsigned int *ht64_call_hpte_insert2; - extern unsigned int *ht64_call_hpte_remove; - extern unsigned int *ht64_call_hpte_updatepp; - - make_bl(ht64_call_hpte_insert1, ppc_md.hpte_insert); - make_bl(ht64_call_hpte_insert2, ppc_md.hpte_insert); - make_bl(ht64_call_hpte_remove, ppc_md.hpte_remove); - make_bl(ht64_call_hpte_updatepp, ppc_md.hpte_updatepp); -#endif /* CONFIG_PPC_64K_PAGES */ - - make_bl(htab_call_hpte_insert1, ppc_md.hpte_insert); - make_bl(htab_call_hpte_insert2, ppc_md.hpte_insert); - make_bl(htab_call_hpte_remove, ppc_md.hpte_remove); - make_bl(htab_call_hpte_updatepp, ppc_md.hpte_updatepp); -} diff --git a/trunk/arch/powerpc/mm/mmu_context_64.c b/trunk/arch/powerpc/mm/mmu_context_64.c index 65d18dca266f..e2051efa09c5 100644 --- a/trunk/arch/powerpc/mm/mmu_context_64.c +++ b/trunk/arch/powerpc/mm/mmu_context_64.c @@ -44,7 +44,9 @@ int init_new_context(struct task_struct *tsk, struct mm_struct *mm) return err; if (index > MAX_CONTEXT) { + spin_lock(&mmu_context_lock); idr_remove(&mmu_context_idr, index); + spin_unlock(&mmu_context_lock); return -ENOMEM; } diff --git a/trunk/arch/powerpc/platforms/83xx/pci.c b/trunk/arch/powerpc/platforms/83xx/pci.c index 16f7d3b30e1d..3baceb00fefa 100644 --- a/trunk/arch/powerpc/platforms/83xx/pci.c +++ b/trunk/arch/powerpc/platforms/83xx/pci.c @@ -91,9 +91,10 @@ int __init add_bridge(struct device_node *dev) mpc83xx_pci2_busno = hose->first_busno; } - printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%08lx. " + printk(KERN_INFO "Found MPC83xx PCI host bridge at 0x%016llx. " "Firmware bus number: %d->%d\n", - rsrc.start, hose->first_busno, hose->last_busno); + (unsigned long long)rsrc.start, hose->first_busno, + hose->last_busno); DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", hose, hose->cfg_addr, hose->cfg_data); diff --git a/trunk/arch/powerpc/platforms/85xx/pci.c b/trunk/arch/powerpc/platforms/85xx/pci.c index bad290110ed1..48c8849c07ca 100644 --- a/trunk/arch/powerpc/platforms/85xx/pci.c +++ b/trunk/arch/powerpc/platforms/85xx/pci.c @@ -79,9 +79,10 @@ int __init add_bridge(struct device_node *dev) mpc85xx_pci2_busno = hose->first_busno; } - printk(KERN_INFO "Found MPC85xx PCI host bridge at 0x%08lx. " + printk(KERN_INFO "Found MPC85xx PCI host bridge at 0x%016llx. " "Firmware bus number: %d->%d\n", - rsrc.start, hose->first_busno, hose->last_busno); + (unsigned long long)rsrc.start, hose->first_busno, + hose->last_busno); DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", hose, hose->cfg_addr, hose->cfg_data); diff --git a/trunk/arch/powerpc/platforms/86xx/Kconfig b/trunk/arch/powerpc/platforms/86xx/Kconfig index 3a87863d2876..d1ecc0f9ab58 100644 --- a/trunk/arch/powerpc/platforms/86xx/Kconfig +++ b/trunk/arch/powerpc/platforms/86xx/Kconfig @@ -7,6 +7,7 @@ choice config MPC8641_HPCN bool "Freescale MPC8641 HPCN" + select PPC_I8259 help This option enables support for the MPC8641 HPCN board. @@ -28,9 +29,4 @@ config PPC_INDIRECT_PCI_BE depends on PPC_86xx default y -config PPC_STD_MMU - bool - depends on PPC_86xx - default y - endmenu diff --git a/trunk/arch/powerpc/platforms/86xx/Makefile b/trunk/arch/powerpc/platforms/86xx/Makefile index 7be796c5d5c9..476a6eeee710 100644 --- a/trunk/arch/powerpc/platforms/86xx/Makefile +++ b/trunk/arch/powerpc/platforms/86xx/Makefile @@ -2,9 +2,6 @@ # Makefile for the PowerPC 86xx linux kernel. # - -ifeq ($(CONFIG_PPC_86xx),y) obj-$(CONFIG_SMP) += mpc86xx_smp.o -endif obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o obj-$(CONFIG_PCI) += pci.o mpc86xx_pcie.o diff --git a/trunk/arch/powerpc/platforms/86xx/mpc8641_hpcn.h b/trunk/arch/powerpc/platforms/86xx/mpc8641_hpcn.h index 5042253758b7..5d2bcf78cef7 100644 --- a/trunk/arch/powerpc/platforms/86xx/mpc8641_hpcn.h +++ b/trunk/arch/powerpc/platforms/86xx/mpc8641_hpcn.h @@ -14,7 +14,6 @@ #ifndef __MPC8641_HPCN_H__ #define __MPC8641_HPCN_H__ -#include #include /* PCI interrupt controller */ diff --git a/trunk/arch/powerpc/platforms/86xx/mpc86xx.h b/trunk/arch/powerpc/platforms/86xx/mpc86xx.h index e3c9e4f417d3..2834462590b8 100644 --- a/trunk/arch/powerpc/platforms/86xx/mpc86xx.h +++ b/trunk/arch/powerpc/platforms/86xx/mpc86xx.h @@ -15,11 +15,13 @@ * mpc86xx_* files. Mostly for use by mpc86xx_setup(). */ -extern int __init add_bridge(struct device_node *dev); +extern int add_bridge(struct device_node *dev); -extern void __init setup_indirect_pcie(struct pci_controller *hose, +extern int mpc86xx_exclude_device(u_char bus, u_char devfn); + +extern void setup_indirect_pcie(struct pci_controller *hose, u32 cfg_addr, u32 cfg_data); -extern void __init setup_indirect_pcie_nomap(struct pci_controller *hose, +extern void setup_indirect_pcie_nomap(struct pci_controller *hose, void __iomem *cfg_addr, void __iomem *cfg_data); diff --git a/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c index 483c21df181e..ebae73eb0063 100644 --- a/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c +++ b/trunk/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c @@ -12,7 +12,6 @@ * option) any later version. */ -#include #include #include #include @@ -36,6 +35,7 @@ #include #include "mpc86xx.h" +#include "mpc8641_hpcn.h" #ifndef CONFIG_PCI unsigned long isa_io_base = 0; @@ -186,17 +186,130 @@ mpc86xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) return PCI_IRQ_TABLE_LOOKUP + I8259_OFFSET; } +static void __devinit quirk_ali1575(struct pci_dev *dev) +{ + unsigned short temp; + + /* + * ALI1575 interrupts route table setup: + * + * IRQ pin IRQ# + * PIRQA ---- 3 + * PIRQB ---- 4 + * PIRQC ---- 5 + * PIRQD ---- 6 + * PIRQE ---- 9 + * PIRQF ---- 10 + * PIRQG ---- 11 + * PIRQH ---- 12 + * + * interrupts for PCI slot0 -- PIRQA / PIRQB / PIRQC / PIRQD + * PCI slot1 -- PIRQB / PIRQC / PIRQD / PIRQA + */ + pci_write_config_dword(dev, 0x48, 0xb9317542); + + /* USB 1.1 OHCI controller 1, interrupt: PIRQE */ + pci_write_config_byte(dev, 0x86, 0x0c); + + /* USB 1.1 OHCI controller 2, interrupt: PIRQF */ + pci_write_config_byte(dev, 0x87, 0x0d); + + /* USB 1.1 OHCI controller 3, interrupt: PIRQH */ + pci_write_config_byte(dev, 0x88, 0x0f); + + /* USB 2.0 controller, interrupt: PIRQ7 */ + pci_write_config_byte(dev, 0x74, 0x06); + + /* Audio controller, interrupt: PIRQE */ + pci_write_config_byte(dev, 0x8a, 0x0c); + + /* Modem controller, interrupt: PIRQF */ + pci_write_config_byte(dev, 0x8b, 0x0d); + + /* HD audio controller, interrupt: PIRQG */ + pci_write_config_byte(dev, 0x8c, 0x0e); + + /* Serial ATA interrupt: PIRQD */ + pci_write_config_byte(dev, 0x8d, 0x0b); + + /* SMB interrupt: PIRQH */ + pci_write_config_byte(dev, 0x8e, 0x0f); + + /* PMU ACPI SCI interrupt: PIRQH */ + pci_write_config_byte(dev, 0x8f, 0x0f); + + /* Primary PATA IDE IRQ: 14 + * Secondary PATA IDE IRQ: 15 + */ + pci_write_config_byte(dev, 0x44, 0x3d); + pci_write_config_byte(dev, 0x75, 0x0f); + + /* Set IRQ14 and IRQ15 to legacy IRQs */ + pci_read_config_word(dev, 0x46, &temp); + temp |= 0xc000; + pci_write_config_word(dev, 0x46, temp); + + /* Set i8259 interrupt trigger + * IRQ 3: Level + * IRQ 4: Level + * IRQ 5: Level + * IRQ 6: Level + * IRQ 7: Level + * IRQ 9: Level + * IRQ 10: Level + * IRQ 11: Level + * IRQ 12: Level + * IRQ 14: Edge + * IRQ 15: Edge + */ + outb(0xfa, 0x4d0); + outb(0x1e, 0x4d1); +} -int -mpc86xx_exclude_device(u_char bus, u_char devfn) +static void __devinit quirk_uli5288(struct pci_dev *dev) { -#if !defined(CONFIG_PCI) - if (bus == 0 && PCI_SLOT(devfn) == 0) - return PCIBIOS_DEVICE_NOT_FOUND; -#endif + unsigned char c; + + pci_read_config_byte(dev,0x83,&c); + c |= 0x80; + pci_write_config_byte(dev, 0x83, c); + + pci_write_config_byte(dev, 0x09, 0x01); + pci_write_config_byte(dev, 0x0a, 0x06); + + pci_read_config_byte(dev,0x83,&c); + c &= 0x7f; + pci_write_config_byte(dev, 0x83, c); - return PCIBIOS_SUCCESSFUL; + pci_read_config_byte(dev,0x84,&c); + c |= 0x01; + pci_write_config_byte(dev, 0x84, c); } + +static void __devinit quirk_uli5229(struct pci_dev *dev) +{ + unsigned short temp; + pci_write_config_word(dev, 0x04, 0x0405); + pci_read_config_word(dev, 0x4a, &temp); + temp |= 0x1000; + pci_write_config_word(dev, 0x4a, temp); +} + +static void __devinit early_uli5249(struct pci_dev *dev) +{ + unsigned char temp; + pci_write_config_word(dev, 0x04, 0x0007); + pci_read_config_byte(dev, 0x7c, &temp); + pci_write_config_byte(dev, 0x7c, 0x80); + pci_write_config_byte(dev, 0x09, 0x01); + pci_write_config_byte(dev, 0x7c, temp); + dev->class |= 0x1; +} + +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_ali1575); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288); +DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229); +DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249); #endif /* CONFIG_PCI */ diff --git a/trunk/arch/powerpc/platforms/86xx/mpc86xx_smp.c b/trunk/arch/powerpc/platforms/86xx/mpc86xx_smp.c index 944ec4b71416..bb7fb41933ad 100644 --- a/trunk/arch/powerpc/platforms/86xx/mpc86xx_smp.c +++ b/trunk/arch/powerpc/platforms/86xx/mpc86xx_smp.c @@ -10,7 +10,6 @@ * option) any later version. */ -#include #include #include #include @@ -34,8 +33,8 @@ extern unsigned long __secondary_hold_acknowledge; static void __init smp_86xx_release_core(int nr) { - void *mcm_vaddr; - unsigned long vaddr, pcr; + __be32 __iomem *mcm_vaddr; + unsigned long pcr; if (nr < 0 || nr >= NR_CPUS) return; @@ -45,10 +44,9 @@ smp_86xx_release_core(int nr) */ mcm_vaddr = ioremap(get_immrbase() + MPC86xx_MCM_OFFSET, MPC86xx_MCM_SIZE); - vaddr = (unsigned long)mcm_vaddr + MCM_PORT_CONFIG_OFFSET; - pcr = in_be32((volatile unsigned *)vaddr); + pcr = in_be32(mcm_vaddr + (MCM_PORT_CONFIG_OFFSET >> 2)); pcr |= 1 << (nr + 24); - out_be32((volatile unsigned *)vaddr, pcr); + out_be32(mcm_vaddr + (MCM_PORT_CONFIG_OFFSET >> 2), pcr); } diff --git a/trunk/arch/powerpc/platforms/86xx/pci.c b/trunk/arch/powerpc/platforms/86xx/pci.c index 5180df7c75bc..bc5139043112 100644 --- a/trunk/arch/powerpc/platforms/86xx/pci.c +++ b/trunk/arch/powerpc/platforms/86xx/pci.c @@ -12,7 +12,6 @@ * option) any later version. */ -#include #include #include #include @@ -122,15 +121,12 @@ static void __init setup_pcie_atmu(struct pci_controller *hose, struct resource static void __init mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size) { - volatile struct ccsr_pex *pcie; u16 cmd; unsigned int temps; DBG("PCIE host controller register offset 0x%08x, size 0x%08x.\n", pcie_offset, pcie_size); - pcie = ioremap(pcie_offset, pcie_size); - early_read_config_word(hose, 0, 0, PCI_COMMAND, &cmd); cmd |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO; @@ -144,6 +140,14 @@ mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size) early_write_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, temps); } +int mpc86xx_exclude_device(u_char bus, u_char devfn) +{ + if (bus == 0 && PCI_SLOT(devfn) == 0) + return PCIBIOS_DEVICE_NOT_FOUND; + + return PCIBIOS_SUCCESSFUL; +} + int __init add_bridge(struct device_node *dev) { int len; @@ -198,128 +202,3 @@ int __init add_bridge(struct device_node *dev) return 0; } - -static void __devinit quirk_ali1575(struct pci_dev *dev) -{ - unsigned short temp; - - /* - * ALI1575 interrupts route table setup: - * - * IRQ pin IRQ# - * PIRQA ---- 3 - * PIRQB ---- 4 - * PIRQC ---- 5 - * PIRQD ---- 6 - * PIRQE ---- 9 - * PIRQF ---- 10 - * PIRQG ---- 11 - * PIRQH ---- 12 - * - * interrupts for PCI slot0 -- PIRQA / PIRQB / PIRQC / PIRQD - * PCI slot1 -- PIRQB / PIRQC / PIRQD / PIRQA - */ - pci_write_config_dword(dev, 0x48, 0xb9317542); - - /* USB 1.1 OHCI controller 1, interrupt: PIRQE */ - pci_write_config_byte(dev, 0x86, 0x0c); - - /* USB 1.1 OHCI controller 2, interrupt: PIRQF */ - pci_write_config_byte(dev, 0x87, 0x0d); - - /* USB 1.1 OHCI controller 3, interrupt: PIRQH */ - pci_write_config_byte(dev, 0x88, 0x0f); - - /* USB 2.0 controller, interrupt: PIRQ7 */ - pci_write_config_byte(dev, 0x74, 0x06); - - /* Audio controller, interrupt: PIRQE */ - pci_write_config_byte(dev, 0x8a, 0x0c); - - /* Modem controller, interrupt: PIRQF */ - pci_write_config_byte(dev, 0x8b, 0x0d); - - /* HD audio controller, interrupt: PIRQG */ - pci_write_config_byte(dev, 0x8c, 0x0e); - - /* Serial ATA interrupt: PIRQD */ - pci_write_config_byte(dev, 0x8d, 0x0b); - - /* SMB interrupt: PIRQH */ - pci_write_config_byte(dev, 0x8e, 0x0f); - - /* PMU ACPI SCI interrupt: PIRQH */ - pci_write_config_byte(dev, 0x8f, 0x0f); - - /* Primary PATA IDE IRQ: 14 - * Secondary PATA IDE IRQ: 15 - */ - pci_write_config_byte(dev, 0x44, 0x3d); - pci_write_config_byte(dev, 0x75, 0x0f); - - /* Set IRQ14 and IRQ15 to legacy IRQs */ - pci_read_config_word(dev, 0x46, &temp); - temp |= 0xc000; - pci_write_config_word(dev, 0x46, temp); - - /* Set i8259 interrupt trigger - * IRQ 3: Level - * IRQ 4: Level - * IRQ 5: Level - * IRQ 6: Level - * IRQ 7: Level - * IRQ 9: Level - * IRQ 10: Level - * IRQ 11: Level - * IRQ 12: Level - * IRQ 14: Edge - * IRQ 15: Edge - */ - outb(0xfa, 0x4d0); - outb(0x1e, 0x4d1); -} - -static void __devinit quirk_uli5288(struct pci_dev *dev) -{ - unsigned char c; - - pci_read_config_byte(dev,0x83,&c); - c |= 0x80; - pci_write_config_byte(dev, 0x83, c); - - pci_write_config_byte(dev, 0x09, 0x01); - pci_write_config_byte(dev, 0x0a, 0x06); - - pci_read_config_byte(dev,0x83,&c); - c &= 0x7f; - pci_write_config_byte(dev, 0x83, c); - - pci_read_config_byte(dev,0x84,&c); - c |= 0x01; - pci_write_config_byte(dev, 0x84, c); -} - -static void __devinit quirk_uli5229(struct pci_dev *dev) -{ - unsigned short temp; - pci_write_config_word(dev, 0x04, 0x0405); - pci_read_config_word(dev, 0x4a, &temp); - temp |= 0x1000; - pci_write_config_word(dev, 0x4a, temp); -} - -static void __devinit early_uli5249(struct pci_dev *dev) -{ - unsigned char temp; - pci_write_config_word(dev, 0x04, 0x0007); - pci_read_config_byte(dev, 0x7c, &temp); - pci_write_config_byte(dev, 0x7c, 0x80); - pci_write_config_byte(dev, 0x09, 0x01); - pci_write_config_byte(dev, 0x7c, temp); - dev->class |= 0x1; -} - -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_ali1575); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288); -DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229); -DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249); diff --git a/trunk/arch/powerpc/platforms/Makefile b/trunk/arch/powerpc/platforms/Makefile index 292863694562..5cf46dc57895 100644 --- a/trunk/arch/powerpc/platforms/Makefile +++ b/trunk/arch/powerpc/platforms/Makefile @@ -14,3 +14,4 @@ obj-$(CONFIG_PPC_PSERIES) += pseries/ obj-$(CONFIG_PPC_ISERIES) += iseries/ obj-$(CONFIG_PPC_MAPLE) += maple/ obj-$(CONFIG_PPC_CELL) += cell/ +obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/ diff --git a/trunk/arch/powerpc/platforms/cell/Kconfig b/trunk/arch/powerpc/platforms/cell/Kconfig index 352bbbacde9a..0c8c7b6ab897 100644 --- a/trunk/arch/powerpc/platforms/cell/Kconfig +++ b/trunk/arch/powerpc/platforms/cell/Kconfig @@ -6,6 +6,7 @@ config SPU_FS default m depends on PPC_CELL select SPU_BASE + select MEMORY_HOTPLUG help The SPU file system is used to access Synergistic Processing Units on machines implementing the Broadband Processor @@ -18,7 +19,6 @@ config SPU_BASE config SPUFS_MMAP bool depends on SPU_FS && SPARSEMEM - select MEMORY_HOTPLUG default y config CBE_RAS diff --git a/trunk/arch/powerpc/platforms/cell/interrupt.c b/trunk/arch/powerpc/platforms/cell/interrupt.c index 1bbf822b4efc..7bff3cbc5723 100644 --- a/trunk/arch/powerpc/platforms/cell/interrupt.c +++ b/trunk/arch/powerpc/platforms/cell/interrupt.c @@ -307,7 +307,7 @@ static void iic_request_ipi(int ipi, const char *name) irq = iic_ipi_to_irq(ipi); /* IPIs are marked SA_INTERRUPT as they must run with irqs * disabled */ - get_irq_desc(irq)->handler = &iic_pic; + get_irq_desc(irq)->chip = &iic_pic; get_irq_desc(irq)->status |= IRQ_PER_CPU; request_irq(irq, iic_ipi_action, SA_INTERRUPT, name, NULL); } @@ -330,7 +330,7 @@ static void iic_setup_spe_handlers(void) for (be=0; be < num_present_cpus() / 2; be++) { for (isrc = 0; isrc < IIC_CLASS_STRIDE * 3; isrc++) { int irq = IIC_NODE_STRIDE * be + IIC_SPE_OFFSET + isrc; - get_irq_desc(irq)->handler = &iic_pic; + get_irq_desc(irq)->chip = &iic_pic; } } } diff --git a/trunk/arch/powerpc/platforms/cell/setup.c b/trunk/arch/powerpc/platforms/cell/setup.c index 3d1831d331e5..00d112f92272 100644 --- a/trunk/arch/powerpc/platforms/cell/setup.c +++ b/trunk/arch/powerpc/platforms/cell/setup.c @@ -125,8 +125,6 @@ static void __init cell_init_early(void) { DBG(" -> cell_init_early()\n"); - hpte_init_native(); - cell_init_iommu(); ppc64_interrupt_controller = IC_CELL_PIC; @@ -139,11 +137,17 @@ static int __init cell_probe(void) { unsigned long root = of_get_flat_dt_root(); - if (of_flat_dt_is_compatible(root, "IBM,CBEA") || - of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) - return 1; + if (!of_flat_dt_is_compatible(root, "IBM,CBEA") && + !of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) + return 0; + +#ifdef CONFIG_UDBG_RTAS_CONSOLE + udbg_init_rtas_console(); +#endif + + hpte_init_native(); - return 0; + return 1; } /* diff --git a/trunk/arch/powerpc/platforms/cell/spider-pic.c b/trunk/arch/powerpc/platforms/cell/spider-pic.c index 55cbdd77a62d..7c3a0b6d34fd 100644 --- a/trunk/arch/powerpc/platforms/cell/spider-pic.c +++ b/trunk/arch/powerpc/platforms/cell/spider-pic.c @@ -162,7 +162,7 @@ void spider_init_IRQ_hardcoded(void) spider_pics[node] = ioremap(spiderpic, 0x800); for (n = 0; n < IIC_NUM_EXT; n++) { int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE; - get_irq_desc(irq)->handler = &spider_pic; + get_irq_desc(irq)->chip = &spider_pic; } /* do not mask any interrupts because of level */ @@ -217,7 +217,7 @@ void spider_init_IRQ(void) for (n = 0; n < IIC_NUM_EXT; n++) { int irq = n + IIC_EXT_OFFSET + node * IIC_NODE_STRIDE; - get_irq_desc(irq)->handler = &spider_pic; + get_irq_desc(irq)->chip = &spider_pic; } /* do not mask any interrupts because of level */ diff --git a/trunk/arch/powerpc/platforms/cell/spu_base.c b/trunk/arch/powerpc/platforms/cell/spu_base.c index db82f503ba2c..b306723abb87 100644 --- a/trunk/arch/powerpc/platforms/cell/spu_base.c +++ b/trunk/arch/powerpc/platforms/cell/spu_base.c @@ -168,12 +168,12 @@ spu_irq_class_0_bottom(struct spu *spu) stat &= mask; - if (stat & 1) /* invalid MFC DMA */ - __spu_trap_invalid_dma(spu); - - if (stat & 2) /* invalid DMA alignment */ + if (stat & 1) /* invalid DMA alignment */ __spu_trap_dma_align(spu); + if (stat & 2) /* invalid MFC DMA */ + __spu_trap_invalid_dma(spu); + if (stat & 4) /* error on SPU */ __spu_trap_error(spu); diff --git a/trunk/arch/powerpc/platforms/cell/spufs/file.c b/trunk/arch/powerpc/platforms/cell/spufs/file.c index 7854a380dce2..58e794f9da1b 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/file.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/file.c @@ -204,7 +204,7 @@ static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_flags |= VM_RESERVED; vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE); + | _PAGE_NO_CACHE | _PAGE_GUARDED); vma->vm_ops = &spufs_cntl_mmap_vmops; return 0; @@ -675,7 +675,7 @@ static int spufs_signal1_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_flags |= VM_RESERVED; vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE); + | _PAGE_NO_CACHE | _PAGE_GUARDED); vma->vm_ops = &spufs_signal1_mmap_vmops; return 0; @@ -762,7 +762,7 @@ static int spufs_signal2_mmap(struct file *file, struct vm_area_struct *vma) /* FIXME: */ vma->vm_flags |= VM_RESERVED; vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE); + | _PAGE_NO_CACHE | _PAGE_GUARDED); vma->vm_ops = &spufs_signal2_mmap_vmops; return 0; @@ -850,7 +850,7 @@ static int spufs_mss_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_flags |= VM_RESERVED; vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE); + | _PAGE_NO_CACHE | _PAGE_GUARDED); vma->vm_ops = &spufs_mss_mmap_vmops; return 0; @@ -899,7 +899,7 @@ static int spufs_mfc_mmap(struct file *file, struct vm_area_struct *vma) vma->vm_flags |= VM_RESERVED; vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) - | _PAGE_NO_CACHE); + | _PAGE_NO_CACHE | _PAGE_GUARDED); vma->vm_ops = &spufs_mfc_mmap_vmops; return 0; diff --git a/trunk/arch/powerpc/platforms/cell/spufs/switch.c b/trunk/arch/powerpc/platforms/cell/spufs/switch.c index a656d810a44a..c7fea2cca534 100644 --- a/trunk/arch/powerpc/platforms/cell/spufs/switch.c +++ b/trunk/arch/powerpc/platforms/cell/spufs/switch.c @@ -464,7 +464,8 @@ static inline void wait_purge_complete(struct spu_state *csa, struct spu *spu) * Poll MFC_CNTL[Ps] until value '11' is read * (purge complete). */ - POLL_WHILE_FALSE(in_be64(&priv2->mfc_control_RW) & + POLL_WHILE_FALSE((in_be64(&priv2->mfc_control_RW) & + MFC_CNTL_PURGE_DMA_STATUS_MASK) == MFC_CNTL_PURGE_DMA_COMPLETE); } @@ -1028,7 +1029,8 @@ static inline void wait_suspend_mfc_complete(struct spu_state *csa, * Restore, Step 47. * Poll MFC_CNTL[Ss] until 11 is returned. */ - POLL_WHILE_FALSE(in_be64(&priv2->mfc_control_RW) & + POLL_WHILE_FALSE((in_be64(&priv2->mfc_control_RW) & + MFC_CNTL_SUSPEND_DMA_STATUS_MASK) == MFC_CNTL_SUSPEND_COMPLETE); } diff --git a/trunk/arch/powerpc/platforms/chrp/pci.c b/trunk/arch/powerpc/platforms/chrp/pci.c index ac224876ce59..53515daf01b1 100644 --- a/trunk/arch/powerpc/platforms/chrp/pci.c +++ b/trunk/arch/powerpc/platforms/chrp/pci.c @@ -143,7 +143,7 @@ hydra_init(void) if (np == NULL || of_address_to_resource(np, 0, &r)) return 0; Hydra = ioremap(r.start, r.end-r.start); - printk("Hydra Mac I/O at %lx\n", r.start); + printk("Hydra Mac I/O at %llx\n", (unsigned long long)r.start); printk("Hydra Feature_Control was %x", in_le32(&Hydra->Feature_Control)); out_le32(&Hydra->Feature_Control, (HYDRA_FC_SCC_CELL_EN | @@ -267,7 +267,7 @@ chrp_find_bridges(void) bus_range[0], bus_range[1]); printk(" controlled by %s", dev->type); if (!is_longtrail) - printk(" at %lx", r.start); + printk(" at %llx", (unsigned long long)r.start); printk("\n"); hose = pcibios_alloc_controller(); diff --git a/trunk/arch/powerpc/platforms/embedded6xx/Kconfig b/trunk/arch/powerpc/platforms/embedded6xx/Kconfig index 4fdbc9ae876b..ba07a9a7c039 100644 --- a/trunk/arch/powerpc/platforms/embedded6xx/Kconfig +++ b/trunk/arch/powerpc/platforms/embedded6xx/Kconfig @@ -74,6 +74,16 @@ config SANDPOINT Select SANDPOINT if configuring for a Motorola Sandpoint X3 (any flavor). +config MPC7448HPC2 + bool "Freescale MPC7448HPC2(Taiga)" + select TSI108_BRIDGE + select DEFAULT_UIMAGE + select PPC_UDBG_16550 + select MPIC + help + Select MPC7448HPC2 if configuring for Freescale MPC7448HPC2 (Taiga) + platform + config RADSTONE_PPC7D bool "Radstone Technology PPC7D board" select PPC_I8259 @@ -221,6 +231,11 @@ config MV64X60 select PPC_INDIRECT_PCI default y +config TSI108_BRIDGE + bool + depends on MPC7448HPC2 + default y + menu "Set bridge options" depends on MV64X60 diff --git a/trunk/arch/powerpc/platforms/embedded6xx/Makefile b/trunk/arch/powerpc/platforms/embedded6xx/Makefile new file mode 100644 index 000000000000..fa499fe59291 --- /dev/null +++ b/trunk/arch/powerpc/platforms/embedded6xx/Makefile @@ -0,0 +1,4 @@ +# +# Makefile for the 6xx/7xx/7xxxx linux kernel. +# +obj-$(CONFIG_MPC7448HPC2) += mpc7448_hpc2.o diff --git a/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c new file mode 100644 index 000000000000..d7a4fc7ca238 --- /dev/null +++ b/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c @@ -0,0 +1,335 @@ +/* + * mpc7448_hpc2.c + * + * Board setup routines for the Freescale Taiga platform + * + * Author: Jacob Pan + * jacob.pan@freescale.com + * Author: Xianghua Xiao + * x.xiao@freescale.com + * Maintainer: Roy Zang + * Add Flat Device Tree support fot mpc7448hpc2 board + * + * Copyright 2004-2006 Freescale Semiconductor, Inc. + * + * 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 kind, whether express + * or implied. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "mpc7448_hpc2.h" +#include +#include + +#undef DEBUG +#ifdef DEBUG +#define DBG(fmt...) do { printk(fmt); } while(0) +#else +#define DBG(fmt...) do { } while(0) +#endif + +#ifndef CONFIG_PCI +isa_io_base = MPC7448_HPC2_ISA_IO_BASE; +isa_mem_base = MPC7448_HPC2_ISA_MEM_BASE; +pci_dram_offset = MPC7448_HPC2_PCI_MEM_OFFSET; +#endif + +extern int tsi108_setup_pci(struct device_node *dev); +extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); +extern void tsi108_pci_int_init(void); +extern int tsi108_irq_cascade(struct pt_regs *regs, void *unused); + +/* + * Define all of the IRQ senses and polarities. Taken from the + * mpc7448hpc manual. + * Note: Likely, this table and the following function should be + * obtained and derived from the OF Device Tree. + */ + +static u_char mpc7448_hpc2_pic_initsenses[] __initdata = { + /* External on-board sources */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[0] XINT0 from FPGA */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[1] XINT1 from FPGA */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[2] PHY_INT from both GIGE */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* INT[3] RESERVED */ + /* Internal Tsi108/109 interrupt sources */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA0 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA1 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA2 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* DMA3 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* UART0 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* UART1 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* I2C */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* GPIO */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* GIGE0 */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* GIGE1 */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* HLP */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* SDC */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Processor IF */ + (IRQ_SENSE_EDGE | IRQ_POLARITY_POSITIVE), /* Reserved IRQ */ + (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* PCI/X block */ +}; + +int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn) +{ + if (bus == 0 && PCI_SLOT(devfn) == 0) + return PCIBIOS_DEVICE_NOT_FOUND; + else + return PCIBIOS_SUCCESSFUL; +} + +/* + * find pci slot by devfn in interrupt map of OF tree + */ +u8 find_slot_by_devfn(unsigned int *interrupt_map, unsigned int devfn) +{ + int i; + unsigned int tmp; + for (i = 0; i < 4; i++){ + tmp = interrupt_map[i*4*7]; + if ((tmp >> 11) == (devfn >> 3)) + return i; + } + return i; +} + +/* + * Scans the interrupt map for pci device + */ +void mpc7448_hpc2_fixup_irq(struct pci_dev *dev) +{ + struct pci_controller *hose; + struct device_node *node; + unsigned int *interrupt; + int busnr; + int len; + u8 slot; + u8 pin; + + /* Lookup the hose */ + busnr = dev->bus->number; + hose = pci_bus_to_hose(busnr); + if (!hose) + printk(KERN_ERR "No pci hose found\n"); + + /* Check it has an OF node associated */ + node = (struct device_node *) hose->arch_data; + if (!node) + printk(KERN_ERR "No pci node found\n"); + + interrupt = (unsigned int *) get_property(node, "interrupt-map", &len); + slot = find_slot_by_devfn(interrupt, dev->devfn); + pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); + if (pin == 0 || pin > 4) + pin = 1; + pin--; + dev->irq = interrupt[slot*4*7 + pin*7 + 5]; + DBG("TSI_PCI: dev->irq = 0x%x\n", dev->irq); +} +/* temporary pci irq map fixup*/ + +void __init mpc7448_hpc2_pcibios_fixup(void) +{ + struct pci_dev *dev = NULL; + for_each_pci_dev(dev) { + mpc7448_hpc2_fixup_irq(dev); + pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); + } +} + +static void __init mpc7448_hpc2_setup_arch(void) +{ + struct device_node *cpu; + struct device_node *np; + if (ppc_md.progress) + ppc_md.progress("mpc7448_hpc2_setup_arch():set_bridge", 0); + + cpu = of_find_node_by_type(NULL, "cpu"); + if (cpu != 0) { + unsigned int *fp; + + fp = (int *)get_property(cpu, "clock-frequency", NULL); + if (fp != 0) + loops_per_jiffy = *fp / HZ; + else + loops_per_jiffy = 50000000 / HZ; + of_node_put(cpu); + } + tsi108_csr_vir_base = get_vir_csrbase(); + +#ifdef CONFIG_ROOT_NFS + ROOT_DEV = Root_NFS; +#else + ROOT_DEV = Root_HDA1; +#endif + +#ifdef CONFIG_BLK_DEV_INITRD + ROOT_DEV = Root_RAM0; +#endif + + /* setup PCI host bridge */ +#ifdef CONFIG_PCI + for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) + tsi108_setup_pci(np); + + ppc_md.pci_exclude_device = mpc7448_hpc2_exclude_device; + if (ppc_md.progress) + ppc_md.progress("tsi108: resources set", 0x100); +#endif + + printk(KERN_INFO "MPC7448HPC2 (TAIGA) Platform\n"); + printk(KERN_INFO + "Jointly ported by Freescale and Tundra Semiconductor\n"); + printk(KERN_INFO + "Enabling L2 cache then enabling the HID0 prefetch engine.\n"); +} + +/* + * Interrupt setup and service. Interrrupts on the mpc7448_hpc2 come + * from the four external INT pins, PCI interrupts are routed via + * PCI interrupt control registers, it generates internal IRQ23 + * + * Interrupt routing on the Taiga Board: + * TSI108:PB_INT[0] -> CPU0:INT# + * TSI108:PB_INT[1] -> CPU0:MCP# + * TSI108:PB_INT[2] -> N/C + * TSI108:PB_INT[3] -> N/C + */ +static void __init mpc7448_hpc2_init_IRQ(void) +{ + struct mpic *mpic; + phys_addr_t mpic_paddr = 0; + struct device_node *tsi_pic; + + tsi_pic = of_find_node_by_type(NULL, "open-pic"); + if (tsi_pic) { + unsigned int size; + void *prop = get_property(tsi_pic, "reg", &size); + mpic_paddr = of_translate_address(tsi_pic, prop); + } + + if (mpic_paddr == 0) { + printk("%s: No tsi108 PIC found !\n", __FUNCTION__); + return; + } + + DBG("%s: tsi108pic phys_addr = 0x%x\n", __FUNCTION__, + (u32) mpic_paddr); + + mpic = mpic_alloc(mpic_paddr, + MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET | + MPIC_SPV_EOI | MPIC_MOD_ID(MPIC_ID_TSI108), + 0, /* num_sources used */ + TSI108_IRQ_BASE, + 0, /* num_sources used */ + NR_IRQS - 4 /* XXXX */, + mpc7448_hpc2_pic_initsenses, + sizeof(mpc7448_hpc2_pic_initsenses), "Tsi108_PIC"); + + BUG_ON(mpic == NULL); /* XXXX */ + + mpic_init(mpic); + mpic_setup_cascade(IRQ_TSI108_PCI, tsi108_irq_cascade, mpic); + tsi108_pci_int_init(); + + /* Configure MPIC outputs to CPU0 */ + tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0); +} + +void mpc7448_hpc2_show_cpuinfo(struct seq_file *m) +{ + seq_printf(m, "vendor\t\t: Freescale Semiconductor\n"); + seq_printf(m, "machine\t\t: MPC7448hpc2\n"); +} + +void mpc7448_hpc2_restart(char *cmd) +{ + local_irq_disable(); + + /* Set exception prefix high - to the firmware */ + _nmask_and_or_msr(0, MSR_IP); + + for (;;) ; /* Spin until reset happens */ +} + +void mpc7448_hpc2_power_off(void) +{ + local_irq_disable(); + for (;;) ; /* No way to shut power off with software */ +} + +void mpc7448_hpc2_halt(void) +{ + mpc7448_hpc2_power_off(); +} + +/* + * Called very early, device-tree isn't unflattened + */ +static int __init mpc7448_hpc2_probe(void) +{ + unsigned long root = of_get_flat_dt_root(); + + if (!of_flat_dt_is_compatible(root, "mpc74xx")) + return 0; + return 1; +} + +static int mpc7448_machine_check_exception(struct pt_regs *regs) +{ + extern void tsi108_clear_pci_cfg_error(void); + const struct exception_table_entry *entry; + + /* Are we prepared to handle this fault */ + if ((entry = search_exception_tables(regs->nip)) != NULL) { + tsi108_clear_pci_cfg_error(); + regs->msr |= MSR_RI; + regs->nip = entry->fixup; + return 1; + } + return 0; + +} +define_machine(mpc7448_hpc2){ + .name = "MPC7448 HPC2", + .probe = mpc7448_hpc2_probe, + .setup_arch = mpc7448_hpc2_setup_arch, + .init_IRQ = mpc7448_hpc2_init_IRQ, + .show_cpuinfo = mpc7448_hpc2_show_cpuinfo, + .get_irq = mpic_get_irq, + .pcibios_fixup = mpc7448_hpc2_pcibios_fixup, + .restart = mpc7448_hpc2_restart, + .calibrate_decr = generic_calibrate_decr, + .machine_check_exception= mpc7448_machine_check_exception, + .progress = udbg_progress, +}; diff --git a/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h b/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h new file mode 100644 index 000000000000..a543a5242e34 --- /dev/null +++ b/trunk/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.h @@ -0,0 +1,26 @@ +/* + * mpc7448_hpc2.h + * + * Definitions for Freescale MPC7448_HPC2 platform + * + * Author: Jacob Pan + * jacob.pan@freescale.com + * Maintainer: Roy Zang + * + * 2006 (c) Freescale Semiconductor, Inc. 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 kind, whether express + * or implied. + */ + +#ifndef __PPC_PLATFORMS_MPC7448_HPC2_H +#define __PPC_PLATFORMS_MPC7448_HPC2_H + +#include + +/* Base Addresses for the PCI bus + */ +#define MPC7448_HPC2_PCI_MEM_OFFSET (0x00000000) +#define MPC7448_HPC2_ISA_IO_BASE (0x00000000) +#define MPC7448_HPC2_ISA_MEM_BASE (0x00000000) +#endif /* __PPC_PLATFORMS_MPC7448_HPC2_H */ diff --git a/trunk/arch/powerpc/platforms/iseries/dt.c b/trunk/arch/powerpc/platforms/iseries/dt.c index d3444aabe76e..d194140c1ebf 100644 --- a/trunk/arch/powerpc/platforms/iseries/dt.c +++ b/trunk/arch/powerpc/platforms/iseries/dt.c @@ -252,6 +252,7 @@ static void __init dt_model(struct iseries_flat_dt *dt) { char buf[16] = "IBM,"; + /* N.B. lparcfg.c knows about the "IBM," prefixes ... */ /* "IBM," + mfgId[2:3] + systemSerial[1:5] */ strne2a(buf + 4, xItExtVpdPanel.mfgID + 2, 2); strne2a(buf + 6, xItExtVpdPanel.systemSerial + 1, 5); @@ -264,6 +265,7 @@ static void __init dt_model(struct iseries_flat_dt *dt) dt_prop_str(dt, "model", buf); dt_prop_str(dt, "compatible", "IBM,iSeries"); + dt_prop_u32(dt, "ibm,partition-no", HvLpConfig_getLpIndex()); } static void __init dt_do_vdevice(struct iseries_flat_dt *dt, diff --git a/trunk/arch/powerpc/platforms/iseries/htab.c b/trunk/arch/powerpc/platforms/iseries/htab.c index 30bdcf3925d9..ed44dfceaa45 100644 --- a/trunk/arch/powerpc/platforms/iseries/htab.c +++ b/trunk/arch/powerpc/platforms/iseries/htab.c @@ -242,13 +242,11 @@ static void iSeries_hpte_invalidate(unsigned long slot, unsigned long va, local_irq_restore(flags); } -void hpte_init_iSeries(void) +void __init hpte_init_iSeries(void) { ppc_md.hpte_invalidate = iSeries_hpte_invalidate; ppc_md.hpte_updatepp = iSeries_hpte_updatepp; ppc_md.hpte_updateboltedpp = iSeries_hpte_updateboltedpp; ppc_md.hpte_insert = iSeries_hpte_insert; ppc_md.hpte_remove = iSeries_hpte_remove; - - htab_finish_init(); } diff --git a/trunk/arch/powerpc/platforms/iseries/irq.c b/trunk/arch/powerpc/platforms/iseries/irq.c index 62bbbcf5ded3..33bb4aa0e1e8 100644 --- a/trunk/arch/powerpc/platforms/iseries/irq.c +++ b/trunk/arch/powerpc/platforms/iseries/irq.c @@ -242,9 +242,9 @@ void __init iSeries_activate_IRQs() for_each_irq (irq) { irq_desc_t *desc = get_irq_desc(irq); - if (desc && desc->handler && desc->handler->startup) { + if (desc && desc->chip && desc->chip->startup) { spin_lock_irqsave(&desc->lock, flags); - desc->handler->startup(irq); + desc->chip->startup(irq); spin_unlock_irqrestore(&desc->lock, flags); } } @@ -324,7 +324,7 @@ int __init iSeries_allocate_IRQ(HvBusNumber bus, + function; virtirq = virt_irq_create_mapping(realirq); - irq_desc[virtirq].handler = &iSeries_IRQ_handler; + irq_desc[virtirq].chip = &iSeries_IRQ_handler; return virtirq; } diff --git a/trunk/arch/powerpc/platforms/iseries/lpevents.c b/trunk/arch/powerpc/platforms/iseries/lpevents.c index 8ca7b9396355..2a9f81ea27d6 100644 --- a/trunk/arch/powerpc/platforms/iseries/lpevents.c +++ b/trunk/arch/powerpc/platforms/iseries/lpevents.c @@ -51,20 +51,21 @@ static unsigned lpEventHandlerPaths[HvLpEvent_Type_NumTypes]; static struct HvLpEvent * get_next_hvlpevent(void) { struct HvLpEvent * event; - event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; + event = (struct HvLpEvent *)hvlpevent_queue.hq_current_event; if (hvlpevent_is_valid(event)) { /* rmb() needed only for weakly consistent machines (regatta) */ rmb(); /* Set pointer to next potential event */ - hvlpevent_queue.xSlicCurEventPtr += ((event->xSizeMinus1 + - LpEventAlign) / LpEventAlign) * LpEventAlign; + hvlpevent_queue.hq_current_event += ((event->xSizeMinus1 + + IT_LP_EVENT_ALIGN) / IT_LP_EVENT_ALIGN) * + IT_LP_EVENT_ALIGN; /* Wrap to beginning if no room at end */ - if (hvlpevent_queue.xSlicCurEventPtr > - hvlpevent_queue.xSlicLastValidEventPtr) { - hvlpevent_queue.xSlicCurEventPtr = - hvlpevent_queue.xSlicEventStackPtr; + if (hvlpevent_queue.hq_current_event > + hvlpevent_queue.hq_last_event) { + hvlpevent_queue.hq_current_event = + hvlpevent_queue.hq_event_stack; } } else { event = NULL; @@ -82,10 +83,10 @@ int hvlpevent_is_pending(void) if (smp_processor_id() >= spread_lpevents) return 0; - next_event = (struct HvLpEvent *)hvlpevent_queue.xSlicCurEventPtr; + next_event = (struct HvLpEvent *)hvlpevent_queue.hq_current_event; return hvlpevent_is_valid(next_event) || - hvlpevent_queue.xPlicOverflowIntPending; + hvlpevent_queue.hq_overflow_pending; } static void hvlpevent_clear_valid(struct HvLpEvent * event) @@ -95,18 +96,18 @@ static void hvlpevent_clear_valid(struct HvLpEvent * event) * ie. on 64-byte boundaries. */ struct HvLpEvent *tmp; - unsigned extra = ((event->xSizeMinus1 + LpEventAlign) / - LpEventAlign) - 1; + unsigned extra = ((event->xSizeMinus1 + IT_LP_EVENT_ALIGN) / + IT_LP_EVENT_ALIGN) - 1; switch (extra) { case 3: - tmp = (struct HvLpEvent*)((char*)event + 3 * LpEventAlign); + tmp = (struct HvLpEvent*)((char*)event + 3 * IT_LP_EVENT_ALIGN); hvlpevent_invalidate(tmp); case 2: - tmp = (struct HvLpEvent*)((char*)event + 2 * LpEventAlign); + tmp = (struct HvLpEvent*)((char*)event + 2 * IT_LP_EVENT_ALIGN); hvlpevent_invalidate(tmp); case 1: - tmp = (struct HvLpEvent*)((char*)event + 1 * LpEventAlign); + tmp = (struct HvLpEvent*)((char*)event + 1 * IT_LP_EVENT_ALIGN); hvlpevent_invalidate(tmp); } @@ -120,7 +121,7 @@ void process_hvlpevents(struct pt_regs *regs) struct HvLpEvent * event; /* If we have recursed, just return */ - if (!spin_trylock(&hvlpevent_queue.lock)) + if (!spin_trylock(&hvlpevent_queue.hq_lock)) return; for (;;) { @@ -148,17 +149,17 @@ void process_hvlpevents(struct pt_regs *regs) printk(KERN_INFO "Unexpected Lp Event type=%d\n", event->xType ); hvlpevent_clear_valid(event); - } else if (hvlpevent_queue.xPlicOverflowIntPending) + } else if (hvlpevent_queue.hq_overflow_pending) /* * No more valid events. If overflow events are * pending process them */ - HvCallEvent_getOverflowLpEvents(hvlpevent_queue.xIndex); + HvCallEvent_getOverflowLpEvents(hvlpevent_queue.hq_index); else break; } - spin_unlock(&hvlpevent_queue.lock); + spin_unlock(&hvlpevent_queue.hq_lock); } static int set_spread_lpevents(char *str) @@ -184,20 +185,20 @@ void setup_hvlpevent_queue(void) { void *eventStack; - spin_lock_init(&hvlpevent_queue.lock); + spin_lock_init(&hvlpevent_queue.hq_lock); /* Allocate a page for the Event Stack. */ - eventStack = alloc_bootmem_pages(LpEventStackSize); - memset(eventStack, 0, LpEventStackSize); + eventStack = alloc_bootmem_pages(IT_LP_EVENT_STACK_SIZE); + memset(eventStack, 0, IT_LP_EVENT_STACK_SIZE); /* Invoke the hypervisor to initialize the event stack */ - HvCallEvent_setLpEventStack(0, eventStack, LpEventStackSize); + HvCallEvent_setLpEventStack(0, eventStack, IT_LP_EVENT_STACK_SIZE); - hvlpevent_queue.xSlicEventStackPtr = (char *)eventStack; - hvlpevent_queue.xSlicCurEventPtr = (char *)eventStack; - hvlpevent_queue.xSlicLastValidEventPtr = (char *)eventStack + - (LpEventStackSize - LpEventMaxSize); - hvlpevent_queue.xIndex = 0; + hvlpevent_queue.hq_event_stack = eventStack; + hvlpevent_queue.hq_current_event = eventStack; + hvlpevent_queue.hq_last_event = (char *)eventStack + + (IT_LP_EVENT_STACK_SIZE - IT_LP_EVENT_MAX_SIZE); + hvlpevent_queue.hq_index = 0; } /* Register a handler for an LpEvent type */ diff --git a/trunk/arch/powerpc/platforms/iseries/proc.c b/trunk/arch/powerpc/platforms/iseries/proc.c index e68b6b5fa89f..c241413629ac 100644 --- a/trunk/arch/powerpc/platforms/iseries/proc.c +++ b/trunk/arch/powerpc/platforms/iseries/proc.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include "processor_vpd.h" diff --git a/trunk/arch/powerpc/platforms/iseries/setup.c b/trunk/arch/powerpc/platforms/iseries/setup.c index 617c724c4590..66c77e4f8ec2 100644 --- a/trunk/arch/powerpc/platforms/iseries/setup.c +++ b/trunk/arch/powerpc/platforms/iseries/setup.c @@ -81,8 +81,6 @@ static void iSeries_pci_final_fixup(void) { } #endif extern int rd_size; /* Defined in drivers/block/rd.c */ -extern unsigned long embedded_sysmap_start; -extern unsigned long embedded_sysmap_end; extern unsigned long iSeries_recal_tb; extern unsigned long iSeries_recal_titan; @@ -320,11 +318,6 @@ static void __init iSeries_init_early(void) iSeries_recal_tb = get_tb(); iSeries_recal_titan = HvCallXm_loadTod(); - /* - * Initialize the hash table management pointers - */ - hpte_init_iSeries(); - /* * Initialize the DMA/TCE management */ @@ -563,16 +556,6 @@ static void __init iSeries_fixup_klimit(void) if (naca.xRamDisk) klimit = KERNELBASE + (u64)naca.xRamDisk + (naca.xRamDiskSize * HW_PAGE_SIZE); - else { - /* - * No ram disk was included - check and see if there - * was an embedded system map. Change klimit to take - * into account any embedded system map - */ - if (embedded_sysmap_end) - klimit = KERNELBASE + ((embedded_sysmap_end + 4095) & - 0xfffffffffffff000); - } } static int __init iSeries_src_init(void) @@ -683,6 +666,8 @@ static int __init iseries_probe(void) */ virt_irq_max = 255; + hpte_init_iSeries(); + return 1; } diff --git a/trunk/arch/powerpc/platforms/maple/pci.c b/trunk/arch/powerpc/platforms/maple/pci.c index 9a4efc0c3b29..f7170ff86dab 100644 --- a/trunk/arch/powerpc/platforms/maple/pci.c +++ b/trunk/arch/powerpc/platforms/maple/pci.c @@ -376,9 +376,10 @@ static void __init maple_fixup_phb_resources(void) unsigned long offset = (unsigned long)hose->io_base_virt - pci_io_base; hose->io_resource.start += offset; hose->io_resource.end += offset; - printk(KERN_INFO "PCI Host %d, io start: %lx; io end: %lx\n", + printk(KERN_INFO "PCI Host %d, io start: %llx; io end: %llx\n", hose->global_number, - hose->io_resource.start, hose->io_resource.end); + (unsigned long long)hose->io_resource.start, + (unsigned long long)hose->io_resource.end); } } diff --git a/trunk/arch/powerpc/platforms/maple/setup.c b/trunk/arch/powerpc/platforms/maple/setup.c index a0505ea48a86..4e32a5417fd1 100644 --- a/trunk/arch/powerpc/platforms/maple/setup.c +++ b/trunk/arch/powerpc/platforms/maple/setup.c @@ -199,11 +199,6 @@ static void __init maple_init_early(void) { DBG(" -> maple_init_early\n"); - /* Initialize hash table, from now on, we can take hash faults - * and call ioremap - */ - hpte_init_native(); - /* Setup interrupt mapping options */ ppc64_interrupt_controller = IC_OPEN_PIC; @@ -272,6 +267,8 @@ static int __init maple_probe(void) */ alloc_dart_table(); + hpte_init_native(); + return 1; } diff --git a/trunk/arch/powerpc/platforms/powermac/backlight.c b/trunk/arch/powerpc/platforms/powermac/backlight.c index 498b042e1837..c7a27eddca6d 100644 --- a/trunk/arch/powerpc/platforms/powermac/backlight.c +++ b/trunk/arch/powerpc/platforms/powermac/backlight.c @@ -119,7 +119,14 @@ int pmac_backlight_set_legacy_brightness(int brightness) down(&pmac_backlight->sem); props = pmac_backlight->props; props->brightness = brightness * - props->max_brightness / OLD_BACKLIGHT_MAX; + (props->max_brightness + 1) / + (OLD_BACKLIGHT_MAX + 1); + + if (props->brightness > props->max_brightness) + props->brightness = props->max_brightness; + else if (props->brightness < 0) + props->brightness = 0; + props->update_status(pmac_backlight); up(&pmac_backlight->sem); @@ -140,8 +147,11 @@ int pmac_backlight_get_legacy_brightness() down(&pmac_backlight->sem); props = pmac_backlight->props; + result = props->brightness * - OLD_BACKLIGHT_MAX / props->max_brightness; + (OLD_BACKLIGHT_MAX + 1) / + (props->max_brightness + 1); + up(&pmac_backlight->sem); } mutex_unlock(&pmac_backlight_mutex); diff --git a/trunk/arch/powerpc/platforms/powermac/pci.c b/trunk/arch/powerpc/platforms/powermac/pci.c index 80035853467b..d524a915aa86 100644 --- a/trunk/arch/powerpc/platforms/powermac/pci.c +++ b/trunk/arch/powerpc/platforms/powermac/pci.c @@ -939,9 +939,10 @@ static int __init add_bridge(struct device_node *dev) disp_name = "Chaos"; primary = 0; } - printk(KERN_INFO "Found %s PCI host bridge at 0x%08lx. " + printk(KERN_INFO "Found %s PCI host bridge at 0x%016llx. " "Firmware bus number: %d->%d\n", - disp_name, rsrc.start, hose->first_busno, hose->last_busno); + disp_name, (unsigned long long)rsrc.start, hose->first_busno, + hose->last_busno); #endif /* CONFIG_PPC32 */ DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", diff --git a/trunk/arch/powerpc/platforms/powermac/pic.c b/trunk/arch/powerpc/platforms/powermac/pic.c index 18bf3011d1e3..9f6189af6dd6 100644 --- a/trunk/arch/powerpc/platforms/powermac/pic.c +++ b/trunk/arch/powerpc/platforms/powermac/pic.c @@ -446,7 +446,7 @@ static void __init pmac_pic_probe_oldstyle(void) /* Set the handler for the main PIC */ for ( i = 0; i < max_real_irqs ; i++ ) - irq_desc[i].handler = &pmac_pic; + irq_desc[i].chip = &pmac_pic; /* Get addresses of first controller if we have a node for it */ BUG_ON(of_address_to_resource(master, 0, &r)); @@ -493,7 +493,7 @@ static void __init pmac_pic_probe_oldstyle(void) /* Setup handlers for secondary controller and hook cascade irq*/ if (slave) { for ( i = max_real_irqs ; i < max_irqs ; i++ ) - irq_desc[i].handler = &gatwick_pic; + irq_desc[i].chip = &gatwick_pic; setup_irq(irq_cascade, &gatwick_cascade_action); } printk(KERN_INFO "irq: System has %d possible interrupts\n", max_irqs); diff --git a/trunk/arch/powerpc/platforms/powermac/setup.c b/trunk/arch/powerpc/platforms/powermac/setup.c index 9cc7db7a8bdc..89c5775f83be 100644 --- a/trunk/arch/powerpc/platforms/powermac/setup.c +++ b/trunk/arch/powerpc/platforms/powermac/setup.c @@ -600,13 +600,6 @@ pmac_halt(void) */ static void __init pmac_init_early(void) { -#ifdef CONFIG_PPC64 - /* Initialize hash table, from now on, we can take hash faults - * and call ioremap - */ - hpte_init_native(); -#endif - /* Enable early btext debug if requested */ if (strstr(cmd_line, "btextdbg")) { udbg_adb_init_early(); @@ -683,6 +676,8 @@ static int __init pmac_probe(void) * part of the cacheable linar mapping */ alloc_dart_table(); + + hpte_init_native(); #endif #ifdef CONFIG_PPC32 diff --git a/trunk/arch/powerpc/platforms/pseries/iommu.c b/trunk/arch/powerpc/platforms/pseries/iommu.c index d03a8b078f9d..8cfb5706790e 100644 --- a/trunk/arch/powerpc/platforms/pseries/iommu.c +++ b/trunk/arch/powerpc/platforms/pseries/iommu.c @@ -92,6 +92,15 @@ static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) *(tcep++) = 0; } +static unsigned long tce_get_pseries(struct iommu_table *tbl, long index) +{ + u64 *tcep; + + index <<= TCE_PAGE_FACTOR; + tcep = ((u64 *)tbl->it_base) + index; + + return *tcep; +} static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages, unsigned long uaddr, @@ -235,6 +244,25 @@ static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long n } } +static unsigned long tce_get_pSeriesLP(struct iommu_table *tbl, long tcenum) +{ + u64 rc; + unsigned long tce_ret; + + tcenum <<= TCE_PAGE_FACTOR; + rc = plpar_tce_get((u64)tbl->it_index, (u64)tcenum << 12, &tce_ret); + + if (rc && printk_ratelimit()) { + printk("tce_get_pSeriesLP: plpar_tce_get failed. rc=%ld\n", + rc); + printk("\tindex = 0x%lx\n", (u64)tbl->it_index); + printk("\ttcenum = 0x%lx\n", (u64)tcenum); + show_stack(current, (unsigned long *)__get_SP()); + } + + return tce_ret; +} + static void iommu_table_setparms(struct pci_controller *phb, struct device_node *dn, struct iommu_table *tbl) @@ -254,7 +282,10 @@ static void iommu_table_setparms(struct pci_controller *phb, } tbl->it_base = (unsigned long)__va(*basep); + +#ifndef CONFIG_CRASH_DUMP memset((void *)tbl->it_base, 0, *sizep); +#endif tbl->it_busno = phb->bus->number; @@ -560,11 +591,13 @@ void iommu_init_early_pSeries(void) ppc_md.tce_build = tce_build_pSeriesLP; ppc_md.tce_free = tce_free_pSeriesLP; } + ppc_md.tce_get = tce_get_pSeriesLP; ppc_md.iommu_bus_setup = iommu_bus_setup_pSeriesLP; ppc_md.iommu_dev_setup = iommu_dev_setup_pSeriesLP; } else { ppc_md.tce_build = tce_build_pSeries; ppc_md.tce_free = tce_free_pSeries; + ppc_md.tce_get = tce_get_pseries; ppc_md.iommu_bus_setup = iommu_bus_setup_pSeries; ppc_md.iommu_dev_setup = iommu_dev_setup_pSeries; } diff --git a/trunk/arch/powerpc/platforms/pseries/lpar.c b/trunk/arch/powerpc/platforms/pseries/lpar.c index 634b7d06d3cc..27480705996f 100644 --- a/trunk/arch/powerpc/platforms/pseries/lpar.c +++ b/trunk/arch/powerpc/platforms/pseries/lpar.c @@ -513,7 +513,7 @@ void pSeries_lpar_flush_hash_range(unsigned long number, int local) spin_unlock_irqrestore(&pSeries_lpar_tlbie_lock, flags); } -void hpte_init_lpar(void) +void __init hpte_init_lpar(void) { ppc_md.hpte_invalidate = pSeries_lpar_hpte_invalidate; ppc_md.hpte_updatepp = pSeries_lpar_hpte_updatepp; @@ -522,6 +522,4 @@ void hpte_init_lpar(void) ppc_md.hpte_remove = pSeries_lpar_hpte_remove; ppc_md.flush_hash_range = pSeries_lpar_flush_hash_range; ppc_md.hpte_clear_all = pSeries_lpar_hptab_clear; - - htab_finish_init(); } diff --git a/trunk/arch/powerpc/platforms/pseries/setup.c b/trunk/arch/powerpc/platforms/pseries/setup.c index 1e28518c6121..b3197ff156c6 100644 --- a/trunk/arch/powerpc/platforms/pseries/setup.c +++ b/trunk/arch/powerpc/platforms/pseries/setup.c @@ -322,11 +322,6 @@ static void __init pSeries_init_early(void) DBG(" -> pSeries_init_early()\n"); fw_feature_init(); - - if (firmware_has_feature(FW_FEATURE_LPAR)) - hpte_init_lpar(); - else - hpte_init_native(); if (firmware_has_feature(FW_FEATURE_LPAR)) find_udbg_vterm(); @@ -384,6 +379,11 @@ static int __init pSeries_probe_hypertas(unsigned long node, if (of_get_flat_dt_prop(node, "ibm,hypertas-functions", NULL) != NULL) powerpc_firmware_features |= FW_FEATURE_LPAR; + if (firmware_has_feature(FW_FEATURE_LPAR)) + hpte_init_lpar(); + else + hpte_init_native(); + return 1; } diff --git a/trunk/arch/powerpc/platforms/pseries/xics.c b/trunk/arch/powerpc/platforms/pseries/xics.c index b14f9b5c114e..19c03dd43000 100644 --- a/trunk/arch/powerpc/platforms/pseries/xics.c +++ b/trunk/arch/powerpc/platforms/pseries/xics.c @@ -238,7 +238,7 @@ static int get_irq_server(unsigned int irq) { unsigned int server; /* For the moment only implement delivery to all cpus or one cpu */ - cpumask_t cpumask = irq_affinity[irq]; + cpumask_t cpumask = irq_desc[irq].affinity; cpumask_t tmp = CPU_MASK_NONE; if (!distribute_irqs) @@ -558,7 +558,7 @@ void xics_init_IRQ(void) } for (i = irq_offset_value(); i < NR_IRQS; ++i) - get_irq_desc(i)->handler = &xics_pic; + get_irq_desc(i)->chip = &xics_pic; xics_setup_cpu(); @@ -701,9 +701,9 @@ void xics_migrate_irqs_away(void) continue; /* We only need to migrate enabled IRQS */ - if (desc == NULL || desc->handler == NULL + if (desc == NULL || desc->chip == NULL || desc->action == NULL - || desc->handler->set_affinity == NULL) + || desc->chip->set_affinity == NULL) continue; spin_lock_irqsave(&desc->lock, flags); @@ -728,8 +728,8 @@ void xics_migrate_irqs_away(void) virq, cpu); /* Reset affinity to all cpus */ - desc->handler->set_affinity(virq, CPU_MASK_ALL); - irq_affinity[virq] = CPU_MASK_ALL; + desc->chip->set_affinity(virq, CPU_MASK_ALL); + irq_desc[irq].affinity = CPU_MASK_ALL; unlock: spin_unlock_irqrestore(&desc->lock, flags); } diff --git a/trunk/arch/powerpc/sysdev/Makefile b/trunk/arch/powerpc/sysdev/Makefile index cef95b023730..054bd8b41ef5 100644 --- a/trunk/arch/powerpc/sysdev/Makefile +++ b/trunk/arch/powerpc/sysdev/Makefile @@ -12,3 +12,5 @@ obj-$(CONFIG_U3_DART) += dart_iommu.o obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o obj-$(CONFIG_PPC_83xx) += ipic.o obj-$(CONFIG_FSL_SOC) += fsl_soc.o +obj-$(CONFIG_PPC_TODC) += todc.o +obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o diff --git a/trunk/arch/powerpc/sysdev/dart.h b/trunk/arch/powerpc/sysdev/dart.h index c2d05763ccbe..1c8817c4835e 100644 --- a/trunk/arch/powerpc/sysdev/dart.h +++ b/trunk/arch/powerpc/sysdev/dart.h @@ -47,8 +47,12 @@ /* U4 registers */ #define DART_BASE_U4_BASE_MASK 0xffffff #define DART_BASE_U4_BASE_SHIFT 0 -#define DART_CNTL_U4_FLUSHTLB 0x20000000 #define DART_CNTL_U4_ENABLE 0x80000000 +#define DART_CNTL_U4_IONE 0x40000000 +#define DART_CNTL_U4_FLUSHTLB 0x20000000 +#define DART_CNTL_U4_IDLE 0x10000000 +#define DART_CNTL_U4_PAR_EN 0x08000000 +#define DART_CNTL_U4_IONE_MASK 0x07ffffff #define DART_SIZE_U4_SIZE_MASK 0x1fff #define DART_SIZE_U4_SIZE_SHIFT 0 diff --git a/trunk/arch/powerpc/sysdev/dart_iommu.c b/trunk/arch/powerpc/sysdev/dart_iommu.c index 6232091cc72b..7c7f34ce4986 100644 --- a/trunk/arch/powerpc/sysdev/dart_iommu.c +++ b/trunk/arch/powerpc/sysdev/dart_iommu.c @@ -101,8 +101,8 @@ static inline void dart_tlb_invalidate_all(void) if (l == (1L << limit)) { if (limit < 4) { limit++; - reg = DART_IN(DART_CNTL); - reg &= ~inv_bit; + reg = DART_IN(DART_CNTL); + reg &= ~inv_bit; DART_OUT(DART_CNTL, reg); goto retry; } else @@ -111,11 +111,39 @@ static inline void dart_tlb_invalidate_all(void) } } +static inline void dart_tlb_invalidate_one(unsigned long bus_rpn) +{ + unsigned int reg; + unsigned int l, limit; + + reg = DART_CNTL_U4_ENABLE | DART_CNTL_U4_IONE | + (bus_rpn & DART_CNTL_U4_IONE_MASK); + DART_OUT(DART_CNTL, reg); + + limit = 0; +wait_more: + l = 0; + while ((DART_IN(DART_CNTL) & DART_CNTL_U4_IONE) && l < (1L << limit)) { + rmb(); + l++; + } + + if (l == (1L << limit)) { + if (limit < 4) { + limit++; + goto wait_more; + } else + panic("DART: TLB did not flush after waiting a long " + "time. Buggy U4 ?"); + } +} + static void dart_flush(struct iommu_table *tbl) { - if (dart_dirty) + if (dart_dirty) { dart_tlb_invalidate_all(); - dart_dirty = 0; + dart_dirty = 0; + } } static void dart_build(struct iommu_table *tbl, long index, @@ -124,6 +152,7 @@ static void dart_build(struct iommu_table *tbl, long index, { unsigned int *dp; unsigned int rpn; + long l; DBG("dart: build at: %lx, %lx, addr: %x\n", index, npages, uaddr); @@ -135,7 +164,8 @@ static void dart_build(struct iommu_table *tbl, long index, /* On U3, all memory is contigous, so we can move this * out of the loop. */ - while (npages--) { + l = npages; + while (l--) { rpn = virt_to_abs(uaddr) >> DART_PAGE_SHIFT; *(dp++) = DARTMAP_VALID | (rpn & DARTMAP_RPNMASK); @@ -143,7 +173,14 @@ static void dart_build(struct iommu_table *tbl, long index, uaddr += DART_PAGE_SIZE; } - dart_dirty = 1; + if (dart_is_u4) { + rpn = index; + mb(); /* make sure all updates have reached memory */ + while (npages--) + dart_tlb_invalidate_one(rpn++); + } else { + dart_dirty = 1; + } } diff --git a/trunk/arch/powerpc/sysdev/i8259.c b/trunk/arch/powerpc/sysdev/i8259.c index b7ac32fdd776..2bff30f6d635 100644 --- a/trunk/arch/powerpc/sysdev/i8259.c +++ b/trunk/arch/powerpc/sysdev/i8259.c @@ -208,7 +208,7 @@ void __init i8259_init(unsigned long intack_addr, int offset) spin_unlock_irqrestore(&i8259_lock, flags); for (i = 0; i < NUM_ISA_INTERRUPTS; ++i) - irq_desc[offset + i].handler = &i8259_pic; + irq_desc[offset + i].chip = &i8259_pic; /* reserve our resources */ setup_irq(offset + 2, &i8259_irqaction); diff --git a/trunk/arch/powerpc/sysdev/ipic.c b/trunk/arch/powerpc/sysdev/ipic.c index 8f01e0f1d847..46801f5ec03f 100644 --- a/trunk/arch/powerpc/sysdev/ipic.c +++ b/trunk/arch/powerpc/sysdev/ipic.c @@ -472,7 +472,7 @@ void __init ipic_init(phys_addr_t phys_addr, ipic_write(primary_ipic->regs, IPIC_SEMSR, temp); for (i = 0 ; i < NR_IPIC_INTS ; i++) { - irq_desc[i+irq_offset].handler = &ipic; + irq_desc[i+irq_offset].chip = &ipic; irq_desc[i+irq_offset].status = IRQ_LEVEL; } diff --git a/trunk/arch/powerpc/sysdev/mpic.c b/trunk/arch/powerpc/sysdev/mpic.c index bffe50d02c99..28df9c827ca6 100644 --- a/trunk/arch/powerpc/sysdev/mpic.c +++ b/trunk/arch/powerpc/sysdev/mpic.c @@ -379,14 +379,14 @@ static inline u32 mpic_physmask(u32 cpumask) /* Get the mpic structure from the IPI number */ static inline struct mpic * mpic_from_ipi(unsigned int ipi) { - return container_of(irq_desc[ipi].handler, struct mpic, hc_ipi); + return container_of(irq_desc[ipi].chip, struct mpic, hc_ipi); } #endif /* Get the mpic structure from the irq number */ static inline struct mpic * mpic_from_irq(unsigned int irq) { - return container_of(irq_desc[irq].handler, struct mpic, hc_irq); + return container_of(irq_desc[irq].chip, struct mpic, hc_irq); } /* Send an EOI */ @@ -752,7 +752,7 @@ void __init mpic_init(struct mpic *mpic) if (!(mpic->flags & MPIC_PRIMARY)) continue; irq_desc[mpic->ipi_offset+i].status |= IRQ_PER_CPU; - irq_desc[mpic->ipi_offset+i].handler = &mpic->hc_ipi; + irq_desc[mpic->ipi_offset+i].chip = &mpic->hc_ipi; #endif /* CONFIG_SMP */ } @@ -813,7 +813,7 @@ void __init mpic_init(struct mpic *mpic) /* init linux descriptors */ if (i < mpic->irq_count) { irq_desc[mpic->irq_offset+i].status = level ? IRQ_LEVEL : 0; - irq_desc[mpic->irq_offset+i].handler = &mpic->hc_irq; + irq_desc[mpic->irq_offset+i].chip = &mpic->hc_irq; } } @@ -906,7 +906,7 @@ void mpic_setup_this_cpu(void) /* let the mpic know we want intrs. default affinity is 0xffffffff * until changed via /proc. That's how it's done on x86. If we want * it differently, then we should make sure we also change the default - * values of irq_affinity in irq.c. + * values of irq_desc[].affinity in irq.c. */ if (distribute_irqs) { for (i = 0; i < mpic->num_sources ; i++) diff --git a/trunk/arch/powerpc/sysdev/todc.c b/trunk/arch/powerpc/sysdev/todc.c new file mode 100644 index 000000000000..0a65980efb50 --- /dev/null +++ b/trunk/arch/powerpc/sysdev/todc.c @@ -0,0 +1,392 @@ +/* + * Time of Day Clock support for the M48T35, M48T37, M48T59, and MC146818 + * Real Time Clocks/Timekeepers. + * + * Author: Mark A. Greer + * + * 2001-2004 (c) MontaVista, Software, Inc. 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 kind, whether express + * or implied. + */ +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +/* + * Depending on the hardware on your board and your board design, the + * RTC/NVRAM may be accessed either directly (like normal memory) or via + * address/data registers. If your board uses the direct method, set + * 'nvram_data' to the base address of your nvram and leave 'nvram_as0' and + * 'nvram_as1' NULL. If your board uses address/data regs to access nvram, + * set 'nvram_as0' to the address of the lower byte, set 'nvram_as1' to the + * address of the upper byte (leave NULL if using mc146818), and set + * 'nvram_data' to the address of the 8-bit data register. + * + * Note: Even though the documentation for the various RTC chips say that it + * take up to a second before it starts updating once the 'R' bit is + * cleared, they always seem to update even though we bang on it many + * times a second. This is true, except for the Dallas Semi 1746/1747 + * (possibly others). Those chips seem to have a real problem whenever + * we set the 'R' bit before reading them, they basically stop counting. + * --MAG + */ + +/* + * 'todc_info' should be initialized in your *_setup.c file to + * point to a fully initialized 'todc_info_t' structure. + * This structure holds all the register offsets for your particular + * TODC/RTC chip. + * TODC_ALLOC()/TODC_INIT() will allocate and initialize this table for you. + */ + +#ifdef RTC_FREQ_SELECT +#undef RTC_FREQ_SELECT +#define RTC_FREQ_SELECT control_b /* Register A */ +#endif + +#ifdef RTC_CONTROL +#undef RTC_CONTROL +#define RTC_CONTROL control_a /* Register B */ +#endif + +#ifdef RTC_INTR_FLAGS +#undef RTC_INTR_FLAGS +#define RTC_INTR_FLAGS watchdog /* Register C */ +#endif + +#ifdef RTC_VALID +#undef RTC_VALID +#define RTC_VALID interrupts /* Register D */ +#endif + +/* Access routines when RTC accessed directly (like normal memory) */ +u_char +todc_direct_read_val(int addr) +{ + return readb((void __iomem *)(todc_info->nvram_data + addr)); +} + +void +todc_direct_write_val(int addr, unsigned char val) +{ + writeb(val, (void __iomem *)(todc_info->nvram_data + addr)); + return; +} + +/* Access routines for accessing m48txx type chips via addr/data regs */ +u_char +todc_m48txx_read_val(int addr) +{ + outb(addr, todc_info->nvram_as0); + outb(addr>>todc_info->as0_bits, todc_info->nvram_as1); + return inb(todc_info->nvram_data); +} + +void +todc_m48txx_write_val(int addr, unsigned char val) +{ + outb(addr, todc_info->nvram_as0); + outb(addr>>todc_info->as0_bits, todc_info->nvram_as1); + outb(val, todc_info->nvram_data); + return; +} + +/* Access routines for accessing mc146818 type chips via addr/data regs */ +u_char +todc_mc146818_read_val(int addr) +{ + outb_p(addr, todc_info->nvram_as0); + return inb_p(todc_info->nvram_data); +} + +void +todc_mc146818_write_val(int addr, unsigned char val) +{ + outb_p(addr, todc_info->nvram_as0); + outb_p(val, todc_info->nvram_data); +} + + +/* + * Routines to make RTC chips with NVRAM buried behind an addr/data pair + * have the NVRAM and clock regs appear at the same level. + * The NVRAM will appear to start at addr 0 and the clock regs will appear + * to start immediately after the NVRAM (actually, start at offset + * todc_info->nvram_size). + */ +static inline u_char +todc_read_val(int addr) +{ + u_char val; + + if (todc_info->sw_flags & TODC_FLAG_2_LEVEL_NVRAM) { + if (addr < todc_info->nvram_size) { /* NVRAM */ + ppc_md.rtc_write_val(todc_info->nvram_addr_reg, addr); + val = ppc_md.rtc_read_val(todc_info->nvram_data_reg); + } else { /* Clock Reg */ + addr -= todc_info->nvram_size; + val = ppc_md.rtc_read_val(addr); + } + } else + val = ppc_md.rtc_read_val(addr); + + return val; +} + +static inline void +todc_write_val(int addr, u_char val) +{ + if (todc_info->sw_flags & TODC_FLAG_2_LEVEL_NVRAM) { + if (addr < todc_info->nvram_size) { /* NVRAM */ + ppc_md.rtc_write_val(todc_info->nvram_addr_reg, addr); + ppc_md.rtc_write_val(todc_info->nvram_data_reg, val); + } else { /* Clock Reg */ + addr -= todc_info->nvram_size; + ppc_md.rtc_write_val(addr, val); + } + } else + ppc_md.rtc_write_val(addr, val); +} + +/* + * TODC routines + * + * There is some ugly stuff in that there are assumptions for the mc146818. + * + * Assumptions: + * - todc_info->control_a has the offset as mc146818 Register B reg + * - todc_info->control_b has the offset as mc146818 Register A reg + * - m48txx control reg's write enable or 'W' bit is same as + * mc146818 Register B 'SET' bit (i.e., 0x80) + * + * These assumptions were made to make the code simpler. + */ +long __init +todc_time_init(void) +{ + u_char cntl_b; + + if (!ppc_md.rtc_read_val) + ppc_md.rtc_read_val = ppc_md.nvram_read_val; + if (!ppc_md.rtc_write_val) + ppc_md.rtc_write_val = ppc_md.nvram_write_val; + + cntl_b = todc_read_val(todc_info->control_b); + + if (todc_info->rtc_type == TODC_TYPE_MC146818) { + if ((cntl_b & 0x70) != 0x20) { + printk(KERN_INFO "TODC real-time-clock was stopped." + " Now starting..."); + cntl_b &= ~0x70; + cntl_b |= 0x20; + } + + todc_write_val(todc_info->control_b, cntl_b); + } else if (todc_info->rtc_type == TODC_TYPE_DS17285) { + u_char mode; + + mode = todc_read_val(TODC_TYPE_DS17285_CNTL_A); + /* Make sure countdown clear is not set */ + mode &= ~0x40; + /* Enable oscillator, extended register set */ + mode |= 0x30; + todc_write_val(TODC_TYPE_DS17285_CNTL_A, mode); + + } else if (todc_info->rtc_type == TODC_TYPE_DS1501) { + u_char month; + + todc_info->enable_read = TODC_DS1501_CNTL_B_TE; + todc_info->enable_write = TODC_DS1501_CNTL_B_TE; + + month = todc_read_val(todc_info->month); + + if ((month & 0x80) == 0x80) { + printk(KERN_INFO "TODC %s %s\n", + "real-time-clock was stopped.", + "Now starting..."); + month &= ~0x80; + todc_write_val(todc_info->month, month); + } + + cntl_b &= ~TODC_DS1501_CNTL_B_TE; + todc_write_val(todc_info->control_b, cntl_b); + } else { /* must be a m48txx type */ + u_char cntl_a; + + todc_info->enable_read = TODC_MK48TXX_CNTL_A_R; + todc_info->enable_write = TODC_MK48TXX_CNTL_A_W; + + cntl_a = todc_read_val(todc_info->control_a); + + /* Check & clear STOP bit in control B register */ + if (cntl_b & TODC_MK48TXX_DAY_CB) { + printk(KERN_INFO "TODC %s %s\n", + "real-time-clock was stopped.", + "Now starting..."); + + cntl_a |= todc_info->enable_write; + cntl_b &= ~TODC_MK48TXX_DAY_CB;/* Start Oscil */ + + todc_write_val(todc_info->control_a, cntl_a); + todc_write_val(todc_info->control_b, cntl_b); + } + + /* Make sure READ & WRITE bits are cleared. */ + cntl_a &= ~(todc_info->enable_write | todc_info->enable_read); + todc_write_val(todc_info->control_a, cntl_a); + } + + return 0; +} + +/* + * There is some ugly stuff in that there are assumptions that for a mc146818, + * the todc_info->control_a has the offset of the mc146818 Register B reg and + * that the register'ss 'SET' bit is the same as the m48txx's write enable + * bit in the control register of the m48txx (i.e., 0x80). + * + * It was done to make the code look simpler. + */ +void +todc_get_rtc_time(struct rtc_time *tm) +{ + uint year = 0, mon = 0, mday = 0, hour = 0, min = 0, sec = 0; + uint limit, i; + u_char save_control, uip = 0; + extern void GregorianDay(struct rtc_time *); + + spin_lock(&rtc_lock); + save_control = todc_read_val(todc_info->control_a); + + if (todc_info->rtc_type != TODC_TYPE_MC146818) { + limit = 1; + + switch (todc_info->rtc_type) { + case TODC_TYPE_DS1553: + case TODC_TYPE_DS1557: + case TODC_TYPE_DS1743: + case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */ + case TODC_TYPE_DS1747: + case TODC_TYPE_DS17285: + break; + default: + todc_write_val(todc_info->control_a, + (save_control | todc_info->enable_read)); + } + } else + limit = 100000000; + + for (i=0; irtc_type == TODC_TYPE_MC146818) + uip = todc_read_val(todc_info->RTC_FREQ_SELECT); + + sec = todc_read_val(todc_info->seconds) & 0x7f; + min = todc_read_val(todc_info->minutes) & 0x7f; + hour = todc_read_val(todc_info->hours) & 0x3f; + mday = todc_read_val(todc_info->day_of_month) & 0x3f; + mon = todc_read_val(todc_info->month) & 0x1f; + year = todc_read_val(todc_info->year) & 0xff; + + if (todc_info->rtc_type == TODC_TYPE_MC146818) { + uip |= todc_read_val(todc_info->RTC_FREQ_SELECT); + if ((uip & RTC_UIP) == 0) + break; + } + } + + if (todc_info->rtc_type != TODC_TYPE_MC146818) { + switch (todc_info->rtc_type) { + case TODC_TYPE_DS1553: + case TODC_TYPE_DS1557: + case TODC_TYPE_DS1743: + case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */ + case TODC_TYPE_DS1747: + case TODC_TYPE_DS17285: + break; + default: + save_control &= ~(todc_info->enable_read); + todc_write_val(todc_info->control_a, save_control); + } + } + spin_unlock(&rtc_lock); + + if ((todc_info->rtc_type != TODC_TYPE_MC146818) + || ((save_control & RTC_DM_BINARY) == 0) + || RTC_ALWAYS_BCD) { + BCD_TO_BIN(sec); + BCD_TO_BIN(min); + BCD_TO_BIN(hour); + BCD_TO_BIN(mday); + BCD_TO_BIN(mon); + BCD_TO_BIN(year); + } + + if ((year + 1900) < 1970) { + year += 100; + } + + tm->tm_sec = sec; + tm->tm_min = min; + tm->tm_hour = hour; + tm->tm_mday = mday; + tm->tm_mon = mon; + tm->tm_year = year; + + GregorianDay(tm); +} + +int +todc_set_rtc_time(struct rtc_time *tm) +{ + u_char save_control, save_freq_select = 0; + + spin_lock(&rtc_lock); + save_control = todc_read_val(todc_info->control_a); + + /* Assuming MK48T59_RTC_CA_WRITE & RTC_SET are equal */ + todc_write_val(todc_info->control_a, + (save_control | todc_info->enable_write)); + save_control &= ~(todc_info->enable_write); /* in case it was set */ + + if (todc_info->rtc_type == TODC_TYPE_MC146818) { + save_freq_select = todc_read_val(todc_info->RTC_FREQ_SELECT); + todc_write_val(todc_info->RTC_FREQ_SELECT, + save_freq_select | RTC_DIV_RESET2); + } + + if ((todc_info->rtc_type != TODC_TYPE_MC146818) + || ((save_control & RTC_DM_BINARY) == 0) + || RTC_ALWAYS_BCD) { + BIN_TO_BCD(tm->tm_sec); + BIN_TO_BCD(tm->tm_min); + BIN_TO_BCD(tm->tm_hour); + BIN_TO_BCD(tm->tm_mon); + BIN_TO_BCD(tm->tm_mday); + BIN_TO_BCD(tm->tm_year); + } + + todc_write_val(todc_info->seconds, tm->tm_sec); + todc_write_val(todc_info->minutes, tm->tm_min); + todc_write_val(todc_info->hours, tm->tm_hour); + todc_write_val(todc_info->month, tm->tm_mon); + todc_write_val(todc_info->day_of_month, tm->tm_mday); + todc_write_val(todc_info->year, tm->tm_year); + + todc_write_val(todc_info->control_a, save_control); + + if (todc_info->rtc_type == TODC_TYPE_MC146818) + todc_write_val(todc_info->RTC_FREQ_SELECT, save_freq_select); + + spin_unlock(&rtc_lock); + return 0; +} diff --git a/trunk/arch/powerpc/sysdev/tsi108_dev.c b/trunk/arch/powerpc/sysdev/tsi108_dev.c new file mode 100644 index 000000000000..26a0cc820cde --- /dev/null +++ b/trunk/arch/powerpc/sysdev/tsi108_dev.c @@ -0,0 +1,145 @@ +/* + * tsi108/109 device setup code + * + * Maintained by Roy Zang < tie-fei.zang@freescale.com > + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2 of the License, or (at your + * option) any later version. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#undef DEBUG + +#ifdef DEBUG +#define DBG(fmt...) do { printk(fmt); } while(0) +#else +#define DBG(fmt...) do { } while(0) +#endif + +static phys_addr_t tsi108_csr_base = -1; + +phys_addr_t get_csrbase(void) +{ + struct device_node *tsi; + + if (tsi108_csr_base != -1) + return tsi108_csr_base; + + tsi = of_find_node_by_type(NULL, "tsi-bridge"); + if (tsi) { + unsigned int size; + void *prop = get_property(tsi, "reg", &size); + tsi108_csr_base = of_translate_address(tsi, prop); + of_node_put(tsi); + }; + return tsi108_csr_base; +} + +u32 get_vir_csrbase(void) +{ + return (u32) (ioremap(get_csrbase(), 0x10000)); +} + +EXPORT_SYMBOL(get_csrbase); +EXPORT_SYMBOL(get_vir_csrbase); + +static int __init tsi108_eth_of_init(void) +{ + struct device_node *np; + unsigned int i; + struct platform_device *tsi_eth_dev; + struct resource res; + int ret; + + for (np = NULL, i = 0; + (np = of_find_compatible_node(np, "network", "tsi-ethernet")) != NULL; + i++) { + struct resource r[2]; + struct device_node *phy; + hw_info tsi_eth_data; + unsigned int *id; + unsigned int *phy_id; + void *mac_addr; + phandle *ph; + + memset(r, 0, sizeof(r)); + memset(&tsi_eth_data, 0, sizeof(tsi_eth_data)); + + ret = of_address_to_resource(np, 0, &r[0]); + DBG("%s: name:start->end = %s:0x%lx-> 0x%lx\n", + __FUNCTION__,r[0].name, r[0].start, r[0].end); + if (ret) + goto err; + + r[1].name = "tx"; + r[1].start = np->intrs[0].line; + r[1].end = np->intrs[0].line; + r[1].flags = IORESOURCE_IRQ; + + tsi_eth_dev = + platform_device_register_simple("tsi-ethernet", i, &r[0], + np->n_intrs + 1); + + if (IS_ERR(tsi_eth_dev)) { + ret = PTR_ERR(tsi_eth_dev); + goto err; + } + + mac_addr = get_property(np, "address", NULL); + memcpy(tsi_eth_data.mac_addr, mac_addr, 6); + + ph = (phandle *) get_property(np, "phy-handle", NULL); + phy = of_find_node_by_phandle(*ph); + + if (phy == NULL) { + ret = -ENODEV; + goto unreg; + } + + id = (u32 *) get_property(phy, "reg", NULL); + phy_id = (u32 *) get_property(phy, "phy-id", NULL); + ret = of_address_to_resource(phy, 0, &res); + if (ret) { + of_node_put(phy); + goto unreg; + } + tsi_eth_data.regs = r[0].start; + tsi_eth_data.phyregs = res.start; + tsi_eth_data.phy = *phy_id; + tsi_eth_data.irq_num = np->intrs[0].line; + of_node_put(phy); + ret = + platform_device_add_data(tsi_eth_dev, &tsi_eth_data, + sizeof(hw_info)); + if (ret) + goto unreg; + } + return 0; +unreg: + platform_device_unregister(tsi_eth_dev); +err: + return ret; +} + +arch_initcall(tsi108_eth_of_init); diff --git a/trunk/arch/powerpc/sysdev/tsi108_pci.c b/trunk/arch/powerpc/sysdev/tsi108_pci.c new file mode 100644 index 000000000000..3265d54c82ed --- /dev/null +++ b/trunk/arch/powerpc/sysdev/tsi108_pci.c @@ -0,0 +1,412 @@ +/* + * Common routines for Tundra Semiconductor TSI108 host bridge. + * + * 2004-2005 (c) Tundra Semiconductor Corp. + * Author: Alex Bounine (alexandreb@tundra.com) + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the Free + * Software Foundation; either version 2 of the License, or (at your option) + * any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License along with + * this program; if not, write to the Free Software Foundation, Inc., 59 + * Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#include +#include +#include +#include +#include +#include + + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#undef DEBUG +#ifdef DEBUG +#define DBG(x...) printk(x) +#else +#define DBG(x...) +#endif + +#define tsi_mk_config_addr(bus, devfunc, offset) \ + ((((bus)<<16) | ((devfunc)<<8) | (offset & 0xfc)) + tsi108_pci_cfg_base) + +u32 tsi108_pci_cfg_base; +u32 tsi108_csr_vir_base; + +extern u32 get_vir_csrbase(void); +extern u32 tsi108_read_reg(u32 reg_offset); +extern void tsi108_write_reg(u32 reg_offset, u32 val); + +int +tsi108_direct_write_config(struct pci_bus *bus, unsigned int devfunc, + int offset, int len, u32 val) +{ + volatile unsigned char *cfg_addr; + + if (ppc_md.pci_exclude_device) + if (ppc_md.pci_exclude_device(bus->number, devfunc)) + return PCIBIOS_DEVICE_NOT_FOUND; + + cfg_addr = (unsigned char *)(tsi_mk_config_addr(bus->number, + devfunc, offset) | + (offset & 0x03)); + +#ifdef DEBUG + printk("PCI CFG write : "); + printk("%d:0x%x:0x%x ", bus->number, devfunc, offset); + printk("%d ADDR=0x%08x ", len, (uint) cfg_addr); + printk("data = 0x%08x\n", val); +#endif + + switch (len) { + case 1: + out_8((u8 *) cfg_addr, val); + break; + case 2: + out_le16((u16 *) cfg_addr, val); + break; + default: + out_le32((u32 *) cfg_addr, val); + break; + } + + return PCIBIOS_SUCCESSFUL; +} + +void tsi108_clear_pci_error(u32 pci_cfg_base) +{ + u32 err_stat, err_addr, pci_stat; + + /* + * Quietly clear PB and PCI error flags set as result + * of PCI/X configuration read requests. + */ + + /* Read PB Error Log Registers */ + + err_stat = tsi108_read_reg(TSI108_PB_OFFSET + TSI108_PB_ERRCS); + err_addr = tsi108_read_reg(TSI108_PB_OFFSET + TSI108_PB_AERR); + + if (err_stat & TSI108_PB_ERRCS_ES) { + /* Clear error flag */ + tsi108_write_reg(TSI108_PB_OFFSET + TSI108_PB_ERRCS, + TSI108_PB_ERRCS_ES); + + /* Clear read error reported in PB_ISR */ + tsi108_write_reg(TSI108_PB_OFFSET + TSI108_PB_ISR, + TSI108_PB_ISR_PBS_RD_ERR); + + /* Clear PCI/X bus cfg errors if applicable */ + if ((err_addr & 0xFF000000) == pci_cfg_base) { + pci_stat = + tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_CSR); + tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_CSR, + pci_stat); + } + } + + return; +} + +#define __tsi108_read_pci_config(x, addr, op) \ + __asm__ __volatile__( \ + " "op" %0,0,%1\n" \ + "1: eieio\n" \ + "2:\n" \ + ".section .fixup,\"ax\"\n" \ + "3: li %0,-1\n" \ + " b 2b\n" \ + ".section __ex_table,\"a\"\n" \ + " .align 2\n" \ + " .long 1b,3b\n" \ + ".text" \ + : "=r"(x) : "r"(addr)) + +int +tsi108_direct_read_config(struct pci_bus *bus, unsigned int devfn, int offset, + int len, u32 * val) +{ + volatile unsigned char *cfg_addr; + u32 temp; + + if (ppc_md.pci_exclude_device) + if (ppc_md.pci_exclude_device(bus->number, devfn)) + return PCIBIOS_DEVICE_NOT_FOUND; + + cfg_addr = (unsigned char *)(tsi_mk_config_addr(bus->number, + devfn, + offset) | (offset & + 0x03)); + + switch (len) { + case 1: + __tsi108_read_pci_config(temp, cfg_addr, "lbzx"); + break; + case 2: + __tsi108_read_pci_config(temp, cfg_addr, "lhbrx"); + break; + default: + __tsi108_read_pci_config(temp, cfg_addr, "lwbrx"); + break; + } + + *val = temp; + +#ifdef DEBUG + if ((0xFFFFFFFF != temp) && (0xFFFF != temp) && (0xFF != temp)) { + printk("PCI CFG read : "); + printk("%d:0x%x:0x%x ", bus->number, devfn, offset); + printk("%d ADDR=0x%08x ", len, (uint) cfg_addr); + printk("data = 0x%x\n", *val); + } +#endif + return PCIBIOS_SUCCESSFUL; +} + +void tsi108_clear_pci_cfg_error(void) +{ + tsi108_clear_pci_error(TSI108_PCI_CFG_BASE_PHYS); +} + +static struct pci_ops tsi108_direct_pci_ops = { + tsi108_direct_read_config, + tsi108_direct_write_config +}; + +int __init tsi108_setup_pci(struct device_node *dev) +{ + int len; + struct pci_controller *hose; + struct resource rsrc; + int *bus_range; + int primary = 0, has_address = 0; + + /* PCI Config mapping */ + tsi108_pci_cfg_base = (u32)ioremap(TSI108_PCI_CFG_BASE_PHYS, + TSI108_PCI_CFG_SIZE); + DBG("TSI_PCI: %s tsi108_pci_cfg_base=0x%x\n", __FUNCTION__, + tsi108_pci_cfg_base); + + /* Fetch host bridge registers address */ + has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); + + /* Get bus range if any */ + bus_range = (int *)get_property(dev, "bus-range", &len); + if (bus_range == NULL || len < 2 * sizeof(int)) { + printk(KERN_WARNING "Can't get bus-range for %s, assume" + " bus 0\n", dev->full_name); + } + + hose = pcibios_alloc_controller(); + + if (!hose) { + printk("PCI Host bridge init failed\n"); + return -ENOMEM; + } + hose->arch_data = dev; + hose->set_cfg_type = 1; + + hose->first_busno = bus_range ? bus_range[0] : 0; + hose->last_busno = bus_range ? bus_range[1] : 0xff; + + (hose)->ops = &tsi108_direct_pci_ops; + + printk(KERN_INFO "Found tsi108 PCI host bridge at 0x%08lx. " + "Firmware bus number: %d->%d\n", + rsrc.start, hose->first_busno, hose->last_busno); + + /* Interpret the "ranges" property */ + /* This also maps the I/O region and sets isa_io/mem_base */ + pci_process_bridge_OF_ranges(hose, dev, primary); + return 0; +} + +/* + * Low level utility functions + */ + +static void tsi108_pci_int_mask(u_int irq) +{ + u_int irp_cfg; + int int_line = (irq - IRQ_PCI_INTAD_BASE); + + irp_cfg = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL); + mb(); + irp_cfg |= (1 << int_line); /* INTx_DIR = output */ + irp_cfg &= ~(3 << (8 + (int_line * 2))); /* INTx_TYPE = unused */ + tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL, irp_cfg); + mb(); + irp_cfg = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL); +} + +static void tsi108_pci_int_unmask(u_int irq) +{ + u_int irp_cfg; + int int_line = (irq - IRQ_PCI_INTAD_BASE); + + irp_cfg = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL); + mb(); + irp_cfg &= ~(1 << int_line); + irp_cfg |= (3 << (8 + (int_line * 2))); + tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL, irp_cfg); + mb(); +} + +static void init_pci_source(void) +{ + tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL, + 0x0000ff00); + tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE, + TSI108_PCI_IRP_ENABLE_P_INT); + mb(); +} + +static inline int get_pci_source(void) +{ + u_int temp = 0; + int irq = -1; + int i; + u_int pci_irp_stat; + static int mask = 0; + + /* Read PCI/X block interrupt status register */ + pci_irp_stat = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_STAT); + mb(); + + if (pci_irp_stat & TSI108_PCI_IRP_STAT_P_INT) { + /* Process Interrupt from PCI bus INTA# - INTD# lines */ + temp = + tsi108_read_reg(TSI108_PCI_OFFSET + + TSI108_PCI_IRP_INTAD) & 0xf; + mb(); + for (i = 0; i < 4; i++, mask++) { + if (temp & (1 << mask % 4)) { + irq = IRQ_PCI_INTA + mask % 4; + mask++; + break; + } + } + + /* Disable interrupts from PCI block */ + temp = tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE); + tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE, + temp & ~TSI108_PCI_IRP_ENABLE_P_INT); + mb(); + (void)tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE); + mb(); + } +#ifdef DEBUG + else { + printk("TSI108_PIC: error in TSI108_PCI_IRP_STAT\n"); + pci_irp_stat = + tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_STAT); + temp = + tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_INTAD); + mb(); + printk(">> stat=0x%08x intad=0x%08x ", pci_irp_stat, temp); + temp = + tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_CFG_CTL); + mb(); + printk("cfg_ctl=0x%08x ", temp); + temp = + tsi108_read_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE); + mb(); + printk("irp_enable=0x%08x\n", temp); + } +#endif /* end of DEBUG */ + + return irq; +} + + +/* + * Linux descriptor level callbacks + */ + +static void tsi108_pci_irq_enable(u_int irq) +{ + tsi108_pci_int_unmask(irq); +} + +static void tsi108_pci_irq_disable(u_int irq) +{ + tsi108_pci_int_mask(irq); +} + +static void tsi108_pci_irq_ack(u_int irq) +{ + tsi108_pci_int_mask(irq); +} + +static void tsi108_pci_irq_end(u_int irq) +{ + tsi108_pci_int_unmask(irq); + + /* Enable interrupts from PCI block */ + tsi108_write_reg(TSI108_PCI_OFFSET + TSI108_PCI_IRP_ENABLE, + tsi108_read_reg(TSI108_PCI_OFFSET + + TSI108_PCI_IRP_ENABLE) | + TSI108_PCI_IRP_ENABLE_P_INT); + mb(); +} + +/* + * Interrupt controller descriptor for cascaded PCI interrupt controller. + */ + +struct hw_interrupt_type tsi108_pci_irq = { + .typename = "tsi108_PCI_int", + .enable = tsi108_pci_irq_enable, + .disable = tsi108_pci_irq_disable, + .ack = tsi108_pci_irq_ack, + .end = tsi108_pci_irq_end, +}; + +/* + * Exported functions + */ + +/* + * The Tsi108 PCI interrupts initialization routine. + * + * The INTA# - INTD# interrupts on the PCI bus are reported by the PCI block + * to the MPIC using single interrupt source (IRQ_TSI108_PCI). Therefore the + * PCI block has to be treated as a cascaded interrupt controller connected + * to the MPIC. + */ + +void __init tsi108_pci_int_init(void) +{ + u_int i; + + DBG("Tsi108_pci_int_init: initializing PCI interrupts\n"); + + for (i = 0; i < NUM_PCI_IRQS; i++) { + irq_desc[i + IRQ_PCI_INTAD_BASE].handler = &tsi108_pci_irq; + irq_desc[i + IRQ_PCI_INTAD_BASE].status |= IRQ_LEVEL; + } + + init_pci_source(); +} + +int tsi108_irq_cascade(struct pt_regs *regs, void *unused) +{ + return get_pci_source(); +} diff --git a/trunk/arch/ppc/8xx_io/commproc.c b/trunk/arch/ppc/8xx_io/commproc.c index 12b84ca51327..9b3ace26280c 100644 --- a/trunk/arch/ppc/8xx_io/commproc.c +++ b/trunk/arch/ppc/8xx_io/commproc.c @@ -187,7 +187,7 @@ cpm_interrupt_init(void) * interrupt vectors */ for ( i = CPM_IRQ_OFFSET ; i < CPM_IRQ_OFFSET + NR_CPM_INTS ; i++ ) - irq_desc[i].handler = &cpm_pic; + irq_desc[i].chip = &cpm_pic; /* Set our interrupt handler with the core CPU. */ if (setup_irq(CPM_INTERRUPT, &cpm_interrupt_irqaction)) diff --git a/trunk/arch/ppc/kernel/pci.c b/trunk/arch/ppc/kernel/pci.c index d20accf9650d..242bb052be67 100644 --- a/trunk/arch/ppc/kernel/pci.c +++ b/trunk/arch/ppc/kernel/pci.c @@ -95,8 +95,10 @@ pcibios_fixup_resources(struct pci_dev *dev) if (!res->flags) continue; if (res->end == 0xffffffff) { - DBG("PCI:%s Resource %d [%08lx-%08lx] is unassigned\n", - pci_name(dev), i, res->start, res->end); + DBG("PCI:%s Resource %d [%016llx-%016llx] is unassigned\n", + pci_name(dev), i, + (unsigned long long)res->start, + (unsigned long long)res->end); res->end -= res->start; res->start = 0; res->flags |= IORESOURCE_UNSET; @@ -169,18 +171,18 @@ EXPORT_SYMBOL(pcibios_bus_to_resource); * but we want to try to avoid allocating at 0x2900-0x2bff * which might have be mirrored at 0x0100-0x03ff.. */ -void pcibios_align_resource(void *data, struct resource *res, unsigned long size, - unsigned long align) +void pcibios_align_resource(void *data, struct resource *res, + resource_size_t size, resource_size_t align) { struct pci_dev *dev = data; if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; + resource_size_t start = res->start; if (size > 0x100) { printk(KERN_ERR "PCI: I/O Region %s/%d too large" - " (%ld bytes)\n", pci_name(dev), - dev->resource - res, size); + " (%lld bytes)\n", pci_name(dev), + dev->resource - res, (unsigned long long)size); } if (start & 0x300) { @@ -251,8 +253,9 @@ pcibios_allocate_bus_resources(struct list_head *bus_list) } } - DBG("PCI: bridge rsrc %lx..%lx (%lx), parent %p\n", - res->start, res->end, res->flags, pr); + DBG("PCI: bridge rsrc %llx..%llx (%lx), parent %p\n", + (unsigned long long)res->start, + (unsigned long long)res->end, res->flags, pr); if (pr) { if (request_resource(pr, res) == 0) continue; @@ -302,8 +305,9 @@ reparent_resources(struct resource *parent, struct resource *res) *pp = NULL; for (p = res->child; p != NULL; p = p->sibling) { p->parent = res; - DBG(KERN_INFO "PCI: reparented %s [%lx..%lx] under %s\n", - p->name, p->start, p->end, res->name); + DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n", + p->name, (unsigned long long)p->start, + (unsigned long long)p->end, res->name); } return 0; } @@ -358,13 +362,15 @@ pci_relocate_bridge_resource(struct pci_bus *bus, int i) try = conflict->start - 1; } if (request_resource(pr, res)) { - DBG(KERN_ERR "PCI: huh? couldn't move to %lx..%lx\n", - res->start, res->end); + DBG(KERN_ERR "PCI: huh? couldn't move to %llx..%llx\n", + (unsigned long long)res->start, + (unsigned long long)res->end); return -1; /* "can't happen" */ } update_bridge_base(bus, i); - printk(KERN_INFO "PCI: bridge %d resource %d moved to %lx..%lx\n", - bus->number, i, res->start, res->end); + printk(KERN_INFO "PCI: bridge %d resource %d moved to %llx..%llx\n", + bus->number, i, (unsigned long long)res->start, + (unsigned long long)res->end); return 0; } @@ -475,15 +481,17 @@ static inline void alloc_resource(struct pci_dev *dev, int idx) { struct resource *pr, *r = &dev->resource[idx]; - DBG("PCI:%s: Resource %d: %08lx-%08lx (f=%lx)\n", - pci_name(dev), idx, r->start, r->end, r->flags); + DBG("PCI:%s: Resource %d: %016llx-%016llx (f=%lx)\n", + pci_name(dev), idx, (unsigned long long)r->start, + (unsigned long long)r->end, r->flags); pr = pci_find_parent_resource(dev, r); if (!pr || request_resource(pr, r) < 0) { printk(KERN_ERR "PCI: Cannot allocate resource region %d" " of device %s\n", idx, pci_name(dev)); if (pr) - DBG("PCI: parent is %p: %08lx-%08lx (f=%lx)\n", - pr, pr->start, pr->end, pr->flags); + DBG("PCI: parent is %p: %016llx-%016llx (f=%lx)\n", + pr, (unsigned long long)pr->start, + (unsigned long long)pr->end, pr->flags); /* We'll assign a new address later */ r->flags |= IORESOURCE_UNSET; r->end -= r->start; @@ -952,8 +960,8 @@ static pgprot_t __pci_mmap_set_pgprot(struct pci_dev *dev, struct resource *rp, else prot |= _PAGE_GUARDED; - printk("PCI map for %s:%lx, prot: %lx\n", pci_name(dev), rp->start, - prot); + printk("PCI map for %s:%llx, prot: %lx\n", pci_name(dev), + (unsigned long long)rp->start, prot); return __pgprot(prot); } @@ -1122,7 +1130,7 @@ long sys_pciconfig_iobase(long which, unsigned long bus, unsigned long devfn) void pci_resource_to_user(const struct pci_dev *dev, int bar, const struct resource *rsrc, - u64 *start, u64 *end) + resource_size_t *start, resource_size_t *end) { struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); unsigned long offset = 0; diff --git a/trunk/arch/ppc/platforms/apus_setup.c b/trunk/arch/ppc/platforms/apus_setup.c index fe0cdc04d436..5c4118a459f3 100644 --- a/trunk/arch/ppc/platforms/apus_setup.c +++ b/trunk/arch/ppc/platforms/apus_setup.c @@ -734,9 +734,9 @@ void apus_init_IRQ(void) for ( i = 0 ; i < AMI_IRQS; i++ ) { irq_desc[i].status = IRQ_LEVEL; if (i < IRQ_AMIGA_AUTO) { - irq_desc[i].handler = &amiga_irqctrl; + irq_desc[i].chip = &amiga_irqctrl; } else { - irq_desc[i].handler = &amiga_sys_irqctrl; + irq_desc[i].chip = &amiga_sys_irqctrl; action = &amiga_sys_irqaction[i-IRQ_AMIGA_AUTO]; if (action->name) setup_irq(i, action); diff --git a/trunk/arch/ppc/platforms/sbc82xx.c b/trunk/arch/ppc/platforms/sbc82xx.c index 866807b4ad0b..41006d2b4b38 100644 --- a/trunk/arch/ppc/platforms/sbc82xx.c +++ b/trunk/arch/ppc/platforms/sbc82xx.c @@ -172,7 +172,7 @@ void __init sbc82xx_init_IRQ(void) /* Set up the interrupt handlers for the i8259 IRQs */ for (i = NR_SIU_INTS; i < NR_SIU_INTS + 8; i++) { - irq_desc[i].handler = &sbc82xx_i8259_ic; + irq_desc[i].chip = &sbc82xx_i8259_ic; irq_desc[i].status |= IRQ_LEVEL; } diff --git a/trunk/arch/ppc/syslib/cpc700_pic.c b/trunk/arch/ppc/syslib/cpc700_pic.c index 5add0a919ef6..172aa215fdb0 100644 --- a/trunk/arch/ppc/syslib/cpc700_pic.c +++ b/trunk/arch/ppc/syslib/cpc700_pic.c @@ -140,12 +140,12 @@ cpc700_init_IRQ(void) /* IRQ 0 is highest */ for (i = 0; i < 17; i++) { - irq_desc[i].handler = &cpc700_pic; + irq_desc[i].chip = &cpc700_pic; cpc700_pic_init_irq(i); } for (i = 20; i < 32; i++) { - irq_desc[i].handler = &cpc700_pic; + irq_desc[i].chip = &cpc700_pic; cpc700_pic_init_irq(i); } diff --git a/trunk/arch/ppc/syslib/cpm2_pic.c b/trunk/arch/ppc/syslib/cpm2_pic.c index 29d95d415ceb..c0fee0beb815 100644 --- a/trunk/arch/ppc/syslib/cpm2_pic.c +++ b/trunk/arch/ppc/syslib/cpm2_pic.c @@ -171,7 +171,7 @@ void cpm2_init_IRQ(void) /* Enable chaining to OpenPIC, and make everything level */ for (i = 0; i < NR_CPM_INTS; i++) { - irq_desc[i+CPM_IRQ_OFFSET].handler = &cpm2_pic; + irq_desc[i+CPM_IRQ_OFFSET].chip = &cpm2_pic; irq_desc[i+CPM_IRQ_OFFSET].status |= IRQ_LEVEL; } } diff --git a/trunk/arch/ppc/syslib/gt64260_pic.c b/trunk/arch/ppc/syslib/gt64260_pic.c index dc3bd9ecbbf6..91096b38ae70 100644 --- a/trunk/arch/ppc/syslib/gt64260_pic.c +++ b/trunk/arch/ppc/syslib/gt64260_pic.c @@ -98,7 +98,7 @@ gt64260_init_irq(void) /* use the gt64260 for all (possible) interrupt sources */ for (i = gt64260_irq_base; i < (gt64260_irq_base + 96); i++) - irq_desc[i].handler = >64260_pic; + irq_desc[i].chip = >64260_pic; if (ppc_md.progress) ppc_md.progress("gt64260_init_irq: exit", 0x0); diff --git a/trunk/arch/ppc/syslib/m82xx_pci.c b/trunk/arch/ppc/syslib/m82xx_pci.c index 1941a8c7ca9a..63fa5b313396 100644 --- a/trunk/arch/ppc/syslib/m82xx_pci.c +++ b/trunk/arch/ppc/syslib/m82xx_pci.c @@ -159,7 +159,7 @@ pq2pci_init_irq(void) immap->im_memctl.memc_or8 = 0xffff8010; #endif for (irq = NR_CPM_INTS; irq < NR_CPM_INTS + 4; irq++) - irq_desc[irq].handler = &pq2pci_ic; + irq_desc[irq].chip = &pq2pci_ic; /* make PCI IRQ level sensitive */ immap->im_intctl.ic_siexr &= diff --git a/trunk/arch/ppc/syslib/m8xx_setup.c b/trunk/arch/ppc/syslib/m8xx_setup.c index dae9af78bde1..0c4c0de7c59f 100644 --- a/trunk/arch/ppc/syslib/m8xx_setup.c +++ b/trunk/arch/ppc/syslib/m8xx_setup.c @@ -347,13 +347,13 @@ m8xx_init_IRQ(void) int i; for (i = SIU_IRQ_OFFSET ; i < SIU_IRQ_OFFSET + NR_SIU_INTS ; i++) - irq_desc[i].handler = &ppc8xx_pic; + irq_desc[i].chip = &ppc8xx_pic; cpm_interrupt_init(); #if defined(CONFIG_PCI) for (i = I8259_IRQ_OFFSET ; i < I8259_IRQ_OFFSET + NR_8259_INTS ; i++) - irq_desc[i].handler = &i8259_pic; + irq_desc[i].chip = &i8259_pic; i8259_pic_irq_offset = I8259_IRQ_OFFSET; i8259_init(0); diff --git a/trunk/arch/ppc/syslib/mpc52xx_pic.c b/trunk/arch/ppc/syslib/mpc52xx_pic.c index c4406f9dc6a3..6425b5cee7db 100644 --- a/trunk/arch/ppc/syslib/mpc52xx_pic.c +++ b/trunk/arch/ppc/syslib/mpc52xx_pic.c @@ -204,9 +204,9 @@ mpc52xx_init_irq(void) out_be32(&intr->main_pri1, 0); out_be32(&intr->main_pri2, 0); - /* Initialize irq_desc[i].handler's with mpc52xx_ic. */ + /* Initialize irq_desc[i].chip's with mpc52xx_ic. */ for (i = 0; i < NR_IRQS; i++) { - irq_desc[i].handler = &mpc52xx_ic; + irq_desc[i].chip = &mpc52xx_ic; irq_desc[i].status = IRQ_LEVEL; } diff --git a/trunk/arch/ppc/syslib/mv64360_pic.c b/trunk/arch/ppc/syslib/mv64360_pic.c index 5a19697060f0..a4244d468381 100644 --- a/trunk/arch/ppc/syslib/mv64360_pic.c +++ b/trunk/arch/ppc/syslib/mv64360_pic.c @@ -119,7 +119,7 @@ mv64360_init_irq(void) /* All interrupts are level interrupts */ for (i = mv64360_irq_base; i < (mv64360_irq_base + 96); i++) { irq_desc[i].status |= IRQ_LEVEL; - irq_desc[i].handler = &mv64360_pic; + irq_desc[i].chip = &mv64360_pic; } if (ppc_md.progress) diff --git a/trunk/arch/ppc/syslib/open_pic.c b/trunk/arch/ppc/syslib/open_pic.c index 70456c8f998c..767a0bc95817 100644 --- a/trunk/arch/ppc/syslib/open_pic.c +++ b/trunk/arch/ppc/syslib/open_pic.c @@ -373,7 +373,7 @@ void __init openpic_init(int offset) OPENPIC_VEC_IPI+i+offset); /* IPIs are per-CPU */ irq_desc[OPENPIC_VEC_IPI+i+offset].status |= IRQ_PER_CPU; - irq_desc[OPENPIC_VEC_IPI+i+offset].handler = &open_pic_ipi; + irq_desc[OPENPIC_VEC_IPI+i+offset].chip = &open_pic_ipi; } #endif @@ -408,7 +408,7 @@ void __init openpic_init(int offset) /* Init descriptors */ for (i = offset; i < NumSources + offset; i++) - irq_desc[i].handler = &open_pic; + irq_desc[i].chip = &open_pic; /* Initialize the spurious interrupt */ if (ppc_md.progress) ppc_md.progress("openpic: spurious",0x3bd); @@ -615,8 +615,8 @@ void __devinit do_openpic_setup_cpu(void) /* let the openpic know we want intrs. default affinity * is 0xffffffff until changed via /proc * That's how it's done on x86. If we want it differently, then - * we should make sure we also change the default values of irq_affinity - * in irq.c. + * we should make sure we also change the default values of + * irq_desc[].affinity in irq.c. */ for (i = 0; i < NumSources; i++) openpic_mapirq(i, msk, CPU_MASK_ALL); diff --git a/trunk/arch/ppc/syslib/open_pic2.c b/trunk/arch/ppc/syslib/open_pic2.c index bcbe40de26fe..b8154efff6ed 100644 --- a/trunk/arch/ppc/syslib/open_pic2.c +++ b/trunk/arch/ppc/syslib/open_pic2.c @@ -290,7 +290,7 @@ void __init openpic2_init(int offset) /* Init descriptors */ for (i = offset; i < NumSources + offset; i++) - irq_desc[i].handler = &open_pic2; + irq_desc[i].chip = &open_pic2; /* Initialize the spurious interrupt */ if (ppc_md.progress) ppc_md.progress("openpic2: spurious",0x3bd); diff --git a/trunk/arch/ppc/syslib/ppc403_pic.c b/trunk/arch/ppc/syslib/ppc403_pic.c index c46043c47225..1584c8b1229f 100644 --- a/trunk/arch/ppc/syslib/ppc403_pic.c +++ b/trunk/arch/ppc/syslib/ppc403_pic.c @@ -121,5 +121,5 @@ ppc4xx_pic_init(void) ppc_md.get_irq = ppc403_pic_get_irq; for (i = 0; i < NR_IRQS; i++) - irq_desc[i].handler = &ppc403_aic; + irq_desc[i].chip = &ppc403_aic; } diff --git a/trunk/arch/ppc/syslib/ppc4xx_pic.c b/trunk/arch/ppc/syslib/ppc4xx_pic.c index fd9af0fc0e9f..e669c1335d47 100644 --- a/trunk/arch/ppc/syslib/ppc4xx_pic.c +++ b/trunk/arch/ppc/syslib/ppc4xx_pic.c @@ -276,7 +276,7 @@ void __init ppc4xx_pic_init(void) /* Attach low-level handlers */ for (i = 0; i < (NR_UICS << 5); ++i) { - irq_desc[i].handler = &__uic[i >> 5].decl; + irq_desc[i].chip = &__uic[i >> 5].decl; if (is_level_sensitive(i)) irq_desc[i].status |= IRQ_LEVEL; } diff --git a/trunk/arch/ppc/syslib/xilinx_pic.c b/trunk/arch/ppc/syslib/xilinx_pic.c index e672b600f315..39a93dc6375b 100644 --- a/trunk/arch/ppc/syslib/xilinx_pic.c +++ b/trunk/arch/ppc/syslib/xilinx_pic.c @@ -143,7 +143,7 @@ ppc4xx_pic_init(void) ppc_md.get_irq = xilinx_pic_get_irq; for (i = 0; i < NR_IRQS; ++i) { - irq_desc[i].handler = &xilinx_intc; + irq_desc[i].chip = &xilinx_intc; if (XPAR_INTC_0_KIND_OF_INTR & (0x00000001 << i)) irq_desc[i].status &= ~IRQ_LEVEL; diff --git a/trunk/arch/s390/appldata/appldata.h b/trunk/arch/s390/appldata/appldata.h index e806a8922bbb..71d65eb30650 100644 --- a/trunk/arch/s390/appldata/appldata.h +++ b/trunk/arch/s390/appldata/appldata.h @@ -3,9 +3,9 @@ * * Definitions and interface for Linux - z/VM Monitor Stream. * - * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. + * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH. * - * Author: Gerald Schaefer + * Author: Gerald Schaefer */ //#define APPLDATA_DEBUG /* Debug messages on/off */ @@ -29,6 +29,22 @@ #define CTL_APPLDATA_NET_SUM 2125 #define CTL_APPLDATA_PROC 2126 +#ifndef CONFIG_64BIT + +#define APPLDATA_START_INTERVAL_REC 0x00 /* Function codes for */ +#define APPLDATA_STOP_REC 0x01 /* DIAG 0xDC */ +#define APPLDATA_GEN_EVENT_RECORD 0x02 +#define APPLDATA_START_CONFIG_REC 0x03 + +#else + +#define APPLDATA_START_INTERVAL_REC 0x80 +#define APPLDATA_STOP_REC 0x81 +#define APPLDATA_GEN_EVENT_RECORD 0x82 +#define APPLDATA_START_CONFIG_REC 0x83 + +#endif /* CONFIG_64BIT */ + #define P_INFO(x...) printk(KERN_INFO MY_PRINT_NAME " info: " x) #define P_ERROR(x...) printk(KERN_ERR MY_PRINT_NAME " error: " x) #define P_WARNING(x...) printk(KERN_WARNING MY_PRINT_NAME " status: " x) @@ -53,7 +69,11 @@ struct appldata_ops { void *data; /* record data */ unsigned int size; /* size of record */ struct module *owner; /* THIS_MODULE */ + char mod_lvl[2]; /* modification level, EBCDIC */ }; extern int appldata_register_ops(struct appldata_ops *ops); extern void appldata_unregister_ops(struct appldata_ops *ops); +extern int appldata_diag(char record_nr, u16 function, unsigned long buffer, + u16 length, char *mod_lvl); + diff --git a/trunk/arch/s390/appldata/appldata_base.c b/trunk/arch/s390/appldata/appldata_base.c index 54d35c130907..61bc44626c04 100644 --- a/trunk/arch/s390/appldata/appldata_base.c +++ b/trunk/arch/s390/appldata/appldata_base.c @@ -5,9 +5,9 @@ * Exports appldata_register_ops() and appldata_unregister_ops() for the * data gathering modules. * - * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. + * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH. * - * Author: Gerald Schaefer + * Author: Gerald Schaefer */ #include @@ -40,22 +40,6 @@ #define TOD_MICRO 0x01000 /* nr. of TOD clock units for 1 microsecond */ -#ifndef CONFIG_64BIT - -#define APPLDATA_START_INTERVAL_REC 0x00 /* Function codes for */ -#define APPLDATA_STOP_REC 0x01 /* DIAG 0xDC */ -#define APPLDATA_GEN_EVENT_RECORD 0x02 -#define APPLDATA_START_CONFIG_REC 0x03 - -#else - -#define APPLDATA_START_INTERVAL_REC 0x80 -#define APPLDATA_STOP_REC 0x81 -#define APPLDATA_GEN_EVENT_RECORD 0x82 -#define APPLDATA_START_CONFIG_REC 0x83 - -#endif /* CONFIG_64BIT */ - /* * Parameter list for DIAGNOSE X'DC' @@ -195,8 +179,8 @@ static void appldata_work_fn(void *data) * * prepare parameter list, issue DIAG 0xDC */ -static int appldata_diag(char record_nr, u16 function, unsigned long buffer, - u16 length) +int appldata_diag(char record_nr, u16 function, unsigned long buffer, + u16 length, char *mod_lvl) { unsigned long ry; struct appldata_product_id { @@ -214,7 +198,7 @@ static int appldata_diag(char record_nr, u16 function, unsigned long buffer, .record_nr = record_nr, .version_nr = {0xF2, 0xF6}, /* "26" */ .release_nr = {0xF0, 0xF1}, /* "01" */ - .mod_lvl = {0xF0, 0xF0}, /* "00" */ + .mod_lvl = {mod_lvl[0], mod_lvl[1]}, }; struct appldata_parameter_list appldata_parameter_list = { .diag = 0xDC, @@ -467,24 +451,25 @@ appldata_generic_handler(ctl_table *ctl, int write, struct file *filp, module_put(ops->owner); return -ENODEV; } - ops->active = 1; ops->callback(ops->data); // init record rc = appldata_diag(ops->record_nr, APPLDATA_START_INTERVAL_REC, - (unsigned long) ops->data, ops->size); + (unsigned long) ops->data, ops->size, + ops->mod_lvl); if (rc != 0) { P_ERROR("START DIAG 0xDC for %s failed, " "return code: %d\n", ops->name, rc); module_put(ops->owner); - ops->active = 0; } else { P_INFO("Monitoring %s data enabled, " "DIAG 0xDC started.\n", ops->name); + ops->active = 1; } } else if ((buf[0] == '0') && (ops->active == 1)) { ops->active = 0; rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC, - (unsigned long) ops->data, ops->size); + (unsigned long) ops->data, ops->size, + ops->mod_lvl); if (rc != 0) { P_ERROR("STOP DIAG 0xDC for %s failed, " "return code: %d\n", ops->name, rc); @@ -633,7 +618,7 @@ appldata_offline_cpu(int cpu) spin_unlock(&appldata_timer_lock); } -static int +static int __cpuinit appldata_cpu_notify(struct notifier_block *self, unsigned long action, void *hcpu) { @@ -710,7 +695,8 @@ static void __exit appldata_exit(void) list_for_each(lh, &appldata_ops_list) { ops = list_entry(lh, struct appldata_ops, list); rc = appldata_diag(ops->record_nr, APPLDATA_STOP_REC, - (unsigned long) ops->data, ops->size); + (unsigned long) ops->data, ops->size, + ops->mod_lvl); if (rc != 0) { P_ERROR("STOP DIAG 0xDC for %s failed, " "return code: %d\n", ops->name, rc); @@ -739,6 +725,7 @@ MODULE_DESCRIPTION("Linux-VM Monitor Stream, base infrastructure"); EXPORT_SYMBOL_GPL(appldata_register_ops); EXPORT_SYMBOL_GPL(appldata_unregister_ops); +EXPORT_SYMBOL_GPL(appldata_diag); #ifdef MODULE /* @@ -779,7 +766,6 @@ unsigned long nr_iowait(void) #endif /* MODULE */ EXPORT_SYMBOL_GPL(si_swapinfo); EXPORT_SYMBOL_GPL(nr_threads); -EXPORT_SYMBOL_GPL(avenrun); EXPORT_SYMBOL_GPL(get_full_page_state); EXPORT_SYMBOL_GPL(nr_running); EXPORT_SYMBOL_GPL(nr_iowait); diff --git a/trunk/arch/s390/appldata/appldata_mem.c b/trunk/arch/s390/appldata/appldata_mem.c index f0e2fbed3d4c..7915a197d96d 100644 --- a/trunk/arch/s390/appldata/appldata_mem.c +++ b/trunk/arch/s390/appldata/appldata_mem.c @@ -4,9 +4,9 @@ * Data gathering module for Linux-VM Monitor Stream, Stage 1. * Collects data related to memory management. * - * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. + * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH. * - * Author: Gerald Schaefer + * Author: Gerald Schaefer */ #include @@ -152,6 +152,7 @@ static struct appldata_ops ops = { .callback = &appldata_get_mem_data, .data = &appldata_mem_data, .owner = THIS_MODULE, + .mod_lvl = {0xF0, 0xF0}, /* EBCDIC "00" */ }; diff --git a/trunk/arch/s390/appldata/appldata_net_sum.c b/trunk/arch/s390/appldata/appldata_net_sum.c index 2a4c7432db4a..39b7bdecbf05 100644 --- a/trunk/arch/s390/appldata/appldata_net_sum.c +++ b/trunk/arch/s390/appldata/appldata_net_sum.c @@ -5,9 +5,9 @@ * Collects accumulated network statistics (Packets received/transmitted, * dropped, errors, ...). * - * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. + * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH. * - * Author: Gerald Schaefer + * Author: Gerald Schaefer */ #include @@ -152,6 +152,7 @@ static struct appldata_ops ops = { .callback = &appldata_get_net_sum_data, .data = &appldata_net_sum_data, .owner = THIS_MODULE, + .mod_lvl = {0xF0, 0xF0}, /* EBCDIC "00" */ }; diff --git a/trunk/arch/s390/appldata/appldata_os.c b/trunk/arch/s390/appldata/appldata_os.c index 99ddd3bf2fba..f2b44a2f1dec 100644 --- a/trunk/arch/s390/appldata/appldata_os.c +++ b/trunk/arch/s390/appldata/appldata_os.c @@ -4,9 +4,9 @@ * Data gathering module for Linux-VM Monitor Stream, Stage 1. * Collects misc. OS related data (CPU utilization, running processes). * - * Copyright (C) 2003 IBM Corporation, IBM Deutschland Entwicklung GmbH. + * Copyright (C) 2003,2006 IBM Corporation, IBM Deutschland Entwicklung GmbH. * - * Author: Gerald Schaefer + * Author: Gerald Schaefer */ #include @@ -44,11 +44,14 @@ struct appldata_os_per_cpu { u32 per_cpu_system; /* ... spent in kernel mode */ u32 per_cpu_idle; /* ... spent in idle mode */ -// New in 2.6 --> + /* New in 2.6 */ u32 per_cpu_irq; /* ... spent in interrupts */ u32 per_cpu_softirq; /* ... spent in softirqs */ u32 per_cpu_iowait; /* ... spent while waiting for I/O */ -// <-- New in 2.6 + + /* New in modification level 01 */ + u32 per_cpu_steal; /* ... stolen by hypervisor */ + u32 cpu_id; /* number of this CPU */ } __attribute__((packed)); struct appldata_os_data { @@ -68,10 +71,9 @@ struct appldata_os_data { u32 avenrun[3]; /* average nr. of running processes during */ /* the last 1, 5 and 15 minutes */ -// New in 2.6 --> + /* New in 2.6 */ u32 nr_iowait; /* number of blocked threads (waiting for I/O) */ -// <-- New in 2.6 /* per cpu data */ struct appldata_os_per_cpu os_cpu[0]; @@ -79,6 +81,14 @@ struct appldata_os_data { static struct appldata_os_data *appldata_os_data; +static struct appldata_ops ops = { + .ctl_nr = CTL_APPLDATA_OS, + .name = "os", + .record_nr = APPLDATA_RECORD_OS_ID, + .owner = THIS_MODULE, + .mod_lvl = {0xF0, 0xF1}, /* EBCDIC "01" */ +}; + static inline void appldata_print_debug(struct appldata_os_data *os_data) { @@ -100,15 +110,17 @@ static inline void appldata_print_debug(struct appldata_os_data *os_data) P_DEBUG("nr_cpus = %u\n", os_data->nr_cpus); for (i = 0; i < os_data->nr_cpus; i++) { P_DEBUG("cpu%u : user = %u, nice = %u, system = %u, " - "idle = %u, irq = %u, softirq = %u, iowait = %u\n", - i, + "idle = %u, irq = %u, softirq = %u, iowait = %u, " + "steal = %u\n", + os_data->os_cpu[i].cpu_id, os_data->os_cpu[i].per_cpu_user, os_data->os_cpu[i].per_cpu_nice, os_data->os_cpu[i].per_cpu_system, os_data->os_cpu[i].per_cpu_idle, os_data->os_cpu[i].per_cpu_irq, os_data->os_cpu[i].per_cpu_softirq, - os_data->os_cpu[i].per_cpu_iowait); + os_data->os_cpu[i].per_cpu_iowait, + os_data->os_cpu[i].per_cpu_steal); } P_DEBUG("sync_count_1 = %u\n", os_data->sync_count_1); @@ -123,14 +135,13 @@ static inline void appldata_print_debug(struct appldata_os_data *os_data) */ static void appldata_get_os_data(void *data) { - int i, j; + int i, j, rc; struct appldata_os_data *os_data; + unsigned int new_size; os_data = data; os_data->sync_count_1++; - os_data->nr_cpus = num_online_cpus(); - os_data->nr_threads = nr_threads; os_data->nr_running = nr_running(); os_data->nr_iowait = nr_iowait(); @@ -154,9 +165,44 @@ static void appldata_get_os_data(void *data) cputime_to_jiffies(kstat_cpu(i).cpustat.softirq); os_data->os_cpu[j].per_cpu_iowait = cputime_to_jiffies(kstat_cpu(i).cpustat.iowait); + os_data->os_cpu[j].per_cpu_steal = + cputime_to_jiffies(kstat_cpu(i).cpustat.steal); + os_data->os_cpu[j].cpu_id = i; j++; } + os_data->nr_cpus = j; + + new_size = sizeof(struct appldata_os_data) + + (os_data->nr_cpus * sizeof(struct appldata_os_per_cpu)); + if (ops.size != new_size) { + if (ops.active) { + rc = appldata_diag(APPLDATA_RECORD_OS_ID, + APPLDATA_START_INTERVAL_REC, + (unsigned long) ops.data, new_size, + ops.mod_lvl); + if (rc != 0) { + P_ERROR("os: START NEW DIAG 0xDC failed, " + "return code: %d, new size = %i\n", rc, + new_size); + P_INFO("os: stopping old record now\n"); + } else + P_INFO("os: new record size = %i\n", new_size); + + rc = appldata_diag(APPLDATA_RECORD_OS_ID, + APPLDATA_STOP_REC, + (unsigned long) ops.data, ops.size, + ops.mod_lvl); + if (rc != 0) + P_ERROR("os: STOP OLD DIAG 0xDC failed, " + "return code: %d, old size = %i\n", rc, + ops.size); + else + P_INFO("os: old record size = %i stopped\n", + ops.size); + } + ops.size = new_size; + } os_data->timestamp = get_clock(); os_data->sync_count_2++; #ifdef APPLDATA_DEBUG @@ -165,15 +211,6 @@ static void appldata_get_os_data(void *data) } -static struct appldata_ops ops = { - .ctl_nr = CTL_APPLDATA_OS, - .name = "os", - .record_nr = APPLDATA_RECORD_OS_ID, - .callback = &appldata_get_os_data, - .owner = THIS_MODULE, -}; - - /* * appldata_os_init() * @@ -181,26 +218,25 @@ static struct appldata_ops ops = { */ static int __init appldata_os_init(void) { - int rc, size; + int rc, max_size; - size = sizeof(struct appldata_os_data) + - (NR_CPUS * sizeof(struct appldata_os_per_cpu)); - if (size > APPLDATA_MAX_REC_SIZE) { - P_ERROR("Size of record = %i, bigger than maximum (%i)!\n", - size, APPLDATA_MAX_REC_SIZE); + max_size = sizeof(struct appldata_os_data) + + (NR_CPUS * sizeof(struct appldata_os_per_cpu)); + if (max_size > APPLDATA_MAX_REC_SIZE) { + P_ERROR("Max. size of OS record = %i, bigger than maximum " + "record size (%i)\n", max_size, APPLDATA_MAX_REC_SIZE); rc = -ENOMEM; goto out; } - P_DEBUG("sizeof(os) = %i, sizeof(os_cpu) = %lu\n", size, + P_DEBUG("max. sizeof(os) = %i, sizeof(os_cpu) = %lu\n", max_size, sizeof(struct appldata_os_per_cpu)); - appldata_os_data = kmalloc(size, GFP_DMA); + appldata_os_data = kzalloc(max_size, GFP_DMA); if (appldata_os_data == NULL) { P_ERROR("No memory for %s!\n", ops.name); rc = -ENOMEM; goto out; } - memset(appldata_os_data, 0, size); appldata_os_data->per_cpu_size = sizeof(struct appldata_os_per_cpu); appldata_os_data->cpu_offset = offsetof(struct appldata_os_data, @@ -208,7 +244,7 @@ static int __init appldata_os_init(void) P_DEBUG("cpu offset = %u\n", appldata_os_data->cpu_offset); ops.data = appldata_os_data; - ops.size = size; + ops.callback = &appldata_get_os_data; rc = appldata_register_ops(&ops); if (rc != 0) { P_ERROR("Error registering ops, rc = %i\n", rc); diff --git a/trunk/arch/s390/kernel/binfmt_elf32.c b/trunk/arch/s390/kernel/binfmt_elf32.c index 1f451c2cb071..12a6311e9838 100644 --- a/trunk/arch/s390/kernel/binfmt_elf32.c +++ b/trunk/arch/s390/kernel/binfmt_elf32.c @@ -177,11 +177,6 @@ struct elf_prpsinfo32 #include -#undef NEW_TO_OLD_UID -#undef NEW_TO_OLD_GID -#define NEW_TO_OLD_UID(uid) ((uid) > 65535) ? (u16)overflowuid : (u16)(uid) -#define NEW_TO_OLD_GID(gid) ((gid) > 65535) ? (u16)overflowgid : (u16)(gid) - #define elf_addr_t u32 /* #define init_elf_binfmt init_elf32_binfmt diff --git a/trunk/arch/s390/kernel/entry.S b/trunk/arch/s390/kernel/entry.S index b2448487854c..aa8b52c2140f 100644 --- a/trunk/arch/s390/kernel/entry.S +++ b/trunk/arch/s390/kernel/entry.S @@ -93,13 +93,22 @@ STACK_SIZE = 1 << STACK_SHIFT l %r13,__LC_SVC_NEW_PSW+4 # load &system_call to %r13 .endm - .macro SAVE_ALL psworg,savearea,sync + .macro SAVE_ALL_SYNC psworg,savearea la %r12,\psworg - .if \sync tm \psworg+1,0x01 # test problem state bit bz BASED(2f) # skip stack setup save l %r15,__LC_KERNEL_STACK # problem state -> load ksp - .else +#ifdef CONFIG_CHECK_STACK + b BASED(3f) +2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD + bz BASED(stack_overflow) +3: +#endif +2: + .endm + + .macro SAVE_ALL_ASYNC psworg,savearea + la %r12,\psworg tm \psworg+1,0x01 # test problem state bit bnz BASED(1f) # from user -> load async stack clc \psworg+4(4),BASED(.Lcritical_end) @@ -115,7 +124,6 @@ STACK_SIZE = 1 << STACK_SHIFT sra %r14,STACK_SHIFT be BASED(2f) 1: l %r15,__LC_ASYNC_STACK - .endif #ifdef CONFIG_CHECK_STACK b BASED(3f) 2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD @@ -196,7 +204,7 @@ system_call: STORE_TIMER __LC_SYNC_ENTER_TIMER sysc_saveall: SAVE_ALL_BASE __LC_SAVE_AREA - SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA lh %r7,0x8a # get svc number from lowcore #ifdef CONFIG_VIRT_CPU_ACCOUNTING @@ -425,7 +433,7 @@ pgm_check_handler: SAVE_ALL_BASE __LC_SAVE_AREA tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception bnz BASED(pgm_per) # got per exception -> special case - SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -464,7 +472,7 @@ pgm_per: # Normal per exception # pgm_per_std: - SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -490,7 +498,7 @@ pgm_no_vtime2: # it was a single stepped SVC that is causing all the trouble # pgm_svcper: - SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -519,7 +527,7 @@ io_int_handler: STORE_TIMER __LC_ASYNC_ENTER_TIMER stck __LC_INT_CLOCK SAVE_ALL_BASE __LC_SAVE_AREA+16 - SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+16,0 + SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+16 #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -631,7 +639,7 @@ ext_int_handler: STORE_TIMER __LC_ASYNC_ENTER_TIMER stck __LC_INT_CLOCK SAVE_ALL_BASE __LC_SAVE_AREA+16 - SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16,0 + SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+16 #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -657,21 +665,31 @@ __critical_end: .globl mcck_int_handler mcck_int_handler: spt __LC_CPU_TIMER_SAVE_AREA # revalidate cpu timer - mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA lm %r0,%r15,__LC_GPREGS_SAVE_AREA # revalidate gprs SAVE_ALL_BASE __LC_SAVE_AREA+32 la %r12,__LC_MCK_OLD_PSW tm __LC_MCCK_CODE,0x80 # system damage? bo BASED(mcck_int_main) # yes -> rest of mcck code invalid - tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? - bo BASED(0f) - spt __LC_LAST_UPDATE_TIMER # revalidate cpu timer #ifdef CONFIG_VIRT_CPU_ACCOUNTING - mvc __LC_ASYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER - mvc __LC_SYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER - mvc __LC_EXIT_TIMER(8),__LC_LAST_UPDATE_TIMER + mvc __LC_SAVE_AREA+52(8),__LC_ASYNC_ENTER_TIMER + mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA + tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? + bo BASED(1f) + la %r14,__LC_SYNC_ENTER_TIMER + clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER + bl BASED(0f) + la %r14,__LC_ASYNC_ENTER_TIMER +0: clc 0(8,%r14),__LC_EXIT_TIMER + bl BASED(0f) + la %r14,__LC_EXIT_TIMER +0: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER + bl BASED(0f) + la %r14,__LC_LAST_UPDATE_TIMER +0: spt 0(%r14) + mvc __LC_ASYNC_ENTER_TIMER(8),0(%r14) +1: #endif -0: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? + tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? bno BASED(mcck_int_main) # no -> skip cleanup critical tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit bnz BASED(mcck_int_main) # from user -> load async stack @@ -691,7 +709,7 @@ mcck_int_main: #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? bno BASED(mcck_no_vtime) # no -> skip cleanup critical - tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ? + tm SP_PSW+1(%r15),0x01 # interrupting from user ? bz BASED(mcck_no_vtime) UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER @@ -715,6 +733,20 @@ mcck_no_vtime: l %r1,BASED(.Ls390_handle_mcck) basr %r14,%r1 # call machine check handler mcck_return: + mvc __LC_RETURN_MCCK_PSW(8),SP_PSW(%r15) # move return PSW + ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit +#ifdef CONFIG_VIRT_CPU_ACCOUNTING + mvc __LC_ASYNC_ENTER_TIMER(8),__LC_SAVE_AREA+52 + tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? + bno BASED(0f) + lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 + stpt __LC_EXIT_TIMER + lpsw __LC_RETURN_MCCK_PSW # back to caller +0: +#endif + lm %r0,%r15,SP_R0(%r15) # load gprs 0-15 + lpsw __LC_RETURN_MCCK_PSW # back to caller + RESTORE_ALL __LC_RETURN_MCCK_PSW,0 #ifdef CONFIG_SMP @@ -781,6 +813,8 @@ cleanup_table_sysc_leave: .long sysc_leave + 0x80000000, sysc_work_loop + 0x80000000 cleanup_table_sysc_work_loop: .long sysc_work_loop + 0x80000000, sysc_reschedule + 0x80000000 +cleanup_table_io_return: + .long io_return + 0x80000000, io_leave + 0x80000000 cleanup_table_io_leave: .long io_leave + 0x80000000, io_done + 0x80000000 cleanup_table_io_work_loop: @@ -806,6 +840,11 @@ cleanup_critical: bl BASED(0f) clc 4(4,%r12),BASED(cleanup_table_sysc_work_loop+4) bl BASED(cleanup_sysc_return) +0: + clc 4(4,%r12),BASED(cleanup_table_io_return) + bl BASED(0f) + clc 4(4,%r12),BASED(cleanup_table_io_return+4) + bl BASED(cleanup_io_return) 0: clc 4(4,%r12),BASED(cleanup_table_io_leave) bl BASED(0f) @@ -839,7 +878,7 @@ cleanup_system_call: mvc __LC_SAVE_AREA(16),0(%r12) 0: st %r13,4(%r12) st %r12,__LC_SAVE_AREA+48 # argh - SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA l %r12,__LC_SAVE_AREA+48 # argh st %r15,12(%r12) @@ -980,7 +1019,6 @@ cleanup_io_leave_insn: .long cleanup_critical #define SYSCALL(esa,esame,emu) .long esa - .globl sys_call_table sys_call_table: #include "syscalls.S" #undef SYSCALL diff --git a/trunk/arch/s390/kernel/entry64.S b/trunk/arch/s390/kernel/entry64.S index 2ac095bc0e25..f3222a1b2861 100644 --- a/trunk/arch/s390/kernel/entry64.S +++ b/trunk/arch/s390/kernel/entry64.S @@ -87,13 +87,22 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ larl %r13,system_call .endm - .macro SAVE_ALL psworg,savearea,sync + .macro SAVE_ALL_SYNC psworg,savearea la %r12,\psworg - .if \sync tm \psworg+1,0x01 # test problem state bit jz 2f # skip stack setup save lg %r15,__LC_KERNEL_STACK # problem state -> load ksp - .else +#ifdef CONFIG_CHECK_STACK + j 3f +2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD + jz stack_overflow +3: +#endif +2: + .endm + + .macro SAVE_ALL_ASYNC psworg,savearea + la %r12,\psworg tm \psworg+1,0x01 # test problem state bit jnz 1f # from user -> load kernel stack clc \psworg+8(8),BASED(.Lcritical_end) @@ -108,7 +117,6 @@ _TIF_WORK_INT = (_TIF_SIGPENDING | _TIF_RESTORE_SIGMASK | _TIF_NEED_RESCHED | \ srag %r14,%r14,STACK_SHIFT jz 2f 1: lg %r15,__LC_ASYNC_STACK # load async stack - .endif #ifdef CONFIG_CHECK_STACK j 3f 2: tml %r15,STACK_SIZE - CONFIG_STACK_GUARD @@ -187,7 +195,7 @@ system_call: STORE_TIMER __LC_SYNC_ENTER_TIMER sysc_saveall: SAVE_ALL_BASE __LC_SAVE_AREA - SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA llgh %r7,__LC_SVC_INT_CODE # get svc number from lowcore #ifdef CONFIG_VIRT_CPU_ACCOUNTING @@ -446,7 +454,7 @@ pgm_check_handler: SAVE_ALL_BASE __LC_SAVE_AREA tm __LC_PGM_INT_CODE+1,0x80 # check whether we got a per exception jnz pgm_per # got per exception -> special case - SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -485,7 +493,7 @@ pgm_per: # Normal per exception # pgm_per_std: - SAVE_ALL __LC_PGM_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_PGM_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_PGM_OLD_PSW,__LC_SAVE_AREA #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -511,7 +519,7 @@ pgm_no_vtime2: # it was a single stepped SVC that is causing all the trouble # pgm_svcper: - SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -539,7 +547,7 @@ io_int_handler: STORE_TIMER __LC_ASYNC_ENTER_TIMER stck __LC_INT_CLOCK SAVE_ALL_BASE __LC_SAVE_AREA+32 - SAVE_ALL __LC_IO_OLD_PSW,__LC_SAVE_AREA+32,0 + SAVE_ALL_ASYNC __LC_IO_OLD_PSW,__LC_SAVE_AREA+32 CREATE_STACK_FRAME __LC_IO_OLD_PSW,__LC_SAVE_AREA+32 #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -647,7 +655,7 @@ ext_int_handler: STORE_TIMER __LC_ASYNC_ENTER_TIMER stck __LC_INT_CLOCK SAVE_ALL_BASE __LC_SAVE_AREA+32 - SAVE_ALL __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32,0 + SAVE_ALL_ASYNC __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32 CREATE_STACK_FRAME __LC_EXT_OLD_PSW,__LC_SAVE_AREA+32 #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm SP_PSW+1(%r15),0x01 # interrupting from user ? @@ -672,21 +680,32 @@ __critical_end: mcck_int_handler: la %r1,4095 # revalidate r1 spt __LC_CPU_TIMER_SAVE_AREA-4095(%r1) # revalidate cpu timer - mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA-4095(%r1) lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)# revalidate gprs SAVE_ALL_BASE __LC_SAVE_AREA+64 la %r12,__LC_MCK_OLD_PSW tm __LC_MCCK_CODE,0x80 # system damage? jo mcck_int_main # yes -> rest of mcck code invalid - tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? - jo 0f - spt __LC_LAST_UPDATE_TIMER #ifdef CONFIG_VIRT_CPU_ACCOUNTING - mvc __LC_ASYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER - mvc __LC_SYNC_ENTER_TIMER(8),__LC_LAST_UPDATE_TIMER - mvc __LC_EXIT_TIMER(8),__LC_LAST_UPDATE_TIMER + la %r14,4095 + mvc __LC_SAVE_AREA+104(8),__LC_ASYNC_ENTER_TIMER + mvc __LC_ASYNC_ENTER_TIMER(8),__LC_CPU_TIMER_SAVE_AREA-4095(%r14) + tm __LC_MCCK_CODE+5,0x02 # stored cpu timer value valid? + jo 1f + la %r14,__LC_SYNC_ENTER_TIMER + clc 0(8,%r14),__LC_ASYNC_ENTER_TIMER + jl 0f + la %r14,__LC_ASYNC_ENTER_TIMER +0: clc 0(8,%r14),__LC_EXIT_TIMER + jl 0f + la %r14,__LC_EXIT_TIMER +0: clc 0(8,%r14),__LC_LAST_UPDATE_TIMER + jl 0f + la %r14,__LC_LAST_UPDATE_TIMER +0: spt 0(%r14) + mvc __LC_ASYNC_ENTER_TIMER(8),0(%r14) +1: #endif -0: tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? + tm __LC_MCCK_CODE+2,0x09 # mwp + ia of old psw valid? jno mcck_int_main # no -> skip cleanup critical tm __LC_MCK_OLD_PSW+1,0x01 # test problem state bit jnz mcck_int_main # from user -> load kernel stack @@ -705,7 +724,7 @@ mcck_int_main: #ifdef CONFIG_VIRT_CPU_ACCOUNTING tm __LC_MCCK_CODE+2,0x08 # mwp of old psw valid? jno mcck_no_vtime # no -> no timer update - tm __LC_MCK_OLD_PSW+1,0x01 # interrupting from user ? + tm SP_PSW+1(%r15),0x01 # interrupting from user ? jz mcck_no_vtime UPDATE_VTIME __LC_EXIT_TIMER,__LC_ASYNC_ENTER_TIMER,__LC_USER_TIMER UPDATE_VTIME __LC_LAST_UPDATE_TIMER,__LC_EXIT_TIMER,__LC_SYSTEM_TIMER @@ -727,7 +746,17 @@ mcck_no_vtime: jno mcck_return brasl %r14,s390_handle_mcck mcck_return: - RESTORE_ALL __LC_RETURN_MCCK_PSW,0 + mvc __LC_RETURN_MCCK_PSW(16),SP_PSW(%r15) # move return PSW + ni __LC_RETURN_MCCK_PSW+1,0xfd # clear wait state bit + lmg %r0,%r15,SP_R0(%r15) # load gprs 0-15 +#ifdef CONFIG_VIRT_CPU_ACCOUNTING + mvc __LC_ASYNC_ENTER_TIMER(8),__LC_SAVE_AREA+104 + tm __LC_RETURN_MCCK_PSW+1,0x01 # returning to user ? + jno 0f + stpt __LC_EXIT_TIMER +0: +#endif + lpswe __LC_RETURN_MCCK_PSW # back to caller #ifdef CONFIG_SMP /* @@ -789,6 +818,8 @@ cleanup_table_sysc_leave: .quad sysc_leave, sysc_work_loop cleanup_table_sysc_work_loop: .quad sysc_work_loop, sysc_reschedule +cleanup_table_io_return: + .quad io_return, io_leave cleanup_table_io_leave: .quad io_leave, io_done cleanup_table_io_work_loop: @@ -814,6 +845,11 @@ cleanup_critical: jl 0f clc 8(8,%r12),BASED(cleanup_table_sysc_work_loop+8) jl cleanup_sysc_return +0: + clc 8(8,%r12),BASED(cleanup_table_io_return) + jl 0f + clc 8(8,%r12),BASED(cleanup_table_io_return+8) + jl cleanup_io_return 0: clc 8(8,%r12),BASED(cleanup_table_io_leave) jl 0f @@ -847,7 +883,7 @@ cleanup_system_call: mvc __LC_SAVE_AREA(32),0(%r12) 0: stg %r13,8(%r12) stg %r12,__LC_SAVE_AREA+96 # argh - SAVE_ALL __LC_SVC_OLD_PSW,__LC_SAVE_AREA,1 + SAVE_ALL_SYNC __LC_SVC_OLD_PSW,__LC_SAVE_AREA CREATE_STACK_FRAME __LC_SVC_OLD_PSW,__LC_SAVE_AREA lg %r12,__LC_SAVE_AREA+96 # argh stg %r15,24(%r12) @@ -957,7 +993,6 @@ cleanup_io_leave_insn: .quad __critical_end #define SYSCALL(esa,esame,emu) .long esame - .globl sys_call_table sys_call_table: #include "syscalls.S" #undef SYSCALL @@ -965,7 +1000,6 @@ sys_call_table: #ifdef CONFIG_COMPAT #define SYSCALL(esa,esame,emu) .long emu - .globl sys_call_table_emu sys_call_table_emu: #include "syscalls.S" #undef SYSCALL diff --git a/trunk/arch/s390/kernel/head.S b/trunk/arch/s390/kernel/head.S index ea88d066bf04..538c82da49b1 100644 --- a/trunk/arch/s390/kernel/head.S +++ b/trunk/arch/s390/kernel/head.S @@ -1,7 +1,7 @@ /* * arch/s390/kernel/head.S * - * (C) Copyright IBM Corp. 1999, 2005 + * Copyright (C) IBM Corp. 1999,2006 * * Author(s): Hartmut Penner * Martin Schwidefsky @@ -482,24 +482,23 @@ start: .macro GET_IPL_DEVICE .Lget_ipl_device: - basr %r12,0 -.LGID: l %r1,0xb8 # get sid + l %r1,0xb8 # get sid sll %r1,15 # test if subchannel is enabled srl %r1,31 ltr %r1,%r1 - bz 0(%r14) # subchannel disabled + bz 2f-.LPG1(%r13) # subchannel disabled l %r1,0xb8 - la %r5,.Lipl_schib-.LGID(%r12) + la %r5,.Lipl_schib-.LPG1(%r13) stsch 0(%r5) # get schib of subchannel - bnz 0(%r14) # schib not available + bnz 2f-.LPG1(%r13) # schib not available tm 5(%r5),0x01 # devno valid? - bno 0(%r14) - la %r6,ipl_parameter_flags-.LGID(%r12) + bno 2f-.LPG1(%r13) + la %r6,ipl_parameter_flags-.LPG1(%r13) oi 3(%r6),0x01 # set flag - la %r2,ipl_devno-.LGID(%r12) + la %r2,ipl_devno-.LPG1(%r13) mvc 0(2,%r2),6(%r5) # store devno tm 4(%r5),0x80 # qdio capable device? - bno 0(%r14) + bno 2f-.LPG1(%r13) oi 3(%r6),0x02 # set flag # copy ipl parameters @@ -523,7 +522,7 @@ start: ar %r2,%r1 sr %r0,%r4 jne 1b - b 0(%r14) + b 2f-.LPG1(%r13) .align 4 .Lipl_schib: @@ -537,6 +536,7 @@ ipl_parameter_flags: .globl ipl_devno ipl_devno: .word 0 +2: .endm #ifdef CONFIG_64BIT diff --git a/trunk/arch/s390/kernel/head31.S b/trunk/arch/s390/kernel/head31.S index 2d3b089bfb83..d00de17b3778 100644 --- a/trunk/arch/s390/kernel/head31.S +++ b/trunk/arch/s390/kernel/head31.S @@ -1,7 +1,7 @@ /* * arch/s390/kernel/head31.S * - * (C) Copyright IBM Corp. 2005 + * Copyright (C) IBM Corp. 2005,2006 * * Author(s): Hartmut Penner * Martin Schwidefsky @@ -16,12 +16,31 @@ # or linload or SALIPL # .org 0x10000 -startup:basr %r13,0 # get base -.LPG1: l %r1, .Lget_ipl_device_addr-.LPG1(%r13) - basr %r14, %r1 +startup:basr %r13,0 # get base +.LPG0: l %r13,0f-.LPG0(%r13) + b 0(%r13) +0: .long startup_continue + +# +# params at 10400 (setup.h) +# + .org PARMAREA + .long 0,0 # IPL_DEVICE + .long 0,RAMDISK_ORIGIN # INITRD_START + .long 0,RAMDISK_SIZE # INITRD_SIZE + + .org COMMAND_LINE + .byte "root=/dev/ram0 ro" + .byte 0 + + .org 0x11000 + +startup_continue: + basr %r13,0 # get base +.LPG1: GET_IPL_DEVICE lctl %c0,%c15,.Lctl-.LPG1(%r13) # load control registers - la %r12,_pstart-.LPG1(%r13) # pointer to parameter area - # move IPL device to lowcore + l %r12,.Lparmaddr-.LPG1(%r13) # pointer to parameter area + # move IPL device to lowcore mvc __LC_IPLDEV(4),IPL_DEVICE-PARMAREA(%r12) # @@ -51,8 +70,8 @@ startup:basr %r13,0 # get base a %r1,__LC_EXT_NEW_PSW+4 # set handler st %r1,__LC_EXT_NEW_PSW+4 - la %r4,_pstart-.LPG1(%r13) # %r4 is our index for sccb stuff - la %r1, .Lsccb-PARMAREA(%r4) # our sccb + l %r4,.Lsccbaddr-.LPG1(%r13) # %r4 is our index for sccb stuff + lr %r1,%r4 # our sccb .insn rre,0xb2200000,%r2,%r1 # service call ipm %r1 srl %r1,28 # get cc code @@ -63,7 +82,7 @@ startup:basr %r13,0 # get base be .Lservicecall-.LPG1(%r13) lpsw .Lwaitsclp-.LPG1(%r13) .Lsclph: - lh %r1,.Lsccbr-PARMAREA(%r4) + lh %r1,.Lsccbr-.Lsccb(%r4) chi %r1,0x10 # 0x0010 is the sucess code je .Lprocsccb # let's process the sccb chi %r1,0x1f0 @@ -74,7 +93,7 @@ startup:basr %r13,0 # get base b .Lservicecall-.LPG1(%r13) .Lprocsccb: lhi %r1,0 - icm %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0 + icm %r1,3,.Lscpincr1-.Lsccb(%r4) # use this one if != 0 jnz .Lscnd lhi %r1,0x800 # otherwise report 2GB .Lscnd: @@ -84,10 +103,10 @@ startup:basr %r13,0 # get base lr %r1,%r3 .Lno2gb: xr %r3,%r3 # same logic - ic %r3,.Lscpa1-PARMAREA(%r4) + ic %r3,.Lscpa1-.Lsccb(%r4) chi %r3,0x00 jne .Lcompmem - l %r3,.Lscpa2-PARMAREA(%r13) + l %r3,.Lscpa2-.Lsccb(%r4) .Lcompmem: mr %r2,%r1 # mem in MB on 128-bit l %r1,.Lonemb-.LPG1(%r13) @@ -95,8 +114,6 @@ startup:basr %r13,0 # get base b .Lfchunk-.LPG1(%r13) .align 4 -.Lget_ipl_device_addr: - .long .Lget_ipl_device .Lpmask: .byte 0 .align 8 @@ -242,6 +259,8 @@ startup:basr %r13,0 # get base .long 0 # cr13: home space segment table .long 0xc0000000 # cr14: machine check handling off .long 0 # cr15: linkage stack operations +.Lduct: .long 0,0,0,0,0,0,0,0 + .long 0,0,0,0,0,0,0,0 .Lpcmem:.long 0x00080000,0x80000000 + .Lchkmem .Lpcfpu:.long 0x00080000,0x80000000 + .Lchkfpu .Lpccsp:.long 0x00080000,0x80000000 + .Lchkcsp @@ -252,25 +271,9 @@ startup:basr %r13,0 # get base .Lmflags:.long machine_flags .Lbss_bgn: .long __bss_start .Lbss_end: .long _end - - .org PARMAREA-64 -.Lduct: .long 0,0,0,0,0,0,0,0 - .long 0,0,0,0,0,0,0,0 - -# -# params at 10400 (setup.h) -# - .org PARMAREA - .global _pstart -_pstart: - .long 0,0 # IPL_DEVICE - .long 0,RAMDISK_ORIGIN # INITRD_START - .long 0,RAMDISK_SIZE # INITRD_SIZE - - .org COMMAND_LINE - .byte "root=/dev/ram0 ro" - .byte 0 - .org 0x11000 +.Lparmaddr: .long PARMAREA +.Lsccbaddr: .long .Lsccb + .align 4096 .Lsccb: .hword 0x1000 # length, one page .byte 0x00,0x00,0x00 @@ -287,18 +290,14 @@ _pstart: .Lscpincr2: .quad 0x00 .fill 3984,1,0 - .org 0x12000 - .global _pend -_pend: - - GET_IPL_DEVICE + .align 4096 #ifdef CONFIG_SHARED_KERNEL .org 0x100000 #endif # -# startup-code, running in virtual mode +# startup-code, running in absolute addressing mode # .globl _stext _stext: basr %r13,0 # get base diff --git a/trunk/arch/s390/kernel/head64.S b/trunk/arch/s390/kernel/head64.S index f08c06f45d5c..47744fcca930 100644 --- a/trunk/arch/s390/kernel/head64.S +++ b/trunk/arch/s390/kernel/head64.S @@ -1,7 +1,7 @@ /* * arch/s390/kernel/head64.S * - * (C) Copyright IBM Corp. 1999,2005 + * Copyright (C) IBM Corp. 1999,2006 * * Author(s): Hartmut Penner * Martin Schwidefsky @@ -15,18 +15,37 @@ # this is called either by the ipl loader or directly by PSW restart # or linload or SALIPL # - .org 0x10000 -startup:basr %r13,0 # get base + .org 0x10000 +startup:basr %r13,0 # get base +.LPG0: l %r13,0f-.LPG0(%r13) + b 0(%r13) +0: .long startup_continue + +# +# params at 10400 (setup.h) +# + .org PARMAREA + .quad 0 # IPL_DEVICE + .quad RAMDISK_ORIGIN # INITRD_START + .quad RAMDISK_SIZE # INITRD_SIZE + + .org COMMAND_LINE + .byte "root=/dev/ram0 ro" + .byte 0 + + .org 0x11000 + +startup_continue: + basr %r13,0 # get base .LPG1: sll %r13,1 # remove high order bit srl %r13,1 - l %r1,.Lget_ipl_device_addr-.LPG1(%r13) - basr %r14,%r1 + GET_IPL_DEVICE lhi %r1,1 # mode 1 = esame slr %r0,%r0 # set cpuid to zero sigp %r1,%r0,0x12 # switch to esame mode sam64 # switch to 64 bit mode lctlg %c0,%c15,.Lctl-.LPG1(%r13) # load control registers - larl %r12,_pstart # pointer to parameter area + lg %r12,.Lparmaddr-.LPG1(%r13)# pointer to parameter area # move IPL device to lowcore mvc __LC_IPLDEV(4),IPL_DEVICE+4-PARMAREA(%r12) @@ -55,8 +74,8 @@ startup:basr %r13,0 # get base larl %r1,.Lsclph stg %r1,__LC_EXT_NEW_PSW+8 # set handler - larl %r4,_pstart # %r4 is our index for sccb stuff - la %r1,.Lsccb-PARMAREA(%r4) # our sccb + larl %r4,.Lsccb # %r4 is our index for sccb stuff + lgr %r1,%r4 # our sccb .insn rre,0xb2200000,%r2,%r1 # service call ipm %r1 srl %r1,28 # get cc code @@ -67,7 +86,7 @@ startup:basr %r13,0 # get base be .Lservicecall-.LPG1(%r13) lpswe .Lwaitsclp-.LPG1(%r13) .Lsclph: - lh %r1,.Lsccbr-PARMAREA(%r4) + lh %r1,.Lsccbr-.Lsccb(%r4) chi %r1,0x10 # 0x0010 is the sucess code je .Lprocsccb # let's process the sccb chi %r1,0x1f0 @@ -78,15 +97,15 @@ startup:basr %r13,0 # get base b .Lservicecall-.LPG1(%r13) .Lprocsccb: lghi %r1,0 - icm %r1,3,.Lscpincr1-PARMAREA(%r4) # use this one if != 0 + icm %r1,3,.Lscpincr1-.Lsccb(%r4) # use this one if != 0 jnz .Lscnd - lg %r1,.Lscpincr2-PARMAREA(%r4) # otherwise use this one + lg %r1,.Lscpincr2-.Lsccb(%r4) # otherwise use this one .Lscnd: xr %r3,%r3 # same logic - ic %r3,.Lscpa1-PARMAREA(%r4) + ic %r3,.Lscpa1-.Lsccb(%r4) chi %r3,0x00 jne .Lcompmem - l %r3,.Lscpa2-PARMAREA(%r13) + l %r3,.Lscpa2-.Lsccb(%r4) .Lcompmem: mlgr %r2,%r1 # mem in MB on 128-bit l %r1,.Lonemb-.LPG1(%r13) @@ -94,8 +113,6 @@ startup:basr %r13,0 # get base b .Lfchunk-.LPG1(%r13) .align 4 -.Lget_ipl_device_addr: - .long .Lget_ipl_device .Lpmask: .byte 0 .align 8 @@ -242,29 +259,16 @@ startup:basr %r13,0 # get base .quad 0 # cr13: home space segment table .quad 0xc0000000 # cr14: machine check handling off .quad 0 # cr15: linkage stack operations +.Lduct: .long 0,0,0,0,0,0,0,0 + .long 0,0,0,0,0,0,0,0 .Lpcmsk:.quad 0x0000000180000000 .L4malign:.quad 0xffffffffffc00000 .Lscan2g:.quad 0x80000000 + 0x20000 - 8 # 2GB + 128K - 8 .Lnop: .long 0x07000700 +.Lparmaddr: + .quad PARMAREA - .org PARMAREA-64 -.Lduct: .long 0,0,0,0,0,0,0,0 - .long 0,0,0,0,0,0,0,0 - -# -# params at 10400 (setup.h) -# - .org PARMAREA - .global _pstart -_pstart: - .quad 0 # IPL_DEVICE - .quad RAMDISK_ORIGIN # INITRD_START - .quad RAMDISK_SIZE # INITRD_SIZE - - .org COMMAND_LINE - .byte "root=/dev/ram0 ro" - .byte 0 - .org 0x11000 + .align 4096 .Lsccb: .hword 0x1000 # length, one page .byte 0x00,0x00,0x00 @@ -281,18 +285,14 @@ _pstart: .Lscpincr2: .quad 0x00 .fill 3984,1,0 - .org 0x12000 - .global _pend -_pend: - - GET_IPL_DEVICE + .align 4096 #ifdef CONFIG_SHARED_KERNEL .org 0x100000 #endif # -# startup-code, running in virtual mode +# startup-code, running in absolute addressing mode # .globl _stext _stext: basr %r13,0 # get base @@ -326,4 +326,3 @@ _stext: basr %r13,0 # get base .align 8 .Ldw: .quad 0x0002000180000000,0x0000000000000000 .Laregs: .long 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 - diff --git a/trunk/arch/s390/kernel/s390_ksyms.c b/trunk/arch/s390/kernel/s390_ksyms.c index 4176c77670c4..0886e739d122 100644 --- a/trunk/arch/s390/kernel/s390_ksyms.c +++ b/trunk/arch/s390/kernel/s390_ksyms.c @@ -46,8 +46,6 @@ EXPORT_SYMBOL(__down_interruptible); */ extern int dump_fpu (struct pt_regs * regs, s390_fp_regs *fpregs); EXPORT_SYMBOL(dump_fpu); -EXPORT_SYMBOL(overflowuid); -EXPORT_SYMBOL(overflowgid); EXPORT_SYMBOL(empty_zero_page); /* diff --git a/trunk/arch/s390/kernel/setup.c b/trunk/arch/s390/kernel/setup.c index b282034452a4..2b2551e3510b 100644 --- a/trunk/arch/s390/kernel/setup.c +++ b/trunk/arch/s390/kernel/setup.c @@ -37,6 +37,7 @@ #include #include #include +#include #include #include @@ -115,6 +116,7 @@ void __devinit cpu_init (void) */ char vmhalt_cmd[128] = ""; char vmpoff_cmd[128] = ""; +char vmpanic_cmd[128] = ""; static inline void strncpy_skip_quote(char *dst, char *src, int n) { @@ -146,6 +148,38 @@ static int __init vmpoff_setup(char *str) __setup("vmpoff=", vmpoff_setup); +static int vmpanic_notify(struct notifier_block *self, unsigned long event, + void *data) +{ + if (MACHINE_IS_VM && strlen(vmpanic_cmd) > 0) + cpcmd(vmpanic_cmd, NULL, 0, NULL); + + return NOTIFY_OK; +} + +#define PANIC_PRI_VMPANIC 0 + +static struct notifier_block vmpanic_nb = { + .notifier_call = vmpanic_notify, + .priority = PANIC_PRI_VMPANIC +}; + +static int __init vmpanic_setup(char *str) +{ + static int register_done __initdata = 0; + + strncpy_skip_quote(vmpanic_cmd, str, 127); + vmpanic_cmd[127] = 0; + if (!register_done) { + register_done = 1; + atomic_notifier_chain_register(&panic_notifier_list, + &vmpanic_nb); + } + return 1; +} + +__setup("vmpanic=", vmpanic_setup); + /* * condev= and conmode= setup parameter. */ @@ -289,19 +323,34 @@ void (*_machine_power_off)(void) = do_machine_power_off_nonsmp; void machine_restart(char *command) { - console_unblank(); + if (!in_interrupt() || oops_in_progress) + /* + * Only unblank the console if we are called in enabled + * context or a bust_spinlocks cleared the way for us. + */ + console_unblank(); _machine_restart(command); } void machine_halt(void) { - console_unblank(); + if (!in_interrupt() || oops_in_progress) + /* + * Only unblank the console if we are called in enabled + * context or a bust_spinlocks cleared the way for us. + */ + console_unblank(); _machine_halt(); } void machine_power_off(void) { - console_unblank(); + if (!in_interrupt() || oops_in_progress) + /* + * Only unblank the console if we are called in enabled + * context or a bust_spinlocks cleared the way for us. + */ + console_unblank(); _machine_power_off(); } diff --git a/trunk/arch/s390/kernel/traps.c b/trunk/arch/s390/kernel/traps.c index a46793beeddd..b7630436f693 100644 --- a/trunk/arch/s390/kernel/traps.c +++ b/trunk/arch/s390/kernel/traps.c @@ -150,13 +150,11 @@ void show_stack(struct task_struct *task, unsigned long *sp) unsigned long *stack; int i; - // debugging aid: "show_stack(NULL);" prints the - // back trace for this cpu. - if (!sp) - sp = task ? (unsigned long *) task->thread.ksp : __r15; + stack = task ? (unsigned long *) task->thread.ksp : __r15; + else + stack = sp; - stack = sp; for (i = 0; i < kstack_depth_to_print; i++) { if (((addr_t) stack & (THREAD_SIZE-1)) == 0) break; diff --git a/trunk/arch/sh/boards/adx/irq_maskreg.c b/trunk/arch/sh/boards/adx/irq_maskreg.c index c0973f8d57ba..357fab1bac2b 100644 --- a/trunk/arch/sh/boards/adx/irq_maskreg.c +++ b/trunk/arch/sh/boards/adx/irq_maskreg.c @@ -102,6 +102,6 @@ static void end_maskreg_irq(unsigned int irq) void make_maskreg_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].handler = &maskreg_irq_type; + irq_desc[irq].chip = &maskreg_irq_type; disable_maskreg_irq(irq); } diff --git a/trunk/arch/sh/boards/bigsur/irq.c b/trunk/arch/sh/boards/bigsur/irq.c index 6ddbcc77244d..1d32425782c0 100644 --- a/trunk/arch/sh/boards/bigsur/irq.c +++ b/trunk/arch/sh/boards/bigsur/irq.c @@ -253,7 +253,7 @@ static void make_bigsur_l1isr(unsigned int irq) { /* sanity check first */ if(irq >= BIGSUR_IRQ_LOW && irq < BIGSUR_IRQ_HIGH) { /* save the handler in the main description table */ - irq_desc[irq].handler = &bigsur_l1irq_type; + irq_desc[irq].chip = &bigsur_l1irq_type; irq_desc[irq].status = IRQ_DISABLED; irq_desc[irq].action = 0; irq_desc[irq].depth = 1; @@ -270,7 +270,7 @@ static void make_bigsur_l2isr(unsigned int irq) { /* sanity check first */ if(irq >= BIGSUR_2NDLVL_IRQ_LOW && irq < BIGSUR_2NDLVL_IRQ_HIGH) { /* save the handler in the main description table */ - irq_desc[irq].handler = &bigsur_l2irq_type; + irq_desc[irq].chip = &bigsur_l2irq_type; irq_desc[irq].status = IRQ_DISABLED; irq_desc[irq].action = 0; irq_desc[irq].depth = 1; diff --git a/trunk/arch/sh/boards/cqreek/irq.c b/trunk/arch/sh/boards/cqreek/irq.c index d1da0d844567..2955adc52310 100644 --- a/trunk/arch/sh/boards/cqreek/irq.c +++ b/trunk/arch/sh/boards/cqreek/irq.c @@ -103,7 +103,7 @@ void __init init_cqreek_IRQ(void) cqreek_irq_data[14].stat_port = BRIDGE_IDE_INTR_STAT; cqreek_irq_data[14].bit = 1; - irq_desc[14].handler = &cqreek_irq_type; + irq_desc[14].chip = &cqreek_irq_type; irq_desc[14].status = IRQ_DISABLED; irq_desc[14].action = 0; irq_desc[14].depth = 1; @@ -117,7 +117,7 @@ void __init init_cqreek_IRQ(void) cqreek_irq_data[10].bit = (1 << 10); /* XXX: Err... we may need demultiplexer for ISA irq... */ - irq_desc[10].handler = &cqreek_irq_type; + irq_desc[10].chip = &cqreek_irq_type; irq_desc[10].status = IRQ_DISABLED; irq_desc[10].action = 0; irq_desc[10].depth = 1; diff --git a/trunk/arch/sh/boards/dreamcast/setup.c b/trunk/arch/sh/boards/dreamcast/setup.c index 55dece35cde5..0027b80a2343 100644 --- a/trunk/arch/sh/boards/dreamcast/setup.c +++ b/trunk/arch/sh/boards/dreamcast/setup.c @@ -70,7 +70,7 @@ int __init platform_setup(void) /* Assign all virtual IRQs to the System ASIC int. handler */ for (i = HW_EVENT_IRQ_BASE; i < HW_EVENT_IRQ_MAX; i++) - irq_desc[i].handler = &systemasic_int; + irq_desc[i].chip = &systemasic_int; board_time_init = aica_time_init; diff --git a/trunk/arch/sh/boards/ec3104/setup.c b/trunk/arch/sh/boards/ec3104/setup.c index 5130ba2b6ff1..4b3ef16a0e96 100644 --- a/trunk/arch/sh/boards/ec3104/setup.c +++ b/trunk/arch/sh/boards/ec3104/setup.c @@ -63,7 +63,7 @@ int __init platform_setup(void) str[i] = ctrl_readb(EC3104_BASE + i); for (i = EC3104_IRQBASE; i < EC3104_IRQBASE + 32; i++) - irq_desc[i].handler = &ec3104_int; + irq_desc[i].chip = &ec3104_int; printk("initializing EC3104 \"%.8s\" at %08x, IRQ %d, IRQ base %d\n", str, EC3104_BASE, EC3104_IRQ, EC3104_IRQBASE); diff --git a/trunk/arch/sh/boards/harp/irq.c b/trunk/arch/sh/boards/harp/irq.c index 52d0ba39031b..701fa55d5297 100644 --- a/trunk/arch/sh/boards/harp/irq.c +++ b/trunk/arch/sh/boards/harp/irq.c @@ -114,7 +114,7 @@ static void enable_harp_irq(unsigned int irq) static void __init make_harp_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].handler = &harp_irq_type; + irq_desc[irq].chip = &harp_irq_type; disable_harp_irq(irq); } diff --git a/trunk/arch/sh/boards/mpc1211/pci.c b/trunk/arch/sh/boards/mpc1211/pci.c index ba3a65439752..9f7ccd33ffb6 100644 --- a/trunk/arch/sh/boards/mpc1211/pci.c +++ b/trunk/arch/sh/boards/mpc1211/pci.c @@ -273,9 +273,9 @@ void __init pcibios_fixup_irqs(void) } void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { - unsigned long start = res->start; + resource_size_t start = res->start; if (res->flags & IORESOURCE_IO) { if (start >= 0x10000UL) { diff --git a/trunk/arch/sh/boards/mpc1211/setup.c b/trunk/arch/sh/boards/mpc1211/setup.c index 2bb581b91683..b72f009c52c2 100644 --- a/trunk/arch/sh/boards/mpc1211/setup.c +++ b/trunk/arch/sh/boards/mpc1211/setup.c @@ -194,7 +194,7 @@ static struct hw_interrupt_type mpc1211_irq_type = { static void make_mpc1211_irq(unsigned int irq) { - irq_desc[irq].handler = &mpc1211_irq_type; + irq_desc[irq].chip = &mpc1211_irq_type; irq_desc[irq].status = IRQ_DISABLED; irq_desc[irq].action = 0; irq_desc[irq].depth = 1; diff --git a/trunk/arch/sh/boards/overdrive/galileo.c b/trunk/arch/sh/boards/overdrive/galileo.c index 276fa11ee4ce..b055809d2ac1 100644 --- a/trunk/arch/sh/boards/overdrive/galileo.c +++ b/trunk/arch/sh/boards/overdrive/galileo.c @@ -536,7 +536,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) } void pcibios_align_resource(void *data, struct resource *res, - unsigned long size) + resource_size_t size) { } diff --git a/trunk/arch/sh/boards/overdrive/irq.c b/trunk/arch/sh/boards/overdrive/irq.c index 715e8feb3a68..2c13a7de6b22 100644 --- a/trunk/arch/sh/boards/overdrive/irq.c +++ b/trunk/arch/sh/boards/overdrive/irq.c @@ -150,7 +150,7 @@ static void enable_od_irq(unsigned int irq) static void __init make_od_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].handler = &od_irq_type; + irq_desc[irq].chip = &od_irq_type; disable_od_irq(irq); } diff --git a/trunk/arch/sh/boards/renesas/hs7751rvoip/irq.c b/trunk/arch/sh/boards/renesas/hs7751rvoip/irq.c index ed4c5b50ea45..52a98b524e1f 100644 --- a/trunk/arch/sh/boards/renesas/hs7751rvoip/irq.c +++ b/trunk/arch/sh/boards/renesas/hs7751rvoip/irq.c @@ -86,7 +86,7 @@ static struct hw_interrupt_type hs7751rvoip_irq_type = { static void make_hs7751rvoip_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].handler = &hs7751rvoip_irq_type; + irq_desc[irq].chip = &hs7751rvoip_irq_type; disable_hs7751rvoip_irq(irq); } diff --git a/trunk/arch/sh/boards/renesas/rts7751r2d/irq.c b/trunk/arch/sh/boards/renesas/rts7751r2d/irq.c index d36c9374aed1..e16915d9cda4 100644 --- a/trunk/arch/sh/boards/renesas/rts7751r2d/irq.c +++ b/trunk/arch/sh/boards/renesas/rts7751r2d/irq.c @@ -100,7 +100,7 @@ static struct hw_interrupt_type rts7751r2d_irq_type = { static void make_rts7751r2d_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].handler = &rts7751r2d_irq_type; + irq_desc[irq].chip = &rts7751r2d_irq_type; disable_rts7751r2d_irq(irq); } diff --git a/trunk/arch/sh/boards/renesas/systemh/irq.c b/trunk/arch/sh/boards/renesas/systemh/irq.c index 7a2eb10edb56..845979181059 100644 --- a/trunk/arch/sh/boards/renesas/systemh/irq.c +++ b/trunk/arch/sh/boards/renesas/systemh/irq.c @@ -105,7 +105,7 @@ static void end_systemh_irq(unsigned int irq) void make_systemh_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].handler = &systemh_irq_type; + irq_desc[irq].chip = &systemh_irq_type; disable_systemh_irq(irq); } diff --git a/trunk/arch/sh/boards/se/73180/irq.c b/trunk/arch/sh/boards/se/73180/irq.c index 70f04caad9a4..402735c7c898 100644 --- a/trunk/arch/sh/boards/se/73180/irq.c +++ b/trunk/arch/sh/boards/se/73180/irq.c @@ -85,7 +85,7 @@ void make_intreq_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].handler = &intreq_irq_type; + irq_desc[irq].chip = &intreq_irq_type; disable_intreq_irq(irq); } diff --git a/trunk/arch/sh/boards/superh/microdev/irq.c b/trunk/arch/sh/boards/superh/microdev/irq.c index efcbd86b7cd2..cb5999425d16 100644 --- a/trunk/arch/sh/boards/superh/microdev/irq.c +++ b/trunk/arch/sh/boards/superh/microdev/irq.c @@ -147,7 +147,7 @@ static void enable_microdev_irq(unsigned int irq) static void __init make_microdev_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].handler = µdev_irq_type; + irq_desc[irq].chip = µdev_irq_type; disable_microdev_irq(irq); } diff --git a/trunk/arch/sh/cchips/hd6446x/hd64461/setup.c b/trunk/arch/sh/cchips/hd6446x/hd64461/setup.c index f014b9bf6922..724db04cb392 100644 --- a/trunk/arch/sh/cchips/hd6446x/hd64461/setup.c +++ b/trunk/arch/sh/cchips/hd6446x/hd64461/setup.c @@ -154,7 +154,7 @@ int __init setup_hd64461(void) outw(0xffff, HD64461_NIMR); for (i = HD64461_IRQBASE; i < HD64461_IRQBASE + 16; i++) { - irq_desc[i].handler = &hd64461_irq_type; + irq_desc[i].chip = &hd64461_irq_type; } setup_irq(CONFIG_HD64461_IRQ, &irq0); diff --git a/trunk/arch/sh/cchips/hd6446x/hd64465/setup.c b/trunk/arch/sh/cchips/hd6446x/hd64465/setup.c index 68e4c4e4283d..cf9142c620b7 100644 --- a/trunk/arch/sh/cchips/hd6446x/hd64465/setup.c +++ b/trunk/arch/sh/cchips/hd6446x/hd64465/setup.c @@ -182,7 +182,7 @@ static int __init setup_hd64465(void) outw(0xffff, HD64465_REG_NIMR); /* mask all interrupts */ for (i = 0; i < HD64465_IRQ_NUM ; i++) { - irq_desc[HD64465_IRQ_BASE + i].handler = &hd64465_irq_type; + irq_desc[HD64465_IRQ_BASE + i].chip = &hd64465_irq_type; } setup_irq(CONFIG_HD64465_IRQ, &irq0); diff --git a/trunk/arch/sh/cchips/voyagergx/irq.c b/trunk/arch/sh/cchips/voyagergx/irq.c index 2ee330b3c38f..892214bade19 100644 --- a/trunk/arch/sh/cchips/voyagergx/irq.c +++ b/trunk/arch/sh/cchips/voyagergx/irq.c @@ -191,7 +191,7 @@ void __init setup_voyagergx_irq(void) flag = 1; } if (flag == 1) - irq_desc[VOYAGER_IRQ_BASE + i].handler = &voyagergx_irq_type; + irq_desc[VOYAGER_IRQ_BASE + i].chip = &voyagergx_irq_type; } setup_irq(IRQ_VOYAGER, &irq0); diff --git a/trunk/arch/sh/drivers/pci/pci.c b/trunk/arch/sh/drivers/pci/pci.c index c1669905abe4..3d546ba329cf 100644 --- a/trunk/arch/sh/drivers/pci/pci.c +++ b/trunk/arch/sh/drivers/pci/pci.c @@ -75,7 +75,7 @@ pcibios_update_resource(struct pci_dev *dev, struct resource *root, } void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) __attribute__ ((weak)); /* @@ -85,10 +85,10 @@ void pcibios_align_resource(void *data, struct resource *res, * modulo 0x400. */ void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; + resource_size_t start = res->start; if (start & 0x300) { start = (start + 0x3ff) & ~0x3ff; diff --git a/trunk/arch/sh/kernel/cpu/irq/imask.c b/trunk/arch/sh/kernel/cpu/irq/imask.c index baed9a550d39..a33ae3e0a5a5 100644 --- a/trunk/arch/sh/kernel/cpu/irq/imask.c +++ b/trunk/arch/sh/kernel/cpu/irq/imask.c @@ -105,6 +105,6 @@ static void shutdown_imask_irq(unsigned int irq) void make_imask_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].handler = &imask_irq_type; + irq_desc[irq].chip = &imask_irq_type; enable_irq(irq); } diff --git a/trunk/arch/sh/kernel/cpu/irq/intc2.c b/trunk/arch/sh/kernel/cpu/irq/intc2.c index 06e8afab32e4..30064bf6e154 100644 --- a/trunk/arch/sh/kernel/cpu/irq/intc2.c +++ b/trunk/arch/sh/kernel/cpu/irq/intc2.c @@ -137,7 +137,7 @@ void make_intc2_irq(unsigned int irq, local_irq_restore(flags); - irq_desc[irq].handler = &intc2_irq_type; + irq_desc[irq].chip = &intc2_irq_type; disable_intc2_irq(irq); } diff --git a/trunk/arch/sh/kernel/cpu/irq/ipr.c b/trunk/arch/sh/kernel/cpu/irq/ipr.c index e55150ed0856..0373b65c77f9 100644 --- a/trunk/arch/sh/kernel/cpu/irq/ipr.c +++ b/trunk/arch/sh/kernel/cpu/irq/ipr.c @@ -115,7 +115,7 @@ void make_ipr_irq(unsigned int irq, unsigned int addr, int pos, int priority) ipr_data[irq].shift = pos*4; /* POSition (0-3) x 4 means shift */ ipr_data[irq].priority = priority; - irq_desc[irq].handler = &ipr_irq_type; + irq_desc[irq].chip = &ipr_irq_type; disable_ipr_irq(irq); } diff --git a/trunk/arch/sh/kernel/cpu/irq/pint.c b/trunk/arch/sh/kernel/cpu/irq/pint.c index 95d6024fe1ae..714963a25bba 100644 --- a/trunk/arch/sh/kernel/cpu/irq/pint.c +++ b/trunk/arch/sh/kernel/cpu/irq/pint.c @@ -85,7 +85,7 @@ static void end_pint_irq(unsigned int irq) void make_pint_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].handler = &pint_irq_type; + irq_desc[irq].chip = &pint_irq_type; disable_pint_irq(irq); } diff --git a/trunk/arch/sh/kernel/irq.c b/trunk/arch/sh/kernel/irq.c index b56e79632f24..c2e07f7f3496 100644 --- a/trunk/arch/sh/kernel/irq.c +++ b/trunk/arch/sh/kernel/irq.c @@ -47,7 +47,7 @@ int show_interrupts(struct seq_file *p, void *v) goto unlock; seq_printf(p, "%3d: ",i); seq_printf(p, "%10u ", kstat_irqs(i)); - seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %14s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) diff --git a/trunk/arch/sh64/kernel/irq.c b/trunk/arch/sh64/kernel/irq.c index d69879c0e063..675776a5477e 100644 --- a/trunk/arch/sh64/kernel/irq.c +++ b/trunk/arch/sh64/kernel/irq.c @@ -65,7 +65,7 @@ int show_interrupts(struct seq_file *p, void *v) goto unlock; seq_printf(p, "%3d: ",i); seq_printf(p, "%10u ", kstat_irqs(i)); - seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %14s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) diff --git a/trunk/arch/sh64/kernel/irq_intc.c b/trunk/arch/sh64/kernel/irq_intc.c index fc99bf4e362c..fa730f5fe2e6 100644 --- a/trunk/arch/sh64/kernel/irq_intc.c +++ b/trunk/arch/sh64/kernel/irq_intc.c @@ -178,7 +178,7 @@ static void end_intc_irq(unsigned int irq) void make_intc_irq(unsigned int irq) { disable_irq_nosync(irq); - irq_desc[irq].handler = &intc_irq_type; + irq_desc[irq].chip = &intc_irq_type; disable_intc_irq(irq); } @@ -208,7 +208,7 @@ void __init init_IRQ(void) /* Set default: per-line enable/disable, priority driven ack/eoi */ for (i = 0; i < NR_INTC_IRQS; i++) { if (platform_int_priority[i] != NO_PRIORITY) { - irq_desc[i].handler = &intc_irq_type; + irq_desc[i].chip = &intc_irq_type; } } diff --git a/trunk/arch/sh64/kernel/pcibios.c b/trunk/arch/sh64/kernel/pcibios.c index 50c61dcb9fae..945920bc24db 100644 --- a/trunk/arch/sh64/kernel/pcibios.c +++ b/trunk/arch/sh64/kernel/pcibios.c @@ -69,10 +69,10 @@ pcibios_update_resource(struct pci_dev *dev, struct resource *root, * modulo 0x400. */ void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; + resource_size_t start = res->start; if (start & 0x300) { start = (start + 0x3ff) & ~0x3ff; diff --git a/trunk/arch/sh64/mach-cayman/irq.c b/trunk/arch/sh64/mach-cayman/irq.c index f797c84bfdd1..05eb7cdc26f0 100644 --- a/trunk/arch/sh64/mach-cayman/irq.c +++ b/trunk/arch/sh64/mach-cayman/irq.c @@ -187,7 +187,7 @@ void init_cayman_irq(void) } for (i=0; istart, res->end - res->start + 1); - return (void __iomem *) (res->start + offset); + return (void __iomem *)(unsigned long)(res->start + offset); } /* @@ -325,7 +325,7 @@ void *sbus_alloc_consistent(struct sbus_dev *sdev, long len, u32 *dma_addrp) res->name = sdev->prom_name; } - return (void *)res->start; + return (void *)(unsigned long)res->start; err_noiommu: release_resource(res); @@ -819,7 +819,9 @@ _sparc_io_get_info(char *buf, char **start, off_t fpos, int length, int *eof, if (p + 32 >= e) /* Better than nothing */ break; if ((nm = r->name) == 0) nm = "???"; - p += sprintf(p, "%08lx-%08lx: %s\n", r->start, r->end, nm); + p += sprintf(p, "%016llx-%016llx: %s\n", + (unsigned long long)r->start, + (unsigned long long)r->end, nm); } return p-buf; diff --git a/trunk/arch/sparc/kernel/pcic.c b/trunk/arch/sparc/kernel/pcic.c index bcfdddd0418a..5df3ebdc0ab1 100644 --- a/trunk/arch/sparc/kernel/pcic.c +++ b/trunk/arch/sparc/kernel/pcic.c @@ -860,7 +860,7 @@ char * __init pcibios_setup(char *str) } void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { } diff --git a/trunk/arch/sparc/kernel/setup.c b/trunk/arch/sparc/kernel/setup.c index a893a9cc9534..2e5d08ce217b 100644 --- a/trunk/arch/sparc/kernel/setup.c +++ b/trunk/arch/sparc/kernel/setup.c @@ -496,7 +496,7 @@ static int __init topology_init(void) if (!p) err = -ENOMEM; else - register_cpu(p, i, NULL); + register_cpu(p, i); } return err; diff --git a/trunk/arch/sparc64/kernel/irq.c b/trunk/arch/sparc64/kernel/irq.c index cc89b06d0178..ab9e640df228 100644 --- a/trunk/arch/sparc64/kernel/irq.c +++ b/trunk/arch/sparc64/kernel/irq.c @@ -151,7 +151,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %9s", irq_desc[i].handler->typename); + seq_printf(p, " %9s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -224,7 +224,7 @@ static inline struct ino_bucket *virt_irq_to_bucket(unsigned int virt_irq) #ifdef CONFIG_SMP static int irq_choose_cpu(unsigned int virt_irq) { - cpumask_t mask = irq_affinity[virt_irq]; + cpumask_t mask = irq_desc[virt_irq].affinity; int cpuid; if (cpus_equal(mask, CPU_MASK_ALL)) { @@ -414,8 +414,8 @@ void irq_install_pre_handler(int virt_irq, data->pre_handler_arg1 = arg1; data->pre_handler_arg2 = arg2; - desc->handler = (desc->handler == &sun4u_irq ? - &sun4u_irq_ack : &sun4v_irq_ack); + desc->chip = (desc->chip == &sun4u_irq ? + &sun4u_irq_ack : &sun4v_irq_ack); } unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) @@ -431,7 +431,7 @@ unsigned int build_irq(int inofixup, unsigned long iclr, unsigned long imap) bucket = &ivector_table[ino]; if (!bucket->virt_irq) { bucket->virt_irq = virt_irq_alloc(__irq(bucket)); - irq_desc[bucket->virt_irq].handler = &sun4u_irq; + irq_desc[bucket->virt_irq].chip = &sun4u_irq; } desc = irq_desc + bucket->virt_irq; @@ -465,7 +465,7 @@ unsigned int sun4v_build_irq(u32 devhandle, unsigned int devino) bucket = &ivector_table[sysino]; if (!bucket->virt_irq) { bucket->virt_irq = virt_irq_alloc(__irq(bucket)); - irq_desc[bucket->virt_irq].handler = &sun4v_irq; + irq_desc[bucket->virt_irq].chip = &sun4v_irq; } desc = irq_desc + bucket->virt_irq; diff --git a/trunk/arch/sparc64/kernel/pci.c b/trunk/arch/sparc64/kernel/pci.c index 6c9e3e94abaa..20ca9ec8fd3b 100644 --- a/trunk/arch/sparc64/kernel/pci.c +++ b/trunk/arch/sparc64/kernel/pci.c @@ -357,7 +357,7 @@ void pcibios_update_irq(struct pci_dev *pdev, int irq) } void pcibios_align_resource(void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { } diff --git a/trunk/arch/um/kernel/irq.c b/trunk/arch/um/kernel/irq.c index 2ffda012385e..fae43a3054a0 100644 --- a/trunk/arch/um/kernel/irq.c +++ b/trunk/arch/um/kernel/irq.c @@ -63,7 +63,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %14s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -451,13 +451,13 @@ void __init init_IRQ(void) irq_desc[TIMER_IRQ].status = IRQ_DISABLED; irq_desc[TIMER_IRQ].action = NULL; irq_desc[TIMER_IRQ].depth = 1; - irq_desc[TIMER_IRQ].handler = &SIGVTALRM_irq_type; + irq_desc[TIMER_IRQ].chip = &SIGVTALRM_irq_type; enable_irq(TIMER_IRQ); for (i = 1; i < NR_IRQS; i++) { irq_desc[i].status = IRQ_DISABLED; irq_desc[i].action = NULL; irq_desc[i].depth = 1; - irq_desc[i].handler = &normal_irq_type; + irq_desc[i].chip = &normal_irq_type; enable_irq(i); } } diff --git a/trunk/arch/v850/kernel/irq.c b/trunk/arch/v850/kernel/irq.c index 7a151c26f82e..858c45819aab 100644 --- a/trunk/arch/v850/kernel/irq.c +++ b/trunk/arch/v850/kernel/irq.c @@ -65,10 +65,10 @@ int show_interrupts(struct seq_file *p, void *v) int j; int count = 0; int num = -1; - const char *type_name = irq_desc[irq].handler->typename; + const char *type_name = irq_desc[irq].chip->typename; for (j = 0; j < NR_IRQS; j++) - if (irq_desc[j].handler->typename == type_name){ + if (irq_desc[j].chip->typename == type_name){ if (irq == j) num = count; count++; @@ -117,7 +117,7 @@ init_irq_handlers (int base_irq, int num, int interval, irq_desc[base_irq].status = IRQ_DISABLED; irq_desc[base_irq].action = NULL; irq_desc[base_irq].depth = 1; - irq_desc[base_irq].handler = irq_type; + irq_desc[base_irq].chip = irq_type; base_irq += interval; } } diff --git a/trunk/arch/v850/kernel/rte_mb_a_pci.c b/trunk/arch/v850/kernel/rte_mb_a_pci.c index ffbb6d073bf2..3a7c5c9c3ac6 100644 --- a/trunk/arch/v850/kernel/rte_mb_a_pci.c +++ b/trunk/arch/v850/kernel/rte_mb_a_pci.c @@ -329,7 +329,7 @@ void pcibios_fixup_bus(struct pci_bus *b) void pcibios_align_resource (void *data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { } diff --git a/trunk/arch/x86_64/Kconfig b/trunk/arch/x86_64/Kconfig index ccc4a7fb97a3..91039844820c 100644 --- a/trunk/arch/x86_64/Kconfig +++ b/trunk/arch/x86_64/Kconfig @@ -370,6 +370,8 @@ config HOTPLUG_CPU can be controlled through /sys/devices/system/cpu/cpu#. Say N if you want to disable CPU hotplug. +config ARCH_ENABLE_MEMORY_HOTPLUG + def_bool y config HPET_TIMER bool diff --git a/trunk/arch/x86_64/kernel/i8259.c b/trunk/arch/x86_64/kernel/i8259.c index 86b2c1e197aa..3dd1659427dc 100644 --- a/trunk/arch/x86_64/kernel/i8259.c +++ b/trunk/arch/x86_64/kernel/i8259.c @@ -235,7 +235,7 @@ void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); io_apic_irqs &= ~(1<typename); + seq_printf(p, " %14s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -118,6 +118,12 @@ asmlinkage unsigned int do_IRQ(struct pt_regs *regs) /* high bit used in ret_from_ code */ unsigned irq = ~regs->orig_rax; + if (unlikely(irq >= NR_IRQS)) { + printk(KERN_EMERG "%s: cannot handle IRQ %d\n", + __FUNCTION__, irq); + BUG(); + } + exit_idle(); irq_enter(); #ifdef CONFIG_DEBUG_STACKOVERFLOW @@ -140,13 +146,13 @@ void fixup_irqs(cpumask_t map) if (irq == 2) continue; - cpus_and(mask, irq_affinity[irq], map); + cpus_and(mask, irq_desc[irq].affinity, map); if (any_online_cpu(mask) == NR_CPUS) { printk("Breaking affinity for irq %i\n", irq); mask = map; } - if (irq_desc[irq].handler->set_affinity) - irq_desc[irq].handler->set_affinity(irq, mask); + if (irq_desc[irq].chip->set_affinity) + irq_desc[irq].chip->set_affinity(irq, mask); else if (irq_desc[irq].action && !(warned++)) printk("Cannot set affinity for irq %i\n", irq); } diff --git a/trunk/arch/x86_64/kernel/nmi.c b/trunk/arch/x86_64/kernel/nmi.c index 399489c93132..0ef9cf2bc45e 100644 --- a/trunk/arch/x86_64/kernel/nmi.c +++ b/trunk/arch/x86_64/kernel/nmi.c @@ -607,11 +607,13 @@ void set_nmi_callback(nmi_callback_t callback) vmalloc_sync_all(); rcu_assign_pointer(nmi_callback, callback); } +EXPORT_SYMBOL_GPL(set_nmi_callback); void unset_nmi_callback(void) { nmi_callback = dummy_nmi_callback; } +EXPORT_SYMBOL_GPL(unset_nmi_callback); #ifdef CONFIG_SYSCTL diff --git a/trunk/arch/xtensa/kernel/irq.c b/trunk/arch/xtensa/kernel/irq.c index 51f9bed455fa..1cf744ee0959 100644 --- a/trunk/arch/xtensa/kernel/irq.c +++ b/trunk/arch/xtensa/kernel/irq.c @@ -100,7 +100,7 @@ int show_interrupts(struct seq_file *p, void *v) for_each_online_cpu(j) seq_printf(p, "%10u ", kstat_cpu(j).irqs[i]); #endif - seq_printf(p, " %14s", irq_desc[i].handler->typename); + seq_printf(p, " %14s", irq_desc[i].chip->typename); seq_printf(p, " %s", action->name); for (action=action->next; action; action = action->next) @@ -181,7 +181,7 @@ void __init init_IRQ(void) int i; for (i=0; i < XTENSA_NR_IRQS; i++) - irq_desc[i].handler = &xtensa_irq_type; + irq_desc[i].chip = &xtensa_irq_type; cached_irq_mask = 0; diff --git a/trunk/arch/xtensa/kernel/pci.c b/trunk/arch/xtensa/kernel/pci.c index c6f471b9eaa0..eda029fc8972 100644 --- a/trunk/arch/xtensa/kernel/pci.c +++ b/trunk/arch/xtensa/kernel/pci.c @@ -71,13 +71,13 @@ static int pci_bus_count; * which might have be mirrored at 0x0100-0x03ff.. */ void -pcibios_align_resource(void *data, struct resource *res, unsigned long size, - unsigned long align) +pcibios_align_resource(void *data, struct resource *res, resource_size_t size, + resource_size_t align) { struct pci_dev *dev = data; if (res->flags & IORESOURCE_IO) { - unsigned long start = res->start; + resource_size_t start = res->start; if (size > 0x100) { printk(KERN_ERR "PCI: I/O Region %s/%d too large" diff --git a/trunk/drivers/amba/bus.c b/trunk/drivers/amba/bus.c index 889855d8d9f9..9e3e2a69c03a 100644 --- a/trunk/drivers/amba/bus.c +++ b/trunk/drivers/amba/bus.c @@ -180,8 +180,9 @@ static DEVICE_ATTR(name, S_IRUGO, show_##name, NULL) amba_attr(id, "%08x\n", dev->periphid); amba_attr(irq0, "%u\n", dev->irq[0]); amba_attr(irq1, "%u\n", dev->irq[1]); -amba_attr(resource, "\t%08lx\t%08lx\t%08lx\n", - dev->res.start, dev->res.end, dev->res.flags); +amba_attr(resource, "\t%016llx\t%016llx\t%016lx\n", + (unsigned long long)dev->res.start, (unsigned long long)dev->res.end, + dev->res.flags); /** * amba_device_register - register an AMBA device diff --git a/trunk/drivers/atm/ambassador.c b/trunk/drivers/atm/ambassador.c index 4b6bf19c39c0..4048681f36d5 100644 --- a/trunk/drivers/atm/ambassador.c +++ b/trunk/drivers/atm/ambassador.c @@ -2257,7 +2257,8 @@ static int __devinit amb_probe(struct pci_dev *pci_dev, const struct pci_device_ } PRINTD (DBG_INFO, "found Madge ATM adapter (amb) at" - " IO %lx, IRQ %u, MEM %p", pci_resource_start(pci_dev, 1), + " IO %llx, IRQ %u, MEM %p", + (unsigned long long)pci_resource_start(pci_dev, 1), irq, bus_to_virt(pci_resource_start(pci_dev, 0))); // check IO region diff --git a/trunk/drivers/atm/firestream.c b/trunk/drivers/atm/firestream.c index 1bca86edf570..d40605c1af73 100644 --- a/trunk/drivers/atm/firestream.c +++ b/trunk/drivers/atm/firestream.c @@ -1658,9 +1658,10 @@ static int __devinit fs_init (struct fs_dev *dev) func_enter (); pci_dev = dev->pci_dev; - printk (KERN_INFO "found a FireStream %d card, base %08lx, irq%d.\n", + printk (KERN_INFO "found a FireStream %d card, base %16llx, irq%d.\n", IS_FS50(dev)?50:155, - pci_resource_start(pci_dev, 0), dev->pci_dev->irq); + (unsigned long long)pci_resource_start(pci_dev, 0), + dev->pci_dev->irq); if (fs_debug & FS_DEBUG_INIT) my_hd ((unsigned char *) dev, sizeof (*dev)); diff --git a/trunk/drivers/block/loop.c b/trunk/drivers/block/loop.c index 3c74ea729fc7..18dd026f470d 100644 --- a/trunk/drivers/block/loop.c +++ b/trunk/drivers/block/loop.c @@ -210,7 +210,7 @@ static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec, { struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */ struct address_space *mapping = file->f_mapping; - struct address_space_operations *aops = mapping->a_ops; + const struct address_space_operations *aops = mapping->a_ops; pgoff_t index; unsigned offset, bv_offs; int len, ret; @@ -784,7 +784,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file, error = -EINVAL; if (S_ISREG(inode->i_mode) || S_ISBLK(inode->i_mode)) { - struct address_space_operations *aops = mapping->a_ops; + const struct address_space_operations *aops = mapping->a_ops; /* * If we can't read - sorry. If we only can't write - well, * it's going to be read-only. diff --git a/trunk/drivers/block/paride/pf.c b/trunk/drivers/block/paride/pf.c index 852b564e903a..1a9dee19efcf 100644 --- a/trunk/drivers/block/paride/pf.c +++ b/trunk/drivers/block/paride/pf.c @@ -707,7 +707,7 @@ static int pf_detect(void) if (pi_init(pf->pi, 0, conf[D_PRT], conf[D_MOD], conf[D_UNI], conf[D_PRO], conf[D_DLY], pf_scratch, PI_PF, verbose, pf->name)) { - if (!pf_probe(pf) && pf->disk) { + if (pf->disk && !pf_probe(pf)) { pf->present = 1; k++; } else diff --git a/trunk/drivers/block/rd.c b/trunk/drivers/block/rd.c index 940bfd7951e5..0378da04cfa2 100644 --- a/trunk/drivers/block/rd.c +++ b/trunk/drivers/block/rd.c @@ -191,7 +191,7 @@ static int ramdisk_set_page_dirty(struct page *page) return 0; } -static struct address_space_operations ramdisk_aops = { +static const struct address_space_operations ramdisk_aops = { .readpage = ramdisk_readpage, .prepare_write = ramdisk_prepare_write, .commit_write = ramdisk_commit_write, diff --git a/trunk/drivers/block/sx8.c b/trunk/drivers/block/sx8.c index 2ae08b343b93..8144ce9f4df0 100644 --- a/trunk/drivers/block/sx8.c +++ b/trunk/drivers/block/sx8.c @@ -1694,9 +1694,10 @@ static int carm_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) DPRINTK("waiting for probe_comp\n"); wait_for_completion(&host->probe_comp); - printk(KERN_INFO "%s: pci %s, ports %d, io %lx, irq %u, major %d\n", + printk(KERN_INFO "%s: pci %s, ports %d, io %llx, irq %u, major %d\n", host->name, pci_name(pdev), (int) CARM_MAX_PORTS, - pci_resource_start(pdev, 0), pdev->irq, host->major); + (unsigned long long)pci_resource_start(pdev, 0), + pdev->irq, host->major); carm_host_id++; pci_set_drvdata(pdev, host); diff --git a/trunk/drivers/char/Kconfig b/trunk/drivers/char/Kconfig index 410d70cb76fb..c40e487d9f5c 100644 --- a/trunk/drivers/char/Kconfig +++ b/trunk/drivers/char/Kconfig @@ -961,6 +961,7 @@ config PC8736x_GPIO config NSC_GPIO tristate "NatSemi Base GPIO Support" + depends on X86_32 # selected by SCx200_GPIO and PC8736x_GPIO # what about 2 selectors differing: m != y help diff --git a/trunk/drivers/char/applicom.c b/trunk/drivers/char/applicom.c index 9275d5e52e6d..72fb60765c45 100644 --- a/trunk/drivers/char/applicom.c +++ b/trunk/drivers/char/applicom.c @@ -209,13 +209,16 @@ static int __init applicom_init(void) RamIO = ioremap(dev->resource[0].start, LEN_RAM_IO); if (!RamIO) { - printk(KERN_INFO "ac.o: Failed to ioremap PCI memory space at 0x%lx\n", dev->resource[0].start); + printk(KERN_INFO "ac.o: Failed to ioremap PCI memory " + "space at 0x%llx\n", + (unsigned long long)dev->resource[0].start); pci_disable_device(dev); return -EIO; } - printk(KERN_INFO "Applicom %s found at mem 0x%lx, irq %d\n", - applicom_pci_devnames[dev->device-1], dev->resource[0].start, + printk(KERN_INFO "Applicom %s found at mem 0x%llx, irq %d\n", + applicom_pci_devnames[dev->device-1], + (unsigned long long)dev->resource[0].start, dev->irq); boardno = ac_register_board(dev->resource[0].start, RamIO,0); diff --git a/trunk/drivers/char/ipmi/ipmi_msghandler.c b/trunk/drivers/char/ipmi/ipmi_msghandler.c index 83ed6ae466a5..ad26f4b997c5 100644 --- a/trunk/drivers/char/ipmi/ipmi_msghandler.c +++ b/trunk/drivers/char/ipmi/ipmi_msghandler.c @@ -3738,11 +3738,8 @@ static int ipmi_init_msghandler(void) proc_ipmi_root->owner = THIS_MODULE; #endif /* CONFIG_PROC_FS */ - init_timer(&ipmi_timer); - ipmi_timer.data = 0; - ipmi_timer.function = ipmi_timeout; - ipmi_timer.expires = jiffies + IPMI_TIMEOUT_JIFFIES; - add_timer(&ipmi_timer); + setup_timer(&ipmi_timer, ipmi_timeout, 0); + mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES); atomic_notifier_chain_register(&panic_notifier_list, &panic_block); diff --git a/trunk/drivers/char/ipmi/ipmi_si_intf.c b/trunk/drivers/char/ipmi/ipmi_si_intf.c index 101c14b9b26d..bd4f2248b758 100644 --- a/trunk/drivers/char/ipmi/ipmi_si_intf.c +++ b/trunk/drivers/char/ipmi/ipmi_si_intf.c @@ -55,23 +55,6 @@ #include #include #include -#ifdef CONFIG_HIGH_RES_TIMERS -#include -# if defined(schedule_next_int) -/* Old high-res timer code, do translations. */ -# define get_arch_cycles(a) quick_update_jiffies_sub(a) -# define arch_cycles_per_jiffy cycles_per_jiffies -# endif -static inline void add_usec_to_timer(struct timer_list *t, long v) -{ - t->arch_cycle_expires += nsec_to_arch_cycle(v * 1000); - while (t->arch_cycle_expires >= arch_cycles_per_jiffy) - { - t->expires++; - t->arch_cycle_expires -= arch_cycles_per_jiffy; - } -} -#endif #include #include #include @@ -243,8 +226,6 @@ static int register_xaction_notifier(struct notifier_block * nb) return atomic_notifier_chain_register(&xaction_notifier_list, nb); } -static void si_restart_short_timer(struct smi_info *smi_info); - static void deliver_recv_msg(struct smi_info *smi_info, struct ipmi_smi_msg *msg) { @@ -768,7 +749,6 @@ static void sender(void *send_info, && (smi_info->curr_msg == NULL)) { start_next_msg(smi_info); - si_restart_short_timer(smi_info); } spin_unlock_irqrestore(&(smi_info->si_lock), flags); } @@ -833,37 +813,6 @@ static void request_events(void *send_info) static int initialized = 0; -/* Must be called with interrupts off and with the si_lock held. */ -static void si_restart_short_timer(struct smi_info *smi_info) -{ -#if defined(CONFIG_HIGH_RES_TIMERS) - unsigned long flags; - unsigned long jiffies_now; - unsigned long seq; - - if (del_timer(&(smi_info->si_timer))) { - /* If we don't delete the timer, then it will go off - immediately, anyway. So we only process if we - actually delete the timer. */ - - do { - seq = read_seqbegin_irqsave(&xtime_lock, flags); - jiffies_now = jiffies; - smi_info->si_timer.expires = jiffies_now; - smi_info->si_timer.arch_cycle_expires - = get_arch_cycles(jiffies_now); - } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - - add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC); - - add_timer(&(smi_info->si_timer)); - spin_lock_irqsave(&smi_info->count_lock, flags); - smi_info->timeout_restarts++; - spin_unlock_irqrestore(&smi_info->count_lock, flags); - } -#endif -} - static void smi_timeout(unsigned long data) { struct smi_info *smi_info = (struct smi_info *) data; @@ -904,31 +853,15 @@ static void smi_timeout(unsigned long data) /* If the state machine asks for a short delay, then shorten the timer timeout. */ if (smi_result == SI_SM_CALL_WITH_DELAY) { -#if defined(CONFIG_HIGH_RES_TIMERS) - unsigned long seq; -#endif spin_lock_irqsave(&smi_info->count_lock, flags); smi_info->short_timeouts++; spin_unlock_irqrestore(&smi_info->count_lock, flags); -#if defined(CONFIG_HIGH_RES_TIMERS) - do { - seq = read_seqbegin_irqsave(&xtime_lock, flags); - smi_info->si_timer.expires = jiffies; - smi_info->si_timer.arch_cycle_expires - = get_arch_cycles(smi_info->si_timer.expires); - } while (read_seqretry_irqrestore(&xtime_lock, seq, flags)); - add_usec_to_timer(&smi_info->si_timer, SI_SHORT_TIMEOUT_USEC); -#else smi_info->si_timer.expires = jiffies + 1; -#endif } else { spin_lock_irqsave(&smi_info->count_lock, flags); smi_info->long_timeouts++; spin_unlock_irqrestore(&smi_info->count_lock, flags); smi_info->si_timer.expires = jiffies + SI_TIMEOUT_JIFFIES; -#if defined(CONFIG_HIGH_RES_TIMERS) - smi_info->si_timer.arch_cycle_expires = 0; -#endif } do_add_timer: diff --git a/trunk/drivers/char/ipmi/ipmi_watchdog.c b/trunk/drivers/char/ipmi/ipmi_watchdog.c index 8f8867170973..1a0a19c53605 100644 --- a/trunk/drivers/char/ipmi/ipmi_watchdog.c +++ b/trunk/drivers/char/ipmi/ipmi_watchdog.c @@ -949,9 +949,10 @@ static int wdog_reboot_handler(struct notifier_block *this, /* Disable the WDT if we are shutting down. */ ipmi_watchdog_state = WDOG_TIMEOUT_NONE; panic_halt_ipmi_set_timeout(); - } else { + } else if (ipmi_watchdog_state != WDOG_TIMEOUT_NONE) { /* Set a long timer to let the reboot happens, but - reboot if it hangs. */ + reboot if it hangs, but only if the watchdog + timer was already running. */ timeout = 120; pretimeout = 0; ipmi_watchdog_state = WDOG_TIMEOUT_RESET; @@ -973,16 +974,17 @@ static int wdog_panic_handler(struct notifier_block *this, { static int panic_event_handled = 0; - /* On a panic, if we have a panic timeout, make sure that the thing - reboots, even if it hangs during that panic. */ - if (watchdog_user && !panic_event_handled) { - /* Make sure the panic doesn't hang, and make sure we - do this only once. */ + /* On a panic, if we have a panic timeout, make sure to extend + the watchdog timer to a reasonable value to complete the + panic, if the watchdog timer is running. Plus the + pretimeout is meaningless at panic time. */ + if (watchdog_user && !panic_event_handled && + ipmi_watchdog_state != WDOG_TIMEOUT_NONE) { + /* Make sure we do this only once. */ panic_event_handled = 1; timeout = 255; pretimeout = 0; - ipmi_watchdog_state = WDOG_TIMEOUT_RESET; panic_halt_ipmi_set_timeout(); } diff --git a/trunk/drivers/char/istallion.c b/trunk/drivers/char/istallion.c index ef20c1fc9c4c..216c79256de3 100644 --- a/trunk/drivers/char/istallion.c +++ b/trunk/drivers/char/istallion.c @@ -42,13 +42,12 @@ #include #include #include +#include #include #include -#ifdef CONFIG_PCI #include -#endif /*****************************************************************************/ @@ -137,6 +136,10 @@ static stlconf_t stli_brdconf[] = { static int stli_nrbrds = ARRAY_SIZE(stli_brdconf); +/* stli_lock must NOT be taken holding brd_lock */ +static spinlock_t stli_lock; /* TTY logic lock */ +static spinlock_t brd_lock; /* Board logic lock */ + /* * There is some experimental EISA board detection code in this driver. * By default it is disabled, but for those that want to try it out, @@ -173,14 +176,6 @@ static char *stli_serialname = "ttyE"; static struct tty_driver *stli_serial; -/* - * We will need to allocate a temporary write buffer for chars that - * come direct from user space. The problem is that a copy from user - * space might cause a page fault (typically on a system that is - * swapping!). All ports will share one buffer - since if the system - * is already swapping a shared buffer won't make things any worse. - */ -static char *stli_tmpwritebuf; #define STLI_TXBUFSIZE 4096 @@ -419,7 +414,7 @@ static int stli_eisamempsize = ARRAY_SIZE(stli_eisamemprobeaddrs); #endif static struct pci_device_id istallion_pci_tbl[] = { - { PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, + { PCI_DEVICE(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA), }, { 0 } }; MODULE_DEVICE_TABLE(pci, istallion_pci_tbl); @@ -682,7 +677,7 @@ static int stli_startbrd(stlibrd_t *brdp); static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp); static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp); static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg); -static void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp); +static void stli_brdpoll(stlibrd_t *brdp, cdkhdr_t __iomem *hdrp); static void stli_poll(unsigned long arg); static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp); static int stli_initopen(stlibrd_t *brdp, stliport_t *portp); @@ -693,7 +688,8 @@ static void stli_dohangup(void *arg); static int stli_setport(stliport_t *portp); static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback); static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback); -static void stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp); +static void __stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback); +static void stli_dodelaycmd(stliport_t *portp, cdkctrl_t __iomem *cp); static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp); static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts); static long stli_mktiocm(unsigned long sigvalue); @@ -799,18 +795,8 @@ static struct class *istallion_class; static int __init istallion_module_init(void) { - unsigned long flags; - -#ifdef DEBUG - printk("init_module()\n"); -#endif - - save_flags(flags); - cli(); stli_init(); - restore_flags(flags); - - return(0); + return 0; } /*****************************************************************************/ @@ -819,33 +805,24 @@ static void __exit istallion_module_exit(void) { stlibrd_t *brdp; stliport_t *portp; - unsigned long flags; int i, j; -#ifdef DEBUG - printk("cleanup_module()\n"); -#endif - printk(KERN_INFO "Unloading %s: version %s\n", stli_drvtitle, stli_drvversion); - save_flags(flags); - cli(); - -/* - * Free up all allocated resources used by the ports. This includes - * memory and interrupts. - */ + /* + * Free up all allocated resources used by the ports. This includes + * memory and interrupts. + */ if (stli_timeron) { stli_timeron = 0; - del_timer(&stli_timerlist); + del_timer_sync(&stli_timerlist); } i = tty_unregister_driver(stli_serial); if (i) { printk("STALLION: failed to un-register tty driver, " "errno=%d\n", -i); - restore_flags(flags); return; } put_tty_driver(stli_serial); @@ -859,16 +836,15 @@ static void __exit istallion_module_exit(void) printk("STALLION: failed to un-register serial memory device, " "errno=%d\n", -i); - kfree(stli_tmpwritebuf); kfree(stli_txcookbuf); for (i = 0; (i < stli_nrbrds); i++) { - if ((brdp = stli_brds[i]) == (stlibrd_t *) NULL) + if ((brdp = stli_brds[i]) == NULL) continue; for (j = 0; (j < STL_MAXPORTS); j++) { portp = brdp->ports[j]; - if (portp != (stliport_t *) NULL) { - if (portp->tty != (struct tty_struct *) NULL) + if (portp != NULL) { + if (portp->tty != NULL) tty_hangup(portp->tty); kfree(portp); } @@ -878,10 +854,8 @@ static void __exit istallion_module_exit(void) if (brdp->iosize > 0) release_region(brdp->iobase, brdp->iosize); kfree(brdp); - stli_brds[i] = (stlibrd_t *) NULL; + stli_brds[i] = NULL; } - - restore_flags(flags); } module_init(istallion_module_init); @@ -895,19 +869,15 @@ module_exit(istallion_module_exit); static void stli_argbrds(void) { - stlconf_t conf; - stlibrd_t *brdp; - int i; - -#ifdef DEBUG - printk("stli_argbrds()\n"); -#endif + stlconf_t conf; + stlibrd_t *brdp; + int i; for (i = stli_nrbrds; i < ARRAY_SIZE(stli_brdsp); i++) { memset(&conf, 0, sizeof(conf)); if (stli_parsebrd(&conf, stli_brdsp[i]) == 0) continue; - if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL) + if ((brdp = stli_allocbrd()) == NULL) continue; stli_nrbrds = i + 1; brdp->brdnr = i; @@ -926,9 +896,9 @@ static void stli_argbrds(void) static unsigned long stli_atol(char *str) { - unsigned long val; - int base, c; - char *sp; + unsigned long val; + int base, c; + char *sp; val = 0; sp = str; @@ -962,15 +932,11 @@ static unsigned long stli_atol(char *str) static int stli_parsebrd(stlconf_t *confp, char **argp) { - char *sp; - int i; - -#ifdef DEBUG - printk("stli_parsebrd(confp=%x,argp=%x)\n", (int) confp, (int) argp); -#endif + char *sp; + int i; - if ((argp[0] == (char *) NULL) || (*argp[0] == 0)) - return(0); + if (argp[0] == NULL || *argp[0] == 0) + return 0; for (sp = argp[0], i = 0; ((*sp != 0) && (i < 25)); sp++, i++) *sp = TOLOWER(*sp); @@ -985,9 +951,9 @@ static int stli_parsebrd(stlconf_t *confp, char **argp) } confp->brdtype = stli_brdstr[i].type; - if ((argp[1] != (char *) NULL) && (*argp[1] != 0)) + if (argp[1] != NULL && *argp[1] != 0) confp->ioaddr1 = stli_atol(argp[1]); - if ((argp[2] != (char *) NULL) && (*argp[2] != 0)) + if (argp[2] != NULL && *argp[2] != 0) confp->memaddr = stli_atol(argp[2]); return(1); } @@ -998,34 +964,29 @@ static int stli_parsebrd(stlconf_t *confp, char **argp) static int stli_open(struct tty_struct *tty, struct file *filp) { - stlibrd_t *brdp; - stliport_t *portp; - unsigned int minordev; - int brdnr, portnr, rc; - -#ifdef DEBUG - printk("stli_open(tty=%x,filp=%x): device=%s\n", (int) tty, - (int) filp, tty->name); -#endif + stlibrd_t *brdp; + stliport_t *portp; + unsigned int minordev; + int brdnr, portnr, rc; minordev = tty->index; brdnr = MINOR2BRD(minordev); if (brdnr >= stli_nrbrds) - return(-ENODEV); + return -ENODEV; brdp = stli_brds[brdnr]; - if (brdp == (stlibrd_t *) NULL) - return(-ENODEV); + if (brdp == NULL) + return -ENODEV; if ((brdp->state & BST_STARTED) == 0) - return(-ENODEV); + return -ENODEV; portnr = MINOR2PORT(minordev); if ((portnr < 0) || (portnr > brdp->nrports)) - return(-ENODEV); + return -ENODEV; portp = brdp->ports[portnr]; - if (portp == (stliport_t *) NULL) - return(-ENODEV); + if (portp == NULL) + return -ENODEV; if (portp->devnr < 1) - return(-ENODEV); + return -ENODEV; /* @@ -1037,8 +998,8 @@ static int stli_open(struct tty_struct *tty, struct file *filp) if (portp->flags & ASYNC_CLOSING) { interruptible_sleep_on(&portp->close_wait); if (portp->flags & ASYNC_HUP_NOTIFY) - return(-EAGAIN); - return(-ERESTARTSYS); + return -EAGAIN; + return -ERESTARTSYS; } /* @@ -1054,7 +1015,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp) wait_event_interruptible(portp->raw_wait, !test_bit(ST_INITIALIZING, &portp->state)); if (signal_pending(current)) - return(-ERESTARTSYS); + return -ERESTARTSYS; if ((portp->flags & ASYNC_INITIALIZED) == 0) { set_bit(ST_INITIALIZING, &portp->state); @@ -1065,7 +1026,7 @@ static int stli_open(struct tty_struct *tty, struct file *filp) clear_bit(ST_INITIALIZING, &portp->state); wake_up_interruptible(&portp->raw_wait); if (rc < 0) - return(rc); + return rc; } /* @@ -1077,8 +1038,8 @@ static int stli_open(struct tty_struct *tty, struct file *filp) if (portp->flags & ASYNC_CLOSING) { interruptible_sleep_on(&portp->close_wait); if (portp->flags & ASYNC_HUP_NOTIFY) - return(-EAGAIN); - return(-ERESTARTSYS); + return -EAGAIN; + return -ERESTARTSYS; } /* @@ -1088,38 +1049,33 @@ static int stli_open(struct tty_struct *tty, struct file *filp) */ if (!(filp->f_flags & O_NONBLOCK)) { if ((rc = stli_waitcarrier(brdp, portp, filp)) != 0) - return(rc); + return rc; } portp->flags |= ASYNC_NORMAL_ACTIVE; - return(0); + return 0; } /*****************************************************************************/ static void stli_close(struct tty_struct *tty, struct file *filp) { - stlibrd_t *brdp; - stliport_t *portp; - unsigned long flags; - -#ifdef DEBUG - printk("stli_close(tty=%x,filp=%x)\n", (int) tty, (int) filp); -#endif + stlibrd_t *brdp; + stliport_t *portp; + unsigned long flags; portp = tty->driver_data; - if (portp == (stliport_t *) NULL) + if (portp == NULL) return; - save_flags(flags); - cli(); + spin_lock_irqsave(&stli_lock, flags); if (tty_hung_up_p(filp)) { - restore_flags(flags); + spin_unlock_irqrestore(&stli_lock, flags); return; } if ((tty->count == 1) && (portp->refcount != 1)) portp->refcount = 1; if (portp->refcount-- > 1) { - restore_flags(flags); + spin_unlock_irqrestore(&stli_lock, flags); return; } @@ -1134,6 +1090,8 @@ static void stli_close(struct tty_struct *tty, struct file *filp) if (tty == stli_txcooktty) stli_flushchars(tty); tty->closing = 1; + spin_unlock_irqrestore(&stli_lock, flags); + if (portp->closing_wait != ASYNC_CLOSING_WAIT_NONE) tty_wait_until_sent(tty, portp->closing_wait); @@ -1157,7 +1115,7 @@ static void stli_close(struct tty_struct *tty, struct file *filp) stli_flushbuffer(tty); tty->closing = 0; - portp->tty = (struct tty_struct *) NULL; + portp->tty = NULL; if (portp->openwaitcnt) { if (portp->close_delay) @@ -1167,7 +1125,6 @@ static void stli_close(struct tty_struct *tty, struct file *filp) portp->flags &= ~(ASYNC_NORMAL_ACTIVE|ASYNC_CLOSING); wake_up_interruptible(&portp->close_wait); - restore_flags(flags); } /*****************************************************************************/ @@ -1182,45 +1139,41 @@ static void stli_close(struct tty_struct *tty, struct file *filp) static int stli_initopen(stlibrd_t *brdp, stliport_t *portp) { - struct tty_struct *tty; - asynotify_t nt; - asyport_t aport; - int rc; - -#ifdef DEBUG - printk("stli_initopen(brdp=%x,portp=%x)\n", (int) brdp, (int) portp); -#endif + struct tty_struct *tty; + asynotify_t nt; + asyport_t aport; + int rc; if ((rc = stli_rawopen(brdp, portp, 0, 1)) < 0) - return(rc); + return rc; memset(&nt, 0, sizeof(asynotify_t)); nt.data = (DT_TXLOW | DT_TXEMPTY | DT_RXBUSY | DT_RXBREAK); nt.signal = SG_DCD; if ((rc = stli_cmdwait(brdp, portp, A_SETNOTIFY, &nt, sizeof(asynotify_t), 0)) < 0) - return(rc); + return rc; tty = portp->tty; - if (tty == (struct tty_struct *) NULL) - return(-ENODEV); + if (tty == NULL) + return -ENODEV; stli_mkasyport(portp, &aport, tty->termios); if ((rc = stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0)) < 0) - return(rc); + return rc; set_bit(ST_GETSIGS, &portp->state); if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, &portp->asig, sizeof(asysigs_t), 1)) < 0) - return(rc); + return rc; if (test_and_clear_bit(ST_GETSIGS, &portp->state)) portp->sigs = stli_mktiocm(portp->asig.sigvalue); stli_mkasysigs(&portp->asig, 1, 1); if ((rc = stli_cmdwait(brdp, portp, A_SETSIGNALS, &portp->asig, sizeof(asysigs_t), 0)) < 0) - return(rc); + return rc; - return(0); + return 0; } /*****************************************************************************/ @@ -1234,22 +1187,15 @@ static int stli_initopen(stlibrd_t *brdp, stliport_t *portp) static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait) { - volatile cdkhdr_t *hdrp; - volatile cdkctrl_t *cp; - volatile unsigned char *bits; - unsigned long flags; - int rc; - -#ifdef DEBUG - printk("stli_rawopen(brdp=%x,portp=%x,arg=%x,wait=%d)\n", - (int) brdp, (int) portp, (int) arg, wait); -#endif + cdkhdr_t __iomem *hdrp; + cdkctrl_t __iomem *cp; + unsigned char __iomem *bits; + unsigned long flags; + int rc; /* * Send a message to the slave to open this port. */ - save_flags(flags); - cli(); /* * Slave is already closing this port. This can happen if a hangup @@ -1260,7 +1206,6 @@ static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, i wait_event_interruptible(portp->raw_wait, !test_bit(ST_CLOSING, &portp->state)); if (signal_pending(current)) { - restore_flags(flags); return -ERESTARTSYS; } @@ -1269,19 +1214,20 @@ static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, i * memory. Once the message is in set the service bits to say that * this port wants service. */ + spin_lock_irqsave(&brd_lock, flags); EBRDENABLE(brdp); - cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; - cp->openarg = arg; - cp->open = 1; - hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + + cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; + writel(arg, &cp->openarg); + writeb(1, &cp->open); + hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); + bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + portp->portidx; - *bits |= portp->portbit; + writeb(readb(bits) | portp->portbit, bits); EBRDDISABLE(brdp); if (wait == 0) { - restore_flags(flags); - return(0); + spin_unlock_irqrestore(&brd_lock, flags); + return 0; } /* @@ -1290,15 +1236,16 @@ static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, i */ rc = 0; set_bit(ST_OPENING, &portp->state); + spin_unlock_irqrestore(&brd_lock, flags); + wait_event_interruptible(portp->raw_wait, !test_bit(ST_OPENING, &portp->state)); if (signal_pending(current)) rc = -ERESTARTSYS; - restore_flags(flags); if ((rc == 0) && (portp->rc != 0)) rc = -EIO; - return(rc); + return rc; } /*****************************************************************************/ @@ -1311,19 +1258,11 @@ static int stli_rawopen(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, i static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, int wait) { - volatile cdkhdr_t *hdrp; - volatile cdkctrl_t *cp; - volatile unsigned char *bits; - unsigned long flags; - int rc; - -#ifdef DEBUG - printk("stli_rawclose(brdp=%x,portp=%x,arg=%x,wait=%d)\n", - (int) brdp, (int) portp, (int) arg, wait); -#endif - - save_flags(flags); - cli(); + cdkhdr_t __iomem *hdrp; + cdkctrl_t __iomem *cp; + unsigned char __iomem *bits; + unsigned long flags; + int rc; /* * Slave is already closing this port. This can happen if a hangup @@ -1333,7 +1272,6 @@ static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, wait_event_interruptible(portp->raw_wait, !test_bit(ST_CLOSING, &portp->state)); if (signal_pending(current)) { - restore_flags(flags); return -ERESTARTSYS; } } @@ -1341,21 +1279,22 @@ static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, /* * Write the close command into shared memory. */ + spin_lock_irqsave(&brd_lock, flags); EBRDENABLE(brdp); - cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; - cp->closearg = arg; - cp->close = 1; - hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + + cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; + writel(arg, &cp->closearg); + writeb(1, &cp->close); + hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); + bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + portp->portidx; - *bits |= portp->portbit; + writeb(readb(bits) |portp->portbit, bits); EBRDDISABLE(brdp); set_bit(ST_CLOSING, &portp->state); - if (wait == 0) { - restore_flags(flags); - return(0); - } + spin_unlock_irqrestore(&brd_lock, flags); + + if (wait == 0) + return 0; /* * Slave is in action, so now we must wait for the open acknowledgment @@ -1366,11 +1305,10 @@ static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, !test_bit(ST_CLOSING, &portp->state)); if (signal_pending(current)) rc = -ERESTARTSYS; - restore_flags(flags); if ((rc == 0) && (portp->rc != 0)) rc = -EIO; - return(rc); + return rc; } /*****************************************************************************/ @@ -1384,36 +1322,21 @@ static int stli_rawclose(stlibrd_t *brdp, stliport_t *portp, unsigned long arg, static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback) { - unsigned long flags; - -#ifdef DEBUG - printk("stli_cmdwait(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d," - "copyback=%d)\n", (int) brdp, (int) portp, (int) cmd, - (int) arg, size, copyback); -#endif - - save_flags(flags); - cli(); wait_event_interruptible(portp->raw_wait, !test_bit(ST_CMDING, &portp->state)); - if (signal_pending(current)) { - restore_flags(flags); + if (signal_pending(current)) return -ERESTARTSYS; - } stli_sendcmd(brdp, portp, cmd, arg, size, copyback); wait_event_interruptible(portp->raw_wait, !test_bit(ST_CMDING, &portp->state)); - if (signal_pending(current)) { - restore_flags(flags); + if (signal_pending(current)) return -ERESTARTSYS; - } - restore_flags(flags); if (portp->rc != 0) - return(-EIO); - return(0); + return -EIO; + return 0; } /*****************************************************************************/ @@ -1425,22 +1348,18 @@ static int stli_cmdwait(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, v static int stli_setport(stliport_t *portp) { - stlibrd_t *brdp; - asyport_t aport; - -#ifdef DEBUG - printk("stli_setport(portp=%x)\n", (int) portp); -#endif + stlibrd_t *brdp; + asyport_t aport; - if (portp == (stliport_t *) NULL) - return(-ENODEV); - if (portp->tty == (struct tty_struct *) NULL) - return(-ENODEV); - if ((portp->brdnr < 0) && (portp->brdnr >= stli_nrbrds)) - return(-ENODEV); + if (portp == NULL) + return -ENODEV; + if (portp->tty == NULL) + return -ENODEV; + if (portp->brdnr < 0 && portp->brdnr >= stli_nrbrds) + return -ENODEV; brdp = stli_brds[portp->brdnr]; - if (brdp == (stlibrd_t *) NULL) - return(-ENODEV); + if (brdp == NULL) + return -ENODEV; stli_mkasyport(portp, &aport, portp->tty->termios); return(stli_cmdwait(brdp, portp, A_SETPORT, &aport, sizeof(asyport_t), 0)); @@ -1455,13 +1374,8 @@ static int stli_setport(stliport_t *portp) static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *filp) { - unsigned long flags; - int rc, doclocal; - -#ifdef DEBUG - printk("stli_waitcarrier(brdp=%x,portp=%x,filp=%x)\n", - (int) brdp, (int) portp, (int) filp); -#endif + unsigned long flags; + int rc, doclocal; rc = 0; doclocal = 0; @@ -1469,11 +1383,11 @@ static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *fil if (portp->tty->termios->c_cflag & CLOCAL) doclocal++; - save_flags(flags); - cli(); + spin_lock_irqsave(&stli_lock, flags); portp->openwaitcnt++; if (! tty_hung_up_p(filp)) portp->refcount--; + spin_unlock_irqrestore(&stli_lock, flags); for (;;) { stli_mkasysigs(&portp->asig, 1, 1); @@ -1499,12 +1413,13 @@ static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *fil interruptible_sleep_on(&portp->open_wait); } + spin_lock_irqsave(&stli_lock, flags); if (! tty_hung_up_p(filp)) portp->refcount++; portp->openwaitcnt--; - restore_flags(flags); + spin_unlock_irqrestore(&stli_lock, flags); - return(rc); + return rc; } /*****************************************************************************/ @@ -1517,46 +1432,38 @@ static int stli_waitcarrier(stlibrd_t *brdp, stliport_t *portp, struct file *fil static int stli_write(struct tty_struct *tty, const unsigned char *buf, int count) { - volatile cdkasy_t *ap; - volatile cdkhdr_t *hdrp; - volatile unsigned char *bits; - unsigned char *shbuf, *chbuf; - stliport_t *portp; - stlibrd_t *brdp; - unsigned int len, stlen, head, tail, size; - unsigned long flags; - -#ifdef DEBUG - printk("stli_write(tty=%x,buf=%x,count=%d)\n", - (int) tty, (int) buf, count); -#endif + cdkasy_t __iomem *ap; + cdkhdr_t __iomem *hdrp; + unsigned char __iomem *bits; + unsigned char __iomem *shbuf; + unsigned char *chbuf; + stliport_t *portp; + stlibrd_t *brdp; + unsigned int len, stlen, head, tail, size; + unsigned long flags; - if ((tty == (struct tty_struct *) NULL) || - (stli_tmpwritebuf == (char *) NULL)) - return(0); if (tty == stli_txcooktty) stli_flushchars(tty); portp = tty->driver_data; - if (portp == (stliport_t *) NULL) - return(0); + if (portp == NULL) + return 0; if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) - return(0); + return 0; brdp = stli_brds[portp->brdnr]; - if (brdp == (stlibrd_t *) NULL) - return(0); + if (brdp == NULL) + return 0; chbuf = (unsigned char *) buf; /* * All data is now local, shove as much as possible into shared memory. */ - save_flags(flags); - cli(); + spin_lock_irqsave(&brd_lock, flags); EBRDENABLE(brdp); - ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr); - head = (unsigned int) ap->txq.head; - tail = (unsigned int) ap->txq.tail; - if (tail != ((unsigned int) ap->txq.tail)) - tail = (unsigned int) ap->txq.tail; + ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); + head = (unsigned int) readw(&ap->txq.head); + tail = (unsigned int) readw(&ap->txq.tail); + if (tail != ((unsigned int) readw(&ap->txq.tail))) + tail = (unsigned int) readw(&ap->txq.tail); size = portp->txsize; if (head >= tail) { len = size - (head - tail) - 1; @@ -1568,11 +1475,11 @@ static int stli_write(struct tty_struct *tty, const unsigned char *buf, int coun len = MIN(len, count); count = 0; - shbuf = (char *) EBRDGETMEMPTR(brdp, portp->txoffset); + shbuf = (char __iomem *) EBRDGETMEMPTR(brdp, portp->txoffset); while (len > 0) { stlen = MIN(len, stlen); - memcpy((shbuf + head), chbuf, stlen); + memcpy_toio(shbuf + head, chbuf, stlen); chbuf += stlen; len -= stlen; count += stlen; @@ -1583,20 +1490,19 @@ static int stli_write(struct tty_struct *tty, const unsigned char *buf, int coun } } - ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr); - ap->txq.head = head; + ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); + writew(head, &ap->txq.head); if (test_bit(ST_TXBUSY, &portp->state)) { - if (ap->changed.data & DT_TXEMPTY) - ap->changed.data &= ~DT_TXEMPTY; + if (readl(&ap->changed.data) & DT_TXEMPTY) + writel(readl(&ap->changed.data) & ~DT_TXEMPTY, &ap->changed.data); } - hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + + hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); + bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + portp->portidx; - *bits |= portp->portbit; + writeb(readb(bits) | portp->portbit, bits); set_bit(ST_TXBUSY, &portp->state); EBRDDISABLE(brdp); - - restore_flags(flags); + spin_unlock_irqrestore(&brd_lock, flags); return(count); } @@ -1613,14 +1519,8 @@ static int stli_write(struct tty_struct *tty, const unsigned char *buf, int coun static void stli_putchar(struct tty_struct *tty, unsigned char ch) { -#ifdef DEBUG - printk("stli_putchar(tty=%x,ch=%x)\n", (int) tty, (int) ch); -#endif - - if (tty == (struct tty_struct *) NULL) - return; if (tty != stli_txcooktty) { - if (stli_txcooktty != (struct tty_struct *) NULL) + if (stli_txcooktty != NULL) stli_flushchars(stli_txcooktty); stli_txcooktty = tty; } @@ -1640,29 +1540,26 @@ static void stli_putchar(struct tty_struct *tty, unsigned char ch) static void stli_flushchars(struct tty_struct *tty) { - volatile cdkhdr_t *hdrp; - volatile unsigned char *bits; - volatile cdkasy_t *ap; - struct tty_struct *cooktty; - stliport_t *portp; - stlibrd_t *brdp; - unsigned int len, stlen, head, tail, size, count, cooksize; - unsigned char *buf, *shbuf; - unsigned long flags; - -#ifdef DEBUG - printk("stli_flushchars(tty=%x)\n", (int) tty); -#endif + cdkhdr_t __iomem *hdrp; + unsigned char __iomem *bits; + cdkasy_t __iomem *ap; + struct tty_struct *cooktty; + stliport_t *portp; + stlibrd_t *brdp; + unsigned int len, stlen, head, tail, size, count, cooksize; + unsigned char *buf; + unsigned char __iomem *shbuf; + unsigned long flags; cooksize = stli_txcooksize; cooktty = stli_txcooktty; stli_txcooksize = 0; stli_txcookrealsize = 0; - stli_txcooktty = (struct tty_struct *) NULL; + stli_txcooktty = NULL; - if (tty == (struct tty_struct *) NULL) + if (tty == NULL) return; - if (cooktty == (struct tty_struct *) NULL) + if (cooktty == NULL) return; if (tty != cooktty) tty = cooktty; @@ -1670,23 +1567,22 @@ static void stli_flushchars(struct tty_struct *tty) return; portp = tty->driver_data; - if (portp == (stliport_t *) NULL) + if (portp == NULL) return; if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) return; brdp = stli_brds[portp->brdnr]; - if (brdp == (stlibrd_t *) NULL) + if (brdp == NULL) return; - save_flags(flags); - cli(); + spin_lock_irqsave(&brd_lock, flags); EBRDENABLE(brdp); - ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr); - head = (unsigned int) ap->txq.head; - tail = (unsigned int) ap->txq.tail; - if (tail != ((unsigned int) ap->txq.tail)) - tail = (unsigned int) ap->txq.tail; + ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); + head = (unsigned int) readw(&ap->txq.head); + tail = (unsigned int) readw(&ap->txq.tail); + if (tail != ((unsigned int) readw(&ap->txq.tail))) + tail = (unsigned int) readw(&ap->txq.tail); size = portp->txsize; if (head >= tail) { len = size - (head - tail) - 1; @@ -1703,7 +1599,7 @@ static void stli_flushchars(struct tty_struct *tty) while (len > 0) { stlen = MIN(len, stlen); - memcpy((shbuf + head), buf, stlen); + memcpy_toio(shbuf + head, buf, stlen); buf += stlen; len -= stlen; count += stlen; @@ -1714,73 +1610,66 @@ static void stli_flushchars(struct tty_struct *tty) } } - ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr); - ap->txq.head = head; + ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); + writew(head, &ap->txq.head); if (test_bit(ST_TXBUSY, &portp->state)) { - if (ap->changed.data & DT_TXEMPTY) - ap->changed.data &= ~DT_TXEMPTY; + if (readl(&ap->changed.data) & DT_TXEMPTY) + writel(readl(&ap->changed.data) & ~DT_TXEMPTY, &ap->changed.data); } - hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + + hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); + bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + portp->portidx; - *bits |= portp->portbit; + writeb(readb(bits) | portp->portbit, bits); set_bit(ST_TXBUSY, &portp->state); EBRDDISABLE(brdp); - restore_flags(flags); + spin_unlock_irqrestore(&brd_lock, flags); } /*****************************************************************************/ static int stli_writeroom(struct tty_struct *tty) { - volatile cdkasyrq_t *rp; - stliport_t *portp; - stlibrd_t *brdp; - unsigned int head, tail, len; - unsigned long flags; - -#ifdef DEBUG - printk("stli_writeroom(tty=%x)\n", (int) tty); -#endif + cdkasyrq_t __iomem *rp; + stliport_t *portp; + stlibrd_t *brdp; + unsigned int head, tail, len; + unsigned long flags; - if (tty == (struct tty_struct *) NULL) - return(0); if (tty == stli_txcooktty) { if (stli_txcookrealsize != 0) { len = stli_txcookrealsize - stli_txcooksize; - return(len); + return len; } } portp = tty->driver_data; - if (portp == (stliport_t *) NULL) - return(0); + if (portp == NULL) + return 0; if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) - return(0); + return 0; brdp = stli_brds[portp->brdnr]; - if (brdp == (stlibrd_t *) NULL) - return(0); + if (brdp == NULL) + return 0; - save_flags(flags); - cli(); + spin_lock_irqsave(&brd_lock, flags); EBRDENABLE(brdp); - rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->txq; - head = (unsigned int) rp->head; - tail = (unsigned int) rp->tail; - if (tail != ((unsigned int) rp->tail)) - tail = (unsigned int) rp->tail; + rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->txq; + head = (unsigned int) readw(&rp->head); + tail = (unsigned int) readw(&rp->tail); + if (tail != ((unsigned int) readw(&rp->tail))) + tail = (unsigned int) readw(&rp->tail); len = (head >= tail) ? (portp->txsize - (head - tail)) : (tail - head); len--; EBRDDISABLE(brdp); - restore_flags(flags); + spin_unlock_irqrestore(&brd_lock, flags); if (tty == stli_txcooktty) { stli_txcookrealsize = len; len -= stli_txcooksize; } - return(len); + return len; } /*****************************************************************************/ @@ -1795,44 +1684,37 @@ static int stli_writeroom(struct tty_struct *tty) static int stli_charsinbuffer(struct tty_struct *tty) { - volatile cdkasyrq_t *rp; - stliport_t *portp; - stlibrd_t *brdp; - unsigned int head, tail, len; - unsigned long flags; - -#ifdef DEBUG - printk("stli_charsinbuffer(tty=%x)\n", (int) tty); -#endif + cdkasyrq_t __iomem *rp; + stliport_t *portp; + stlibrd_t *brdp; + unsigned int head, tail, len; + unsigned long flags; - if (tty == (struct tty_struct *) NULL) - return(0); if (tty == stli_txcooktty) stli_flushchars(tty); portp = tty->driver_data; - if (portp == (stliport_t *) NULL) - return(0); + if (portp == NULL) + return 0; if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) - return(0); + return 0; brdp = stli_brds[portp->brdnr]; - if (brdp == (stlibrd_t *) NULL) - return(0); + if (brdp == NULL) + return 0; - save_flags(flags); - cli(); + spin_lock_irqsave(&brd_lock, flags); EBRDENABLE(brdp); - rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->txq; - head = (unsigned int) rp->head; - tail = (unsigned int) rp->tail; - if (tail != ((unsigned int) rp->tail)) - tail = (unsigned int) rp->tail; + rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->txq; + head = (unsigned int) readw(&rp->head); + tail = (unsigned int) readw(&rp->tail); + if (tail != ((unsigned int) readw(&rp->tail))) + tail = (unsigned int) readw(&rp->tail); len = (head >= tail) ? (head - tail) : (portp->txsize - (tail - head)); if ((len == 0) && test_bit(ST_TXBUSY, &portp->state)) len = 1; EBRDDISABLE(brdp); - restore_flags(flags); + spin_unlock_irqrestore(&brd_lock, flags); - return(len); + return len; } /*****************************************************************************/ @@ -1843,12 +1725,8 @@ static int stli_charsinbuffer(struct tty_struct *tty) static int stli_getserial(stliport_t *portp, struct serial_struct __user *sp) { - struct serial_struct sio; - stlibrd_t *brdp; - -#ifdef DEBUG - printk("stli_getserial(portp=%x,sp=%x)\n", (int) portp, (int) sp); -#endif + struct serial_struct sio; + stlibrd_t *brdp; memset(&sio, 0, sizeof(struct serial_struct)); sio.type = PORT_UNKNOWN; @@ -1863,7 +1741,7 @@ static int stli_getserial(stliport_t *portp, struct serial_struct __user *sp) sio.hub6 = 0; brdp = stli_brds[portp->brdnr]; - if (brdp != (stlibrd_t *) NULL) + if (brdp != NULL) sio.port = brdp->iobase; return copy_to_user(sp, &sio, sizeof(struct serial_struct)) ? @@ -1880,12 +1758,8 @@ static int stli_getserial(stliport_t *portp, struct serial_struct __user *sp) static int stli_setserial(stliport_t *portp, struct serial_struct __user *sp) { - struct serial_struct sio; - int rc; - -#ifdef DEBUG - printk("stli_setserial(portp=%p,sp=%p)\n", portp, sp); -#endif + struct serial_struct sio; + int rc; if (copy_from_user(&sio, sp, sizeof(struct serial_struct))) return -EFAULT; @@ -1894,7 +1768,7 @@ static int stli_setserial(stliport_t *portp, struct serial_struct __user *sp) (sio.close_delay != portp->close_delay) || ((sio.flags & ~ASYNC_USR_MASK) != (portp->flags & ~ASYNC_USR_MASK))) - return(-EPERM); + return -EPERM; } portp->flags = (portp->flags & ~ASYNC_USR_MASK) | @@ -1905,8 +1779,8 @@ static int stli_setserial(stliport_t *portp, struct serial_struct __user *sp) portp->custom_divisor = sio.custom_divisor; if ((rc = stli_setport(portp)) < 0) - return(rc); - return(0); + return rc; + return 0; } /*****************************************************************************/ @@ -1917,19 +1791,19 @@ static int stli_tiocmget(struct tty_struct *tty, struct file *file) stlibrd_t *brdp; int rc; - if (portp == (stliport_t *) NULL) - return(-ENODEV); - if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) - return(0); + if (portp == NULL) + return -ENODEV; + if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) + return 0; brdp = stli_brds[portp->brdnr]; - if (brdp == (stlibrd_t *) NULL) - return(0); + if (brdp == NULL) + return 0; if (tty->flags & (1 << TTY_IO_ERROR)) - return(-EIO); + return -EIO; if ((rc = stli_cmdwait(brdp, portp, A_GETSIGNALS, &portp->asig, sizeof(asysigs_t), 1)) < 0) - return(rc); + return rc; return stli_mktiocm(portp->asig.sigvalue); } @@ -1941,15 +1815,15 @@ static int stli_tiocmset(struct tty_struct *tty, struct file *file, stlibrd_t *brdp; int rts = -1, dtr = -1; - if (portp == (stliport_t *) NULL) - return(-ENODEV); - if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) - return(0); + if (portp == NULL) + return -ENODEV; + if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) + return 0; brdp = stli_brds[portp->brdnr]; - if (brdp == (stlibrd_t *) NULL) - return(0); + if (brdp == NULL) + return 0; if (tty->flags & (1 << TTY_IO_ERROR)) - return(-EIO); + return -EIO; if (set & TIOCM_RTS) rts = 1; @@ -1968,32 +1842,25 @@ static int stli_tiocmset(struct tty_struct *tty, struct file *file, static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cmd, unsigned long arg) { - stliport_t *portp; - stlibrd_t *brdp; - unsigned int ival; - int rc; + stliport_t *portp; + stlibrd_t *brdp; + unsigned int ival; + int rc; void __user *argp = (void __user *)arg; -#ifdef DEBUG - printk("stli_ioctl(tty=%x,file=%x,cmd=%x,arg=%x)\n", - (int) tty, (int) file, cmd, (int) arg); -#endif - - if (tty == (struct tty_struct *) NULL) - return(-ENODEV); portp = tty->driver_data; - if (portp == (stliport_t *) NULL) - return(-ENODEV); - if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) - return(0); + if (portp == NULL) + return -ENODEV; + if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) + return 0; brdp = stli_brds[portp->brdnr]; - if (brdp == (stlibrd_t *) NULL) - return(0); + if (brdp == NULL) + return 0; if ((cmd != TIOCGSERIAL) && (cmd != TIOCSSERIAL) && (cmd != COM_GETPORTSTATS) && (cmd != COM_CLRPORTSTATS)) { if (tty->flags & (1 << TTY_IO_ERROR)) - return(-EIO); + return -EIO; } rc = 0; @@ -2040,7 +1907,7 @@ static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm break; } - return(rc); + return rc; } /*****************************************************************************/ @@ -2052,24 +1919,20 @@ static int stli_ioctl(struct tty_struct *tty, struct file *file, unsigned int cm static void stli_settermios(struct tty_struct *tty, struct termios *old) { - stliport_t *portp; - stlibrd_t *brdp; - struct termios *tiosp; - asyport_t aport; - -#ifdef DEBUG - printk("stli_settermios(tty=%x,old=%x)\n", (int) tty, (int) old); -#endif + stliport_t *portp; + stlibrd_t *brdp; + struct termios *tiosp; + asyport_t aport; - if (tty == (struct tty_struct *) NULL) + if (tty == NULL) return; portp = tty->driver_data; - if (portp == (stliport_t *) NULL) + if (portp == NULL) return; - if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) + if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) return; brdp = stli_brds[portp->brdnr]; - if (brdp == (stlibrd_t *) NULL) + if (brdp == NULL) return; tiosp = tty->termios; @@ -2102,18 +1965,9 @@ static void stli_settermios(struct tty_struct *tty, struct termios *old) static void stli_throttle(struct tty_struct *tty) { - stliport_t *portp; - -#ifdef DEBUG - printk("stli_throttle(tty=%x)\n", (int) tty); -#endif - - if (tty == (struct tty_struct *) NULL) - return; - portp = tty->driver_data; - if (portp == (stliport_t *) NULL) + stliport_t *portp = tty->driver_data; + if (portp == NULL) return; - set_bit(ST_RXSTOP, &portp->state); } @@ -2127,88 +1981,30 @@ static void stli_throttle(struct tty_struct *tty) static void stli_unthrottle(struct tty_struct *tty) { - stliport_t *portp; - -#ifdef DEBUG - printk("stli_unthrottle(tty=%x)\n", (int) tty); -#endif - - if (tty == (struct tty_struct *) NULL) + stliport_t *portp = tty->driver_data; + if (portp == NULL) return; - portp = tty->driver_data; - if (portp == (stliport_t *) NULL) - return; - clear_bit(ST_RXSTOP, &portp->state); } /*****************************************************************************/ /* - * Stop the transmitter. Basically to do this we will just turn TX - * interrupts off. + * Stop the transmitter. */ static void stli_stop(struct tty_struct *tty) { - stlibrd_t *brdp; - stliport_t *portp; - asyctrl_t actrl; - -#ifdef DEBUG - printk("stli_stop(tty=%x)\n", (int) tty); -#endif - - if (tty == (struct tty_struct *) NULL) - return; - portp = tty->driver_data; - if (portp == (stliport_t *) NULL) - return; - if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) - return; - brdp = stli_brds[portp->brdnr]; - if (brdp == (stlibrd_t *) NULL) - return; - - memset(&actrl, 0, sizeof(asyctrl_t)); - actrl.txctrl = CT_STOPFLOW; -#if 0 - stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0); -#endif } /*****************************************************************************/ /* - * Start the transmitter again. Just turn TX interrupts back on. + * Start the transmitter again. */ static void stli_start(struct tty_struct *tty) { - stliport_t *portp; - stlibrd_t *brdp; - asyctrl_t actrl; - -#ifdef DEBUG - printk("stli_start(tty=%x)\n", (int) tty); -#endif - - if (tty == (struct tty_struct *) NULL) - return; - portp = tty->driver_data; - if (portp == (stliport_t *) NULL) - return; - if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) - return; - brdp = stli_brds[portp->brdnr]; - if (brdp == (stlibrd_t *) NULL) - return; - - memset(&actrl, 0, sizeof(asyctrl_t)); - actrl.txctrl = CT_STARTFLOW; -#if 0 - stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0); -#endif } /*****************************************************************************/ @@ -2224,22 +2020,9 @@ static void stli_start(struct tty_struct *tty) static void stli_dohangup(void *arg) { - stliport_t *portp; - -#ifdef DEBUG - printk(KERN_DEBUG "stli_dohangup(portp=%x)\n", (int) arg); -#endif - - /* - * FIXME: There's a module removal race here: tty_hangup - * calls schedule_work which will call into this - * driver later. - */ - portp = (stliport_t *) arg; - if (portp != (stliport_t *) NULL) { - if (portp->tty != (struct tty_struct *) NULL) { - tty_hangup(portp->tty); - } + stliport_t *portp = (stliport_t *) arg; + if (portp->tty != NULL) { + tty_hangup(portp->tty); } } @@ -2254,31 +2037,25 @@ static void stli_dohangup(void *arg) static void stli_hangup(struct tty_struct *tty) { - stliport_t *portp; - stlibrd_t *brdp; - unsigned long flags; - -#ifdef DEBUG - printk(KERN_DEBUG "stli_hangup(tty=%x)\n", (int) tty); -#endif + stliport_t *portp; + stlibrd_t *brdp; + unsigned long flags; - if (tty == (struct tty_struct *) NULL) - return; portp = tty->driver_data; - if (portp == (stliport_t *) NULL) + if (portp == NULL) return; - if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) + if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) return; brdp = stli_brds[portp->brdnr]; - if (brdp == (stlibrd_t *) NULL) + if (brdp == NULL) return; portp->flags &= ~ASYNC_INITIALIZED; - save_flags(flags); - cli(); - if (! test_bit(ST_CLOSING, &portp->state)) + if (!test_bit(ST_CLOSING, &portp->state)) stli_rawclose(brdp, portp, 0, 0); + + spin_lock_irqsave(&stli_lock, flags); if (tty->termios->c_cflag & HUPCL) { stli_mkasysigs(&portp->asig, 0, 0); if (test_bit(ST_CMDING, &portp->state)) { @@ -2290,14 +2067,15 @@ static void stli_hangup(struct tty_struct *tty) &portp->asig, sizeof(asysigs_t), 0); } } - restore_flags(flags); clear_bit(ST_TXBUSY, &portp->state); clear_bit(ST_RXSTOP, &portp->state); set_bit(TTY_IO_ERROR, &tty->flags); - portp->tty = (struct tty_struct *) NULL; + portp->tty = NULL; portp->flags &= ~ASYNC_NORMAL_ACTIVE; portp->refcount = 0; + spin_unlock_irqrestore(&stli_lock, flags); + wake_up_interruptible(&portp->open_wait); } @@ -2312,29 +2090,22 @@ static void stli_hangup(struct tty_struct *tty) static void stli_flushbuffer(struct tty_struct *tty) { - stliport_t *portp; - stlibrd_t *brdp; - unsigned long ftype, flags; - -#ifdef DEBUG - printk(KERN_DEBUG "stli_flushbuffer(tty=%x)\n", (int) tty); -#endif + stliport_t *portp; + stlibrd_t *brdp; + unsigned long ftype, flags; - if (tty == (struct tty_struct *) NULL) - return; portp = tty->driver_data; - if (portp == (stliport_t *) NULL) + if (portp == NULL) return; - if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) + if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) return; brdp = stli_brds[portp->brdnr]; - if (brdp == (stlibrd_t *) NULL) + if (brdp == NULL) return; - save_flags(flags); - cli(); + spin_lock_irqsave(&brd_lock, flags); if (tty == stli_txcooktty) { - stli_txcooktty = (struct tty_struct *) NULL; + stli_txcooktty = NULL; stli_txcooksize = 0; stli_txcookrealsize = 0; } @@ -2346,15 +2117,10 @@ static void stli_flushbuffer(struct tty_struct *tty) ftype |= FLUSHRX; clear_bit(ST_DOFLUSHRX, &portp->state); } - stli_sendcmd(brdp, portp, A_FLUSH, &ftype, - sizeof(unsigned long), 0); + __stli_sendcmd(brdp, portp, A_FLUSH, &ftype, sizeof(u32), 0); } - restore_flags(flags); - - wake_up_interruptible(&tty->write_wait); - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) - (tty->ldisc.write_wakeup)(tty); + spin_unlock_irqrestore(&brd_lock, flags); + tty_wakeup(tty); } /*****************************************************************************/ @@ -2364,55 +2130,31 @@ static void stli_breakctl(struct tty_struct *tty, int state) stlibrd_t *brdp; stliport_t *portp; long arg; - /* long savestate, savetime; */ -#ifdef DEBUG - printk(KERN_DEBUG "stli_breakctl(tty=%x,state=%d)\n", (int) tty, state); -#endif - - if (tty == (struct tty_struct *) NULL) - return; portp = tty->driver_data; - if (portp == (stliport_t *) NULL) + if (portp == NULL) return; - if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) + if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) return; brdp = stli_brds[portp->brdnr]; - if (brdp == (stlibrd_t *) NULL) + if (brdp == NULL) return; -/* - * Due to a bug in the tty send_break() code we need to preserve - * the current process state and timeout... - savetime = current->timeout; - savestate = current->state; - */ - arg = (state == -1) ? BREAKON : BREAKOFF; stli_cmdwait(brdp, portp, A_BREAK, &arg, sizeof(long), 0); - -/* - * - current->timeout = savetime; - current->state = savestate; - */ } /*****************************************************************************/ static void stli_waituntilsent(struct tty_struct *tty, int timeout) { - stliport_t *portp; - unsigned long tend; - -#ifdef DEBUG - printk(KERN_DEBUG "stli_waituntilsent(tty=%x,timeout=%x)\n", (int) tty, timeout); -#endif + stliport_t *portp; + unsigned long tend; - if (tty == (struct tty_struct *) NULL) + if (tty == NULL) return; portp = tty->driver_data; - if (portp == (stliport_t *) NULL) + if (portp == NULL) return; if (timeout == 0) @@ -2436,19 +2178,13 @@ static void stli_sendxchar(struct tty_struct *tty, char ch) stliport_t *portp; asyctrl_t actrl; -#ifdef DEBUG - printk(KERN_DEBUG "stli_sendxchar(tty=%x,ch=%x)\n", (int) tty, ch); -#endif - - if (tty == (struct tty_struct *) NULL) - return; portp = tty->driver_data; - if (portp == (stliport_t *) NULL) + if (portp == NULL) return; - if ((portp->brdnr < 0) || (portp->brdnr >= stli_nrbrds)) + if (portp->brdnr < 0 || portp->brdnr >= stli_nrbrds) return; brdp = stli_brds[portp->brdnr]; - if (brdp == (stlibrd_t *) NULL) + if (brdp == NULL) return; memset(&actrl, 0, sizeof(asyctrl_t)); @@ -2460,7 +2196,6 @@ static void stli_sendxchar(struct tty_struct *tty, char ch) actrl.txctrl = CT_SENDCHR; actrl.tximdch = ch; } - stli_cmdwait(brdp, portp, A_PORTCTRL, &actrl, sizeof(asyctrl_t), 0); } @@ -2476,17 +2211,17 @@ static void stli_sendxchar(struct tty_struct *tty, char ch) static int stli_portinfo(stlibrd_t *brdp, stliport_t *portp, int portnr, char *pos) { - char *sp, *uart; - int rc, cnt; + char *sp, *uart; + int rc, cnt; rc = stli_portcmdstats(portp); uart = "UNKNOWN"; if (brdp->state & BST_STARTED) { switch (stli_comstats.hwid) { - case 0: uart = "2681"; break; - case 1: uart = "SC26198"; break; - default: uart = "CD1400"; break; + case 0: uart = "2681"; break; + case 1: uart = "SC26198"; break; + default:uart = "CD1400"; break; } } @@ -2537,17 +2272,11 @@ static int stli_portinfo(stlibrd_t *brdp, stliport_t *portp, int portnr, char *p static int stli_readproc(char *page, char **start, off_t off, int count, int *eof, void *data) { - stlibrd_t *brdp; - stliport_t *portp; - int brdnr, portnr, totalport; - int curoff, maxoff; - char *pos; - -#ifdef DEBUG - printk(KERN_DEBUG "stli_readproc(page=%x,start=%x,off=%x,count=%d,eof=%x," - "data=%x\n", (int) page, (int) start, (int) off, count, - (int) eof, (int) data); -#endif + stlibrd_t *brdp; + stliport_t *portp; + int brdnr, portnr, totalport; + int curoff, maxoff; + char *pos; pos = page; totalport = 0; @@ -2568,7 +2297,7 @@ static int stli_readproc(char *page, char **start, off_t off, int count, int *eo */ for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) { brdp = stli_brds[brdnr]; - if (brdp == (stlibrd_t *) NULL) + if (brdp == NULL) continue; if (brdp->state == 0) continue; @@ -2583,7 +2312,7 @@ static int stli_readproc(char *page, char **start, off_t off, int count, int *eo for (portnr = 0; (portnr < brdp->nrports); portnr++, totalport++) { portp = brdp->ports[portnr]; - if (portp == (stliport_t *) NULL) + if (portp == NULL) continue; if (off >= (curoff += MAXLINE)) continue; @@ -2610,49 +2339,54 @@ static int stli_readproc(char *page, char **start, off_t off, int count, int *eo * a poll routine that does not have user context. Therefore you cannot * copy back directly into user space, or to the kernel stack of a * process. This routine does not sleep, so can be called from anywhere. + * + * The caller must hold the brd_lock (see also stli_sendcmd the usual + * entry point) */ -static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback) +static void __stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback) { - volatile cdkhdr_t *hdrp; - volatile cdkctrl_t *cp; - volatile unsigned char *bits; - unsigned long flags; + cdkhdr_t __iomem *hdrp; + cdkctrl_t __iomem *cp; + unsigned char __iomem *bits; + unsigned long flags; -#ifdef DEBUG - printk(KERN_DEBUG "stli_sendcmd(brdp=%x,portp=%x,cmd=%x,arg=%x,size=%d," - "copyback=%d)\n", (int) brdp, (int) portp, (int) cmd, - (int) arg, size, copyback); -#endif - - save_flags(flags); - cli(); + spin_lock_irqsave(&brd_lock, flags); if (test_bit(ST_CMDING, &portp->state)) { printk(KERN_ERR "STALLION: command already busy, cmd=%x!\n", (int) cmd); - restore_flags(flags); + spin_unlock_irqrestore(&brd_lock, flags); return; } EBRDENABLE(brdp); - cp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; + cp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->ctrl; if (size > 0) { - memcpy((void *) &(cp->args[0]), arg, size); + memcpy_toio((void __iomem *) &(cp->args[0]), arg, size); if (copyback) { portp->argp = arg; portp->argsize = size; } } - cp->status = 0; - cp->cmd = cmd; - hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - bits = ((volatile unsigned char *) hdrp) + brdp->slaveoffset + + writel(0, &cp->status); + writel(cmd, &cp->cmd); + hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); + bits = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset + portp->portidx; - *bits |= portp->portbit; + writeb(readb(bits) | portp->portbit, bits); set_bit(ST_CMDING, &portp->state); EBRDDISABLE(brdp); - restore_flags(flags); + spin_unlock_irqrestore(&brd_lock, flags); +} + +static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, void *arg, int size, int copyback) +{ + unsigned long flags; + + spin_lock_irqsave(&brd_lock, flags); + __stli_sendcmd(brdp, portp, cmd, arg, size, copyback); + spin_unlock_irqrestore(&brd_lock, flags); } /*****************************************************************************/ @@ -2667,28 +2401,23 @@ static void stli_sendcmd(stlibrd_t *brdp, stliport_t *portp, unsigned long cmd, static void stli_read(stlibrd_t *brdp, stliport_t *portp) { - volatile cdkasyrq_t *rp; - volatile char *shbuf; + cdkasyrq_t __iomem *rp; + char __iomem *shbuf; struct tty_struct *tty; - unsigned int head, tail, size; - unsigned int len, stlen; - -#ifdef DEBUG - printk(KERN_DEBUG "stli_read(brdp=%x,portp=%d)\n", - (int) brdp, (int) portp); -#endif + unsigned int head, tail, size; + unsigned int len, stlen; if (test_bit(ST_RXSTOP, &portp->state)) return; tty = portp->tty; - if (tty == (struct tty_struct *) NULL) + if (tty == NULL) return; - rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->rxq; - head = (unsigned int) rp->head; - if (head != ((unsigned int) rp->head)) - head = (unsigned int) rp->head; - tail = (unsigned int) rp->tail; + rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->rxq; + head = (unsigned int) readw(&rp->head); + if (head != ((unsigned int) readw(&rp->head))) + head = (unsigned int) readw(&rp->head); + tail = (unsigned int) readw(&rp->tail); size = portp->rxsize; if (head >= tail) { len = head - tail; @@ -2699,12 +2428,15 @@ static void stli_read(stlibrd_t *brdp, stliport_t *portp) } len = tty_buffer_request_room(tty, len); - /* FIXME : iomap ? */ - shbuf = (volatile char *) EBRDGETMEMPTR(brdp, portp->rxoffset); + + shbuf = (char __iomem *) EBRDGETMEMPTR(brdp, portp->rxoffset); while (len > 0) { + unsigned char *cptr; + stlen = MIN(len, stlen); - tty_insert_flip_string(tty, (char *)(shbuf + tail), stlen); + tty_prepare_flip_string(tty, &cptr, stlen); + memcpy_fromio(cptr, shbuf + tail, stlen); len -= stlen; tail += stlen; if (tail >= size) { @@ -2712,8 +2444,8 @@ static void stli_read(stlibrd_t *brdp, stliport_t *portp) stlen = head; } } - rp = &((volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr))->rxq; - rp->tail = tail; + rp = &((cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr))->rxq; + writew(tail, &rp->tail); if (head != tail) set_bit(ST_RXING, &portp->state); @@ -2729,9 +2461,9 @@ static void stli_read(stlibrd_t *brdp, stliport_t *portp) * difficult to deal with them here. */ -static void stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp) +static void stli_dodelaycmd(stliport_t *portp, cdkctrl_t __iomem *cp) { - int cmd; + int cmd; if (test_bit(ST_DOSIGS, &portp->state)) { if (test_bit(ST_DOFLUSHTX, &portp->state) && @@ -2746,10 +2478,10 @@ static void stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp) clear_bit(ST_DOFLUSHTX, &portp->state); clear_bit(ST_DOFLUSHRX, &portp->state); clear_bit(ST_DOSIGS, &portp->state); - memcpy((void *) &(cp->args[0]), (void *) &portp->asig, + memcpy_toio((void __iomem *) &(cp->args[0]), (void *) &portp->asig, sizeof(asysigs_t)); - cp->status = 0; - cp->cmd = cmd; + writel(0, &cp->status); + writel(cmd, &cp->cmd); set_bit(ST_CMDING, &portp->state); } else if (test_bit(ST_DOFLUSHTX, &portp->state) || test_bit(ST_DOFLUSHRX, &portp->state)) { @@ -2757,9 +2489,9 @@ static void stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp) cmd |= ((test_bit(ST_DOFLUSHRX, &portp->state)) ? FLUSHRX : 0); clear_bit(ST_DOFLUSHTX, &portp->state); clear_bit(ST_DOFLUSHRX, &portp->state); - memcpy((void *) &(cp->args[0]), (void *) &cmd, sizeof(int)); - cp->status = 0; - cp->cmd = A_FLUSH; + memcpy_toio((void __iomem *) &(cp->args[0]), (void *) &cmd, sizeof(int)); + writel(0, &cp->status); + writel(A_FLUSH, &cp->cmd); set_bit(ST_CMDING, &portp->state); } } @@ -2779,30 +2511,25 @@ static void stli_dodelaycmd(stliport_t *portp, volatile cdkctrl_t *cp) static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp) { - volatile cdkasy_t *ap; - volatile cdkctrl_t *cp; - struct tty_struct *tty; - asynotify_t nt; - unsigned long oldsigs; - int rc, donerx; - -#ifdef DEBUG - printk(KERN_DEBUG "stli_hostcmd(brdp=%x,channr=%d)\n", - (int) brdp, channr); -#endif - - ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr); + cdkasy_t __iomem *ap; + cdkctrl_t __iomem *cp; + struct tty_struct *tty; + asynotify_t nt; + unsigned long oldsigs; + int rc, donerx; + + ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); cp = &ap->ctrl; /* * Check if we are waiting for an open completion message. */ if (test_bit(ST_OPENING, &portp->state)) { - rc = (int) cp->openarg; - if ((cp->open == 0) && (rc != 0)) { + rc = readl(&cp->openarg); + if (readb(&cp->open) == 0 && rc != 0) { if (rc > 0) rc--; - cp->openarg = 0; + writel(0, &cp->openarg); portp->rc = rc; clear_bit(ST_OPENING, &portp->state); wake_up_interruptible(&portp->raw_wait); @@ -2813,11 +2540,11 @@ static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp) * Check if we are waiting for a close completion message. */ if (test_bit(ST_CLOSING, &portp->state)) { - rc = (int) cp->closearg; - if ((cp->close == 0) && (rc != 0)) { + rc = (int) readl(&cp->closearg); + if (readb(&cp->close) == 0 && rc != 0) { if (rc > 0) rc--; - cp->closearg = 0; + writel(0, &cp->closearg); portp->rc = rc; clear_bit(ST_CLOSING, &portp->state); wake_up_interruptible(&portp->raw_wait); @@ -2829,16 +2556,16 @@ static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp) * need to copy out the command results associated with this command. */ if (test_bit(ST_CMDING, &portp->state)) { - rc = cp->status; - if ((cp->cmd == 0) && (rc != 0)) { + rc = readl(&cp->status); + if (readl(&cp->cmd) == 0 && rc != 0) { if (rc > 0) rc--; - if (portp->argp != (void *) NULL) { - memcpy(portp->argp, (void *) &(cp->args[0]), + if (portp->argp != NULL) { + memcpy_fromio(portp->argp, (void __iomem *) &(cp->args[0]), portp->argsize); - portp->argp = (void *) NULL; + portp->argp = NULL; } - cp->status = 0; + writel(0, &cp->status); portp->rc = rc; clear_bit(ST_CMDING, &portp->state); stli_dodelaycmd(portp, cp); @@ -2877,18 +2604,15 @@ static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp) if (nt.data & DT_TXEMPTY) clear_bit(ST_TXBUSY, &portp->state); if (nt.data & (DT_TXEMPTY | DT_TXLOW)) { - if (tty != (struct tty_struct *) NULL) { - if ((tty->flags & (1 << TTY_DO_WRITE_WAKEUP)) && - tty->ldisc.write_wakeup) { - (tty->ldisc.write_wakeup)(tty); - EBRDENABLE(brdp); - } + if (tty != NULL) { + tty_wakeup(tty); + EBRDENABLE(brdp); wake_up_interruptible(&tty->write_wait); } } if ((nt.data & DT_RXBREAK) && (portp->rxmarkmsk & BRKINT)) { - if (tty != (struct tty_struct *) NULL) { + if (tty != NULL) { tty_insert_flip_char(tty, 0, TTY_BREAK); if (portp->flags & ASYNC_SAK) { do_SAK(tty); @@ -2932,14 +2656,14 @@ static int stli_hostcmd(stlibrd_t *brdp, stliport_t *portp) * at the cdk header structure. */ -static void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp) +static void stli_brdpoll(stlibrd_t *brdp, cdkhdr_t __iomem *hdrp) { - stliport_t *portp; - unsigned char hostbits[(STL_MAXCHANS / 8) + 1]; - unsigned char slavebits[(STL_MAXCHANS / 8) + 1]; - unsigned char *slavep; - int bitpos, bitat, bitsize; - int channr, nrdevs, slavebitchange; + stliport_t *portp; + unsigned char hostbits[(STL_MAXCHANS / 8) + 1]; + unsigned char slavebits[(STL_MAXCHANS / 8) + 1]; + unsigned char __iomem *slavep; + int bitpos, bitat, bitsize; + int channr, nrdevs, slavebitchange; bitsize = brdp->bitsize; nrdevs = brdp->nrdevs; @@ -2951,7 +2675,7 @@ static void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp) * 8 service bits at a time in the inner loop, so we can bypass * the lot if none of them want service. */ - memcpy(&hostbits[0], (((unsigned char *) hdrp) + brdp->hostoffset), + memcpy_fromio(&hostbits[0], (((unsigned char __iomem *) hdrp) + brdp->hostoffset), bitsize); memset(&slavebits[0], 0, bitsize); @@ -2978,11 +2702,11 @@ static void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp) * service may initiate more slave requests. */ if (slavebitchange) { - hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - slavep = ((unsigned char *) hdrp) + brdp->slaveoffset; + hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); + slavep = ((unsigned char __iomem *) hdrp) + brdp->slaveoffset; for (bitpos = 0; (bitpos < bitsize); bitpos++) { - if (slavebits[bitpos]) - slavep[bitpos] &= ~slavebits[bitpos]; + if (readb(slavebits + bitpos)) + writeb(readb(slavep + bitpos) & ~slavebits[bitpos], slavebits + bitpos); } } } @@ -3000,9 +2724,9 @@ static void stli_brdpoll(stlibrd_t *brdp, volatile cdkhdr_t *hdrp) static void stli_poll(unsigned long arg) { - volatile cdkhdr_t *hdrp; - stlibrd_t *brdp; - int brdnr; + cdkhdr_t __iomem *hdrp; + stlibrd_t *brdp; + int brdnr; stli_timerlist.expires = STLI_TIMEOUT; add_timer(&stli_timerlist); @@ -3012,16 +2736,18 @@ static void stli_poll(unsigned long arg) */ for (brdnr = 0; (brdnr < stli_nrbrds); brdnr++) { brdp = stli_brds[brdnr]; - if (brdp == (stlibrd_t *) NULL) + if (brdp == NULL) continue; if ((brdp->state & BST_STARTED) == 0) continue; + spin_lock(&brd_lock); EBRDENABLE(brdp); - hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); - if (hdrp->hostreq) + hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); + if (readb(&hdrp->hostreq)) stli_brdpoll(brdp, hdrp); EBRDDISABLE(brdp); + spin_unlock(&brd_lock); } } @@ -3034,11 +2760,6 @@ static void stli_poll(unsigned long arg) static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tiosp) { -#ifdef DEBUG - printk(KERN_DEBUG "stli_mkasyport(portp=%x,pp=%x,tiosp=%d)\n", - (int) portp, (int) pp, (int) tiosp); -#endif - memset(pp, 0, sizeof(asyport_t)); /* @@ -3157,11 +2878,6 @@ static void stli_mkasyport(stliport_t *portp, asyport_t *pp, struct termios *tio static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts) { -#ifdef DEBUG - printk(KERN_DEBUG "stli_mkasysigs(sp=%x,dtr=%d,rts=%d)\n", - (int) sp, dtr, rts); -#endif - memset(sp, 0, sizeof(asysigs_t)); if (dtr >= 0) { sp->signal |= SG_DTR; @@ -3182,13 +2898,7 @@ static void stli_mkasysigs(asysigs_t *sp, int dtr, int rts) static long stli_mktiocm(unsigned long sigvalue) { - long tiocm; - -#ifdef DEBUG - printk(KERN_DEBUG "stli_mktiocm(sigvalue=%x)\n", (int) sigvalue); -#endif - - tiocm = 0; + long tiocm = 0; tiocm |= ((sigvalue & SG_DCD) ? TIOCM_CD : 0); tiocm |= ((sigvalue & SG_CTS) ? TIOCM_CTS : 0); tiocm |= ((sigvalue & SG_RI) ? TIOCM_RI : 0); @@ -3210,10 +2920,6 @@ static int stli_initports(stlibrd_t *brdp) stliport_t *portp; int i, panelnr, panelport; -#ifdef DEBUG - printk(KERN_DEBUG "stli_initports(brdp=%x)\n", (int) brdp); -#endif - for (i = 0, panelnr = 0, panelport = 0; (i < brdp->nrports); i++) { portp = kzalloc(sizeof(stliport_t), GFP_KERNEL); if (!portp) { @@ -3240,7 +2946,7 @@ static int stli_initports(stlibrd_t *brdp) brdp->ports[i] = portp; } - return(0); + return 0; } /*****************************************************************************/ @@ -3253,10 +2959,6 @@ static void stli_ecpinit(stlibrd_t *brdp) { unsigned long memconf; -#ifdef DEBUG - printk(KERN_DEBUG "stli_ecpinit(brdp=%d)\n", (int) brdp); -#endif - outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR)); udelay(10); outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR)); @@ -3270,9 +2972,6 @@ static void stli_ecpinit(stlibrd_t *brdp) static void stli_ecpenable(stlibrd_t *brdp) { -#ifdef DEBUG - printk(KERN_DEBUG "stli_ecpenable(brdp=%x)\n", (int) brdp); -#endif outb(ECP_ATENABLE, (brdp->iobase + ECP_ATCONFR)); } @@ -3280,9 +2979,6 @@ static void stli_ecpenable(stlibrd_t *brdp) static void stli_ecpdisable(stlibrd_t *brdp) { -#ifdef DEBUG - printk(KERN_DEBUG "stli_ecpdisable(brdp=%x)\n", (int) brdp); -#endif outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR)); } @@ -3290,13 +2986,8 @@ static void stli_ecpdisable(stlibrd_t *brdp) static char *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { - void *ptr; - unsigned char val; - -#ifdef DEBUG - printk(KERN_DEBUG "stli_ecpgetmemptr(brdp=%x,offset=%x)\n", (int) brdp, - (int) offset); -#endif + void *ptr; + unsigned char val; if (offset > brdp->memsize) { printk(KERN_ERR "STALLION: shared memory pointer=%x out of " @@ -3316,10 +3007,6 @@ static char *stli_ecpgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) static void stli_ecpreset(stlibrd_t *brdp) { -#ifdef DEBUG - printk(KERN_DEBUG "stli_ecpreset(brdp=%x)\n", (int) brdp); -#endif - outb(ECP_ATSTOP, (brdp->iobase + ECP_ATCONFR)); udelay(10); outb(ECP_ATDISABLE, (brdp->iobase + ECP_ATCONFR)); @@ -3330,9 +3017,6 @@ static void stli_ecpreset(stlibrd_t *brdp) static void stli_ecpintr(stlibrd_t *brdp) { -#ifdef DEBUG - printk(KERN_DEBUG "stli_ecpintr(brdp=%x)\n", (int) brdp); -#endif outb(0x1, brdp->iobase); } @@ -3346,10 +3030,6 @@ static void stli_ecpeiinit(stlibrd_t *brdp) { unsigned long memconf; -#ifdef DEBUG - printk(KERN_DEBUG "stli_ecpeiinit(brdp=%x)\n", (int) brdp); -#endif - outb(0x1, (brdp->iobase + ECP_EIBRDENAB)); outb(ECP_EISTOP, (brdp->iobase + ECP_EICONFR)); udelay(10); @@ -3383,11 +3063,6 @@ static char *stli_ecpeigetmemptr(stlibrd_t *brdp, unsigned long offset, int line void *ptr; unsigned char val; -#ifdef DEBUG - printk(KERN_DEBUG "stli_ecpeigetmemptr(brdp=%x,offset=%x,line=%d)\n", - (int) brdp, (int) offset, line); -#endif - if (offset > brdp->memsize) { printk(KERN_ERR "STALLION: shared memory pointer=%x out of " "range at line=%d(%d), brd=%d\n", @@ -3437,8 +3112,8 @@ static void stli_ecpmcdisable(stlibrd_t *brdp) static char *stli_ecpmcgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { - void *ptr; - unsigned char val; + void *ptr; + unsigned char val; if (offset > brdp->memsize) { printk(KERN_ERR "STALLION: shared memory pointer=%x out of " @@ -3472,10 +3147,6 @@ static void stli_ecpmcreset(stlibrd_t *brdp) static void stli_ecppciinit(stlibrd_t *brdp) { -#ifdef DEBUG - printk(KERN_DEBUG "stli_ecppciinit(brdp=%x)\n", (int) brdp); -#endif - outb(ECP_PCISTOP, (brdp->iobase + ECP_PCICONFR)); udelay(10); outb(0, (brdp->iobase + ECP_PCICONFR)); @@ -3489,11 +3160,6 @@ static char *stli_ecppcigetmemptr(stlibrd_t *brdp, unsigned long offset, int lin void *ptr; unsigned char val; -#ifdef DEBUG - printk(KERN_DEBUG "stli_ecppcigetmemptr(brdp=%x,offset=%x,line=%d)\n", - (int) brdp, (int) offset, line); -#endif - if (offset > brdp->memsize) { printk(KERN_ERR "STALLION: shared memory pointer=%x out of " "range at line=%d(%d), board=%d\n", @@ -3528,10 +3194,6 @@ static void stli_onbinit(stlibrd_t *brdp) { unsigned long memconf; -#ifdef DEBUG - printk(KERN_DEBUG "stli_onbinit(brdp=%d)\n", (int) brdp); -#endif - outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR)); udelay(10); outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR)); @@ -3547,9 +3209,6 @@ static void stli_onbinit(stlibrd_t *brdp) static void stli_onbenable(stlibrd_t *brdp) { -#ifdef DEBUG - printk(KERN_DEBUG "stli_onbenable(brdp=%x)\n", (int) brdp); -#endif outb((brdp->enabval | ONB_ATENABLE), (brdp->iobase + ONB_ATCONFR)); } @@ -3557,9 +3216,6 @@ static void stli_onbenable(stlibrd_t *brdp) static void stli_onbdisable(stlibrd_t *brdp) { -#ifdef DEBUG - printk(KERN_DEBUG "stli_onbdisable(brdp=%x)\n", (int) brdp); -#endif outb((brdp->enabval | ONB_ATDISABLE), (brdp->iobase + ONB_ATCONFR)); } @@ -3569,11 +3225,6 @@ static char *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { void *ptr; -#ifdef DEBUG - printk(KERN_DEBUG "stli_onbgetmemptr(brdp=%x,offset=%x)\n", (int) brdp, - (int) offset); -#endif - if (offset > brdp->memsize) { printk(KERN_ERR "STALLION: shared memory pointer=%x out of " "range at line=%d(%d), brd=%d\n", @@ -3589,11 +3240,6 @@ static char *stli_onbgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) static void stli_onbreset(stlibrd_t *brdp) { - -#ifdef DEBUG - printk(KERN_DEBUG "stli_onbreset(brdp=%x)\n", (int) brdp); -#endif - outb(ONB_ATSTOP, (brdp->iobase + ONB_ATCONFR)); udelay(10); outb(ONB_ATDISABLE, (brdp->iobase + ONB_ATCONFR)); @@ -3610,10 +3256,6 @@ static void stli_onbeinit(stlibrd_t *brdp) { unsigned long memconf; -#ifdef DEBUG - printk(KERN_DEBUG "stli_onbeinit(brdp=%d)\n", (int) brdp); -#endif - outb(0x1, (brdp->iobase + ONB_EIBRDENAB)); outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR)); udelay(10); @@ -3632,9 +3274,6 @@ static void stli_onbeinit(stlibrd_t *brdp) static void stli_onbeenable(stlibrd_t *brdp) { -#ifdef DEBUG - printk(KERN_DEBUG "stli_onbeenable(brdp=%x)\n", (int) brdp); -#endif outb(ONB_EIENABLE, (brdp->iobase + ONB_EICONFR)); } @@ -3642,9 +3281,6 @@ static void stli_onbeenable(stlibrd_t *brdp) static void stli_onbedisable(stlibrd_t *brdp) { -#ifdef DEBUG - printk(KERN_DEBUG "stli_onbedisable(brdp=%x)\n", (int) brdp); -#endif outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR)); } @@ -3652,13 +3288,8 @@ static void stli_onbedisable(stlibrd_t *brdp) static char *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { - void *ptr; - unsigned char val; - -#ifdef DEBUG - printk(KERN_DEBUG "stli_onbegetmemptr(brdp=%x,offset=%x,line=%d)\n", - (int) brdp, (int) offset, line); -#endif + void *ptr; + unsigned char val; if (offset > brdp->memsize) { printk(KERN_ERR "STALLION: shared memory pointer=%x out of " @@ -3681,11 +3312,6 @@ static char *stli_onbegetmemptr(stlibrd_t *brdp, unsigned long offset, int line) static void stli_onbereset(stlibrd_t *brdp) { - -#ifdef DEBUG - printk(KERN_ERR "stli_onbereset(brdp=%x)\n", (int) brdp); -#endif - outb(ONB_EISTOP, (brdp->iobase + ONB_EICONFR)); udelay(10); outb(ONB_EIDISABLE, (brdp->iobase + ONB_EICONFR)); @@ -3700,11 +3326,6 @@ static void stli_onbereset(stlibrd_t *brdp) static void stli_bbyinit(stlibrd_t *brdp) { - -#ifdef DEBUG - printk(KERN_ERR "stli_bbyinit(brdp=%d)\n", (int) brdp); -#endif - outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR)); udelay(10); outb(0, (brdp->iobase + BBY_ATCONFR)); @@ -3717,24 +3338,13 @@ static void stli_bbyinit(stlibrd_t *brdp) static char *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { - void *ptr; - unsigned char val; + void *ptr; + unsigned char val; -#ifdef DEBUG - printk(KERN_ERR "stli_bbygetmemptr(brdp=%x,offset=%x)\n", (int) brdp, - (int) offset); -#endif + BUG_ON(offset > brdp->memsize); - if (offset > brdp->memsize) { - printk(KERN_ERR "STALLION: shared memory pointer=%x out of " - "range at line=%d(%d), brd=%d\n", - (int) offset, line, __LINE__, brdp->brdnr); - ptr = NULL; - val = 0; - } else { - ptr = brdp->membase + (offset % BBY_PAGESIZE); - val = (unsigned char) (offset / BBY_PAGESIZE); - } + ptr = brdp->membase + (offset % BBY_PAGESIZE); + val = (unsigned char) (offset / BBY_PAGESIZE); outb(val, (brdp->iobase + BBY_ATCONFR)); return(ptr); } @@ -3743,11 +3353,6 @@ static char *stli_bbygetmemptr(stlibrd_t *brdp, unsigned long offset, int line) static void stli_bbyreset(stlibrd_t *brdp) { - -#ifdef DEBUG - printk(KERN_DEBUG "stli_bbyreset(brdp=%x)\n", (int) brdp); -#endif - outb(BBY_ATSTOP, (brdp->iobase + BBY_ATCONFR)); udelay(10); outb(0, (brdp->iobase + BBY_ATCONFR)); @@ -3762,11 +3367,6 @@ static void stli_bbyreset(stlibrd_t *brdp) static void stli_stalinit(stlibrd_t *brdp) { - -#ifdef DEBUG - printk(KERN_DEBUG "stli_stalinit(brdp=%d)\n", (int) brdp); -#endif - outb(0x1, brdp->iobase); mdelay(1000); } @@ -3775,36 +3375,18 @@ static void stli_stalinit(stlibrd_t *brdp) static char *stli_stalgetmemptr(stlibrd_t *brdp, unsigned long offset, int line) { - void *ptr; - -#ifdef DEBUG - printk(KERN_DEBUG "stli_stalgetmemptr(brdp=%x,offset=%x)\n", (int) brdp, - (int) offset); -#endif - - if (offset > brdp->memsize) { - printk(KERN_ERR "STALLION: shared memory pointer=%x out of " - "range at line=%d(%d), brd=%d\n", - (int) offset, line, __LINE__, brdp->brdnr); - ptr = NULL; - } else { - ptr = brdp->membase + (offset % STAL_PAGESIZE); - } - return(ptr); + BUG_ON(offset > brdp->memsize); + return brdp->membase + (offset % STAL_PAGESIZE); } /*****************************************************************************/ static void stli_stalreset(stlibrd_t *brdp) { - volatile unsigned long *vecp; + u32 __iomem *vecp; -#ifdef DEBUG - printk(KERN_DEBUG "stli_stalreset(brdp=%x)\n", (int) brdp); -#endif - - vecp = (volatile unsigned long *) (brdp->membase + 0x30); - *vecp = 0xffff0000; + vecp = (u32 __iomem *) (brdp->membase + 0x30); + writel(0xffff0000, vecp); outb(0, brdp->iobase); mdelay(1000); } @@ -3818,15 +3400,11 @@ static void stli_stalreset(stlibrd_t *brdp) static int stli_initecp(stlibrd_t *brdp) { - cdkecpsig_t sig; - cdkecpsig_t *sigsp; - unsigned int status, nxtid; - char *name; - int panelnr, nrports; - -#ifdef DEBUG - printk(KERN_DEBUG "stli_initecp(brdp=%x)\n", (int) brdp); -#endif + cdkecpsig_t sig; + cdkecpsig_t __iomem *sigsp; + unsigned int status, nxtid; + char *name; + int panelnr, nrports; if (!request_region(brdp->iobase, brdp->iosize, "istallion")) return -EIO; @@ -3834,7 +3412,7 @@ static int stli_initecp(stlibrd_t *brdp) if ((brdp->iobase == 0) || (brdp->memaddr == 0)) { release_region(brdp->iobase, brdp->iosize); - return(-ENODEV); + return -ENODEV; } brdp->iosize = ECP_IOSIZE; @@ -3903,7 +3481,7 @@ static int stli_initecp(stlibrd_t *brdp) default: release_region(brdp->iobase, brdp->iosize); - return(-EINVAL); + return -EINVAL; } /* @@ -3915,10 +3493,10 @@ static int stli_initecp(stlibrd_t *brdp) EBRDINIT(brdp); brdp->membase = ioremap(brdp->memaddr, brdp->memsize); - if (brdp->membase == (void *) NULL) + if (brdp->membase == NULL) { release_region(brdp->iobase, brdp->iosize); - return(-ENOMEM); + return -ENOMEM; } /* @@ -3927,23 +3505,14 @@ static int stli_initecp(stlibrd_t *brdp) * this is, and what it is connected to it. */ EBRDENABLE(brdp); - sigsp = (cdkecpsig_t *) EBRDGETMEMPTR(brdp, CDK_SIGADDR); + sigsp = (cdkecpsig_t __iomem *) EBRDGETMEMPTR(brdp, CDK_SIGADDR); memcpy(&sig, sigsp, sizeof(cdkecpsig_t)); EBRDDISABLE(brdp); -#if 0 - printk("%s(%d): sig-> magic=%x rom=%x panel=%x,%x,%x,%x,%x,%x,%x,%x\n", - __FILE__, __LINE__, (int) sig.magic, sig.romver, sig.panelid[0], - (int) sig.panelid[1], (int) sig.panelid[2], - (int) sig.panelid[3], (int) sig.panelid[4], - (int) sig.panelid[5], (int) sig.panelid[6], - (int) sig.panelid[7]); -#endif - - if (sig.magic != ECP_MAGIC) + if (sig.magic != cpu_to_le32(ECP_MAGIC)) { release_region(brdp->iobase, brdp->iosize); - return(-ENODEV); + return -ENODEV; } /* @@ -3967,7 +3536,7 @@ static int stli_initecp(stlibrd_t *brdp) brdp->state |= BST_FOUND; - return(0); + return 0; } /*****************************************************************************/ @@ -3979,20 +3548,16 @@ static int stli_initecp(stlibrd_t *brdp) static int stli_initonb(stlibrd_t *brdp) { - cdkonbsig_t sig; - cdkonbsig_t *sigsp; - char *name; - int i; - -#ifdef DEBUG - printk(KERN_DEBUG "stli_initonb(brdp=%x)\n", (int) brdp); -#endif + cdkonbsig_t sig; + cdkonbsig_t __iomem *sigsp; + char *name; + int i; /* * Do a basic sanity check on the IO and memory addresses. */ - if ((brdp->iobase == 0) || (brdp->memaddr == 0)) - return(-ENODEV); + if (brdp->iobase == 0 || brdp->memaddr == 0) + return -ENODEV; brdp->iosize = ONB_IOSIZE; @@ -4010,7 +3575,6 @@ static int stli_initonb(stlibrd_t *brdp) case BRD_ONBOARD2: case BRD_ONBOARD2_32: case BRD_ONBOARDRS: - brdp->membase = (void *) brdp->memaddr; brdp->memsize = ONB_MEMSIZE; brdp->pagesize = ONB_ATPAGESIZE; brdp->init = stli_onbinit; @@ -4028,7 +3592,6 @@ static int stli_initonb(stlibrd_t *brdp) break; case BRD_ONBOARDE: - brdp->membase = (void *) brdp->memaddr; brdp->memsize = ONB_EIMEMSIZE; brdp->pagesize = ONB_EIPAGESIZE; brdp->init = stli_onbeinit; @@ -4044,7 +3607,6 @@ static int stli_initonb(stlibrd_t *brdp) case BRD_BRUMBY4: case BRD_BRUMBY8: case BRD_BRUMBY16: - brdp->membase = (void *) brdp->memaddr; brdp->memsize = BBY_MEMSIZE; brdp->pagesize = BBY_PAGESIZE; brdp->init = stli_bbyinit; @@ -4058,7 +3620,6 @@ static int stli_initonb(stlibrd_t *brdp) break; case BRD_STALLION: - brdp->membase = (void *) brdp->memaddr; brdp->memsize = STAL_MEMSIZE; brdp->pagesize = STAL_PAGESIZE; brdp->init = stli_stalinit; @@ -4073,7 +3634,7 @@ static int stli_initonb(stlibrd_t *brdp) default: release_region(brdp->iobase, brdp->iosize); - return(-EINVAL); + return -EINVAL; } /* @@ -4085,10 +3646,10 @@ static int stli_initonb(stlibrd_t *brdp) EBRDINIT(brdp); brdp->membase = ioremap(brdp->memaddr, brdp->memsize); - if (brdp->membase == (void *) NULL) + if (brdp->membase == NULL) { release_region(brdp->iobase, brdp->iosize); - return(-ENOMEM); + return -ENOMEM; } /* @@ -4097,21 +3658,17 @@ static int stli_initonb(stlibrd_t *brdp) * this is, and how many ports. */ EBRDENABLE(brdp); - sigsp = (cdkonbsig_t *) EBRDGETMEMPTR(brdp, CDK_SIGADDR); - memcpy(&sig, sigsp, sizeof(cdkonbsig_t)); + sigsp = (cdkonbsig_t __iomem *) EBRDGETMEMPTR(brdp, CDK_SIGADDR); + memcpy_fromio(&sig, sigsp, sizeof(cdkonbsig_t)); EBRDDISABLE(brdp); -#if 0 - printk("%s(%d): sig-> magic=%x:%x:%x:%x romver=%x amask=%x:%x:%x\n", - __FILE__, __LINE__, sig.magic0, sig.magic1, sig.magic2, - sig.magic3, sig.romver, sig.amask0, sig.amask1, sig.amask2); -#endif - - if ((sig.magic0 != ONB_MAGIC0) || (sig.magic1 != ONB_MAGIC1) || - (sig.magic2 != ONB_MAGIC2) || (sig.magic3 != ONB_MAGIC3)) + if (sig.magic0 != cpu_to_le16(ONB_MAGIC0) || + sig.magic1 != cpu_to_le16(ONB_MAGIC1) || + sig.magic2 != cpu_to_le16(ONB_MAGIC2) || + sig.magic3 != cpu_to_le16(ONB_MAGIC3)) { release_region(brdp->iobase, brdp->iosize); - return(-ENODEV); + return -ENODEV; } /* @@ -4132,7 +3689,7 @@ static int stli_initonb(stlibrd_t *brdp) brdp->state |= BST_FOUND; - return(0); + return 0; } /*****************************************************************************/ @@ -4145,31 +3702,25 @@ static int stli_initonb(stlibrd_t *brdp) static int stli_startbrd(stlibrd_t *brdp) { - volatile cdkhdr_t *hdrp; - volatile cdkmem_t *memp; - volatile cdkasy_t *ap; - unsigned long flags; - stliport_t *portp; - int portnr, nrdevs, i, rc; - -#ifdef DEBUG - printk(KERN_DEBUG "stli_startbrd(brdp=%x)\n", (int) brdp); -#endif - - rc = 0; - - save_flags(flags); - cli(); + cdkhdr_t __iomem *hdrp; + cdkmem_t __iomem *memp; + cdkasy_t __iomem *ap; + unsigned long flags; + stliport_t *portp; + int portnr, nrdevs, i, rc = 0; + u32 memoff; + + spin_lock_irqsave(&brd_lock, flags); EBRDENABLE(brdp); - hdrp = (volatile cdkhdr_t *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); + hdrp = (cdkhdr_t __iomem *) EBRDGETMEMPTR(brdp, CDK_CDKADDR); nrdevs = hdrp->nrdevs; #if 0 printk("%s(%d): CDK version %d.%d.%d --> " "nrdevs=%d memp=%x hostp=%x slavep=%x\n", - __FILE__, __LINE__, hdrp->ver_release, hdrp->ver_modification, - hdrp->ver_fix, nrdevs, (int) hdrp->memp, (int) hdrp->hostp, - (int) hdrp->slavep); + __FILE__, __LINE__, readb(&hdrp->ver_release), readb(&hdrp->ver_modification), + readb(&hdrp->ver_fix), nrdevs, (int) readl(&hdrp->memp), readl(&hdrp->hostp), + readl(&hdrp->slavep)); #endif if (nrdevs < (brdp->nrports + 1)) { @@ -4181,14 +3732,14 @@ static int stli_startbrd(stlibrd_t *brdp) brdp->hostoffset = hdrp->hostp - CDK_CDKADDR; brdp->slaveoffset = hdrp->slavep - CDK_CDKADDR; brdp->bitsize = (nrdevs + 7) / 8; - memp = (volatile cdkmem_t *) hdrp->memp; - if (((unsigned long) memp) > brdp->memsize) { + memoff = readl(&hdrp->memp); + if (memoff > brdp->memsize) { printk(KERN_ERR "STALLION: corrupted shared memory region?\n"); rc = -EIO; goto stli_donestartup; } - memp = (volatile cdkmem_t *) EBRDGETMEMPTR(brdp, (unsigned long) memp); - if (memp->dtype != TYP_ASYNCTRL) { + memp = (cdkmem_t __iomem *) EBRDGETMEMPTR(brdp, memoff); + if (readw(&memp->dtype) != TYP_ASYNCTRL) { printk(KERN_ERR "STALLION: no slave control device found\n"); goto stli_donestartup; } @@ -4200,19 +3751,19 @@ static int stli_startbrd(stlibrd_t *brdp) * change pages while reading memory map. */ for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++, memp++) { - if (memp->dtype != TYP_ASYNC) + if (readw(&memp->dtype) != TYP_ASYNC) break; portp = brdp->ports[portnr]; - if (portp == (stliport_t *) NULL) + if (portp == NULL) break; portp->devnr = i; - portp->addr = memp->offset; + portp->addr = readl(&memp->offset); portp->reqbit = (unsigned char) (0x1 << (i * 8 / nrdevs)); portp->portidx = (unsigned char) (i / 8); portp->portbit = (unsigned char) (0x1 << (i % 8)); } - hdrp->slavereq = 0xff; + writeb(0xff, &hdrp->slavereq); /* * For each port setup a local copy of the RX and TX buffer offsets @@ -4221,22 +3772,22 @@ static int stli_startbrd(stlibrd_t *brdp) */ for (i = 1, portnr = 0; (i < nrdevs); i++, portnr++) { portp = brdp->ports[portnr]; - if (portp == (stliport_t *) NULL) + if (portp == NULL) break; if (portp->addr == 0) break; - ap = (volatile cdkasy_t *) EBRDGETMEMPTR(brdp, portp->addr); - if (ap != (volatile cdkasy_t *) NULL) { - portp->rxsize = ap->rxq.size; - portp->txsize = ap->txq.size; - portp->rxoffset = ap->rxq.offset; - portp->txoffset = ap->txq.offset; + ap = (cdkasy_t __iomem *) EBRDGETMEMPTR(brdp, portp->addr); + if (ap != NULL) { + portp->rxsize = readw(&ap->rxq.size); + portp->txsize = readw(&ap->txq.size); + portp->rxoffset = readl(&ap->rxq.offset); + portp->txoffset = readl(&ap->txq.offset); } } stli_donestartup: EBRDDISABLE(brdp); - restore_flags(flags); + spin_unlock_irqrestore(&brd_lock, flags); if (rc == 0) brdp->state |= BST_STARTED; @@ -4247,7 +3798,7 @@ static int stli_startbrd(stlibrd_t *brdp) add_timer(&stli_timerlist); } - return(rc); + return rc; } /*****************************************************************************/ @@ -4258,10 +3809,6 @@ static int stli_startbrd(stlibrd_t *brdp) static int __init stli_brdinit(stlibrd_t *brdp) { -#ifdef DEBUG - printk(KERN_DEBUG "stli_brdinit(brdp=%x)\n", (int) brdp); -#endif - stli_brds[brdp->brdnr] = brdp; switch (brdp->brdtype) { @@ -4289,11 +3836,11 @@ static int __init stli_brdinit(stlibrd_t *brdp) case BRD_ECHPCI: printk(KERN_ERR "STALLION: %s board type not supported in " "this driver\n", stli_brdnames[brdp->brdtype]); - return(ENODEV); + return -ENODEV; default: printk(KERN_ERR "STALLION: board=%d is unknown board " "type=%d\n", brdp->brdnr, brdp->brdtype); - return(ENODEV); + return -ENODEV; } if ((brdp->state & BST_FOUND) == 0) { @@ -4301,7 +3848,7 @@ static int __init stli_brdinit(stlibrd_t *brdp) "io=%x mem=%x\n", stli_brdnames[brdp->brdtype], brdp->brdnr, brdp->iobase, (int) brdp->memaddr); - return(ENODEV); + return -ENODEV; } stli_initports(brdp); @@ -4309,7 +3856,7 @@ static int __init stli_brdinit(stlibrd_t *brdp) "nrpanels=%d nrports=%d\n", stli_brdnames[brdp->brdtype], brdp->brdnr, brdp->iobase, (int) brdp->memaddr, brdp->nrpanels, brdp->nrports); - return(0); + return 0; } /*****************************************************************************/ @@ -4321,14 +3868,10 @@ static int __init stli_brdinit(stlibrd_t *brdp) static int stli_eisamemprobe(stlibrd_t *brdp) { - cdkecpsig_t ecpsig, *ecpsigp; - cdkonbsig_t onbsig, *onbsigp; + cdkecpsig_t ecpsig, __iomem *ecpsigp; + cdkonbsig_t onbsig, __iomem *onbsigp; int i, foundit; -#ifdef DEBUG - printk(KERN_DEBUG "stli_eisamemprobe(brdp=%x)\n", (int) brdp); -#endif - /* * First up we reset the board, to get it into a known state. There * is only 2 board types here we need to worry about. Don;t use the @@ -4352,7 +3895,7 @@ static int stli_eisamemprobe(stlibrd_t *brdp) mdelay(1); stli_onbeenable(brdp); } else { - return(-ENODEV); + return -ENODEV; } foundit = 0; @@ -4364,25 +3907,24 @@ static int stli_eisamemprobe(stlibrd_t *brdp) */ for (i = 0; (i < stli_eisamempsize); i++) { brdp->memaddr = stli_eisamemprobeaddrs[i]; - brdp->membase = (void *) brdp->memaddr; brdp->membase = ioremap(brdp->memaddr, brdp->memsize); - if (brdp->membase == (void *) NULL) + if (brdp->membase == NULL) continue; if (brdp->brdtype == BRD_ECPE) { - ecpsigp = (cdkecpsig_t *) stli_ecpeigetmemptr(brdp, + ecpsigp = (cdkecpsig_t __iomem *) stli_ecpeigetmemptr(brdp, CDK_SIGADDR, __LINE__); - memcpy(&ecpsig, ecpsigp, sizeof(cdkecpsig_t)); - if (ecpsig.magic == ECP_MAGIC) + memcpy_fromio(&ecpsig, ecpsigp, sizeof(cdkecpsig_t)); + if (ecpsig.magic == cpu_to_le32(ECP_MAGIC)) foundit = 1; } else { - onbsigp = (cdkonbsig_t *) stli_onbegetmemptr(brdp, + onbsigp = (cdkonbsig_t __iomem *) stli_onbegetmemptr(brdp, CDK_SIGADDR, __LINE__); - memcpy(&onbsig, onbsigp, sizeof(cdkonbsig_t)); - if ((onbsig.magic0 == ONB_MAGIC0) && - (onbsig.magic1 == ONB_MAGIC1) && - (onbsig.magic2 == ONB_MAGIC2) && - (onbsig.magic3 == ONB_MAGIC3)) + memcpy_fromio(&onbsig, onbsigp, sizeof(cdkonbsig_t)); + if ((onbsig.magic0 == cpu_to_le16(ONB_MAGIC0)) && + (onbsig.magic1 == cpu_to_le16(ONB_MAGIC1)) && + (onbsig.magic2 == cpu_to_le16(ONB_MAGIC2)) && + (onbsig.magic3 == cpu_to_le16(ONB_MAGIC3))) foundit = 1; } @@ -4406,9 +3948,9 @@ static int stli_eisamemprobe(stlibrd_t *brdp) printk(KERN_ERR "STALLION: failed to probe shared memory " "region for %s in EISA slot=%d\n", stli_brdnames[brdp->brdtype], (brdp->iobase >> 12)); - return(-ENODEV); + return -ENODEV; } - return(0); + return 0; } static int stli_getbrdnr(void) @@ -4439,22 +3981,16 @@ static int stli_getbrdnr(void) static int stli_findeisabrds(void) { - stlibrd_t *brdp; - unsigned int iobase, eid; - int i; - -#ifdef DEBUG - printk(KERN_DEBUG "stli_findeisabrds()\n"); -#endif + stlibrd_t *brdp; + unsigned int iobase, eid; + int i; /* - * Firstly check if this is an EISA system. Do this by probing for - * the system board EISA ID. If this is not an EISA system then + * Firstly check if this is an EISA system. If this is not an EISA system then * don't bother going any further! */ - outb(0xff, 0xc80); - if (inb(0xc80) == 0xff) - return(0); + if (EISA_bus) + return 0; /* * Looks like an EISA system, so go searching for EISA boards. @@ -4472,7 +4008,7 @@ static int stli_findeisabrds(void) */ for (i = 0; (i < STL_MAXBRDS); i++) { brdp = stli_brds[i]; - if (brdp == (stlibrd_t *) NULL) + if (brdp == NULL) continue; if (brdp->iobase == iobase) break; @@ -4484,10 +4020,10 @@ static int stli_findeisabrds(void) * We have found a Stallion board and it is not configured already. * Allocate a board structure and initialize it. */ - if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL) - return(-ENOMEM); + if ((brdp = stli_allocbrd()) == NULL) + return -ENOMEM; if ((brdp->brdnr = stli_getbrdnr()) < 0) - return(-ENOMEM); + return -ENOMEM; eid = inb(iobase + 0xc82); if (eid == ECP_EISAID) brdp->brdtype = BRD_ECPE; @@ -4502,7 +4038,7 @@ static int stli_findeisabrds(void) stli_brdinit(brdp); } - return(0); + return 0; } /*****************************************************************************/ @@ -4523,32 +4059,18 @@ static int stli_findeisabrds(void) static int stli_initpcibrd(int brdtype, struct pci_dev *devp) { - stlibrd_t *brdp; - -#ifdef DEBUG - printk(KERN_DEBUG "stli_initpcibrd(brdtype=%d,busnr=%x,devnr=%x)\n", - brdtype, dev->bus->number, dev->devfn); -#endif + stlibrd_t *brdp; if (pci_enable_device(devp)) - return(-EIO); - if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL) - return(-ENOMEM); + return -EIO; + if ((brdp = stli_allocbrd()) == NULL) + return -ENOMEM; if ((brdp->brdnr = stli_getbrdnr()) < 0) { printk(KERN_INFO "STALLION: too many boards found, " "maximum supported %d\n", STL_MAXBRDS); - return(0); + return 0; } brdp->brdtype = brdtype; - -#ifdef DEBUG - printk(KERN_DEBUG "%s(%d): BAR[]=%lx,%lx,%lx,%lx\n", __FILE__, __LINE__, - pci_resource_start(devp, 0), - pci_resource_start(devp, 1), - pci_resource_start(devp, 2), - pci_resource_start(devp, 3)); -#endif - /* * We have all resources from the board, so lets setup the actual * board structure now. @@ -4557,7 +4079,7 @@ static int stli_initpcibrd(int brdtype, struct pci_dev *devp) brdp->memaddr = pci_resource_start(devp, 2); stli_brdinit(brdp); - return(0); + return 0; } /*****************************************************************************/ @@ -4569,20 +4091,12 @@ static int stli_initpcibrd(int brdtype, struct pci_dev *devp) static int stli_findpcibrds(void) { - struct pci_dev *dev = NULL; - int rc; - -#ifdef DEBUG - printk("stli_findpcibrds()\n"); -#endif + struct pci_dev *dev = NULL; - while ((dev = pci_find_device(PCI_VENDOR_ID_STALLION, - PCI_DEVICE_ID_ECRA, dev))) { - if ((rc = stli_initpcibrd(BRD_ECPPCI, dev))) - return(rc); + while ((dev = pci_get_device(PCI_VENDOR_ID_STALLION, PCI_DEVICE_ID_ECRA, dev))) { + stli_initpcibrd(BRD_ECPPCI, dev); } - - return(0); + return 0; } #endif @@ -4595,17 +4109,16 @@ static int stli_findpcibrds(void) static stlibrd_t *stli_allocbrd(void) { - stlibrd_t *brdp; + stlibrd_t *brdp; brdp = kzalloc(sizeof(stlibrd_t), GFP_KERNEL); if (!brdp) { printk(KERN_ERR "STALLION: failed to allocate memory " - "(size=%d)\n", sizeof(stlibrd_t)); + "(size=%Zd)\n", sizeof(stlibrd_t)); return NULL; } - brdp->magic = STLI_BOARDMAGIC; - return(brdp); + return brdp; } /*****************************************************************************/ @@ -4617,13 +4130,9 @@ static stlibrd_t *stli_allocbrd(void) static int stli_initbrds(void) { - stlibrd_t *brdp, *nxtbrdp; - stlconf_t *confp; - int i, j; - -#ifdef DEBUG - printk(KERN_DEBUG "stli_initbrds()\n"); -#endif + stlibrd_t *brdp, *nxtbrdp; + stlconf_t *confp; + int i, j; if (stli_nrbrds > STL_MAXBRDS) { printk(KERN_INFO "STALLION: too many boards in configuration " @@ -4638,11 +4147,9 @@ static int stli_initbrds(void) */ for (i = 0; (i < stli_nrbrds); i++) { confp = &stli_brdconf[i]; -#ifdef MODULE stli_parsebrd(confp, stli_brdsp[i]); -#endif - if ((brdp = stli_allocbrd()) == (stlibrd_t *) NULL) - return(-ENOMEM); + if ((brdp = stli_allocbrd()) == NULL) + return -ENOMEM; brdp->brdnr = i; brdp->brdtype = confp->brdtype; brdp->iobase = confp->ioaddr1; @@ -4654,9 +4161,7 @@ static int stli_initbrds(void) * Static configuration table done, so now use dynamic methods to * see if any more boards should be configured. */ -#ifdef MODULE stli_argbrds(); -#endif if (STLI_EISAPROBE) stli_findeisabrds(); #ifdef CONFIG_PCI @@ -4672,11 +4177,11 @@ static int stli_initbrds(void) if (stli_nrbrds > 1) { for (i = 0; (i < stli_nrbrds); i++) { brdp = stli_brds[i]; - if (brdp == (stlibrd_t *) NULL) + if (brdp == NULL) continue; for (j = i + 1; (j < stli_nrbrds); j++) { nxtbrdp = stli_brds[j]; - if (nxtbrdp == (stlibrd_t *) NULL) + if (nxtbrdp == NULL) continue; if ((brdp->membase >= nxtbrdp->membase) && (brdp->membase <= (nxtbrdp->membase + @@ -4691,7 +4196,7 @@ static int stli_initbrds(void) if (stli_shared == 0) { for (i = 0; (i < stli_nrbrds); i++) { brdp = stli_brds[i]; - if (brdp == (stlibrd_t *) NULL) + if (brdp == NULL) continue; if (brdp->state & BST_FOUND) { EBRDENABLE(brdp); @@ -4701,7 +4206,7 @@ static int stli_initbrds(void) } } - return(0); + return 0; } /*****************************************************************************/ @@ -4714,48 +4219,55 @@ static int stli_initbrds(void) static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, loff_t *offp) { - unsigned long flags; - void *memptr; - stlibrd_t *brdp; - int brdnr, size, n; - -#ifdef DEBUG - printk(KERN_DEBUG "stli_memread(fp=%x,buf=%x,count=%x,offp=%x)\n", - (int) fp, (int) buf, count, (int) offp); -#endif + unsigned long flags; + void *memptr; + stlibrd_t *brdp; + int brdnr, size, n; + void *p; + loff_t off = *offp; brdnr = iminor(fp->f_dentry->d_inode); if (brdnr >= stli_nrbrds) - return(-ENODEV); + return -ENODEV; brdp = stli_brds[brdnr]; - if (brdp == (stlibrd_t *) NULL) - return(-ENODEV); + if (brdp == NULL) + return -ENODEV; if (brdp->state == 0) - return(-ENODEV); - if (fp->f_pos >= brdp->memsize) - return(0); + return -ENODEV; + if (off >= brdp->memsize || off + count < off) + return 0; - size = MIN(count, (brdp->memsize - fp->f_pos)); + size = MIN(count, (brdp->memsize - off)); + + /* + * Copy the data a page at a time + */ + + p = (void *)__get_free_page(GFP_KERNEL); + if(p == NULL) + return -ENOMEM; - save_flags(flags); - cli(); - EBRDENABLE(brdp); while (size > 0) { - memptr = (void *) EBRDGETMEMPTR(brdp, fp->f_pos); - n = MIN(size, (brdp->pagesize - (((unsigned long) fp->f_pos) % brdp->pagesize))); - if (copy_to_user(buf, memptr, n)) { + spin_lock_irqsave(&brd_lock, flags); + EBRDENABLE(brdp); + memptr = (void *) EBRDGETMEMPTR(brdp, off); + n = MIN(size, (brdp->pagesize - (((unsigned long) off) % brdp->pagesize))); + n = MIN(n, PAGE_SIZE); + memcpy_fromio(p, memptr, n); + EBRDDISABLE(brdp); + spin_unlock_irqrestore(&brd_lock, flags); + if (copy_to_user(buf, p, n)) { count = -EFAULT; goto out; } - fp->f_pos += n; + off += n; buf += n; size -= n; } out: - EBRDDISABLE(brdp); - restore_flags(flags); - - return(count); + *offp = off; + free_page((unsigned long)p); + return count; } /*****************************************************************************/ @@ -4764,54 +4276,65 @@ static ssize_t stli_memread(struct file *fp, char __user *buf, size_t count, lof * Code to handle an "staliomem" write operation. This device is the * contents of the board shared memory. It is used for down loading * the slave image (and debugging :-) + * + * FIXME: copy under lock */ static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t count, loff_t *offp) { - unsigned long flags; - void *memptr; - stlibrd_t *brdp; - char __user *chbuf; - int brdnr, size, n; - -#ifdef DEBUG - printk(KERN_DEBUG "stli_memwrite(fp=%x,buf=%x,count=%x,offp=%x)\n", - (int) fp, (int) buf, count, (int) offp); -#endif + unsigned long flags; + void *memptr; + stlibrd_t *brdp; + char __user *chbuf; + int brdnr, size, n; + void *p; + loff_t off = *offp; brdnr = iminor(fp->f_dentry->d_inode); + if (brdnr >= stli_nrbrds) - return(-ENODEV); + return -ENODEV; brdp = stli_brds[brdnr]; - if (brdp == (stlibrd_t *) NULL) - return(-ENODEV); + if (brdp == NULL) + return -ENODEV; if (brdp->state == 0) - return(-ENODEV); - if (fp->f_pos >= brdp->memsize) - return(0); + return -ENODEV; + if (off >= brdp->memsize || off + count < off) + return 0; chbuf = (char __user *) buf; - size = MIN(count, (brdp->memsize - fp->f_pos)); + size = MIN(count, (brdp->memsize - off)); + + /* + * Copy the data a page at a time + */ + + p = (void *)__get_free_page(GFP_KERNEL); + if(p == NULL) + return -ENOMEM; - save_flags(flags); - cli(); - EBRDENABLE(brdp); while (size > 0) { - memptr = (void *) EBRDGETMEMPTR(brdp, fp->f_pos); - n = MIN(size, (brdp->pagesize - (((unsigned long) fp->f_pos) % brdp->pagesize))); - if (copy_from_user(memptr, chbuf, n)) { - count = -EFAULT; + n = MIN(size, (brdp->pagesize - (((unsigned long) off) % brdp->pagesize))); + n = MIN(n, PAGE_SIZE); + if (copy_from_user(p, chbuf, n)) { + if (count == 0) + count = -EFAULT; goto out; } - fp->f_pos += n; + spin_lock_irqsave(&brd_lock, flags); + EBRDENABLE(brdp); + memptr = (void *) EBRDGETMEMPTR(brdp, off); + memcpy_toio(memptr, p, n); + EBRDDISABLE(brdp); + spin_unlock_irqrestore(&brd_lock, flags); + off += n; chbuf += n; size -= n; } out: - EBRDDISABLE(brdp); - restore_flags(flags); - - return(count); + free_page((unsigned long) p); + *offp = off; + return count; } /*****************************************************************************/ @@ -4822,16 +4345,16 @@ static ssize_t stli_memwrite(struct file *fp, const char __user *buf, size_t cou static int stli_getbrdstats(combrd_t __user *bp) { - stlibrd_t *brdp; - int i; + stlibrd_t *brdp; + int i; if (copy_from_user(&stli_brdstats, bp, sizeof(combrd_t))) return -EFAULT; if (stli_brdstats.brd >= STL_MAXBRDS) - return(-ENODEV); + return -ENODEV; brdp = stli_brds[stli_brdstats.brd]; - if (brdp == (stlibrd_t *) NULL) - return(-ENODEV); + if (brdp == NULL) + return -ENODEV; memset(&stli_brdstats, 0, sizeof(combrd_t)); stli_brdstats.brd = brdp->brdnr; @@ -4850,7 +4373,7 @@ static int stli_getbrdstats(combrd_t __user *bp) if (copy_to_user(bp, &stli_brdstats, sizeof(combrd_t))) return -EFAULT; - return(0); + return 0; } /*****************************************************************************/ @@ -4861,19 +4384,19 @@ static int stli_getbrdstats(combrd_t __user *bp) static stliport_t *stli_getport(int brdnr, int panelnr, int portnr) { - stlibrd_t *brdp; - int i; + stlibrd_t *brdp; + int i; - if ((brdnr < 0) || (brdnr >= STL_MAXBRDS)) - return((stliport_t *) NULL); + if (brdnr < 0 || brdnr >= STL_MAXBRDS) + return NULL; brdp = stli_brds[brdnr]; - if (brdp == (stlibrd_t *) NULL) - return((stliport_t *) NULL); + if (brdp == NULL) + return NULL; for (i = 0; (i < panelnr); i++) portnr += brdp->panels[i]; if ((portnr < 0) || (portnr >= brdp->nrports)) - return((stliport_t *) NULL); - return(brdp->ports[portnr]); + return NULL; + return brdp->ports[portnr]; } /*****************************************************************************/ @@ -4892,16 +4415,16 @@ static int stli_portcmdstats(stliport_t *portp) memset(&stli_comstats, 0, sizeof(comstats_t)); - if (portp == (stliport_t *) NULL) - return(-ENODEV); + if (portp == NULL) + return -ENODEV; brdp = stli_brds[portp->brdnr]; - if (brdp == (stlibrd_t *) NULL) - return(-ENODEV); + if (brdp == NULL) + return -ENODEV; if (brdp->state & BST_STARTED) { if ((rc = stli_cmdwait(brdp, portp, A_GETSTATS, &stli_cdkstats, sizeof(asystats_t), 1)) < 0) - return(rc); + return rc; } else { memset(&stli_cdkstats, 0, sizeof(asystats_t)); } @@ -4912,13 +4435,12 @@ static int stli_portcmdstats(stliport_t *portp) stli_comstats.state = portp->state; stli_comstats.flags = portp->flags; - save_flags(flags); - cli(); - if (portp->tty != (struct tty_struct *) NULL) { + spin_lock_irqsave(&brd_lock, flags); + if (portp->tty != NULL) { if (portp->tty->driver_data == portp) { stli_comstats.ttystate = portp->tty->flags; - stli_comstats.rxbuffered = -1 /*portp->tty->flip.count*/; - if (portp->tty->termios != (struct termios *) NULL) { + stli_comstats.rxbuffered = -1; + if (portp->tty->termios != NULL) { stli_comstats.cflags = portp->tty->termios->c_cflag; stli_comstats.iflags = portp->tty->termios->c_iflag; stli_comstats.oflags = portp->tty->termios->c_oflag; @@ -4926,7 +4448,7 @@ static int stli_portcmdstats(stliport_t *portp) } } } - restore_flags(flags); + spin_unlock_irqrestore(&brd_lock, flags); stli_comstats.txtotal = stli_cdkstats.txchars; stli_comstats.rxtotal = stli_cdkstats.rxchars + stli_cdkstats.ringover; @@ -4948,7 +4470,7 @@ static int stli_portcmdstats(stliport_t *portp) stli_comstats.hwid = stli_cdkstats.hwid; stli_comstats.signals = stli_mktiocm(stli_cdkstats.signals); - return(0); + return 0; } /*****************************************************************************/ @@ -4961,8 +4483,8 @@ static int stli_portcmdstats(stliport_t *portp) static int stli_getportstats(stliport_t *portp, comstats_t __user *cp) { - stlibrd_t *brdp; - int rc; + stlibrd_t *brdp; + int rc; if (!portp) { if (copy_from_user(&stli_comstats, cp, sizeof(comstats_t))) @@ -4992,8 +4514,8 @@ static int stli_getportstats(stliport_t *portp, comstats_t __user *cp) static int stli_clrportstats(stliport_t *portp, comstats_t __user *cp) { - stlibrd_t *brdp; - int rc; + stlibrd_t *brdp; + int rc; if (!portp) { if (copy_from_user(&stli_comstats, cp, sizeof(comstats_t))) @@ -5031,7 +4553,7 @@ static int stli_clrportstats(stliport_t *portp, comstats_t __user *cp) static int stli_getportstruct(stliport_t __user *arg) { - stliport_t *portp; + stliport_t *portp; if (copy_from_user(&stli_dummyport, arg, sizeof(stliport_t))) return -EFAULT; @@ -5052,7 +4574,7 @@ static int stli_getportstruct(stliport_t __user *arg) static int stli_getbrdstruct(stlibrd_t __user *arg) { - stlibrd_t *brdp; + stlibrd_t *brdp; if (copy_from_user(&stli_dummybrd, arg, sizeof(stlibrd_t))) return -EFAULT; @@ -5076,15 +4598,10 @@ static int stli_getbrdstruct(stlibrd_t __user *arg) static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, unsigned long arg) { - stlibrd_t *brdp; - int brdnr, rc, done; + stlibrd_t *brdp; + int brdnr, rc, done; void __user *argp = (void __user *)arg; -#ifdef DEBUG - printk(KERN_DEBUG "stli_memioctl(ip=%x,fp=%x,cmd=%x,arg=%x)\n", - (int) ip, (int) fp, cmd, (int) arg); -#endif - /* * First up handle the board independent ioctls. */ @@ -5115,7 +4632,7 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un } if (done) - return(rc); + return rc; /* * Now handle the board specific ioctls. These all depend on the @@ -5123,12 +4640,12 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un */ brdnr = iminor(ip); if (brdnr >= STL_MAXBRDS) - return(-ENODEV); + return -ENODEV; brdp = stli_brds[brdnr]; if (!brdp) - return(-ENODEV); + return -ENODEV; if (brdp->state == 0) - return(-ENODEV); + return -ENODEV; switch (cmd) { case STL_BINTR: @@ -5152,8 +4669,7 @@ static int stli_memioctl(struct inode *ip, struct file *fp, unsigned int cmd, un rc = -ENOIOCTLCMD; break; } - - return(rc); + return rc; } static struct tty_operations stli_ops = { @@ -5187,6 +4703,9 @@ int __init stli_init(void) int i; printk(KERN_INFO "%s: version %s\n", stli_drvtitle, stli_drvversion); + spin_lock_init(&stli_lock); + spin_lock_init(&brd_lock); + stli_initbrds(); stli_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); @@ -5196,10 +4715,6 @@ int __init stli_init(void) /* * Allocate a temporary write buffer. */ - stli_tmpwritebuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL); - if (!stli_tmpwritebuf) - printk(KERN_ERR "STALLION: failed to allocate memory " - "(size=%d)\n", STLI_TXBUFSIZE); stli_txcookbuf = kmalloc(STLI_TXBUFSIZE, GFP_KERNEL); if (!stli_txcookbuf) printk(KERN_ERR "STALLION: failed to allocate memory " @@ -5243,7 +4758,7 @@ int __init stli_init(void) printk(KERN_ERR "STALLION: failed to register serial driver\n"); return -EBUSY; } - return(0); + return 0; } /*****************************************************************************/ diff --git a/trunk/drivers/char/mxser.c b/trunk/drivers/char/mxser.c index 645d9d713aec..72cfd09091e0 100644 --- a/trunk/drivers/char/mxser.c +++ b/trunk/drivers/char/mxser.c @@ -996,7 +996,6 @@ static int mxser_open(struct tty_struct *tty, struct file *filp) info->session = current->signal->session; info->pgrp = process_group(current); - clear_bit(TTY_DONT_FLIP, &tty->flags); /* status = mxser_get_msr(info->base, 0, info->port); diff --git a/trunk/drivers/char/n_tty.c b/trunk/drivers/char/n_tty.c index b9371d5bf790..603b9ade5eb0 100644 --- a/trunk/drivers/char/n_tty.c +++ b/trunk/drivers/char/n_tty.c @@ -1132,7 +1132,7 @@ static inline int input_available_p(struct tty_struct *tty, int amt) * buffer, and once to drain the space from the (physical) beginning of * the buffer to head pointer. * - * Called under the tty->atomic_read_lock sem and with TTY_DONT_FLIP set + * Called under the tty->atomic_read_lock sem * */ @@ -1271,7 +1271,6 @@ static ssize_t read_chan(struct tty_struct *tty, struct file *file, } add_wait_queue(&tty->read_wait, &wait); - set_bit(TTY_DONT_FLIP, &tty->flags); while (nr) { /* First test for status change. */ if (tty->packet && tty->link->ctrl_status) { @@ -1315,9 +1314,7 @@ static ssize_t read_chan(struct tty_struct *tty, struct file *file, break; } n_tty_set_room(tty); - clear_bit(TTY_DONT_FLIP, &tty->flags); timeout = schedule_timeout(timeout); - set_bit(TTY_DONT_FLIP, &tty->flags); continue; } __set_current_state(TASK_RUNNING); @@ -1394,7 +1391,6 @@ static ssize_t read_chan(struct tty_struct *tty, struct file *file, if (time) timeout = time; } - clear_bit(TTY_DONT_FLIP, &tty->flags); mutex_unlock(&tty->atomic_read_lock); remove_wait_queue(&tty->read_wait, &wait); diff --git a/trunk/drivers/char/pty.c b/trunk/drivers/char/pty.c index 9b5a2c0e7008..0c17f61549b4 100644 --- a/trunk/drivers/char/pty.c +++ b/trunk/drivers/char/pty.c @@ -101,7 +101,7 @@ static void pty_unthrottle(struct tty_struct * tty) * * FIXME: Our pty_write method is called with our ldisc lock held but * not our partners. We can't just take the other one blindly without - * risking deadlocks. There is also the small matter of TTY_DONT_FLIP + * risking deadlocks. */ static int pty_write(struct tty_struct * tty, const unsigned char *buf, int count) { diff --git a/trunk/drivers/char/stallion.c b/trunk/drivers/char/stallion.c index bf361a5ba70d..00b4a2187164 100644 --- a/trunk/drivers/char/stallion.c +++ b/trunk/drivers/char/stallion.c @@ -3029,6 +3029,9 @@ static int __init stl_init(void) int i; printk(KERN_INFO "%s: version %s\n", stl_drvtitle, stl_drvversion); + spin_lock_init(&stallion_lock); + spin_lock_init(&brd_lock); + stl_initbrds(); stl_serial = alloc_tty_driver(STL_MAXBRDS * STL_MAXPORTS); diff --git a/trunk/drivers/char/tty_io.c b/trunk/drivers/char/tty_io.c index bd74e82d8a72..8d19f7281f0b 100644 --- a/trunk/drivers/char/tty_io.c +++ b/trunk/drivers/char/tty_io.c @@ -267,7 +267,6 @@ static struct tty_buffer *tty_buffer_alloc(size_t size) p->used = 0; p->size = size; p->next = NULL; - p->active = 0; p->commit = 0; p->read = 0; p->char_buf_ptr = (char *)(p->data); @@ -327,10 +326,9 @@ int tty_buffer_request_room(struct tty_struct *tty, size_t size) /* OPTIMISATION: We could keep a per tty "zero" sized buffer to remove this conditional if its worth it. This would be invisible to the callers */ - if ((b = tty->buf.tail) != NULL) { + if ((b = tty->buf.tail) != NULL) left = b->size - b->used; - b->active = 1; - } else + else left = 0; if (left < size) { @@ -338,12 +336,10 @@ int tty_buffer_request_room(struct tty_struct *tty, size_t size) if ((n = tty_buffer_find(tty, size)) != NULL) { if (b != NULL) { b->next = n; - b->active = 0; b->commit = b->used; } else tty->buf.head = n; tty->buf.tail = n; - n->active = 1; } else size = left; } @@ -404,10 +400,8 @@ void tty_schedule_flip(struct tty_struct *tty) { unsigned long flags; spin_lock_irqsave(&tty->buf.lock, flags); - if (tty->buf.tail != NULL) { - tty->buf.tail->active = 0; + if (tty->buf.tail != NULL) tty->buf.tail->commit = tty->buf.tail->used; - } spin_unlock_irqrestore(&tty->buf.lock, flags); schedule_delayed_work(&tty->buf.work, 1); } @@ -784,11 +778,8 @@ static int tty_set_ldisc(struct tty_struct *tty, int ldisc) } clear_bit(TTY_LDISC, &tty->flags); - clear_bit(TTY_DONT_FLIP, &tty->flags); - if (o_tty) { + if (o_tty) clear_bit(TTY_LDISC, &o_tty->flags); - clear_bit(TTY_DONT_FLIP, &o_tty->flags); - } spin_unlock_irqrestore(&tty_ldisc_lock, flags); /* @@ -1955,7 +1946,6 @@ static void release_dev(struct file * filp) * race with the set_ldisc code path. */ clear_bit(TTY_LDISC, &tty->flags); - clear_bit(TTY_DONT_FLIP, &tty->flags); cancel_delayed_work(&tty->buf.work); /* @@ -2775,8 +2765,7 @@ static void flush_to_ldisc(void *private_) struct tty_struct *tty = (struct tty_struct *) private_; unsigned long flags; struct tty_ldisc *disc; - struct tty_buffer *tbuf; - int count; + struct tty_buffer *tbuf, *head; char *char_buf; unsigned char *flag_buf; @@ -2784,32 +2773,37 @@ static void flush_to_ldisc(void *private_) if (disc == NULL) /* !TTY_LDISC */ return; - if (test_bit(TTY_DONT_FLIP, &tty->flags)) { - /* - * Do it after the next timer tick: - */ - schedule_delayed_work(&tty->buf.work, 1); - goto out; - } spin_lock_irqsave(&tty->buf.lock, flags); - while((tbuf = tty->buf.head) != NULL) { - while ((count = tbuf->commit - tbuf->read) != 0) { - char_buf = tbuf->char_buf_ptr + tbuf->read; - flag_buf = tbuf->flag_buf_ptr + tbuf->read; - tbuf->read += count; + head = tty->buf.head; + if (head != NULL) { + tty->buf.head = NULL; + for (;;) { + int count = head->commit - head->read; + if (!count) { + if (head->next == NULL) + break; + tbuf = head; + head = head->next; + tty_buffer_free(tty, tbuf); + continue; + } + if (!tty->receive_room) { + schedule_delayed_work(&tty->buf.work, 1); + break; + } + if (count > tty->receive_room) + count = tty->receive_room; + char_buf = head->char_buf_ptr + head->read; + flag_buf = head->flag_buf_ptr + head->read; + head->read += count; spin_unlock_irqrestore(&tty->buf.lock, flags); disc->receive_buf(tty, char_buf, flag_buf, count); spin_lock_irqsave(&tty->buf.lock, flags); } - if (tbuf->active) - break; - tty->buf.head = tbuf->next; - if (tty->buf.head == NULL) - tty->buf.tail = NULL; - tty_buffer_free(tty, tbuf); + tty->buf.head = head; } spin_unlock_irqrestore(&tty->buf.lock, flags); -out: + tty_ldisc_deref(disc); } @@ -2902,10 +2896,8 @@ void tty_flip_buffer_push(struct tty_struct *tty) { unsigned long flags; spin_lock_irqsave(&tty->buf.lock, flags); - if (tty->buf.tail != NULL) { - tty->buf.tail->active = 0; + if (tty->buf.tail != NULL) tty->buf.tail->commit = tty->buf.tail->used; - } spin_unlock_irqrestore(&tty->buf.lock, flags); if (tty->low_latency) diff --git a/trunk/drivers/char/vr41xx_giu.c b/trunk/drivers/char/vr41xx_giu.c index 05e6e814d86f..073da48c092e 100644 --- a/trunk/drivers/char/vr41xx_giu.c +++ b/trunk/drivers/char/vr41xx_giu.c @@ -689,9 +689,9 @@ static int __devinit giu_probe(struct platform_device *dev) for (i = GIU_IRQ_BASE; i <= GIU_IRQ_LAST; i++) { if (i < GIU_IRQ(GIUINT_HIGH_OFFSET)) - irq_desc[i].handler = &giuint_low_irq_type; + irq_desc[i].chip = &giuint_low_irq_type; else - irq_desc[i].handler = &giuint_high_irq_type; + irq_desc[i].chip = &giuint_high_irq_type; } return cascade_irq(GIUINT_IRQ, giu_get_irq); diff --git a/trunk/drivers/char/watchdog/at91_wdt.c b/trunk/drivers/char/watchdog/at91_wdt.c index ac83bc4b019a..00080655533d 100644 --- a/trunk/drivers/char/watchdog/at91_wdt.c +++ b/trunk/drivers/char/watchdog/at91_wdt.c @@ -17,14 +17,15 @@ #include #include #include +#include #include #include #include #include -#define WDT_DEFAULT_TIME 5 /* 5 seconds */ -#define WDT_MAX_TIME 256 /* 256 seconds */ +#define WDT_DEFAULT_TIME 5 /* seconds */ +#define WDT_MAX_TIME 256 /* seconds */ static int wdt_time = WDT_DEFAULT_TIME; static int nowayout = WATCHDOG_NOWAYOUT; @@ -32,8 +33,10 @@ static int nowayout = WATCHDOG_NOWAYOUT; module_param(wdt_time, int, 0); MODULE_PARM_DESC(wdt_time, "Watchdog time in seconds. (default="__MODULE_STRING(WDT_DEFAULT_TIME) ")"); +#ifdef CONFIG_WATCHDOG_NOWAYOUT module_param(nowayout, int, 0); MODULE_PARM_DESC(nowayout, "Watchdog cannot be stopped once started (default=" __MODULE_STRING(WATCHDOG_NOWAYOUT) ")"); +#endif static unsigned long at91wdt_busy; @@ -138,7 +141,7 @@ static int at91_wdt_ioctl(struct inode *inode, struct file *file, case WDIOC_SETTIMEOUT: if (get_user(new_value, p)) return -EFAULT; - + if (at91_wdt_settimeout(new_value)) return -EINVAL; @@ -196,27 +199,84 @@ static struct miscdevice at91wdt_miscdev = { .fops = &at91wdt_fops, }; -static int __init at91_wdt_init(void) +static int __init at91wdt_probe(struct platform_device *pdev) { int res; - /* Check that the heartbeat value is within range; if not reset to the default */ - if (at91_wdt_settimeout(wdt_time)) { - at91_wdt_settimeout(WDT_DEFAULT_TIME); - printk(KERN_INFO "at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time); - } + if (at91wdt_miscdev.dev) + return -EBUSY; + at91wdt_miscdev.dev = &pdev->dev; res = misc_register(&at91wdt_miscdev); if (res) return res; - printk("AT91 Watchdog Timer enabled (%d seconds, nowayout=%d)\n", wdt_time, nowayout); + printk("AT91 Watchdog Timer enabled (%d seconds%s)\n", wdt_time, nowayout ? ", nowayout" : ""); return 0; } +static int __exit at91wdt_remove(struct platform_device *pdev) +{ + int res; + + res = misc_deregister(&at91wdt_miscdev); + if (!res) + at91wdt_miscdev.dev = NULL; + + return res; +} + +static void at91wdt_shutdown(struct platform_device *pdev) +{ + at91_wdt_stop(); +} + +#ifdef CONFIG_PM + +static int at91wdt_suspend(struct platform_device *pdev, pm_message_t message) +{ + at91_wdt_stop(); + return 0; +} + +static int at91wdt_resume(struct platform_device *pdev) +{ + if (at91wdt_busy) + at91_wdt_start(); + return 0; +} + +#else +#define at91wdt_suspend NULL +#define at91wdt_resume NULL +#endif + +static struct platform_driver at91wdt_driver = { + .probe = at91wdt_probe, + .remove = __exit_p(at91wdt_remove), + .shutdown = at91wdt_shutdown, + .suspend = at91wdt_suspend, + .resume = at91wdt_resume, + .driver = { + .name = "at91_wdt", + .owner = THIS_MODULE, + }, +}; + +static int __init at91_wdt_init(void) +{ + /* Check that the heartbeat value is within range; if not reset to the default */ + if (at91_wdt_settimeout(wdt_time)) { + at91_wdt_settimeout(WDT_DEFAULT_TIME); + pr_info("at91_wdt: wdt_time value must be 1 <= wdt_time <= 256, using %d\n", wdt_time); + } + + return platform_driver_register(&at91wdt_driver); +} + static void __exit at91_wdt_exit(void) { - misc_deregister(&at91wdt_miscdev); + platform_driver_unregister(&at91wdt_driver); } module_init(at91_wdt_init); diff --git a/trunk/drivers/char/watchdog/i8xx_tco.c b/trunk/drivers/char/watchdog/i8xx_tco.c index fa2ba9ebe42a..bfbdbbf3c2f2 100644 --- a/trunk/drivers/char/watchdog/i8xx_tco.c +++ b/trunk/drivers/char/watchdog/i8xx_tco.c @@ -205,6 +205,23 @@ static int tco_timer_set_heartbeat (int t) return 0; } +static int tco_timer_get_timeleft (int *time_left) +{ + unsigned char val; + + spin_lock(&tco_lock); + + /* read the TCO Timer */ + val = inb (TCO1_RLD); + val &= 0x3f; + + spin_unlock(&tco_lock); + + *time_left = (int)((val * 6) / 10); + + return 0; +} + /* * /dev/watchdog handling */ @@ -272,6 +289,7 @@ static int i8xx_tco_ioctl (struct inode *inode, struct file *file, { int new_options, retval = -EINVAL; int new_heartbeat; + int time_left; void __user *argp = (void __user *)arg; int __user *p = argp; static struct watchdog_info ident = { @@ -320,7 +338,7 @@ static int i8xx_tco_ioctl (struct inode *inode, struct file *file, return -EFAULT; if (tco_timer_set_heartbeat(new_heartbeat)) - return -EINVAL; + return -EINVAL; tco_timer_keepalive (); /* Fall */ @@ -329,6 +347,14 @@ static int i8xx_tco_ioctl (struct inode *inode, struct file *file, case WDIOC_GETTIMEOUT: return put_user(heartbeat, p); + case WDIOC_GETTIMELEFT: + { + if (tco_timer_get_timeleft(&time_left)) + return -EINVAL; + + return put_user(time_left, p); + } + default: return -ENOIOCTLCMD; } diff --git a/trunk/drivers/char/watchdog/pcwd_pci.c b/trunk/drivers/char/watchdog/pcwd_pci.c index 2451edbefece..1f40ecefbf72 100644 --- a/trunk/drivers/char/watchdog/pcwd_pci.c +++ b/trunk/drivers/char/watchdog/pcwd_pci.c @@ -21,7 +21,7 @@ */ /* - * A bells and whistles driver is available from: + * A bells and whistles driver is available from: * http://www.kernel.org/pub/linux/kernel/people/wim/pcwd/pcwd_pci/ * * More info available at http://www.berkprod.com/ or http://www.pcwatchdog.com/ @@ -390,6 +390,24 @@ static int pcipcwd_get_temperature(int *temperature) return 0; } +static int pcipcwd_get_timeleft(int *time_left) +{ + int msb; + int lsb; + + /* Read the time that's left before rebooting */ + /* Note: if the board is not yet armed then we will read 0xFFFF */ + send_command(CMD_READ_WATCHDOG_TIMEOUT, &msb, &lsb); + + *time_left = (msb << 8) + lsb; + + if (debug >= VERBOSE) + printk(KERN_DEBUG PFX "Time left before next reboot: %d\n", + *time_left); + + return 0; +} + /* * /dev/watchdog handling */ @@ -512,6 +530,16 @@ static int pcipcwd_ioctl(struct inode *inode, struct file *file, case WDIOC_GETTIMEOUT: return put_user(heartbeat, p); + case WDIOC_GETTIMELEFT: + { + int time_left; + + if (pcipcwd_get_timeleft(&time_left)) + return -EFAULT; + + return put_user(time_left, p); + } + default: return -ENOIOCTLCMD; } diff --git a/trunk/drivers/char/watchdog/pcwd_usb.c b/trunk/drivers/char/watchdog/pcwd_usb.c index 3fdfda9324fa..0d072bed501d 100644 --- a/trunk/drivers/char/watchdog/pcwd_usb.c +++ b/trunk/drivers/char/watchdog/pcwd_usb.c @@ -317,6 +317,19 @@ static int usb_pcwd_get_temperature(struct usb_pcwd_private *usb_pcwd, int *temp return 0; } +static int usb_pcwd_get_timeleft(struct usb_pcwd_private *usb_pcwd, int *time_left) +{ + unsigned char msb, lsb; + + /* Read the time that's left before rebooting */ + /* Note: if the board is not yet armed then we will read 0xFFFF */ + usb_pcwd_send_command(usb_pcwd, CMD_READ_WATCHDOG_TIMEOUT, &msb, &lsb); + + *time_left = (msb << 8) + lsb; + + return 0; +} + /* * /dev/watchdog handling */ @@ -422,6 +435,16 @@ static int usb_pcwd_ioctl(struct inode *inode, struct file *file, case WDIOC_GETTIMEOUT: return put_user(heartbeat, p); + case WDIOC_GETTIMELEFT: + { + int time_left; + + if (usb_pcwd_get_timeleft(usb_pcwd_device, &time_left)) + return -EFAULT; + + return put_user(time_left, p); + } + default: return -ENOIOCTLCMD; } diff --git a/trunk/drivers/ide/Kconfig b/trunk/drivers/ide/Kconfig index d633081fa4c5..d1266fe2d1ab 100644 --- a/trunk/drivers/ide/Kconfig +++ b/trunk/drivers/ide/Kconfig @@ -774,11 +774,18 @@ config BLK_DEV_IDEDMA_PMAC performance. config BLK_DEV_IDE_PMAC_BLINK - bool "Blink laptop LED on drive activity" + bool "Blink laptop LED on drive activity (DEPRECATED)" depends on BLK_DEV_IDE_PMAC && ADB_PMU + select ADB_PMU_LED + select LEDS_TRIGGERS + select LEDS_TRIGGER_IDE_DISK help This option enables the use of the sleep LED as a hard drive activity LED. + This option is deprecated, it only selects ADB_PMU_LED and + LEDS_TRIGGER_IDE_DISK and changes the code in the new led class + device to default to the ide-disk trigger (which should be set + from userspace via sysfs). config BLK_DEV_IDE_SWARM tristate "IDE for Sibyte evaluation boards" diff --git a/trunk/drivers/ide/ide-io.c b/trunk/drivers/ide/ide-io.c index 935cb2583770..26ceab1e90bb 100644 --- a/trunk/drivers/ide/ide-io.c +++ b/trunk/drivers/ide/ide-io.c @@ -505,7 +505,7 @@ static ide_startstop_t ide_ata_error(ide_drive_t *drive, struct request *rq, u8 } } - if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ) + if ((stat & DRQ_STAT) && rq_data_dir(rq) == READ && hwif->err_stops_fifo == 0) try_to_flush_leftover_data(drive); if (hwif->INB(IDE_STATUS_REG) & (BUSY_STAT|DRQ_STAT)) diff --git a/trunk/drivers/ide/ide-iops.c b/trunk/drivers/ide/ide-iops.c index 97a49e77a8f1..32117f0ec5c0 100644 --- a/trunk/drivers/ide/ide-iops.c +++ b/trunk/drivers/ide/ide-iops.c @@ -597,6 +597,10 @@ u8 eighty_ninty_three (ide_drive_t *drive) { if(HWIF(drive)->udma_four == 0) return 0; + + /* Check for SATA but only if we are ATA5 or higher */ + if (drive->id->hw_config == 0 && (drive->id->major_rev_num & 0x7FE0)) + return 1; if (!(drive->id->hw_config & 0x6000)) return 0; #ifndef CONFIG_IDEDMA_IVB diff --git a/trunk/drivers/ide/pci/aec62xx.c b/trunk/drivers/ide/pci/aec62xx.c index c743e68c33aa..3edd7060510f 100644 --- a/trunk/drivers/ide/pci/aec62xx.c +++ b/trunk/drivers/ide/pci/aec62xx.c @@ -22,7 +22,7 @@ struct chipset_bus_clock_list_entry { u8 ultra_settings; }; -static struct chipset_bus_clock_list_entry aec6xxx_33_base [] = { +static const struct chipset_bus_clock_list_entry aec6xxx_33_base [] = { { XFER_UDMA_6, 0x31, 0x07 }, { XFER_UDMA_5, 0x31, 0x06 }, { XFER_UDMA_4, 0x31, 0x05 }, @@ -42,7 +42,7 @@ static struct chipset_bus_clock_list_entry aec6xxx_33_base [] = { { 0, 0x00, 0x00 } }; -static struct chipset_bus_clock_list_entry aec6xxx_34_base [] = { +static const struct chipset_bus_clock_list_entry aec6xxx_34_base [] = { { XFER_UDMA_6, 0x41, 0x06 }, { XFER_UDMA_5, 0x41, 0x05 }, { XFER_UDMA_4, 0x41, 0x04 }, @@ -254,7 +254,8 @@ static unsigned int __devinit init_chipset_aec62xx(struct pci_dev *dev, const ch if (dev->resource[PCI_ROM_RESOURCE].start) { pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); - printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start); + printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, + (unsigned long)dev->resource[PCI_ROM_RESOURCE].start); } if (bus_speed <= 33) @@ -425,12 +426,12 @@ static int __devinit aec62xx_init_one(struct pci_dev *dev, const struct pci_devi return d->init_setup(dev, d); } -static struct pci_device_id aec62xx_pci_tbl[] = { - { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP850UF, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 }, - { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1 }, - { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860R, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2 }, - { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3 }, - { PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865R, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4 }, +static const struct pci_device_id aec62xx_pci_tbl[] = { + { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP850UF), 0 }, + { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860), 1 }, + { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP860R), 2 }, + { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865), 3 }, + { PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_ATP865R), 4 }, { 0, }, }; MODULE_DEVICE_TABLE(pci, aec62xx_pci_tbl); diff --git a/trunk/drivers/ide/pci/cmd64x.c b/trunk/drivers/ide/pci/cmd64x.c index 3d9c7afc8695..92b7b1549b16 100644 --- a/trunk/drivers/ide/pci/cmd64x.c +++ b/trunk/drivers/ide/pci/cmd64x.c @@ -189,14 +189,6 @@ static int cmd64x_get_info (char *buffer, char **addr, off_t offset, int count) #endif /* defined(DISPLAY_CMD64X_TIMINGS) && defined(CONFIG_PROC_FS) */ -/* - * Registers and masks for easy access by drive index: - */ -#if 0 -static u8 prefetch_regs[4] = {CNTRL, CNTRL, ARTTIM23, ARTTIM23}; -static u8 prefetch_masks[4] = {CNTRL_DIS_RA0, CNTRL_DIS_RA1, ARTTIM23_DIS_RA2, ARTTIM23_DIS_RA3}; -#endif - /* * This routine writes the prepared setup/active/recovery counts * for a drive into the cmd646 chipset registers to active them. @@ -606,13 +598,6 @@ static unsigned int __devinit init_chipset_cmd64x(struct pci_dev *dev, const cha pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); class_rev &= 0xff; -#ifdef __i386__ - if (dev->resource[PCI_ROM_RESOURCE].start) { - pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); - printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, dev->resource[PCI_ROM_RESOURCE].start); - } -#endif - switch(dev->device) { case PCI_DEVICE_ID_CMD_643: break; diff --git a/trunk/drivers/ide/pci/hpt34x.c b/trunk/drivers/ide/pci/hpt34x.c index be334da7a754..7da550281cf2 100644 --- a/trunk/drivers/ide/pci/hpt34x.c +++ b/trunk/drivers/ide/pci/hpt34x.c @@ -176,7 +176,7 @@ static unsigned int __devinit init_chipset_hpt34x(struct pci_dev *dev, const cha pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); printk(KERN_INFO "HPT345: ROM enabled at 0x%08lx\n", - dev->resource[PCI_ROM_RESOURCE].start); + (unsigned long)dev->resource[PCI_ROM_RESOURCE].start); } pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0); } else { diff --git a/trunk/drivers/ide/pci/pdc202xx_new.c b/trunk/drivers/ide/pci/pdc202xx_new.c index acd63173199b..5a8334d134fb 100644 --- a/trunk/drivers/ide/pci/pdc202xx_new.c +++ b/trunk/drivers/ide/pci/pdc202xx_new.c @@ -313,8 +313,8 @@ static unsigned int __devinit init_chipset_pdcnew(struct pci_dev *dev, const cha if (dev->resource[PCI_ROM_RESOURCE].start) { pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); - printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", - name, dev->resource[PCI_ROM_RESOURCE].start); + printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, + (unsigned long)dev->resource[PCI_ROM_RESOURCE].start); } #ifdef CONFIG_PPC_PMAC @@ -338,6 +338,8 @@ static void __devinit init_hwif_pdc202new(ide_hwif_t *hwif) hwif->ultra_mask = 0x7f; hwif->mwdma_mask = 0x07; + hwif->err_stops_fifo = 1; + hwif->ide_dma_check = &pdcnew_config_drive_xfer_rate; hwif->ide_dma_lostirq = &pdcnew_ide_dma_lostirq; hwif->ide_dma_timeout = &pdcnew_ide_dma_timeout; diff --git a/trunk/drivers/ide/pci/pdc202xx_old.c b/trunk/drivers/ide/pci/pdc202xx_old.c index 22d17548ecdb..1e209d8f9437 100644 --- a/trunk/drivers/ide/pci/pdc202xx_old.c +++ b/trunk/drivers/ide/pci/pdc202xx_old.c @@ -101,31 +101,6 @@ static const char *pdc_quirk_drives[] = { #define MC1 0x02 /* DMA"C" timing */ #define MC0 0x01 /* DMA"C" timing */ -#if 0 - unsigned long bibma = pci_resource_start(dev, 4); - u8 hi = 0, lo = 0; - - u8 sc1c = inb_p((u16)bibma + 0x1c); - u8 sc1e = inb_p((u16)bibma + 0x1e); - u8 sc1f = inb_p((u16)bibma + 0x1f); - - p += sprintf(p, "Host Mode : %s\n", - (sc1f & 0x08) ? "Tri-Stated" : "Normal"); - p += sprintf(p, "Bus Clocking : %s\n", - ((sc1f & 0xC0) == 0xC0) ? "100 External" : - ((sc1f & 0x80) == 0x80) ? "66 External" : - ((sc1f & 0x40) == 0x40) ? "33 External" : "33 PCI Internal"); - p += sprintf(p, "IO pad select : %s mA\n", - ((sc1c & 0x03) == 0x03) ? "10" : - ((sc1c & 0x02) == 0x02) ? "8" : - ((sc1c & 0x01) == 0x01) ? "6" : - ((sc1c & 0x00) == 0x00) ? "4" : "??"); - hi = sc1e >> 4; - lo = sc1e & 0xf; - p += sprintf(p, "Status Polling Period : %d\n", hi); - p += sprintf(p, "Interrupt Check Status Polling Delay : %d\n", lo); -#endif - static u8 pdc202xx_ratemask (ide_drive_t *drive) { u8 mode; @@ -505,73 +480,20 @@ static void pdc202xx_reset (ide_drive_t *drive) pdc202xx_reset_host(hwif); pdc202xx_reset_host(mate); -#if 0 - /* - * FIXME: Have to kick all the drives again :-/ - * What a pain in the ACE! - */ - if (hwif->present) { - u16 hunit = 0; - for (hunit = 0; hunit < MAX_DRIVES; ++hunit) { - ide_drive_t *hdrive = &hwif->drives[hunit]; - if (hdrive->present) { - if (hwif->ide_dma_check) - hwif->ide_dma_check(hdrive); - else - hwif->tuneproc(hdrive, 5); - } - } - } - if (mate->present) { - u16 munit = 0; - for (munit = 0; munit < MAX_DRIVES; ++munit) { - ide_drive_t *mdrive = &mate->drives[munit]; - if (mdrive->present) { - if (mate->ide_dma_check) - mate->ide_dma_check(mdrive); - else - mate->tuneproc(mdrive, 5); - } - } - } -#else hwif->tuneproc(drive, 5); -#endif } -static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev, const char *name) +static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev, + const char *name) { + /* This doesn't appear needed */ if (dev->resource[PCI_ROM_RESOURCE].start) { pci_write_config_dword(dev, PCI_ROM_ADDRESS, dev->resource[PCI_ROM_RESOURCE].start | PCI_ROM_ADDRESS_ENABLE); - printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", - name, dev->resource[PCI_ROM_RESOURCE].start); - } - - /* - * software reset - this is required because the bios - * will set UDMA timing on if the hdd supports it. The - * user may want to turn udma off. A bug in the pdc20262 - * is that it cannot handle a downgrade in timing from - * UDMA to DMA. Disk accesses after issuing a set - * feature command will result in errors. A software - * reset leaves the timing registers intact, - * but resets the drives. - */ -#if 0 - if ((dev->device == PCI_DEVICE_ID_PROMISE_20267) || - (dev->device == PCI_DEVICE_ID_PROMISE_20265) || - (dev->device == PCI_DEVICE_ID_PROMISE_20263) || - (dev->device == PCI_DEVICE_ID_PROMISE_20262)) { - unsigned long high_16 = pci_resource_start(dev, 4); - byte udma_speed_flag = inb(high_16 + 0x001f); - outb(udma_speed_flag | 0x10, high_16 + 0x001f); - mdelay(100); - outb(udma_speed_flag & ~0x10, high_16 + 0x001f); - mdelay(2000); /* 2 seconds ?! */ + printk(KERN_INFO "%s: ROM enabled at 0x%08lx\n", name, + (unsigned long)dev->resource[PCI_ROM_RESOURCE].start); } -#endif return dev->irq; } @@ -599,6 +521,8 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif) hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; + hwif->err_stops_fifo = 1; + hwif->ide_dma_check = &pdc202xx_config_drive_xfer_rate; hwif->ide_dma_lostirq = &pdc202xx_ide_dma_lostirq; hwif->ide_dma_timeout = &pdc202xx_ide_dma_timeout; @@ -687,19 +611,6 @@ static int __devinit init_setup_pdc202ata4(struct pci_dev *dev, "mirror fixed.\n", d->name); } } - -#if 0 - if (dev->device == PCI_DEVICE_ID_PROMISE_20262) - if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || - (tmp & e->mask) != e->val)) - - if (d->enablebits[0].reg != d->enablebits[1].reg) { - d->enablebits[0].reg = d->enablebits[1].reg; - d->enablebits[0].mask = d->enablebits[1].mask; - d->enablebits[0].val = d->enablebits[1].val; - } -#endif - return ide_setup_pci_device(dev, d); } @@ -714,22 +625,6 @@ static int __devinit init_setup_pdc20265(struct pci_dev *dev, "attached to I2O RAID controller.\n"); return -ENODEV; } - -#if 0 - { - u8 pri = 0, sec = 0; - - if (e->reg && (pci_read_config_byte(dev, e->reg, &tmp) || - (tmp & e->mask) != e->val)) - - if (d->enablebits[0].reg != d->enablebits[1].reg) { - d->enablebits[0].reg = d->enablebits[1].reg; - d->enablebits[0].mask = d->enablebits[1].mask; - d->enablebits[0].val = d->enablebits[1].val; - } - } -#endif - return ide_setup_pci_device(dev, d); } diff --git a/trunk/drivers/ide/pci/sc1200.c b/trunk/drivers/ide/pci/sc1200.c index 24e21b2838c1..778b82ae964d 100644 --- a/trunk/drivers/ide/pci/sc1200.c +++ b/trunk/drivers/ide/pci/sc1200.c @@ -395,7 +395,6 @@ static int sc1200_resume (struct pci_dev *dev) { ide_hwif_t *hwif = NULL; -printk("SC1200: resume\n"); pci_set_power_state(dev, PCI_D0); // bring chip back from sleep state dev->current_state = PM_EVENT_ON; pci_enable_device(dev); @@ -405,7 +404,6 @@ printk("SC1200: resume\n"); while ((hwif = lookup_pci_dev(hwif, dev)) != NULL) { unsigned int basereg, r, d, format; sc1200_saved_state_t *ss = (sc1200_saved_state_t *)hwif->config_data; -printk("%s: SC1200: resume\n", hwif->name); // // Restore timing registers: this may be unnecessary if BIOS also does it @@ -493,7 +491,7 @@ static int __devinit sc1200_init_one(struct pci_dev *dev, const struct pci_devic } static struct pci_device_id sc1200_pci_tbl[] = { - { PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { PCI_DEVICE(PCI_VENDOR_ID_NS, PCI_DEVICE_ID_NS_SCx200_IDE), 0}, { 0, }, }; MODULE_DEVICE_TABLE(pci, sc1200_pci_tbl); diff --git a/trunk/drivers/ide/pci/serverworks.c b/trunk/drivers/ide/pci/serverworks.c index 0d3073f4eab4..5100b827a935 100644 --- a/trunk/drivers/ide/pci/serverworks.c +++ b/trunk/drivers/ide/pci/serverworks.c @@ -123,11 +123,11 @@ static u8 svwks_csb_check (struct pci_dev *dev) } static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed) { - u8 udma_modes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; - u8 dma_modes[] = { 0x77, 0x21, 0x20 }; - u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 }; - u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 }; - u8 drive_pci2[] = { 0x45, 0x44, 0x47, 0x46 }; + static const u8 udma_modes[] = { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05 }; + static const u8 dma_modes[] = { 0x77, 0x21, 0x20 }; + static const u8 pio_modes[] = { 0x5d, 0x47, 0x34, 0x22, 0x20 }; + static const u8 drive_pci[] = { 0x41, 0x40, 0x43, 0x42 }; + static const u8 drive_pci2[] = { 0x45, 0x44, 0x47, 0x46 }; ide_hwif_t *hwif = HWIF(drive); struct pci_dev *dev = hwif->pci_dev; @@ -392,16 +392,6 @@ static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const cha } outb_p(0x06, 0x0c00); dev->irq = inb_p(0x0c01); -#if 0 - printk("%s: device class (0x%04x)\n", - name, dev->class); - if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) { - dev->class &= ~0x000F0F00; - // dev->class |= ~0x00000400; - dev->class |= ~0x00010100; - /**/ - } -#endif } else { struct pci_dev * findev = NULL; u8 reg41 = 0; @@ -452,7 +442,7 @@ static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const cha pci_write_config_byte(dev, 0x5A, btr); } - return (dev->irq) ? dev->irq : 0; + return dev->irq; } static unsigned int __devinit ata66_svwks_svwks (ide_hwif_t *hwif) @@ -500,11 +490,6 @@ static unsigned int __devinit ata66_svwks (ide_hwif_t *hwif) { struct pci_dev *dev = hwif->pci_dev; - /* Per Specified Design by OEM, and ASIC Architect */ - if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) || - (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) - return 1; - /* Server Works */ if (dev->subsystem_vendor == PCI_VENDOR_ID_SERVERWORKS) return ata66_svwks_svwks (hwif); @@ -517,10 +502,14 @@ static unsigned int __devinit ata66_svwks (ide_hwif_t *hwif) if (dev->subsystem_vendor == PCI_VENDOR_ID_SUN) return ata66_svwks_cobalt (hwif); + /* Per Specified Design by OEM, and ASIC Architect */ + if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) || + (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) + return 1; + return 0; } -#undef CAN_SW_DMA static void __devinit init_hwif_svwks (ide_hwif_t *hwif) { u8 dma_stat = 0; @@ -537,9 +526,6 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif) hwif->ultra_mask = 0x3f; hwif->mwdma_mask = 0x07; -#ifdef CAN_SW_DMA - hwif->swdma_mask = 0x07; -#endif /* CAN_SW_DMA */ hwif->autodma = 0; @@ -562,8 +548,6 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif) hwif->drives[1].autodma = (dma_stat & 0x40); hwif->drives[0].autotune = (!(dma_stat & 0x20)); hwif->drives[1].autotune = (!(dma_stat & 0x40)); -// hwif->drives[0].autodma = hwif->autodma; -// hwif->drives[1].autodma = hwif->autodma; } /* @@ -593,11 +577,6 @@ static int __devinit init_setup_csb6 (struct pci_dev *dev, ide_pci_device_t *d) if (dev->resource[0].start == 0x01f1) d->bootable = ON_BOARD; } -#if 0 - if ((IDE_PCI_DEVID_EQ(d->devid, DEVID_CSB6) && - (!(PCI_FUNC(dev->devfn) & 1))) - d->autodma = AUTODMA; -#endif d->channels = ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE || dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2) && @@ -671,11 +650,11 @@ static int __devinit svwks_init_one(struct pci_dev *dev, const struct pci_device } static struct pci_device_id svwks_pci_tbl[] = { - { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, - { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, - { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, - { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 3}, - { PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 4}, + { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE), 0}, + { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE), 1}, + { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE), 2}, + { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2), 3}, + { PCI_DEVICE(PCI_VENDOR_ID_SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_HT1000IDE), 4}, { 0, }, }; MODULE_DEVICE_TABLE(pci, svwks_pci_tbl); diff --git a/trunk/drivers/ide/pci/siimage.c b/trunk/drivers/ide/pci/siimage.c index f1ca154dd52c..72dade14c725 100644 --- a/trunk/drivers/ide/pci/siimage.c +++ b/trunk/drivers/ide/pci/siimage.c @@ -38,9 +38,6 @@ #include -#undef SIIMAGE_VIRTUAL_DMAPIO -#undef SIIMAGE_LARGE_DMA - /** * pdev_is_sata - check if device is SATA * @pdev: PCI device to check @@ -461,36 +458,6 @@ static int siimage_io_ide_dma_test_irq (ide_drive_t *drive) return 0; } -#if 0 -/** - * siimage_mmio_ide_dma_count - DMA bytes done - * @drive - * - * If we are doing VDMA the CMD680 requires a little bit - * of more careful handling and we have to read the counts - * off ourselves. For non VDMA life is normal. - */ - -static int siimage_mmio_ide_dma_count (ide_drive_t *drive) -{ -#ifdef SIIMAGE_VIRTUAL_DMAPIO - struct request *rq = HWGROUP(drive)->rq; - ide_hwif_t *hwif = HWIF(drive); - u32 count = (rq->nr_sectors * SECTOR_SIZE); - u32 rcount = 0; - unsigned long addr = siimage_selreg(hwif, 0x1C); - - hwif->OUTL(count, addr); - rcount = hwif->INL(addr); - - printk("\n%s: count = %d, rcount = %d, nr_sectors = %lu\n", - drive->name, count, rcount, rq->nr_sectors); - -#endif /* SIIMAGE_VIRTUAL_DMAPIO */ - return __ide_dma_count(drive); -} -#endif - /** * siimage_mmio_ide_dma_test_irq - check we caused an IRQ * @drive: drive we are testing @@ -512,12 +479,10 @@ static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive) u32 sata_error = hwif->INL(SATA_ERROR_REG); hwif->OUTL(sata_error, SATA_ERROR_REG); watchdog = (sata_error & 0x00680000) ? 1 : 0; -#if 1 printk(KERN_WARNING "%s: sata_error = 0x%08x, " "watchdog = %d, %s\n", drive->name, sata_error, watchdog, __FUNCTION__); -#endif } else { watchdog = (ext_stat & 0x8000) ? 1 : 0; @@ -863,7 +828,7 @@ static unsigned int __devinit init_chipset_siimage(struct pci_dev *dev, const ch * time. * * The hardware supports buffered taskfiles and also some rather nice - * extended PRD tables. Unfortunately right now we don't. + * extended PRD tables. For better SI3112 support use the libata driver */ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) @@ -900,9 +865,6 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) * so we can't currently use it sanely since we want to * use LBA48 mode. */ -// base += 0x10; -// hwif->no_lba48 = 1; - hw.io_ports[IDE_DATA_OFFSET] = base; hw.io_ports[IDE_ERROR_OFFSET] = base + 1; hw.io_ports[IDE_NSECTOR_OFFSET] = base + 2; @@ -936,15 +898,8 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif) base = (unsigned long) addr; -#ifdef SIIMAGE_LARGE_DMA -/* Watch the brackets - even Ken and Dennis get some language design wrong */ - hwif->dma_base = base + (ch ? 0x18 : 0x10); - hwif->dma_base2 = base + (ch ? 0x08 : 0x00); - hwif->dma_prdtable = hwif->dma_base2 + 4; -#else /* ! SIIMAGE_LARGE_DMA */ hwif->dma_base = base + (ch ? 0x08 : 0x00); hwif->dma_base2 = base + (ch ? 0x18 : 0x10); -#endif /* SIIMAGE_LARGE_DMA */ hwif->mmio = 2; } @@ -1052,9 +1007,16 @@ static void __devinit init_hwif_siimage(ide_hwif_t *hwif) hwif->reset_poll = &siimage_reset_poll; hwif->pre_reset = &siimage_pre_reset; - if(is_sata(hwif)) + if(is_sata(hwif)) { + static int first = 1; + hwif->busproc = &siimage_busproc; + if (first) { + printk(KERN_INFO "siimage: For full SATA support you should use the libata sata_sil module.\n"); + first = 0; + } + } if (!hwif->dma_base) { hwif->drives[0].autotune = 1; hwif->drives[1].autotune = 1; @@ -1121,10 +1083,10 @@ static int __devinit siimage_init_one(struct pci_dev *dev, const struct pci_devi } static struct pci_device_id siimage_pci_tbl[] = { - { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { PCI_DEVICE(PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_680), 0}, #ifdef CONFIG_BLK_DEV_IDE_SATA - { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3112, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 1}, - { PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_1210SA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 2}, + { PCI_DEVICE(PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_3112), 1}, + { PCI_DEVICE(PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_SII_1210SA), 2}, #endif { 0, }, }; diff --git a/trunk/drivers/ide/pci/sl82c105.c b/trunk/drivers/ide/pci/sl82c105.c index 8a5c7b286b2b..900301e43818 100644 --- a/trunk/drivers/ide/pci/sl82c105.c +++ b/trunk/drivers/ide/pci/sl82c105.c @@ -447,7 +447,6 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n", hwif->name, rev); } else { -#ifdef CONFIG_BLK_DEV_IDEDMA dma_state |= 0x60; hwif->atapi_dma = 1; @@ -468,7 +467,6 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) if (hwif->mate) hwif->serialized = hwif->mate->serialized = 1; -#endif /* CONFIG_BLK_DEV_IDEDMA */ } hwif->OUTB(dma_state, hwif->dma_base + 2); } @@ -489,7 +487,7 @@ static int __devinit sl82c105_init_one(struct pci_dev *dev, const struct pci_dev } static struct pci_device_id sl82c105_pci_tbl[] = { - { PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { PCI_DEVICE(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105), 0}, { 0, }, }; MODULE_DEVICE_TABLE(pci, sl82c105_pci_tbl); diff --git a/trunk/drivers/ide/pci/slc90e66.c b/trunk/drivers/ide/pci/slc90e66.c index 5112c726633b..0968f6bc669a 100644 --- a/trunk/drivers/ide/pci/slc90e66.c +++ b/trunk/drivers/ide/pci/slc90e66.c @@ -72,7 +72,8 @@ static void slc90e66_tune_drive (ide_drive_t *drive, u8 pio) u16 master_data; u8 slave_data; /* ISP RTC */ - u8 timings[][2] = { { 0, 0 }, + static const u8 timings[][2]= { + { 0, 0 }, { 0, 0 }, { 1, 0 }, { 2, 1 }, @@ -119,7 +120,6 @@ static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed) pci_read_config_word(dev, 0x4a, ®4a); switch(speed) { -#ifdef CONFIG_BLK_DEV_IDEDMA case XFER_UDMA_4: u_speed = 4 << (drive->dn * 4); break; case XFER_UDMA_3: u_speed = 3 << (drive->dn * 4); break; case XFER_UDMA_2: u_speed = 2 << (drive->dn * 4); break; @@ -128,7 +128,6 @@ static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed) case XFER_MW_DMA_2: case XFER_MW_DMA_1: case XFER_SW_DMA_2: break; -#endif /* CONFIG_BLK_DEV_IDEDMA */ case XFER_PIO_4: case XFER_PIO_3: case XFER_PIO_2: @@ -156,7 +155,6 @@ static int slc90e66_tune_chipset (ide_drive_t *drive, u8 xferspeed) return (ide_config_drive_speed(drive, speed)); } -#ifdef CONFIG_BLK_DEV_IDEDMA static int slc90e66_config_drive_for_dma (ide_drive_t *drive) { u8 speed = ide_dma_speed(drive, slc90e66_ratemask(drive)); @@ -194,7 +192,6 @@ static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive) /* IORDY not supported */ return 0; } -#endif /* CONFIG_BLK_DEV_IDEDMA */ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif) { @@ -222,7 +219,6 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif) hwif->mwdma_mask = 0x07; hwif->swdma_mask = 0x07; -#ifdef CONFIG_BLK_DEV_IDEDMA if (!(hwif->udma_four)) /* bit[0(1)]: 0:80, 1:40 */ hwif->udma_four = (reg47 & mask) ? 0 : 1; @@ -232,7 +228,6 @@ static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif) hwif->autodma = 1; hwif->drives[0].autodma = hwif->autodma; hwif->drives[1].autodma = hwif->autodma; -#endif /* !CONFIG_BLK_DEV_IDEDMA */ } static ide_pci_device_t slc90e66_chipset __devinitdata = { @@ -250,7 +245,7 @@ static int __devinit slc90e66_init_one(struct pci_dev *dev, const struct pci_dev } static struct pci_device_id slc90e66_pci_tbl[] = { - { PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, + { PCI_DEVICE(PCI_VENDOR_ID_EFAR, PCI_DEVICE_ID_EFAR_SLC90E66_1), 0}, { 0, }, }; MODULE_DEVICE_TABLE(pci, slc90e66_pci_tbl); diff --git a/trunk/drivers/ide/ppc/pmac.c b/trunk/drivers/ide/ppc/pmac.c index ffca8b63ee79..e8ef3455ec35 100644 --- a/trunk/drivers/ide/ppc/pmac.c +++ b/trunk/drivers/ide/ppc/pmac.c @@ -420,107 +420,6 @@ static void pmac_ide_kauai_selectproc(ide_drive_t *drive); #endif /* CONFIG_BLK_DEV_IDEDMA_PMAC */ -/* - * Below is the code for blinking the laptop LED along with hard - * disk activity. - */ - -#ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK - -/* Set to 50ms minimum led-on time (also used to limit frequency - * of requests sent to the PMU - */ -#define PMU_HD_BLINK_TIME (HZ/50) - -static struct adb_request pmu_blink_on, pmu_blink_off; -static spinlock_t pmu_blink_lock; -static unsigned long pmu_blink_stoptime; -static int pmu_blink_ledstate; -static struct timer_list pmu_blink_timer; -static int pmu_ide_blink_enabled; - - -static void -pmu_hd_blink_timeout(unsigned long data) -{ - unsigned long flags; - - spin_lock_irqsave(&pmu_blink_lock, flags); - - /* We may have been triggered again in a racy way, check - * that we really want to switch it off - */ - if (time_after(pmu_blink_stoptime, jiffies)) - goto done; - - /* Previous req. not complete, try 100ms more */ - if (pmu_blink_off.complete == 0) - mod_timer(&pmu_blink_timer, jiffies + PMU_HD_BLINK_TIME); - else if (pmu_blink_ledstate) { - pmu_request(&pmu_blink_off, NULL, 4, 0xee, 4, 0, 0); - pmu_blink_ledstate = 0; - } -done: - spin_unlock_irqrestore(&pmu_blink_lock, flags); -} - -static void -pmu_hd_kick_blink(void *data, int rw) -{ - unsigned long flags; - - pmu_blink_stoptime = jiffies + PMU_HD_BLINK_TIME; - wmb(); - mod_timer(&pmu_blink_timer, pmu_blink_stoptime); - /* Fast path when LED is already ON */ - if (pmu_blink_ledstate == 1) - return; - spin_lock_irqsave(&pmu_blink_lock, flags); - if (pmu_blink_on.complete && !pmu_blink_ledstate) { - pmu_request(&pmu_blink_on, NULL, 4, 0xee, 4, 0, 1); - pmu_blink_ledstate = 1; - } - spin_unlock_irqrestore(&pmu_blink_lock, flags); -} - -static int -pmu_hd_blink_init(void) -{ - struct device_node *dt; - const char *model; - - /* Currently, I only enable this feature on KeyLargo based laptops, - * older laptops may support it (at least heathrow/paddington) but - * I don't feel like loading those venerable old machines with so - * much additional interrupt & PMU activity... - */ - if (pmu_get_model() != PMU_KEYLARGO_BASED) - return 0; - - dt = of_find_node_by_path("/"); - if (dt == NULL) - return 0; - model = (const char *)get_property(dt, "model", NULL); - if (model == NULL) - return 0; - if (strncmp(model, "PowerBook", strlen("PowerBook")) != 0 && - strncmp(model, "iBook", strlen("iBook")) != 0) { - of_node_put(dt); - return 0; - } - of_node_put(dt); - - pmu_blink_on.complete = 1; - pmu_blink_off.complete = 1; - spin_lock_init(&pmu_blink_lock); - init_timer(&pmu_blink_timer); - pmu_blink_timer.function = pmu_hd_blink_timeout; - - return 1; -} - -#endif /* CONFIG_BLK_DEV_IDE_PMAC_BLINK */ - /* * N.B. this can't be an initfunc, because the media-bay task can * call ide_[un]register at any time. @@ -1192,23 +1091,6 @@ pmac_ide_do_suspend(ide_hwif_t *hwif) pmif->timings[0] = 0; pmif->timings[1] = 0; -#ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK - /* Note: This code will be called for every hwif, thus we'll - * try several time to stop the LED blinker timer, but that - * should be harmless - */ - if (pmu_ide_blink_enabled) { - unsigned long flags; - - /* Make sure we don't hit the PMU blink */ - spin_lock_irqsave(&pmu_blink_lock, flags); - if (pmu_blink_ledstate) - del_timer(&pmu_blink_timer); - pmu_blink_ledstate = 0; - spin_unlock_irqrestore(&pmu_blink_lock, flags); - } -#endif /* CONFIG_BLK_DEV_IDE_PMAC_BLINK */ - disable_irq(pmif->irq); /* The media bay will handle itself just fine */ @@ -1376,13 +1258,6 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif) hwif->selectproc = pmac_ide_selectproc; hwif->speedproc = pmac_ide_tune_chipset; -#ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK - pmu_ide_blink_enabled = pmu_hd_blink_init(); - - if (pmu_ide_blink_enabled) - hwif->led_act = pmu_hd_kick_blink; -#endif - printk(KERN_INFO "ide%d: Found Apple %s controller, bus ID %d%s, irq %d\n", hwif->index, model_name[pmif->kind], pmif->aapl_bus_id, pmif->mediabay ? " (mediabay)" : "", hwif->irq); diff --git a/trunk/drivers/ieee1394/ohci1394.c b/trunk/drivers/ieee1394/ohci1394.c index 3d278412e1ca..800c8d518430 100644 --- a/trunk/drivers/ieee1394/ohci1394.c +++ b/trunk/drivers/ieee1394/ohci1394.c @@ -590,11 +590,11 @@ static void ohci_initialize(struct ti_ohci *ohci) buf = reg_read(ohci, OHCI1394_Version); sprintf (irq_buf, "%d", ohci->dev->irq); PRINT(KERN_INFO, "OHCI-1394 %d.%d (PCI): IRQ=[%s] " - "MMIO=[%lx-%lx] Max Packet=[%d] IR/IT contexts=[%d/%d]", + "MMIO=[%llx-%llx] Max Packet=[%d] IR/IT contexts=[%d/%d]", ((((buf) >> 16) & 0xf) + (((buf) >> 20) & 0xf) * 10), ((((buf) >> 4) & 0xf) + ((buf) & 0xf) * 10), irq_buf, - pci_resource_start(ohci->dev, 0), - pci_resource_start(ohci->dev, 0) + OHCI1394_REGISTER_SIZE - 1, + (unsigned long long)pci_resource_start(ohci->dev, 0), + (unsigned long long)pci_resource_start(ohci->dev, 0) + OHCI1394_REGISTER_SIZE - 1, ohci->max_packet_size, ohci->nb_iso_rcv_ctx, ohci->nb_iso_xmit_ctx); @@ -3217,7 +3217,7 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, { struct hpsb_host *host; struct ti_ohci *ohci; /* shortcut to currently handled device */ - unsigned long ohci_base; + resource_size_t ohci_base; if (pci_enable_device(dev)) FAIL(-ENXIO, "Failed to enable OHCI hardware"); @@ -3270,15 +3270,16 @@ static int __devinit ohci1394_pci_probe(struct pci_dev *dev, * clearly says it's 2kb, so this shouldn't be a problem. */ ohci_base = pci_resource_start(dev, 0); if (pci_resource_len(dev, 0) < OHCI1394_REGISTER_SIZE) - PRINT(KERN_WARNING, "PCI resource length of %lx too small!", - pci_resource_len(dev, 0)); + PRINT(KERN_WARNING, "PCI resource length of 0x%llx too small!", + (unsigned long long)pci_resource_len(dev, 0)); /* Seems PCMCIA handles this internally. Not sure why. Seems * pretty bogus to force a driver to special case this. */ #ifndef PCMCIA if (!request_mem_region (ohci_base, OHCI1394_REGISTER_SIZE, OHCI1394_DRIVER_NAME)) - FAIL(-ENOMEM, "MMIO resource (0x%lx - 0x%lx) unavailable", - ohci_base, ohci_base + OHCI1394_REGISTER_SIZE); + FAIL(-ENOMEM, "MMIO resource (0x%llx - 0x%llx) unavailable", + (unsigned long long)ohci_base, + (unsigned long long)ohci_base + OHCI1394_REGISTER_SIZE); #endif ohci->init_state = OHCI_INIT_HAVE_MEM_REGION; diff --git a/trunk/drivers/infiniband/hw/ipath/ipath_driver.c b/trunk/drivers/infiniband/hw/ipath/ipath_driver.c index dddcdae736ac..e4b897fa569a 100644 --- a/trunk/drivers/infiniband/hw/ipath/ipath_driver.c +++ b/trunk/drivers/infiniband/hw/ipath/ipath_driver.c @@ -460,10 +460,10 @@ static int __devinit ipath_init_one(struct pci_dev *pdev, for (j = 0; j < 6; j++) { if (!pdev->resource[j].start) continue; - ipath_cdbg(VERBOSE, "BAR %d start %lx, end %lx, len %lx\n", - j, pdev->resource[j].start, - pdev->resource[j].end, - pci_resource_len(pdev, j)); + ipath_cdbg(VERBOSE, "BAR %d start %llx, end %llx, len %llx\n", + j, (unsigned long long)pdev->resource[j].start, + (unsigned long long)pdev->resource[j].end, + (unsigned long long)pci_resource_len(pdev, j)); } if (!addr) { diff --git a/trunk/drivers/infiniband/hw/mthca/mthca_main.c b/trunk/drivers/infiniband/hw/mthca/mthca_main.c index 9b9ff7bff357..465fd220569c 100644 --- a/trunk/drivers/infiniband/hw/mthca/mthca_main.c +++ b/trunk/drivers/infiniband/hw/mthca/mthca_main.c @@ -172,8 +172,9 @@ static int __devinit mthca_dev_lim(struct mthca_dev *mdev, struct mthca_dev_lim if (dev_lim->uar_size > pci_resource_len(mdev->pdev, 2)) { mthca_err(mdev, "HCA reported UAR size of 0x%x bigger than " - "PCI resource 2 size of 0x%lx, aborting.\n", - dev_lim->uar_size, pci_resource_len(mdev->pdev, 2)); + "PCI resource 2 size of 0x%llx, aborting.\n", + dev_lim->uar_size, + (unsigned long long)pci_resource_len(mdev->pdev, 2)); return -ENODEV; } diff --git a/trunk/drivers/input/joystick/db9.c b/trunk/drivers/input/joystick/db9.c index 6f31f054d1bb..5080e15c6d30 100644 --- a/trunk/drivers/input/joystick/db9.c +++ b/trunk/drivers/input/joystick/db9.c @@ -584,7 +584,7 @@ static struct db9 __init *db9_probe(int parport, int mode) goto err_out; } - if (db9_mode[mode].bidirectional && !(pp->modes & PARPORT_MODE_TRISTATE)) { + if (db9_mode->bidirectional && !(pp->modes & PARPORT_MODE_TRISTATE)) { printk(KERN_ERR "db9.c: specified parport is not bidirectional\n"); err = -EINVAL; goto err_put_pp; diff --git a/trunk/drivers/input/keyboard/atkbd.c b/trunk/drivers/input/keyboard/atkbd.c index ffde8f86e0fb..ce1f10e8984b 100644 --- a/trunk/drivers/input/keyboard/atkbd.c +++ b/trunk/drivers/input/keyboard/atkbd.c @@ -459,7 +459,7 @@ static irqreturn_t atkbd_interrupt(struct serio *serio, unsigned char data, } input_regs(dev, regs); - input_report_key(dev, keycode, value); + input_event(dev, EV_KEY, keycode, value); input_sync(dev); if (value && add_release_event) { diff --git a/trunk/drivers/input/misc/wistron_btns.c b/trunk/drivers/input/misc/wistron_btns.c index e4e5be111c96..ccf0faeee5c1 100644 --- a/trunk/drivers/input/misc/wistron_btns.c +++ b/trunk/drivers/input/misc/wistron_btns.c @@ -285,6 +285,15 @@ static struct key_entry keymap_fujitsu_n3510[] = { { KE_END, 0 } }; +static struct key_entry keymap_wistron_ms2111[] = { + { KE_KEY, 0x11, KEY_PROG1 }, + { KE_KEY, 0x12, KEY_PROG2 }, + { KE_KEY, 0x13, KEY_PROG3 }, + { KE_KEY, 0x31, KEY_MAIL }, + { KE_KEY, 0x36, KEY_WWW }, + { KE_END, 0 } +}; + static struct key_entry keymap_wistron_ms2141[] = { { KE_KEY, 0x11, KEY_PROG1 }, { KE_KEY, 0x12, KEY_PROG2 }, @@ -326,6 +335,7 @@ static struct key_entry keymap_aopen_1559as[] = { { KE_WIFI, 0x30, 0 }, { KE_KEY, 0x31, KEY_MAIL }, { KE_KEY, 0x36, KEY_WWW }, + { KE_END, 0 }, }; /* @@ -388,6 +398,15 @@ static struct dmi_system_id dmi_ids[] = { }, .driver_data = keymap_aopen_1559as }, + { + .callback = dmi_matched, + .ident = "Medion MD 9783", + .matches = { + DMI_MATCH(DMI_SYS_VENDOR, "MEDIONNB"), + DMI_MATCH(DMI_PRODUCT_NAME, "MD 9783"), + }, + .driver_data = keymap_wistron_ms2111 + }, { NULL, } }; diff --git a/trunk/drivers/input/serio/ct82c710.c b/trunk/drivers/input/serio/ct82c710.c index 096b6a0b5cca..1ac739ef2ffa 100644 --- a/trunk/drivers/input/serio/ct82c710.c +++ b/trunk/drivers/input/serio/ct82c710.c @@ -189,7 +189,7 @@ static int __devinit ct82c710_probe(struct platform_device *dev) strlcpy(ct82c710_port->name, "C&T 82c710 mouse port", sizeof(ct82c710_port->name)); snprintf(ct82c710_port->phys, sizeof(ct82c710_port->phys), - "isa%04lx/serio0", CT82C710_DATA); + "isa%16llx/serio0", (unsigned long long)CT82C710_DATA); serio_register_port(ct82c710_port); @@ -241,8 +241,8 @@ static int __init ct82c710_init(void) serio_register_port(ct82c710_port); - printk(KERN_INFO "serio: C&T 82c710 mouse port at %#lx irq %d\n", - CT82C710_DATA, CT82C710_IRQ); + printk(KERN_INFO "serio: C&T 82c710 mouse port at %#llx irq %d\n", + (unsigned long long)CT82C710_DATA, CT82C710_IRQ); return 0; diff --git a/trunk/drivers/isdn/hisax/hfc_pci.c b/trunk/drivers/isdn/hisax/hfc_pci.c index 91d25acb5ede..3622720f0505 100644 --- a/trunk/drivers/isdn/hisax/hfc_pci.c +++ b/trunk/drivers/isdn/hisax/hfc_pci.c @@ -1688,7 +1688,7 @@ setup_hfcpci(struct IsdnCard *card) printk(KERN_WARNING "HFC-PCI: No IRQ for PCI card found\n"); return (0); } - cs->hw.hfcpci.pci_io = (char *) dev_hfcpci->resource[ 1].start; + cs->hw.hfcpci.pci_io = (char *)(unsigned long)dev_hfcpci->resource[1].start; printk(KERN_INFO "HiSax: HFC-PCI card manufacturer: %s card name: %s\n", id_list[i].vendor_name, id_list[i].card_name); } else { printk(KERN_WARNING "HFC-PCI: No PCI card found\n"); diff --git a/trunk/drivers/isdn/hisax/telespci.c b/trunk/drivers/isdn/hisax/telespci.c index e2bb4fd8e25e..e82ab2251b82 100644 --- a/trunk/drivers/isdn/hisax/telespci.c +++ b/trunk/drivers/isdn/hisax/telespci.c @@ -311,8 +311,9 @@ setup_telespci(struct IsdnCard *card) } cs->hw.teles0.membase = ioremap(pci_resource_start(dev_tel, 0), PAGE_SIZE); - printk(KERN_INFO "Found: Zoran, base-address: 0x%lx, irq: 0x%x\n", - pci_resource_start(dev_tel, 0), dev_tel->irq); + printk(KERN_INFO "Found: Zoran, base-address: 0x%llx, irq: 0x%x\n", + (unsigned long long)pci_resource_start(dev_tel, 0), + dev_tel->irq); } else { printk(KERN_WARNING "TelesPCI: No PCI card found\n"); return(0); diff --git a/trunk/drivers/isdn/i4l/isdn_x25iface.c b/trunk/drivers/isdn/i4l/isdn_x25iface.c index 743ac4077f35..8b3efc243161 100644 --- a/trunk/drivers/isdn/i4l/isdn_x25iface.c +++ b/trunk/drivers/isdn/i4l/isdn_x25iface.c @@ -208,7 +208,7 @@ static int isdn_x25iface_receive(struct concap_proto *cprot, struct sk_buff *skb */ static int isdn_x25iface_connect_ind(struct concap_proto *cprot) { - struct sk_buff * skb = dev_alloc_skb(1); + struct sk_buff * skb; enum wan_states *state_p = &( ( (ix25_pdata_t*) (cprot->proto_data) ) -> state); IX25DEBUG( "isdn_x25iface_connect_ind %s \n" @@ -220,6 +220,8 @@ static int isdn_x25iface_connect_ind(struct concap_proto *cprot) return -1; } *state_p = WAN_CONNECTED; + + skb = dev_alloc_skb(1); if( skb ){ *( skb_put(skb, 1) ) = 0x01; skb->protocol = x25_type_trans(skb, cprot->net_dev); diff --git a/trunk/drivers/macintosh/Kconfig b/trunk/drivers/macintosh/Kconfig index 37cd6ee4586b..54f3f6b94efc 100644 --- a/trunk/drivers/macintosh/Kconfig +++ b/trunk/drivers/macintosh/Kconfig @@ -78,6 +78,18 @@ config ADB_PMU this device; you should do so if your machine is one of those mentioned above. +config ADB_PMU_LED + bool "Support for the Power/iBook front LED" + depends on ADB_PMU + select NEW_LEDS + select LEDS_CLASS + help + Support the front LED on Power/iBooks as a generic LED that can + be triggered by any of the supported triggers. To get the + behaviour of the old CONFIG_BLK_DEV_IDE_PMAC_BLINK, select this + and the ide-disk LED trigger and configure appropriately through + sysfs. + config PMAC_SMU bool "Support for SMU based PowerMacs" depends on PPC_PMAC64 diff --git a/trunk/drivers/macintosh/Makefile b/trunk/drivers/macintosh/Makefile index 45a268f8047e..b53d45f87b0b 100644 --- a/trunk/drivers/macintosh/Makefile +++ b/trunk/drivers/macintosh/Makefile @@ -12,6 +12,7 @@ obj-$(CONFIG_INPUT_ADBHID) += adbhid.o obj-$(CONFIG_ANSLCD) += ans-lcd.o obj-$(CONFIG_ADB_PMU) += via-pmu.o via-pmu-event.o +obj-$(CONFIG_ADB_PMU_LED) += via-pmu-led.o obj-$(CONFIG_PMAC_BACKLIGHT) += via-pmu-backlight.o obj-$(CONFIG_ADB_CUDA) += via-cuda.o obj-$(CONFIG_PMAC_APM_EMU) += apm_emu.o diff --git a/trunk/drivers/macintosh/macio_asic.c b/trunk/drivers/macintosh/macio_asic.c index 431bd37225a1..c687ac703941 100644 --- a/trunk/drivers/macintosh/macio_asic.c +++ b/trunk/drivers/macintosh/macio_asic.c @@ -428,10 +428,10 @@ static struct macio_dev * macio_add_one_device(struct macio_chip *chip, /* MacIO itself has a different reg, we use it's PCI base */ if (np == chip->of_node) { - sprintf(dev->ofdev.dev.bus_id, "%1d.%08lx:%.*s", + sprintf(dev->ofdev.dev.bus_id, "%1d.%016llx:%.*s", chip->lbus.index, #ifdef CONFIG_PCI - pci_resource_start(chip->lbus.pdev, 0), + (unsigned long long)pci_resource_start(chip->lbus.pdev, 0), #else 0, /* NuBus may want to do something better here */ #endif diff --git a/trunk/drivers/macintosh/via-pmu-led.c b/trunk/drivers/macintosh/via-pmu-led.c new file mode 100644 index 000000000000..af8375ed0f5e --- /dev/null +++ b/trunk/drivers/macintosh/via-pmu-led.c @@ -0,0 +1,144 @@ +/* + * via-pmu LED class device + * + * Copyright 2006 Johannes Berg + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or + * NON INFRINGEMENT. See the GNU General Public License for more + * details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + * + */ +#include +#include +#include +#include +#include +#include +#include + +static spinlock_t pmu_blink_lock; +static struct adb_request pmu_blink_req; +/* -1: no change, 0: request off, 1: request on */ +static int requested_change; +static int sleeping; + +static void pmu_req_done(struct adb_request * req) +{ + unsigned long flags; + + spin_lock_irqsave(&pmu_blink_lock, flags); + /* if someone requested a change in the meantime + * (we only see the last one which is fine) + * then apply it now */ + if (requested_change != -1 && !sleeping) + pmu_request(&pmu_blink_req, NULL, 4, 0xee, 4, 0, requested_change); + /* reset requested change */ + requested_change = -1; + spin_unlock_irqrestore(&pmu_blink_lock, flags); +} + +static void pmu_led_set(struct led_classdev *led_cdev, + enum led_brightness brightness) +{ + unsigned long flags; + + spin_lock_irqsave(&pmu_blink_lock, flags); + switch (brightness) { + case LED_OFF: + requested_change = 0; + break; + case LED_FULL: + requested_change = 1; + break; + default: + goto out; + break; + } + /* if request isn't done, then don't do anything */ + if (pmu_blink_req.complete && !sleeping) + pmu_request(&pmu_blink_req, NULL, 4, 0xee, 4, 0, requested_change); + out: + spin_unlock_irqrestore(&pmu_blink_lock, flags); +} + +static struct led_classdev pmu_led = { + .name = "pmu-front-led", +#ifdef CONFIG_BLK_DEV_IDE_PMAC_BLINK + .default_trigger = "ide-disk", +#endif + .brightness_set = pmu_led_set, +}; + +#ifdef CONFIG_PM +static int pmu_led_sleep_call(struct pmu_sleep_notifier *self, int when) +{ + unsigned long flags; + + spin_lock_irqsave(&pmu_blink_lock, flags); + + switch (when) { + case PBOOK_SLEEP_REQUEST: + sleeping = 1; + break; + case PBOOK_WAKE: + sleeping = 0; + break; + default: + /* do nothing */ + break; + } + spin_unlock_irqrestore(&pmu_blink_lock, flags); + + return PBOOK_SLEEP_OK; +} + +static struct pmu_sleep_notifier via_pmu_led_sleep_notif = { + .notifier_call = pmu_led_sleep_call, +}; +#endif + +static int __init via_pmu_led_init(void) +{ + struct device_node *dt; + const char *model; + + /* only do this on keylargo based models */ + if (pmu_get_model() != PMU_KEYLARGO_BASED) + return -ENODEV; + + dt = of_find_node_by_path("/"); + if (dt == NULL) + return -ENODEV; + model = (const char *)get_property(dt, "model", NULL); + if (model == NULL) + return -ENODEV; + if (strncmp(model, "PowerBook", strlen("PowerBook")) != 0 && + strncmp(model, "iBook", strlen("iBook")) != 0) { + of_node_put(dt); + /* ignore */ + return -ENODEV; + } + of_node_put(dt); + + spin_lock_init(&pmu_blink_lock); + /* no outstanding req */ + pmu_blink_req.complete = 1; + pmu_blink_req.done = pmu_req_done; +#ifdef CONFIG_PM + pmu_register_sleep_notifier(&via_pmu_led_sleep_notif); +#endif + return led_classdev_register(NULL, &pmu_led); +} + +late_initcall(via_pmu_led_init); diff --git a/trunk/drivers/md/raid5.c b/trunk/drivers/md/raid5.c index f920e50ea124..837ec4eb3d60 100644 --- a/trunk/drivers/md/raid5.c +++ b/trunk/drivers/md/raid5.c @@ -2827,7 +2827,6 @@ static inline sector_t sync_request(mddev_t *mddev, sector_t sector_nr, int *ski struct stripe_head *sh; int pd_idx; int raid_disks = conf->raid_disks; - int data_disks = raid_disks - conf->max_degraded; sector_t max_sector = mddev->size << 1; int sync_blocks; int still_degraded = 0; diff --git a/trunk/drivers/media/video/bt8xx/bttv-driver.c b/trunk/drivers/media/video/bt8xx/bttv-driver.c index 423e954948be..aa3203ae670c 100644 --- a/trunk/drivers/media/video/bt8xx/bttv-driver.c +++ b/trunk/drivers/media/video/bt8xx/bttv-driver.c @@ -4019,8 +4019,9 @@ static int __devinit bttv_probe(struct pci_dev *dev, if (!request_mem_region(pci_resource_start(dev,0), pci_resource_len(dev,0), btv->c.name)) { - printk(KERN_WARNING "bttv%d: can't request iomem (0x%lx).\n", - btv->c.nr, pci_resource_start(dev,0)); + printk(KERN_WARNING "bttv%d: can't request iomem (0x%llx).\n", + btv->c.nr, + (unsigned long long)pci_resource_start(dev,0)); return -EBUSY; } pci_set_master(dev); @@ -4031,8 +4032,9 @@ static int __devinit bttv_probe(struct pci_dev *dev, pci_read_config_byte(dev, PCI_LATENCY_TIMER, &lat); printk(KERN_INFO "bttv%d: Bt%d (rev %d) at %s, ", bttv_num,btv->id, btv->revision, pci_name(dev)); - printk("irq: %d, latency: %d, mmio: 0x%lx\n", - btv->c.pci->irq, lat, pci_resource_start(dev,0)); + printk("irq: %d, latency: %d, mmio: 0x%llx\n", + btv->c.pci->irq, lat, + (unsigned long long)pci_resource_start(dev,0)); schedule(); btv->bt848_mmio=ioremap(pci_resource_start(dev,0), 0x1000); diff --git a/trunk/drivers/media/video/cx88/cx88-alsa.c b/trunk/drivers/media/video/cx88/cx88-alsa.c index 2194cbeca33b..292a5e81eb75 100644 --- a/trunk/drivers/media/video/cx88/cx88-alsa.c +++ b/trunk/drivers/media/video/cx88/cx88-alsa.c @@ -712,9 +712,9 @@ static int __devinit snd_cx88_create(struct snd_card *card, pci_read_config_byte(pci, PCI_LATENCY_TIMER, &chip->pci_lat); dprintk(1,"ALSA %s/%i: found at %s, rev: %d, irq: %d, " - "latency: %d, mmio: 0x%lx\n", core->name, devno, + "latency: %d, mmio: 0x%llx\n", core->name, devno, pci_name(pci), chip->pci_rev, pci->irq, - chip->pci_lat,pci_resource_start(pci,0)); + chip->pci_lat,(unsigned long long)pci_resource_start(pci,0)); chip->irq = pci->irq; synchronize_irq(chip->irq); @@ -766,8 +766,8 @@ static int __devinit cx88_audio_initdev(struct pci_dev *pci, strcpy (card->driver, "CX88x"); sprintf(card->shortname, "Conexant CX%x", pci->device); - sprintf(card->longname, "%s at %#lx", - card->shortname, pci_resource_start(pci, 0)); + sprintf(card->longname, "%s at %#llx", + card->shortname,(unsigned long long)pci_resource_start(pci, 0)); strcpy (card->mixername, "CX88"); dprintk (0, "%s/%i: ALSA support for cx2388x boards\n", diff --git a/trunk/drivers/media/video/cx88/cx88-core.c b/trunk/drivers/media/video/cx88/cx88-core.c index 26f4c0fb8c36..973d3f39b2d5 100644 --- a/trunk/drivers/media/video/cx88/cx88-core.c +++ b/trunk/drivers/media/video/cx88/cx88-core.c @@ -1031,8 +1031,8 @@ static int get_ressources(struct cx88_core *core, struct pci_dev *pci) pci_resource_len(pci,0), core->name)) return 0; - printk(KERN_ERR "%s: can't get MMIO memory @ 0x%lx\n", - core->name,pci_resource_start(pci,0)); + printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n", + core->name,(unsigned long long)pci_resource_start(pci,0)); return -EBUSY; } diff --git a/trunk/drivers/media/video/cx88/cx88-mpeg.c b/trunk/drivers/media/video/cx88/cx88-mpeg.c index a9d7795a8e14..2c12aca1b6a3 100644 --- a/trunk/drivers/media/video/cx88/cx88-mpeg.c +++ b/trunk/drivers/media/video/cx88/cx88-mpeg.c @@ -420,9 +420,9 @@ int cx8802_init_common(struct cx8802_dev *dev) pci_read_config_byte(dev->pci, PCI_CLASS_REVISION, &dev->pci_rev); pci_read_config_byte(dev->pci, PCI_LATENCY_TIMER, &dev->pci_lat); printk(KERN_INFO "%s/2: found at %s, rev: %d, irq: %d, " - "latency: %d, mmio: 0x%lx\n", dev->core->name, + "latency: %d, mmio: 0x%llx\n", dev->core->name, pci_name(dev->pci), dev->pci_rev, dev->pci->irq, - dev->pci_lat,pci_resource_start(dev->pci,0)); + dev->pci_lat,(unsigned long long)pci_resource_start(dev->pci,0)); /* initialize driver struct */ spin_lock_init(&dev->slock); diff --git a/trunk/drivers/media/video/cx88/cx88-video.c b/trunk/drivers/media/video/cx88/cx88-video.c index dcda5291b990..8d5cf474b68e 100644 --- a/trunk/drivers/media/video/cx88/cx88-video.c +++ b/trunk/drivers/media/video/cx88/cx88-video.c @@ -1847,9 +1847,9 @@ static int __devinit cx8800_initdev(struct pci_dev *pci_dev, pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); printk(KERN_INFO "%s/0: found at %s, rev: %d, irq: %d, " - "latency: %d, mmio: 0x%lx\n", core->name, + "latency: %d, mmio: 0x%llx\n", core->name, pci_name(pci_dev), dev->pci_rev, pci_dev->irq, - dev->pci_lat,pci_resource_start(pci_dev,0)); + dev->pci_lat,(unsigned long long)pci_resource_start(pci_dev,0)); pci_set_master(pci_dev); if (!pci_dma_supported(pci_dev,0xffffffff)) { diff --git a/trunk/drivers/media/video/saa7134/saa7134-core.c b/trunk/drivers/media/video/saa7134/saa7134-core.c index f0c2111f14ad..da3007d2f411 100644 --- a/trunk/drivers/media/video/saa7134/saa7134-core.c +++ b/trunk/drivers/media/video/saa7134/saa7134-core.c @@ -871,9 +871,9 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, pci_read_config_byte(pci_dev, PCI_CLASS_REVISION, &dev->pci_rev); pci_read_config_byte(pci_dev, PCI_LATENCY_TIMER, &dev->pci_lat); printk(KERN_INFO "%s: found at %s, rev: %d, irq: %d, " - "latency: %d, mmio: 0x%lx\n", dev->name, + "latency: %d, mmio: 0x%llx\n", dev->name, pci_name(pci_dev), dev->pci_rev, pci_dev->irq, - dev->pci_lat,pci_resource_start(pci_dev,0)); + dev->pci_lat,(unsigned long long)pci_resource_start(pci_dev,0)); pci_set_master(pci_dev); if (!pci_dma_supported(pci_dev, DMA_32BIT_MASK)) { printk("%s: Oops: no 32bit PCI DMA ???\n",dev->name); @@ -905,8 +905,8 @@ static int __devinit saa7134_initdev(struct pci_dev *pci_dev, pci_resource_len(pci_dev,0), dev->name)) { err = -EBUSY; - printk(KERN_ERR "%s: can't get MMIO memory @ 0x%lx\n", - dev->name,pci_resource_start(pci_dev,0)); + printk(KERN_ERR "%s: can't get MMIO memory @ 0x%llx\n", + dev->name,(unsigned long long)pci_resource_start(pci_dev,0)); goto fail1; } dev->lmmio = ioremap(pci_resource_start(pci_dev,0), 0x1000); diff --git a/trunk/drivers/message/i2o/iop.c b/trunk/drivers/message/i2o/iop.c index c74e5460f834..3305c12372a2 100644 --- a/trunk/drivers/message/i2o/iop.c +++ b/trunk/drivers/message/i2o/iop.c @@ -683,9 +683,10 @@ static int i2o_iop_systab_set(struct i2o_controller *c) c->mem_alloc = 1; sb->current_mem_size = 1 + res->end - res->start; sb->current_mem_base = res->start; - osm_info("%s: allocated %ld bytes of PCI memory at " - "0x%08lX.\n", c->name, - 1 + res->end - res->start, res->start); + osm_info("%s: allocated %llu bytes of PCI memory at " + "0x%016llX.\n", c->name, + (unsigned long long)(1 + res->end - res->start), + (unsigned long long)res->start); } } @@ -704,9 +705,10 @@ static int i2o_iop_systab_set(struct i2o_controller *c) c->io_alloc = 1; sb->current_io_size = 1 + res->end - res->start; sb->current_mem_base = res->start; - osm_info("%s: allocated %ld bytes of PCI I/O at 0x%08lX" - ".\n", c->name, 1 + res->end - res->start, - res->start); + osm_info("%s: allocated %llu bytes of PCI I/O at " + "0x%016llX.\n", c->name, + (unsigned long long)(1 + res->end - res->start), + (unsigned long long)res->start); } } diff --git a/trunk/drivers/mmc/mmci.c b/trunk/drivers/mmc/mmci.c index da8e4d7339cc..8576a65ca1c3 100644 --- a/trunk/drivers/mmc/mmci.c +++ b/trunk/drivers/mmc/mmci.c @@ -546,9 +546,9 @@ static int mmci_probe(struct amba_device *dev, void *id) mmc_add_host(mmc); - printk(KERN_INFO "%s: MMCI rev %x cfg %02x at 0x%08lx irq %d,%d\n", + printk(KERN_INFO "%s: MMCI rev %x cfg %02x at 0x%016llx irq %d,%d\n", mmc_hostname(mmc), amba_rev(dev), amba_config(dev), - dev->res.start, dev->irq[0], dev->irq[1]); + (unsigned long long)dev->res.start, dev->irq[0], dev->irq[1]); init_timer(&host->timer); host->timer.data = (unsigned long)host; diff --git a/trunk/drivers/mtd/devices/pmc551.c b/trunk/drivers/mtd/devices/pmc551.c index f620d74f1004..30f07b473ae2 100644 --- a/trunk/drivers/mtd/devices/pmc551.c +++ b/trunk/drivers/mtd/devices/pmc551.c @@ -551,11 +551,11 @@ static u32 fixup_pmc551 (struct pci_dev *dev) /* * Some screen fun */ - printk(KERN_DEBUG "pmc551: %d%c (0x%x) of %sprefetchable memory at 0x%lx\n", + printk(KERN_DEBUG "pmc551: %d%c (0x%x) of %sprefetchable memory at 0x%llx\n", (size<1024)?size:(size<1048576)?size>>10:size>>20, (size<1024)?'B':(size<1048576)?'K':'M', size, ((dcmd&(0x1<<3)) == 0)?"non-":"", - (dev->resource[0].start)&PCI_BASE_ADDRESS_MEM_MASK ); + (unsigned long long)((dev->resource[0].start)&PCI_BASE_ADDRESS_MEM_MASK)); /* * Check to see the state of the memory @@ -685,8 +685,8 @@ static int __init init_pmc551(void) break; } - printk(KERN_NOTICE "pmc551: Found PCI V370PDC at 0x%lX\n", - PCI_Device->resource[0].start); + printk(KERN_NOTICE "pmc551: Found PCI V370PDC at 0x%llx\n", + (unsigned long long)PCI_Device->resource[0].start); /* * The PMC551 device acts VERY weird if you don't init it diff --git a/trunk/drivers/mtd/maps/amd76xrom.c b/trunk/drivers/mtd/maps/amd76xrom.c index c350878d4592..a50587005263 100644 --- a/trunk/drivers/mtd/maps/amd76xrom.c +++ b/trunk/drivers/mtd/maps/amd76xrom.c @@ -123,9 +123,10 @@ static int __devinit amd76xrom_init_one (struct pci_dev *pdev, window->rsrc.parent = NULL; printk(KERN_ERR MOD_NAME " %s(): Unable to register resource" - " 0x%.08lx-0x%.08lx - kernel bug?\n", + " 0x%.16llx-0x%.16llx - kernel bug?\n", __func__, - window->rsrc.start, window->rsrc.end); + (unsigned long long)window->rsrc.start, + (unsigned long long)window->rsrc.end); } #if 0 diff --git a/trunk/drivers/mtd/maps/ichxrom.c b/trunk/drivers/mtd/maps/ichxrom.c index ea5073781b3a..16732794edf3 100644 --- a/trunk/drivers/mtd/maps/ichxrom.c +++ b/trunk/drivers/mtd/maps/ichxrom.c @@ -177,9 +177,10 @@ static int __devinit ichxrom_init_one (struct pci_dev *pdev, window->rsrc.parent = NULL; printk(KERN_DEBUG MOD_NAME ": %s(): Unable to register resource" - " 0x%.08lx-0x%.08lx - kernel bug?\n", + " 0x%.16llx-0x%.16llx - kernel bug?\n", __func__, - window->rsrc.start, window->rsrc.end); + (unsigned long long)window->rsrc.start, + (unsigned long long)window->rsrc.end); } /* Map the firmware hub into my address space. */ diff --git a/trunk/drivers/mtd/maps/scx200_docflash.c b/trunk/drivers/mtd/maps/scx200_docflash.c index 28b8a571a91a..331a15859d71 100644 --- a/trunk/drivers/mtd/maps/scx200_docflash.c +++ b/trunk/drivers/mtd/maps/scx200_docflash.c @@ -164,8 +164,9 @@ static int __init init_scx200_docflash(void) outl(pmr, scx200_cb_base + SCx200_PMR); } - printk(KERN_INFO NAME ": DOCCS mapped at 0x%lx-0x%lx, width %d\n", - docmem.start, docmem.end, width); + printk(KERN_INFO NAME ": DOCCS mapped at 0x%llx-0x%llx, width %d\n", + (unsigned long long)docmem.start, + (unsigned long long)docmem.end, width); scx200_docflash_map.size = size; if (width == 8) diff --git a/trunk/drivers/mtd/maps/sun_uflash.c b/trunk/drivers/mtd/maps/sun_uflash.c index 24a03152d196..4db2055cee31 100644 --- a/trunk/drivers/mtd/maps/sun_uflash.c +++ b/trunk/drivers/mtd/maps/sun_uflash.c @@ -62,9 +62,10 @@ int uflash_devinit(struct linux_ebus_device *edev, struct device_node *dp) /* Non-CFI userflash device-- once I find one we * can work on supporting it. */ - printk("%s: unsupported device at 0x%lx (%d regs): " \ + printk("%s: unsupported device at 0x%llx (%d regs): " \ "email ebrower@usa.net\n", - dp->full_name, res->start, edev->num_addrs); + dp->full_name, (unsigned long long)res->start, + edev->num_addrs); return -ENODEV; } diff --git a/trunk/drivers/net/3c59x.c b/trunk/drivers/net/3c59x.c index b467c383ae60..d2f808979a2b 100644 --- a/trunk/drivers/net/3c59x.c +++ b/trunk/drivers/net/3c59x.c @@ -1407,8 +1407,10 @@ static int __devinit vortex_probe1(struct device *gendev, } if (print_info) { - printk(KERN_INFO "%s: CardBus functions mapped %8.8lx->%p\n", - print_name, pci_resource_start(pdev, 2), + printk(KERN_INFO "%s: CardBus functions mapped " + "%16.16llx->%p\n", + print_name, + (unsigned long long)pci_resource_start(pdev, 2), vp->cb_fn_base); } EL3WINDOW(2); diff --git a/trunk/drivers/net/8139cp.c b/trunk/drivers/net/8139cp.c index 0cdc830449d8..d26dd6a7062d 100644 --- a/trunk/drivers/net/8139cp.c +++ b/trunk/drivers/net/8139cp.c @@ -1823,7 +1823,7 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) struct cp_private *cp; int rc; void __iomem *regs; - long pciaddr; + resource_size_t pciaddr; unsigned int addr_len, i, pci_using_dac; u8 pci_rev; @@ -1883,8 +1883,8 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) } if (pci_resource_len(pdev, 1) < CP_REGS_SIZE) { rc = -EIO; - printk(KERN_ERR PFX "MMIO resource (%lx) too small on pci dev %s\n", - pci_resource_len(pdev, 1), pci_name(pdev)); + printk(KERN_ERR PFX "MMIO resource (%llx) too small on pci dev %s\n", + (unsigned long long)pci_resource_len(pdev, 1), pci_name(pdev)); goto err_out_res; } @@ -1916,8 +1916,9 @@ static int cp_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) regs = ioremap(pciaddr, CP_REGS_SIZE); if (!regs) { rc = -EIO; - printk(KERN_ERR PFX "Cannot map PCI MMIO (%lx@%lx) on pci dev %s\n", - pci_resource_len(pdev, 1), pciaddr, pci_name(pdev)); + printk(KERN_ERR PFX "Cannot map PCI MMIO (%llx@%llx) on pci dev %s\n", + (unsigned long long)pci_resource_len(pdev, 1), + (unsigned long long)pciaddr, pci_name(pdev)); goto err_out_res; } dev->base_addr = (unsigned long) regs; diff --git a/trunk/drivers/net/8139too.c b/trunk/drivers/net/8139too.c index abd6261465f1..ed2e3c03bc88 100644 --- a/trunk/drivers/net/8139too.c +++ b/trunk/drivers/net/8139too.c @@ -1341,9 +1341,9 @@ static int rtl8139_open (struct net_device *dev) netif_start_queue (dev); if (netif_msg_ifup(tp)) - printk(KERN_DEBUG "%s: rtl8139_open() ioaddr %#lx IRQ %d" - " GP Pins %2.2x %s-duplex.\n", - dev->name, pci_resource_start (tp->pci_dev, 1), + printk(KERN_DEBUG "%s: rtl8139_open() ioaddr %#llx IRQ %d" + " GP Pins %2.2x %s-duplex.\n", dev->name, + (unsigned long long)pci_resource_start (tp->pci_dev, 1), dev->irq, RTL_R8 (MediaStatus), tp->mii.full_duplex ? "full" : "half"); diff --git a/trunk/drivers/net/e100.c b/trunk/drivers/net/e100.c index f37170cc1a37..93a286570923 100644 --- a/trunk/drivers/net/e100.c +++ b/trunk/drivers/net/e100.c @@ -2678,9 +2678,9 @@ static int __devinit e100_probe(struct pci_dev *pdev, goto err_out_free; } - DPRINTK(PROBE, INFO, "addr 0x%lx, irq %d, " + DPRINTK(PROBE, INFO, "addr 0x%llx, irq %d, " "MAC addr %02X:%02X:%02X:%02X:%02X:%02X\n", - pci_resource_start(pdev, 0), pdev->irq, + (unsigned long long)pci_resource_start(pdev, 0), pdev->irq, netdev->dev_addr[0], netdev->dev_addr[1], netdev->dev_addr[2], netdev->dev_addr[3], netdev->dev_addr[4], netdev->dev_addr[5]); diff --git a/trunk/drivers/net/skge.c b/trunk/drivers/net/skge.c index 19a4a16055dc..1608efab4e3d 100644 --- a/trunk/drivers/net/skge.c +++ b/trunk/drivers/net/skge.c @@ -3354,8 +3354,8 @@ static int __devinit skge_probe(struct pci_dev *pdev, if (err) goto err_out_free_irq; - printk(KERN_INFO PFX DRV_VERSION " addr 0x%lx irq %d chip %s rev %d\n", - pci_resource_start(pdev, 0), pdev->irq, + printk(KERN_INFO PFX DRV_VERSION " addr 0x%llx irq %d chip %s rev %d\n", + (unsigned long long)pci_resource_start(pdev, 0), pdev->irq, skge_board_name(hw), hw->chip_rev); if ((dev = skge_devinit(hw, 0, using_dac)) == NULL) diff --git a/trunk/drivers/net/sky2.c b/trunk/drivers/net/sky2.c index d3577871be28..e122007e16da 100644 --- a/trunk/drivers/net/sky2.c +++ b/trunk/drivers/net/sky2.c @@ -3311,9 +3311,9 @@ static int __devinit sky2_probe(struct pci_dev *pdev, if (err) goto err_out_iounmap; - printk(KERN_INFO PFX "v%s addr 0x%lx irq %d Yukon-%s (0x%x) rev %d\n", - DRV_VERSION, pci_resource_start(pdev, 0), pdev->irq, - yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL], + printk(KERN_INFO PFX "v%s addr 0x%llx irq %d Yukon-%s (0x%x) rev %d\n", + DRV_VERSION, (unsigned long long)pci_resource_start(pdev, 0), + pdev->irq, yukon2_name[hw->chip_id - CHIP_ID_YUKON_XL], hw->chip_id, hw->chip_rev); dev = sky2_init_netdev(hw, 0, using_dac); diff --git a/trunk/drivers/net/tulip/de2104x.c b/trunk/drivers/net/tulip/de2104x.c index 5f743b972949..fc2468ecce0b 100644 --- a/trunk/drivers/net/tulip/de2104x.c +++ b/trunk/drivers/net/tulip/de2104x.c @@ -2007,8 +2007,8 @@ static int __init de_init_one (struct pci_dev *pdev, } if (pci_resource_len(pdev, 1) < DE_REGS_SIZE) { rc = -EIO; - printk(KERN_ERR PFX "MMIO resource (%lx) too small on pci dev %s\n", - pci_resource_len(pdev, 1), pci_name(pdev)); + printk(KERN_ERR PFX "MMIO resource (%llx) too small on pci dev %s\n", + (unsigned long long)pci_resource_len(pdev, 1), pci_name(pdev)); goto err_out_res; } @@ -2016,8 +2016,9 @@ static int __init de_init_one (struct pci_dev *pdev, regs = ioremap_nocache(pciaddr, DE_REGS_SIZE); if (!regs) { rc = -EIO; - printk(KERN_ERR PFX "Cannot map PCI MMIO (%lx@%lx) on pci dev %s\n", - pci_resource_len(pdev, 1), pciaddr, pci_name(pdev)); + printk(KERN_ERR PFX "Cannot map PCI MMIO (%llx@%lx) on pci dev %s\n", + (unsigned long long)pci_resource_len(pdev, 1), + pciaddr, pci_name(pdev)); goto err_out_res; } dev->base_addr = (unsigned long) regs; diff --git a/trunk/drivers/net/tulip/tulip_core.c b/trunk/drivers/net/tulip/tulip_core.c index e0de66739a42..53fd9b56d0bd 100644 --- a/trunk/drivers/net/tulip/tulip_core.c +++ b/trunk/drivers/net/tulip/tulip_core.c @@ -1350,10 +1350,10 @@ static int __devinit tulip_init_one (struct pci_dev *pdev, SET_MODULE_OWNER(dev); SET_NETDEV_DEV(dev, &pdev->dev); if (pci_resource_len (pdev, 0) < tulip_tbl[chip_idx].io_size) { - printk (KERN_ERR PFX "%s: I/O region (0x%lx@0x%lx) too small, " + printk (KERN_ERR PFX "%s: I/O region (0x%llx@0x%llx) too small, " "aborting\n", pci_name(pdev), - pci_resource_len (pdev, 0), - pci_resource_start (pdev, 0)); + (unsigned long long)pci_resource_len (pdev, 0), + (unsigned long long)pci_resource_start (pdev, 0)); goto err_out_free_netdev; } diff --git a/trunk/drivers/net/typhoon.c b/trunk/drivers/net/typhoon.c index e49e8b520c28..e24d2dafcf6c 100644 --- a/trunk/drivers/net/typhoon.c +++ b/trunk/drivers/net/typhoon.c @@ -2568,9 +2568,10 @@ typhoon_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) pci_set_drvdata(pdev, dev); - printk(KERN_INFO "%s: %s at %s 0x%lx, ", + printk(KERN_INFO "%s: %s at %s 0x%llx, ", dev->name, typhoon_card_info[card_id].name, - use_mmio ? "MMIO" : "IO", pci_resource_start(pdev, use_mmio)); + use_mmio ? "MMIO" : "IO", + (unsigned long long)pci_resource_start(pdev, use_mmio)); for(i = 0; i < 5; i++) printk("%2.2x:", dev->dev_addr[i]); printk("%2.2x\n", dev->dev_addr[i]); diff --git a/trunk/drivers/net/wan/dscc4.c b/trunk/drivers/net/wan/dscc4.c index 4505540e3c59..04a376ec0ed8 100644 --- a/trunk/drivers/net/wan/dscc4.c +++ b/trunk/drivers/net/wan/dscc4.c @@ -732,15 +732,15 @@ static int __devinit dscc4_init_one(struct pci_dev *pdev, ioaddr = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); if (!ioaddr) { - printk(KERN_ERR "%s: cannot remap MMIO region %lx @ %lx\n", - DRV_NAME, pci_resource_len(pdev, 0), - pci_resource_start(pdev, 0)); + printk(KERN_ERR "%s: cannot remap MMIO region %llx @ %llx\n", + DRV_NAME, (unsigned long long)pci_resource_len(pdev, 0), + (unsigned long long)pci_resource_start(pdev, 0)); rc = -EIO; goto err_free_mmio_regions_2; } - printk(KERN_DEBUG "Siemens DSCC4, MMIO at %#lx (regs), %#lx (lbi), IRQ %d\n", - pci_resource_start(pdev, 0), - pci_resource_start(pdev, 1), pdev->irq); + printk(KERN_DEBUG "Siemens DSCC4, MMIO at %#llx (regs), %#llx (lbi), IRQ %d\n", + (unsigned long long)pci_resource_start(pdev, 0), + (unsigned long long)pci_resource_start(pdev, 1), pdev->irq); /* Cf errata DS5 p.2 */ pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0xf8); diff --git a/trunk/drivers/net/wan/pc300_drv.c b/trunk/drivers/net/wan/pc300_drv.c index a3e65d1bc19b..d7897ae89f90 100644 --- a/trunk/drivers/net/wan/pc300_drv.c +++ b/trunk/drivers/net/wan/pc300_drv.c @@ -3445,9 +3445,9 @@ cpc_init_one(struct pci_dev *pdev, const struct pci_device_id *ent) card = (pc300_t *) kmalloc(sizeof(pc300_t), GFP_KERNEL); if (card == NULL) { - printk("PC300 found at RAM 0x%08lx, " + printk("PC300 found at RAM 0x%016llx, " "but could not allocate card structure.\n", - pci_resource_start(pdev, 3)); + (unsigned long long)pci_resource_start(pdev, 3)); err = -ENOMEM; goto err_disable_dev; } diff --git a/trunk/drivers/parisc/Kconfig b/trunk/drivers/parisc/Kconfig index 3f5de867acd7..1d3b84b4af3f 100644 --- a/trunk/drivers/parisc/Kconfig +++ b/trunk/drivers/parisc/Kconfig @@ -140,18 +140,37 @@ config CHASSIS_LCD_LED If unsure, say Y. config PDC_CHASSIS - bool "PDC chassis State Panel support" + bool "PDC chassis state codes support" default y help - Say Y here if you want to enable support for the LED State front - panel as found on E class, and support for the GSP Virtual Front - Panel (LED State and message logging) as found on high end - servers such as A, L and N-class. - - This has nothing to do with Chassis LCD and LED support. + Say Y here if you want to enable support for Chassis codes. + That includes support for LED State front panel as found on E + class, and support for the GSP Virtual Front Panel (LED State and + message logging) as found on high end servers such as A, L and + N-class. + This driver will also display progress messages on LCD display, + such as "INI", "RUN" and "FLT", and might thus clobber messages + shown by the LED/LCD driver. + This driver updates the state panel (LED and/or LCD) upon system + state change (eg: boot, shutdown or panic). If unsure, say Y. + +config PDC_CHASSIS_WARN + bool "PDC chassis warnings support" + depends on PROC_FS + default y + help + Say Y here if you want to enable support for Chassis warnings. + This will add a proc entry '/proc/chassis' giving some information + about the overall health state of the system. + This includes NVRAM battery level, overtemp or failures such as + fans or power units. + + If unsure, say Y. + + config PDC_STABLE tristate "PDC Stable Storage support" depends on SYSFS diff --git a/trunk/drivers/parisc/dino.c b/trunk/drivers/parisc/dino.c index 6e8ed0c81a6c..ce0a6ebcff15 100644 --- a/trunk/drivers/parisc/dino.c +++ b/trunk/drivers/parisc/dino.c @@ -299,7 +299,7 @@ struct pci_port_ops dino_port_ops = { static void dino_disable_irq(unsigned int irq) { - struct dino_device *dino_dev = irq_desc[irq].handler_data; + struct dino_device *dino_dev = irq_desc[irq].chip_data; int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); DBG(KERN_WARNING "%s(0x%p, %d)\n", __FUNCTION__, dino_dev, irq); @@ -311,7 +311,7 @@ static void dino_disable_irq(unsigned int irq) static void dino_enable_irq(unsigned int irq) { - struct dino_device *dino_dev = irq_desc[irq].handler_data; + struct dino_device *dino_dev = irq_desc[irq].chip_data; int local_irq = gsc_find_local_irq(irq, dino_dev->global_irq, DINO_LOCAL_IRQS); u32 tmp; diff --git a/trunk/drivers/parisc/eisa.c b/trunk/drivers/parisc/eisa.c index 9d3bd15bf53b..58f0ce8d78e0 100644 --- a/trunk/drivers/parisc/eisa.c +++ b/trunk/drivers/parisc/eisa.c @@ -350,7 +350,7 @@ static int __devinit eisa_probe(struct parisc_device *dev) irq_desc[2].action = &irq2_action; for (i = 0; i < 16; i++) { - irq_desc[i].handler = &eisa_interrupt_type; + irq_desc[i].chip = &eisa_interrupt_type; } EISA_bus = 1; diff --git a/trunk/drivers/parisc/gsc.c b/trunk/drivers/parisc/gsc.c index 16d40f95978d..5476ba7709b3 100644 --- a/trunk/drivers/parisc/gsc.c +++ b/trunk/drivers/parisc/gsc.c @@ -109,7 +109,7 @@ int gsc_find_local_irq(unsigned int irq, int *global_irqs, int limit) static void gsc_asic_disable_irq(unsigned int irq) { - struct gsc_asic *irq_dev = irq_desc[irq].handler_data; + struct gsc_asic *irq_dev = irq_desc[irq].chip_data; int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); u32 imr; @@ -124,7 +124,7 @@ static void gsc_asic_disable_irq(unsigned int irq) static void gsc_asic_enable_irq(unsigned int irq) { - struct gsc_asic *irq_dev = irq_desc[irq].handler_data; + struct gsc_asic *irq_dev = irq_desc[irq].chip_data; int local_irq = gsc_find_local_irq(irq, irq_dev->global_irq, 32); u32 imr; @@ -164,8 +164,8 @@ int gsc_assign_irq(struct hw_interrupt_type *type, void *data) if (irq > GSC_IRQ_MAX) return NO_IRQ; - irq_desc[irq].handler = type; - irq_desc[irq].handler_data = data; + irq_desc[irq].chip = type; + irq_desc[irq].chip_data = data; return irq++; } diff --git a/trunk/drivers/parisc/iosapic.c b/trunk/drivers/parisc/iosapic.c index 7a458d5bc751..1fbda77cefc2 100644 --- a/trunk/drivers/parisc/iosapic.c +++ b/trunk/drivers/parisc/iosapic.c @@ -619,7 +619,7 @@ iosapic_set_irt_data( struct vector_info *vi, u32 *dp0, u32 *dp1) static struct vector_info *iosapic_get_vector(unsigned int irq) { - return irq_desc[irq].handler_data; + return irq_desc[irq].chip_data; } static void iosapic_disable_irq(unsigned int irq) diff --git a/trunk/drivers/parisc/pdc_stable.c b/trunk/drivers/parisc/pdc_stable.c index bbeabe3fc4c6..ea1b7a63598e 100644 --- a/trunk/drivers/parisc/pdc_stable.c +++ b/trunk/drivers/parisc/pdc_stable.c @@ -28,8 +28,15 @@ * following code can deal with just 96 bytes of Stable Storage, and all * sizes between 96 and 192 bytes (provided they are multiple of struct * device_path size, eg: 128, 160 and 192) to provide full information. - * The code makes no use of data above 192 bytes. One last word: there's one - * path we can always count on: the primary path. + * One last word: there's one path we can always count on: the primary path. + * Anything above 224 bytes is used for 'osdep2' OS-dependent storage area. + * + * The first OS-dependent area should always be available. Obviously, this is + * not true for the other one. Also bear in mind that reading/writing from/to + * osdep2 is much more expensive than from/to osdep1. + * NOTE: We do not handle the 2 bytes OS-dep area at 0x5D, nor the first + * 2 bytes of storage available right after OSID. That's a total of 4 bytes + * sacrificed: -ETOOLAZY :P * * The current policy wrt file permissions is: * - write: root only @@ -64,15 +71,18 @@ #include #include -#define PDCS_VERSION "0.22" +#define PDCS_VERSION "0.30" #define PDCS_PREFIX "PDC Stable Storage" #define PDCS_ADDR_PPRI 0x00 #define PDCS_ADDR_OSID 0x40 +#define PDCS_ADDR_OSD1 0x48 +#define PDCS_ADDR_DIAG 0x58 #define PDCS_ADDR_FSIZ 0x5C #define PDCS_ADDR_PCON 0x60 #define PDCS_ADDR_PALT 0x80 #define PDCS_ADDR_PKBD 0xA0 +#define PDCS_ADDR_OSD2 0xE0 MODULE_AUTHOR("Thibaut VARENE "); MODULE_DESCRIPTION("sysfs interface to HP PDC Stable Storage data"); @@ -82,6 +92,9 @@ MODULE_VERSION(PDCS_VERSION); /* holds Stable Storage size. Initialized once and for all, no lock needed */ static unsigned long pdcs_size __read_mostly; +/* holds OS ID. Initialized once and for all, hopefully to 0x0006 */ +static u16 pdcs_osid __read_mostly; + /* This struct defines what we need to deal with a parisc pdc path entry */ struct pdcspath_entry { rwlock_t rw_lock; /* to protect path entry access */ @@ -609,27 +622,64 @@ static ssize_t pdcs_osid_read(struct subsystem *entry, char *buf) { char *out = buf; - __u32 result; - char *tmpstr = NULL; if (!entry || !buf) return -EINVAL; - /* get OSID */ - if (pdc_stable_read(PDCS_ADDR_OSID, &result, sizeof(result)) != PDC_OK) + out += sprintf(out, "%s dependent data (0x%.4x)\n", + os_id_to_string(pdcs_osid), pdcs_osid); + + return out - buf; +} + +/** + * pdcs_osdep1_read - Stable Storage OS-Dependent data area 1 output. + * @entry: An allocated and populated subsytem struct. We don't use it tho. + * @buf: The output buffer to write to. + * + * This can hold 16 bytes of OS-Dependent data. + */ +static ssize_t +pdcs_osdep1_read(struct subsystem *entry, char *buf) +{ + char *out = buf; + u32 result[4]; + + if (!entry || !buf) + return -EINVAL; + + if (pdc_stable_read(PDCS_ADDR_OSD1, &result, sizeof(result)) != PDC_OK) return -EIO; - /* the actual result is 16 bits away */ - switch (result >> 16) { - case 0x0000: tmpstr = "No OS-dependent data"; break; - case 0x0001: tmpstr = "HP-UX dependent data"; break; - case 0x0002: tmpstr = "MPE-iX dependent data"; break; - case 0x0003: tmpstr = "OSF dependent data"; break; - case 0x0004: tmpstr = "HP-RT dependent data"; break; - case 0x0005: tmpstr = "Novell Netware dependent data"; break; - default: tmpstr = "Unknown"; break; - } - out += sprintf(out, "%s (0x%.4x)\n", tmpstr, (result >> 16)); + out += sprintf(out, "0x%.8x\n", result[0]); + out += sprintf(out, "0x%.8x\n", result[1]); + out += sprintf(out, "0x%.8x\n", result[2]); + out += sprintf(out, "0x%.8x\n", result[3]); + + return out - buf; +} + +/** + * pdcs_diagnostic_read - Stable Storage Diagnostic register output. + * @entry: An allocated and populated subsytem struct. We don't use it tho. + * @buf: The output buffer to write to. + * + * I have NFC how to interpret the content of that register ;-). + */ +static ssize_t +pdcs_diagnostic_read(struct subsystem *entry, char *buf) +{ + char *out = buf; + u32 result; + + if (!entry || !buf) + return -EINVAL; + + /* get diagnostic */ + if (pdc_stable_read(PDCS_ADDR_DIAG, &result, sizeof(result)) != PDC_OK) + return -EIO; + + out += sprintf(out, "0x%.4x\n", (result >> 16)); return out - buf; } @@ -645,7 +695,7 @@ static ssize_t pdcs_fastsize_read(struct subsystem *entry, char *buf) { char *out = buf; - __u32 result; + u32 result; if (!entry || !buf) return -EINVAL; @@ -663,6 +713,39 @@ pdcs_fastsize_read(struct subsystem *entry, char *buf) return out - buf; } +/** + * pdcs_osdep2_read - Stable Storage OS-Dependent data area 2 output. + * @entry: An allocated and populated subsytem struct. We don't use it tho. + * @buf: The output buffer to write to. + * + * This can hold pdcs_size - 224 bytes of OS-Dependent data, when available. + */ +static ssize_t +pdcs_osdep2_read(struct subsystem *entry, char *buf) +{ + char *out = buf; + unsigned long size; + unsigned short i; + u32 result; + + if (unlikely(pdcs_size <= 224)) + return -ENODATA; + + size = pdcs_size - 224; + + if (!entry || !buf) + return -EINVAL; + + for (i=0; i 16) + return -EMSGSIZE; + + /* We'll use a local copy of buf */ + memset(in, 0, 16); + memcpy(in, buf, count); + + if (pdc_stable_write(PDCS_ADDR_OSD1, &in, sizeof(in)) != PDC_OK) + return -EIO; + + return count; +} + +/** + * pdcs_osdep2_write - Stable Storage OS-Dependent data area 2 input. + * @entry: An allocated and populated subsytem struct. We don't use it tho. + * @buf: The input buffer to read from. + * @count: The number of bytes to be read. + * + * This can store pdcs_size - 224 bytes of OS-Dependent data. We use a + * byte-by-byte write approach. It's up to userspace to deal with it when + * constructing its input buffer. + */ +static ssize_t +pdcs_osdep2_write(struct subsystem *entry, const char *buf, size_t count) +{ + unsigned long size; + unsigned short i; + u8 in[4]; + + if (!capable(CAP_SYS_ADMIN)) + return -EACCES; + + if (!entry || !buf || !count) + return -EINVAL; + + if (unlikely(pdcs_size <= 224)) + return -ENOSYS; + + if (unlikely(pdcs_osid != OS_ID_LINUX)) + return -EPERM; + + size = pdcs_size - 224; + + if (count > size) + return -EMSGSIZE; + + /* We'll use a local copy of buf */ + + for (i=0; i> 16); + /* For now we'll register the stable subsys within this driver */ if ((rc = firmware_register(&stable_subsys))) goto fail_firmreg; @@ -887,7 +1068,7 @@ pdc_stable_init(void) /* register the paths subsys as a subsystem of stable subsys */ kset_set_kset_s(&paths_subsys, stable_subsys); - if ((rc= subsystem_register(&paths_subsys))) + if ((rc = subsystem_register(&paths_subsys))) goto fail_subsysreg; /* now we create all "files" for the paths subsys */ diff --git a/trunk/drivers/parisc/sba_iommu.c b/trunk/drivers/parisc/sba_iommu.c index 278f325021ee..d09e39e39c60 100644 --- a/trunk/drivers/parisc/sba_iommu.c +++ b/trunk/drivers/parisc/sba_iommu.c @@ -316,10 +316,10 @@ static int reserve_sba_gart = 1; ** ** Superdome (in particular, REO) allows only 64-bit CSR accesses. */ -#define READ_REG32(addr) le32_to_cpu(__raw_readl(addr)) -#define READ_REG64(addr) le64_to_cpu(__raw_readq(addr)) -#define WRITE_REG32(val, addr) __raw_writel(cpu_to_le32(val), addr) -#define WRITE_REG64(val, addr) __raw_writeq(cpu_to_le64(val), addr) +#define READ_REG32(addr) readl(addr) +#define READ_REG64(addr) readq(addr) +#define WRITE_REG32(val, addr) writel((val), (addr)) +#define WRITE_REG64(val, addr) writeq((val), (addr)) #ifdef CONFIG_64BIT #define READ_REG(addr) READ_REG64(addr) @@ -1427,7 +1427,7 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) iov_order = get_order(iova_space_size >> (IOVP_SHIFT - PAGE_SHIFT)); ioc->pdir_size = (iova_space_size / IOVP_SIZE) * sizeof(u64); - DBG_INIT("%s() hpa 0x%lx IOV %dMB (%d bits)\n", + DBG_INIT("%s() hpa 0x%p IOV %dMB (%d bits)\n", __FUNCTION__, ioc->ioc_hpa, iova_space_size >> 20, iov_order + PAGE_SHIFT); @@ -1764,7 +1764,7 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa, sba_dev->num_ioc = num_ioc; for (i = 0; i < num_ioc; i++) { - unsigned long ioc_hpa = sba_dev->ioc[i].ioc_hpa; + void __iomem *ioc_hpa = sba_dev->ioc[i].ioc_hpa; unsigned int j; for (j=0; j < sizeof(u64) * ROPES_PER_IOC; j+=sizeof(u64)) { @@ -1776,7 +1776,8 @@ printk("sba_hw_init(): mem_boot 0x%x 0x%x 0x%x 0x%x\n", PAGE0->mem_boot.hpa, * Improves netperf UDP_STREAM by ~10% for bcm5701. */ if (IS_PLUTO(sba_dev->iodc)) { - unsigned long rope_cfg, cfg_val; + void __iomem *rope_cfg; + unsigned long cfg_val; rope_cfg = ioc_hpa + IOC_ROPE0_CFG + j; cfg_val = READ_REG(rope_cfg); @@ -1902,7 +1903,7 @@ sba_common_init(struct sba_device *sba_dev) * (bit #61, big endian), we have to flush and sync every time * IO-PDIR is changed in Ike/Astro. */ - if (boot_cpu_data.pdc.capabilities & PDC_MODEL_IOPDIR_FDC) { + if (ioc_needs_fdc) { printk(KERN_INFO MODULE_NAME " FDC/SYNC required.\n"); } else { printk(KERN_INFO MODULE_NAME " IOC has cache coherent PDIR.\n"); diff --git a/trunk/drivers/parisc/superio.c b/trunk/drivers/parisc/superio.c index 828eb45062de..a988dc7a9abd 100644 --- a/trunk/drivers/parisc/superio.c +++ b/trunk/drivers/parisc/superio.c @@ -360,7 +360,7 @@ int superio_fixup_irq(struct pci_dev *pcidev) #endif for (i = 0; i < 16; i++) { - irq_desc[i].handler = &superio_interrupt_type; + irq_desc[i].chip = &superio_interrupt_type; } /* diff --git a/trunk/drivers/pci/bus.c b/trunk/drivers/pci/bus.c index 723092682023..5f7db9d2436e 100644 --- a/trunk/drivers/pci/bus.c +++ b/trunk/drivers/pci/bus.c @@ -34,11 +34,11 @@ */ int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, - unsigned long size, unsigned long align, unsigned long min, - unsigned int type_mask, - void (*alignf)(void *, struct resource *, - unsigned long, unsigned long), - void *alignf_data) + resource_size_t size, resource_size_t align, + resource_size_t min, unsigned int type_mask, + void (*alignf)(void *, struct resource *, resource_size_t, + resource_size_t), + void *alignf_data) { int i, ret = -ENOMEM; diff --git a/trunk/drivers/pci/hotplug/cpcihp_zt5550.c b/trunk/drivers/pci/hotplug/cpcihp_zt5550.c index f7cb00da38df..1ec165df8522 100644 --- a/trunk/drivers/pci/hotplug/cpcihp_zt5550.c +++ b/trunk/drivers/pci/hotplug/cpcihp_zt5550.c @@ -95,8 +95,8 @@ static int zt5550_hc_config(struct pci_dev *pdev) hc_dev = pdev; dbg("hc_dev = %p", hc_dev); - dbg("pci resource start %lx", pci_resource_start(hc_dev, 1)); - dbg("pci resource len %lx", pci_resource_len(hc_dev, 1)); + dbg("pci resource start %llx", (unsigned long long)pci_resource_start(hc_dev, 1)); + dbg("pci resource len %llx", (unsigned long long)pci_resource_len(hc_dev, 1)); if(!request_mem_region(pci_resource_start(hc_dev, 1), pci_resource_len(hc_dev, 1), MY_NAME)) { @@ -108,8 +108,9 @@ static int zt5550_hc_config(struct pci_dev *pdev) hc_registers = ioremap(pci_resource_start(hc_dev, 1), pci_resource_len(hc_dev, 1)); if(!hc_registers) { - err("cannot remap MMIO region %lx @ %lx", - pci_resource_len(hc_dev, 1), pci_resource_start(hc_dev, 1)); + err("cannot remap MMIO region %llx @ %llx", + (unsigned long long)pci_resource_len(hc_dev, 1), + (unsigned long long)pci_resource_start(hc_dev, 1)); ret = -ENODEV; goto exit_release_region; } diff --git a/trunk/drivers/pci/hotplug/cpqphp_core.c b/trunk/drivers/pci/hotplug/cpqphp_core.c index 9bc1deb8df52..f8658d63f077 100644 --- a/trunk/drivers/pci/hotplug/cpqphp_core.c +++ b/trunk/drivers/pci/hotplug/cpqphp_core.c @@ -1089,8 +1089,8 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) } dbg("pdev = %p\n", pdev); - dbg("pci resource start %lx\n", pci_resource_start(pdev, 0)); - dbg("pci resource len %lx\n", pci_resource_len(pdev, 0)); + dbg("pci resource start %llx\n", (unsigned long long)pci_resource_start(pdev, 0)); + dbg("pci resource len %llx\n", (unsigned long long)pci_resource_len(pdev, 0)); if (!request_mem_region(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0), MY_NAME)) { @@ -1102,9 +1102,9 @@ static int cpqhpc_probe(struct pci_dev *pdev, const struct pci_device_id *ent) ctrl->hpc_reg = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); if (!ctrl->hpc_reg) { - err("cannot remap MMIO region %lx @ %lx\n", - pci_resource_len(pdev, 0), - pci_resource_start(pdev, 0)); + err("cannot remap MMIO region %llx @ %llx\n", + (unsigned long long)pci_resource_len(pdev, 0), + (unsigned long long)pci_resource_start(pdev, 0)); rc = -ENODEV; goto err_free_mem_region; } diff --git a/trunk/drivers/pci/hotplug/pciehp_hpc.c b/trunk/drivers/pci/hotplug/pciehp_hpc.c index d77138ecb098..11f7858f0064 100644 --- a/trunk/drivers/pci/hotplug/pciehp_hpc.c +++ b/trunk/drivers/pci/hotplug/pciehp_hpc.c @@ -1398,8 +1398,9 @@ int pcie_init(struct controller * ctrl, struct pcie_device *dev) for ( rc = 0; rc < DEVICE_COUNT_RESOURCE; rc++) if (pci_resource_len(pdev, rc) > 0) - dbg("pci resource[%d] start=0x%lx(len=0x%lx)\n", rc, - pci_resource_start(pdev, rc), pci_resource_len(pdev, rc)); + dbg("pci resource[%d] start=0x%llx(len=0x%llx)\n", rc, + (unsigned long long)pci_resource_start(pdev, rc), + (unsigned long long)pci_resource_len(pdev, rc)); info("HPC vendor_id %x device_id %x ss_vid %x ss_did %x\n", pdev->vendor, pdev->device, pdev->subsystem_vendor, pdev->subsystem_device); diff --git a/trunk/drivers/pci/hotplug/shpchp_sysfs.c b/trunk/drivers/pci/hotplug/shpchp_sysfs.c index f5cfbf2c047c..620e1139e607 100644 --- a/trunk/drivers/pci/hotplug/shpchp_sysfs.c +++ b/trunk/drivers/pci/hotplug/shpchp_sysfs.c @@ -51,8 +51,10 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha res = bus->resource[index]; if (res && (res->flags & IORESOURCE_MEM) && !(res->flags & IORESOURCE_PREFETCH)) { - out += sprintf(out, "start = %8.8lx, length = %8.8lx\n", - res->start, (res->end - res->start)); + out += sprintf(out, "start = %8.8llx, " + "length = %8.8llx\n", + (unsigned long long)res->start, + (unsigned long long)(res->end - res->start)); } } out += sprintf(out, "Free resources: prefetchable memory\n"); @@ -60,16 +62,20 @@ static ssize_t show_ctrl (struct device *dev, struct device_attribute *attr, cha res = bus->resource[index]; if (res && (res->flags & IORESOURCE_MEM) && (res->flags & IORESOURCE_PREFETCH)) { - out += sprintf(out, "start = %8.8lx, length = %8.8lx\n", - res->start, (res->end - res->start)); + out += sprintf(out, "start = %8.8llx, " + "length = %8.8llx\n", + (unsigned long long)res->start, + (unsigned long long)(res->end - res->start)); } } out += sprintf(out, "Free resources: IO\n"); for (index = 0; index < PCI_BUS_NUM_RESOURCES; index++) { res = bus->resource[index]; if (res && (res->flags & IORESOURCE_IO)) { - out += sprintf(out, "start = %8.8lx, length = %8.8lx\n", - res->start, (res->end - res->start)); + out += sprintf(out, "start = %8.8llx, " + "length = %8.8llx\n", + (unsigned long long)res->start, + (unsigned long long)(res->end - res->start)); } } out += sprintf(out, "Free resources: bus numbers\n"); diff --git a/trunk/drivers/pci/msi.c b/trunk/drivers/pci/msi.c index 7f8429284fab..76d023d8a33b 100644 --- a/trunk/drivers/pci/msi.c +++ b/trunk/drivers/pci/msi.c @@ -429,12 +429,12 @@ static void irq_handler_init(int cap_id, int pos, int mask) spin_lock_irqsave(&irq_desc[pos].lock, flags); if (cap_id == PCI_CAP_ID_MSIX) - irq_desc[pos].handler = &msix_irq_type; + irq_desc[pos].chip = &msix_irq_type; else { if (!mask) - irq_desc[pos].handler = &msi_irq_wo_maskbit_type; + irq_desc[pos].chip = &msi_irq_wo_maskbit_type; else - irq_desc[pos].handler = &msi_irq_w_maskbit_type; + irq_desc[pos].chip = &msi_irq_w_maskbit_type; } spin_unlock_irqrestore(&irq_desc[pos].lock, flags); } diff --git a/trunk/drivers/pci/pci-sysfs.c b/trunk/drivers/pci/pci-sysfs.c index bc405c035ce3..606f9b6f70eb 100644 --- a/trunk/drivers/pci/pci-sysfs.c +++ b/trunk/drivers/pci/pci-sysfs.c @@ -87,7 +87,7 @@ resource_show(struct device * dev, struct device_attribute *attr, char * buf) char * str = buf; int i; int max = 7; - u64 start, end; + resource_size_t start, end; if (pci_dev->subordinate) max = DEVICE_COUNT_RESOURCE; @@ -365,7 +365,7 @@ pci_mmap_resource(struct kobject *kobj, struct bin_attribute *attr, struct device, kobj)); struct resource *res = (struct resource *)attr->private; enum pci_mmap_state mmap_type; - u64 start, end; + resource_size_t start, end; int i; for (i = 0; i < PCI_ROM_RESOURCE; i++) diff --git a/trunk/drivers/pci/pci.c b/trunk/drivers/pci/pci.c index 23d3b17c8cad..cf57d7de3765 100644 --- a/trunk/drivers/pci/pci.c +++ b/trunk/drivers/pci/pci.c @@ -691,10 +691,12 @@ int pci_request_region(struct pci_dev *pdev, int bar, const char *res_name) return 0; err_out: - printk (KERN_WARNING "PCI: Unable to reserve %s region #%d:%lx@%lx for device %s\n", + printk (KERN_WARNING "PCI: Unable to reserve %s region #%d:%llx@%llx " + "for device %s\n", pci_resource_flags(pdev, bar) & IORESOURCE_IO ? "I/O" : "mem", bar + 1, /* PCI BAR # */ - pci_resource_len(pdev, bar), pci_resource_start(pdev, bar), + (unsigned long long)pci_resource_len(pdev, bar), + (unsigned long long)pci_resource_start(pdev, bar), pci_name(pdev)); return -EBUSY; } diff --git a/trunk/drivers/pci/pci.h b/trunk/drivers/pci/pci.h index 29bdeca031a8..9cc842b666eb 100644 --- a/trunk/drivers/pci/pci.h +++ b/trunk/drivers/pci/pci.h @@ -6,10 +6,10 @@ extern int pci_create_sysfs_dev_files(struct pci_dev *pdev); extern void pci_remove_sysfs_dev_files(struct pci_dev *pdev); extern void pci_cleanup_rom(struct pci_dev *dev); extern int pci_bus_alloc_resource(struct pci_bus *bus, struct resource *res, - unsigned long size, unsigned long align, - unsigned long min, unsigned int type_mask, + resource_size_t size, resource_size_t align, + resource_size_t min, unsigned int type_mask, void (*alignf)(void *, struct resource *, - unsigned long, unsigned long), + resource_size_t, resource_size_t), void *alignf_data); /* Firmware callbacks */ extern int (*platform_pci_choose_state)(struct pci_dev *dev, pm_message_t state); diff --git a/trunk/drivers/pci/proc.c b/trunk/drivers/pci/proc.c index 54b2ebc9c91a..99cf33379769 100644 --- a/trunk/drivers/pci/proc.c +++ b/trunk/drivers/pci/proc.c @@ -302,12 +302,6 @@ static struct file_operations proc_bus_pci_operations = { #endif /* HAVE_PCI_MMAP */ }; -#if BITS_PER_LONG == 32 -#define LONG_FORMAT "\t%08lx" -#else -#define LONG_FORMAT "\t%16lx" -#endif - /* iterator */ static void *pci_seq_start(struct seq_file *m, loff_t *pos) { @@ -356,18 +350,18 @@ static int show_device(struct seq_file *m, void *v) dev->irq); /* Here should be 7 and not PCI_NUM_RESOURCES as we need to preserve compatibility */ for (i=0; i<7; i++) { - u64 start, end; + resource_size_t start, end; pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); - seq_printf(m, LONG_FORMAT, - ((unsigned long)start) | - (dev->resource[i].flags & PCI_REGION_FLAG_MASK)); + seq_printf(m, "\t%16llx", + (unsigned long long)(start | + (dev->resource[i].flags & PCI_REGION_FLAG_MASK))); } for (i=0; i<7; i++) { - u64 start, end; + resource_size_t start, end; pci_resource_to_user(dev, i, &dev->resource[i], &start, &end); - seq_printf(m, LONG_FORMAT, + seq_printf(m, "\t%16llx", dev->resource[i].start < dev->resource[i].end ? - (unsigned long)(end - start) + 1 : 0); + (unsigned long long)(end - start) + 1 : 0); } seq_putc(m, '\t'); if (drv) diff --git a/trunk/drivers/pci/rom.c b/trunk/drivers/pci/rom.c index 598a115cd00e..cbb69cf41311 100644 --- a/trunk/drivers/pci/rom.c +++ b/trunk/drivers/pci/rom.c @@ -80,8 +80,8 @@ void __iomem *pci_map_rom(struct pci_dev *pdev, size_t *size) } else { if (res->flags & IORESOURCE_ROM_COPY) { *size = pci_resource_len(pdev, PCI_ROM_RESOURCE); - return (void __iomem *)pci_resource_start(pdev, - PCI_ROM_RESOURCE); + return (void __iomem *)(unsigned long) + pci_resource_start(pdev, PCI_ROM_RESOURCE); } else { /* assign the ROM an address if it doesn't have one */ if (res->parent == NULL && @@ -170,11 +170,11 @@ void __iomem *pci_map_rom_copy(struct pci_dev *pdev, size_t *size) return rom; res->end = res->start + *size; - memcpy_fromio((void*)res->start, rom, *size); + memcpy_fromio((void*)(unsigned long)res->start, rom, *size); pci_unmap_rom(pdev, rom); res->flags |= IORESOURCE_ROM_COPY; - return (void __iomem *)res->start; + return (void __iomem *)(unsigned long)res->start; } /** @@ -227,7 +227,7 @@ void pci_cleanup_rom(struct pci_dev *pdev) { struct resource *res = &pdev->resource[PCI_ROM_RESOURCE]; if (res->flags & IORESOURCE_ROM_COPY) { - kfree((void*)res->start); + kfree((void*)(unsigned long)res->start); res->flags &= ~IORESOURCE_ROM_COPY; res->start = 0; res->end = 0; diff --git a/trunk/drivers/pci/setup-bus.c b/trunk/drivers/pci/setup-bus.c index 35086e80faa9..47c1071ad84e 100644 --- a/trunk/drivers/pci/setup-bus.c +++ b/trunk/drivers/pci/setup-bus.c @@ -357,8 +357,10 @@ pbus_size_mem(struct pci_bus *bus, unsigned long mask, unsigned long type) order = __ffs(align) - 20; if (order > 11) { printk(KERN_WARNING "PCI: region %s/%d " - "too large: %lx-%lx\n", - pci_name(dev), i, r->start, r->end); + "too large: %llx-%llx\n", + pci_name(dev), i, + (unsigned long long)r->start, + (unsigned long long)r->end); r->flags = 0; continue; } diff --git a/trunk/drivers/pci/setup-res.c b/trunk/drivers/pci/setup-res.c index 577f4b55c46d..ab78e4bbdd83 100644 --- a/trunk/drivers/pci/setup-res.c +++ b/trunk/drivers/pci/setup-res.c @@ -40,8 +40,9 @@ pci_update_resource(struct pci_dev *dev, struct resource *res, int resno) pcibios_resource_to_bus(dev, ®ion, res); - pr_debug(" got res [%lx:%lx] bus [%lx:%lx] flags %lx for " - "BAR %d of %s\n", res->start, res->end, + pr_debug(" got res [%llx:%llx] bus [%lx:%lx] flags %lx for " + "BAR %d of %s\n", (unsigned long long)res->start, + (unsigned long long)res->end, region.start, region.end, res->flags, resno, pci_name(dev)); new = region.start | (res->flags & PCI_REGION_FLAG_MASK); @@ -104,10 +105,12 @@ pci_claim_resource(struct pci_dev *dev, int resource) err = insert_resource(root, res); if (err) { - printk(KERN_ERR "PCI: %s region %d of %s %s [%lx:%lx]\n", - root ? "Address space collision on" : - "No parent found for", - resource, dtype, pci_name(dev), res->start, res->end); + printk(KERN_ERR "PCI: %s region %d of %s %s [%llx:%llx]\n", + root ? "Address space collision on" : + "No parent found for", + resource, dtype, pci_name(dev), + (unsigned long long)res->start, + (unsigned long long)res->end); } return err; @@ -118,7 +121,7 @@ int pci_assign_resource(struct pci_dev *dev, int resno) { struct pci_bus *bus = dev->bus; struct resource *res = dev->resource + resno; - unsigned long size, min, align; + resource_size_t size, min, align; int ret; size = res->end - res->start + 1; @@ -145,9 +148,11 @@ int pci_assign_resource(struct pci_dev *dev, int resno) } if (ret) { - printk(KERN_ERR "PCI: Failed to allocate %s resource #%d:%lx@%lx for %s\n", - res->flags & IORESOURCE_IO ? "I/O" : "mem", - resno, size, res->start, pci_name(dev)); + printk(KERN_ERR "PCI: Failed to allocate %s resource " + "#%d:%llx@%llx for %s\n", + res->flags & IORESOURCE_IO ? "I/O" : "mem", + resno, (unsigned long long)size, + (unsigned long long)res->start, pci_name(dev)); } else if (resno < PCI_BRIDGE_RESOURCES) { pci_update_resource(dev, res, resno); } @@ -204,7 +209,7 @@ pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) for (i = 0; i < PCI_NUM_RESOURCES; i++) { struct resource *r; struct resource_list *list, *tmp; - unsigned long r_align; + resource_size_t r_align; r = &dev->resource[i]; r_align = r->end - r->start; @@ -213,13 +218,14 @@ pdev_sort_resources(struct pci_dev *dev, struct resource_list *head) continue; if (!r_align) { printk(KERN_WARNING "PCI: Ignore bogus resource %d " - "[%lx:%lx] of %s\n", - i, r->start, r->end, pci_name(dev)); + "[%llx:%llx] of %s\n", + i, (unsigned long long)r->start, + (unsigned long long)r->end, pci_name(dev)); continue; } r_align = (i < PCI_BRIDGE_RESOURCES) ? r_align + 1 : r->start; for (list = head; ; list = list->next) { - unsigned long align = 0; + resource_size_t align = 0; struct resource_list *ln = list->next; int idx; diff --git a/trunk/drivers/pcmcia/hd64465_ss.c b/trunk/drivers/pcmcia/hd64465_ss.c index b39435bbfaeb..c662e4f89d46 100644 --- a/trunk/drivers/pcmcia/hd64465_ss.c +++ b/trunk/drivers/pcmcia/hd64465_ss.c @@ -244,8 +244,8 @@ static void hs_map_irq(hs_socket_t *sp, unsigned int irq) hs_mapped_irq[irq].sock = sp; /* insert ourselves as the irq controller */ - hs_mapped_irq[irq].old_handler = irq_desc[irq].handler; - irq_desc[irq].handler = &hd64465_ss_irq_type; + hs_mapped_irq[irq].old_handler = irq_desc[irq].chip; + irq_desc[irq].chip = &hd64465_ss_irq_type; } @@ -260,7 +260,7 @@ static void hs_unmap_irq(hs_socket_t *sp, unsigned int irq) return; /* restore the original irq controller */ - irq_desc[irq].handler = hs_mapped_irq[irq].old_handler; + irq_desc[irq].chip = hs_mapped_irq[irq].old_handler; } /*============================================================*/ diff --git a/trunk/drivers/pcmcia/i82365.c b/trunk/drivers/pcmcia/i82365.c index a2f05f485156..ff51a65d9433 100644 --- a/trunk/drivers/pcmcia/i82365.c +++ b/trunk/drivers/pcmcia/i82365.c @@ -1084,9 +1084,10 @@ static int i365_set_mem_map(u_short sock, struct pccard_mem_map *mem) u_short base, i; u_char map; - debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, %#lx-%#lx, " + debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, %#llx-%#llx, " "%#x)\n", sock, mem->map, mem->flags, mem->speed, - mem->res->start, mem->res->end, mem->card_start); + (unsigned long long)mem->res->start, + (unsigned long long)mem->res->end, mem->card_start); map = mem->map; if ((map > 4) || (mem->card_start > 0x3ffffff) || diff --git a/trunk/drivers/pcmcia/pd6729.c b/trunk/drivers/pcmcia/pd6729.c index 247ab837f841..9ee26c1b8635 100644 --- a/trunk/drivers/pcmcia/pd6729.c +++ b/trunk/drivers/pcmcia/pd6729.c @@ -642,7 +642,8 @@ static int __devinit pd6729_pci_probe(struct pci_dev *dev, goto err_out_free_mem; printk(KERN_INFO "pd6729: Cirrus PD6729 PCI to PCMCIA Bridge " - "at 0x%lx on irq %d\n", pci_resource_start(dev, 0), dev->irq); + "at 0x%llx on irq %d\n", + (unsigned long long)pci_resource_start(dev, 0), dev->irq); /* * Since we have no memory BARs some firmware may not * have had PCI_COMMAND_MEMORY enabled, yet the device needs it. diff --git a/trunk/drivers/pcmcia/rsrc_nonstatic.c b/trunk/drivers/pcmcia/rsrc_nonstatic.c index 0f8b157c9717..c3176b16b7be 100644 --- a/trunk/drivers/pcmcia/rsrc_nonstatic.c +++ b/trunk/drivers/pcmcia/rsrc_nonstatic.c @@ -72,7 +72,7 @@ static DEFINE_MUTEX(rsrc_mutex); ======================================================================*/ static struct resource * -make_resource(unsigned long b, unsigned long n, int flags, char *name) +make_resource(resource_size_t b, resource_size_t n, int flags, char *name) { struct resource *res = kzalloc(sizeof(*res), GFP_KERNEL); @@ -86,8 +86,8 @@ make_resource(unsigned long b, unsigned long n, int flags, char *name) } static struct resource * -claim_region(struct pcmcia_socket *s, unsigned long base, unsigned long size, - int type, char *name) +claim_region(struct pcmcia_socket *s, resource_size_t base, + resource_size_t size, int type, char *name) { struct resource *res, *parent; @@ -519,10 +519,10 @@ struct pcmcia_align_data { static void pcmcia_common_align(void *align_data, struct resource *res, - unsigned long size, unsigned long align) + resource_size_t size, resource_size_t align) { struct pcmcia_align_data *data = align_data; - unsigned long start; + resource_size_t start; /* * Ensure that we have the correct start address */ @@ -533,8 +533,8 @@ pcmcia_common_align(void *align_data, struct resource *res, } static void -pcmcia_align(void *align_data, struct resource *res, - unsigned long size, unsigned long align) +pcmcia_align(void *align_data, struct resource *res, resource_size_t size, + resource_size_t align) { struct pcmcia_align_data *data = align_data; struct resource_map *m; @@ -808,8 +808,10 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s) if (res->flags & IORESOURCE_IO) { if (res == &ioport_resource) continue; - printk(KERN_INFO "pcmcia: parent PCI bridge I/O window: 0x%lx - 0x%lx\n", - res->start, res->end); + printk(KERN_INFO "pcmcia: parent PCI bridge I/O " + "window: 0x%llx - 0x%llx\n", + (unsigned long long)res->start, + (unsigned long long)res->end); if (!adjust_io(s, ADD_MANAGED_RESOURCE, res->start, res->end)) done |= IORESOURCE_IO; @@ -818,8 +820,10 @@ static int nonstatic_autoadd_resources(struct pcmcia_socket *s) if (res->flags & IORESOURCE_MEM) { if (res == &iomem_resource) continue; - printk(KERN_INFO "pcmcia: parent PCI bridge Memory window: 0x%lx - 0x%lx\n", - res->start, res->end); + printk(KERN_INFO "pcmcia: parent PCI bridge Memory " + "window: 0x%llx - 0x%llx\n", + (unsigned long long)res->start, + (unsigned long long)res->end); if (!adjust_memory(s, ADD_MANAGED_RESOURCE, res->start, res->end)) done |= IORESOURCE_MEM; } diff --git a/trunk/drivers/pcmcia/tcic.c b/trunk/drivers/pcmcia/tcic.c index 73bad1d5cb23..65a60671659f 100644 --- a/trunk/drivers/pcmcia/tcic.c +++ b/trunk/drivers/pcmcia/tcic.c @@ -756,8 +756,9 @@ static int tcic_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *m u_long base, len, mmap; debug(1, "SetMemMap(%d, %d, %#2.2x, %d ns, " - "%#lx-%#lx, %#x)\n", psock, mem->map, mem->flags, - mem->speed, mem->res->start, mem->res->end, mem->card_start); + "%#llx-%#llx, %#x)\n", psock, mem->map, mem->flags, + mem->speed, (unsigned long long)mem->res->start, + (unsigned long long)mem->res->end, mem->card_start); if ((mem->map > 3) || (mem->card_start > 0x3ffffff) || (mem->res->start > 0xffffff) || (mem->res->end > 0xffffff) || (mem->res->start > mem->res->end) || (mem->speed > 1000)) diff --git a/trunk/drivers/pnp/interface.c b/trunk/drivers/pnp/interface.c index a2d8ce7fef9c..3163e3d73da1 100644 --- a/trunk/drivers/pnp/interface.c +++ b/trunk/drivers/pnp/interface.c @@ -264,7 +264,7 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_at if (pnp_port_flags(dev, i) & IORESOURCE_DISABLED) pnp_printf(buffer," disabled\n"); else - pnp_printf(buffer," 0x%lx-0x%lx\n", + pnp_printf(buffer," 0x%llx-0x%llx\n", pnp_port_start(dev, i), pnp_port_end(dev, i)); } @@ -275,7 +275,7 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_at if (pnp_mem_flags(dev, i) & IORESOURCE_DISABLED) pnp_printf(buffer," disabled\n"); else - pnp_printf(buffer," 0x%lx-0x%lx\n", + pnp_printf(buffer," 0x%llx-0x%llx\n", pnp_mem_start(dev, i), pnp_mem_end(dev, i)); } @@ -286,7 +286,7 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_at if (pnp_irq_flags(dev, i) & IORESOURCE_DISABLED) pnp_printf(buffer," disabled\n"); else - pnp_printf(buffer," %ld\n", + pnp_printf(buffer," %lld\n", pnp_irq(dev, i)); } } @@ -296,7 +296,7 @@ static ssize_t pnp_show_current_resources(struct device *dmdev, struct device_at if (pnp_dma_flags(dev, i) & IORESOURCE_DISABLED) pnp_printf(buffer," disabled\n"); else - pnp_printf(buffer," %ld\n", + pnp_printf(buffer," %lld\n", pnp_dma(dev, i)); } } diff --git a/trunk/drivers/pnp/manager.c b/trunk/drivers/pnp/manager.c index 6fff109bdab6..1d7a5b87f4cb 100644 --- a/trunk/drivers/pnp/manager.c +++ b/trunk/drivers/pnp/manager.c @@ -20,7 +20,8 @@ DECLARE_MUTEX(pnp_res_mutex); static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) { - unsigned long *start, *end, *flags; + resource_size_t *start, *end; + unsigned long *flags; if (!dev || !rule) return -EINVAL; @@ -63,7 +64,8 @@ static int pnp_assign_port(struct pnp_dev *dev, struct pnp_port *rule, int idx) static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) { - unsigned long *start, *end, *flags; + resource_size_t *start, *end; + unsigned long *flags; if (!dev || !rule) return -EINVAL; @@ -116,7 +118,8 @@ static int pnp_assign_mem(struct pnp_dev *dev, struct pnp_mem *rule, int idx) static int pnp_assign_irq(struct pnp_dev * dev, struct pnp_irq *rule, int idx) { - unsigned long *start, *end, *flags; + resource_size_t *start, *end; + unsigned long *flags; int i; /* IRQ priority: this table is good for i386 */ @@ -168,7 +171,8 @@ static int pnp_assign_irq(struct pnp_dev * dev, struct pnp_irq *rule, int idx) static int pnp_assign_dma(struct pnp_dev *dev, struct pnp_dma *rule, int idx) { - unsigned long *start, *end, *flags; + resource_size_t *start, *end; + unsigned long *flags; int i; /* DMA priority: this table is good for i386 */ @@ -582,7 +586,8 @@ int pnp_disable_dev(struct pnp_dev *dev) * @size: size of region * */ -void pnp_resource_change(struct resource *resource, unsigned long start, unsigned long size) +void pnp_resource_change(struct resource *resource, resource_size_t start, + resource_size_t size) { if (resource == NULL) return; diff --git a/trunk/drivers/pnp/resource.c b/trunk/drivers/pnp/resource.c index 6ded527169f4..7bb892f58cc0 100644 --- a/trunk/drivers/pnp/resource.c +++ b/trunk/drivers/pnp/resource.c @@ -241,7 +241,7 @@ int pnp_check_port(struct pnp_dev * dev, int idx) { int tmp; struct pnp_dev *tdev; - unsigned long *port, *end, *tport, *tend; + resource_size_t *port, *end, *tport, *tend; port = &dev->res.port_resource[idx].start; end = &dev->res.port_resource[idx].end; @@ -297,7 +297,7 @@ int pnp_check_mem(struct pnp_dev * dev, int idx) { int tmp; struct pnp_dev *tdev; - unsigned long *addr, *end, *taddr, *tend; + resource_size_t *addr, *end, *taddr, *tend; addr = &dev->res.mem_resource[idx].start; end = &dev->res.mem_resource[idx].end; @@ -358,7 +358,7 @@ int pnp_check_irq(struct pnp_dev * dev, int idx) { int tmp; struct pnp_dev *tdev; - unsigned long * irq = &dev->res.irq_resource[idx].start; + resource_size_t * irq = &dev->res.irq_resource[idx].start; /* if the resource doesn't exist, don't complain about it */ if (cannot_compare(dev->res.irq_resource[idx].flags)) @@ -423,7 +423,7 @@ int pnp_check_dma(struct pnp_dev * dev, int idx) #ifndef CONFIG_IA64 int tmp; struct pnp_dev *tdev; - unsigned long * dma = &dev->res.dma_resource[idx].start; + resource_size_t * dma = &dev->res.dma_resource[idx].start; /* if the resource doesn't exist, don't complain about it */ if (cannot_compare(dev->res.dma_resource[idx].flags)) diff --git a/trunk/drivers/rtc/Kconfig b/trunk/drivers/rtc/Kconfig index bccff400b198..f2fc81a9074d 100644 --- a/trunk/drivers/rtc/Kconfig +++ b/trunk/drivers/rtc/Kconfig @@ -162,6 +162,16 @@ config RTC_DRV_PCF8583 This driver can also be built as a module. If so, the module will be called rtc-pcf8583. +config RTC_DRV_RS5C348 + tristate "Ricoh RS5C348A/B" + depends on RTC_CLASS && SPI + help + If you say yes here you get support for the + Ricoh RS5C348A and RS5C348B RTC chips. + + This driver can also be built as a module. If so, the module + will be called rtc-rs5c348. + config RTC_DRV_RS5C372 tristate "Ricoh RS5C372A/B" depends on RTC_CLASS && I2C diff --git a/trunk/drivers/rtc/Makefile b/trunk/drivers/rtc/Makefile index 900d210dd1a2..da5e38774e13 100644 --- a/trunk/drivers/rtc/Makefile +++ b/trunk/drivers/rtc/Makefile @@ -19,6 +19,7 @@ obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o obj-$(CONFIG_RTC_DRV_PCF8563) += rtc-pcf8563.o obj-$(CONFIG_RTC_DRV_PCF8583) += rtc-pcf8583.o obj-$(CONFIG_RTC_DRV_RS5C372) += rtc-rs5c372.o +obj-$(CONFIG_RTC_DRV_RS5C348) += rtc-rs5c348.o obj-$(CONFIG_RTC_DRV_M48T86) += rtc-m48t86.o obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o obj-$(CONFIG_RTC_DRV_EP93XX) += rtc-ep93xx.o diff --git a/trunk/drivers/rtc/rtc-rs5c348.c b/trunk/drivers/rtc/rtc-rs5c348.c new file mode 100644 index 000000000000..0964d1dba925 --- /dev/null +++ b/trunk/drivers/rtc/rtc-rs5c348.c @@ -0,0 +1,246 @@ +/* + * A SPI driver for the Ricoh RS5C348 RTC + * + * Copyright (C) 2006 Atsushi Nemoto + * + * 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. + * + * The board specific init code should provide characteristics of this + * device: + * Mode 1 (High-Active, Shift-Then-Sample), High Avtive CS + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define DRV_VERSION "0.1" + +#define RS5C348_REG_SECS 0 +#define RS5C348_REG_MINS 1 +#define RS5C348_REG_HOURS 2 +#define RS5C348_REG_WDAY 3 +#define RS5C348_REG_DAY 4 +#define RS5C348_REG_MONTH 5 +#define RS5C348_REG_YEAR 6 +#define RS5C348_REG_CTL1 14 +#define RS5C348_REG_CTL2 15 + +#define RS5C348_SECS_MASK 0x7f +#define RS5C348_MINS_MASK 0x7f +#define RS5C348_HOURS_MASK 0x3f +#define RS5C348_WDAY_MASK 0x03 +#define RS5C348_DAY_MASK 0x3f +#define RS5C348_MONTH_MASK 0x1f + +#define RS5C348_BIT_PM 0x20 /* REG_HOURS */ +#define RS5C348_BIT_Y2K 0x80 /* REG_MONTH */ +#define RS5C348_BIT_24H 0x20 /* REG_CTL1 */ +#define RS5C348_BIT_XSTP 0x10 /* REG_CTL2 */ +#define RS5C348_BIT_VDET 0x40 /* REG_CTL2 */ + +#define RS5C348_CMD_W(addr) (((addr) << 4) | 0x08) /* single write */ +#define RS5C348_CMD_R(addr) (((addr) << 4) | 0x0c) /* single read */ +#define RS5C348_CMD_MW(addr) (((addr) << 4) | 0x00) /* burst write */ +#define RS5C348_CMD_MR(addr) (((addr) << 4) | 0x04) /* burst read */ + +struct rs5c348_plat_data { + struct rtc_device *rtc; + int rtc_24h; +}; + +static int +rs5c348_rtc_set_time(struct device *dev, struct rtc_time *tm) +{ + struct spi_device *spi = to_spi_device(dev); + struct rs5c348_plat_data *pdata = spi->dev.platform_data; + u8 txbuf[5+7], *txp; + int ret; + + /* Transfer 5 bytes before writing SEC. This gives 31us for carry. */ + txp = txbuf; + txbuf[0] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */ + txbuf[1] = 0; /* dummy */ + txbuf[2] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */ + txbuf[3] = 0; /* dummy */ + txbuf[4] = RS5C348_CMD_MW(RS5C348_REG_SECS); /* cmd, sec, ... */ + txp = &txbuf[5]; + txp[RS5C348_REG_SECS] = BIN2BCD(tm->tm_sec); + txp[RS5C348_REG_MINS] = BIN2BCD(tm->tm_min); + if (pdata->rtc_24h) { + txp[RS5C348_REG_HOURS] = BIN2BCD(tm->tm_hour); + } else { + /* hour 0 is AM12, noon is PM12 */ + txp[RS5C348_REG_HOURS] = BIN2BCD((tm->tm_hour + 11) % 12 + 1) | + (tm->tm_hour >= 12 ? RS5C348_BIT_PM : 0); + } + txp[RS5C348_REG_WDAY] = BIN2BCD(tm->tm_wday); + txp[RS5C348_REG_DAY] = BIN2BCD(tm->tm_mday); + txp[RS5C348_REG_MONTH] = BIN2BCD(tm->tm_mon + 1) | + (tm->tm_year >= 100 ? RS5C348_BIT_Y2K : 0); + txp[RS5C348_REG_YEAR] = BIN2BCD(tm->tm_year % 100); + /* write in one transfer to avoid data inconsistency */ + ret = spi_write_then_read(spi, txbuf, sizeof(txbuf), NULL, 0); + udelay(62); /* Tcsr 62us */ + return ret; +} + +static int +rs5c348_rtc_read_time(struct device *dev, struct rtc_time *tm) +{ + struct spi_device *spi = to_spi_device(dev); + struct rs5c348_plat_data *pdata = spi->dev.platform_data; + u8 txbuf[5], rxbuf[7]; + int ret; + + /* Transfer 5 byte befores reading SEC. This gives 31us for carry. */ + txbuf[0] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */ + txbuf[1] = 0; /* dummy */ + txbuf[2] = RS5C348_CMD_R(RS5C348_REG_CTL2); /* cmd, ctl2 */ + txbuf[3] = 0; /* dummy */ + txbuf[4] = RS5C348_CMD_MR(RS5C348_REG_SECS); /* cmd, sec, ... */ + + /* read in one transfer to avoid data inconsistency */ + ret = spi_write_then_read(spi, txbuf, sizeof(txbuf), + rxbuf, sizeof(rxbuf)); + udelay(62); /* Tcsr 62us */ + if (ret < 0) + return ret; + + tm->tm_sec = BCD2BIN(rxbuf[RS5C348_REG_SECS] & RS5C348_SECS_MASK); + tm->tm_min = BCD2BIN(rxbuf[RS5C348_REG_MINS] & RS5C348_MINS_MASK); + tm->tm_hour = BCD2BIN(rxbuf[RS5C348_REG_HOURS] & RS5C348_HOURS_MASK); + if (!pdata->rtc_24h) { + tm->tm_hour %= 12; + if (rxbuf[RS5C348_REG_HOURS] & RS5C348_BIT_PM) + tm->tm_hour += 12; + } + tm->tm_wday = BCD2BIN(rxbuf[RS5C348_REG_WDAY] & RS5C348_WDAY_MASK); + tm->tm_mday = BCD2BIN(rxbuf[RS5C348_REG_DAY] & RS5C348_DAY_MASK); + tm->tm_mon = + BCD2BIN(rxbuf[RS5C348_REG_MONTH] & RS5C348_MONTH_MASK) - 1; + /* year is 1900 + tm->tm_year */ + tm->tm_year = BCD2BIN(rxbuf[RS5C348_REG_YEAR]) + + ((rxbuf[RS5C348_REG_MONTH] & RS5C348_BIT_Y2K) ? 100 : 0); + + if (rtc_valid_tm(tm) < 0) { + dev_err(&spi->dev, "retrieved date/time is not valid.\n"); + rtc_time_to_tm(0, tm); + } + + return 0; +} + +static struct rtc_class_ops rs5c348_rtc_ops = { + .read_time = rs5c348_rtc_read_time, + .set_time = rs5c348_rtc_set_time, +}; + +static struct spi_driver rs5c348_driver; + +static int __devinit rs5c348_probe(struct spi_device *spi) +{ + int ret; + struct rtc_device *rtc; + struct rs5c348_plat_data *pdata; + + pdata = kzalloc(sizeof(struct rs5c348_plat_data), GFP_KERNEL); + if (!pdata) + return -ENOMEM; + spi->dev.platform_data = pdata; + + /* Check D7 of SECOND register */ + ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_SECS)); + if (ret < 0 || (ret & 0x80)) { + dev_err(&spi->dev, "not found.\n"); + goto kfree_exit; + } + + dev_info(&spi->dev, "chip found, driver version " DRV_VERSION "\n"); + dev_info(&spi->dev, "spiclk %u KHz.\n", + (spi->max_speed_hz + 500) / 1000); + + /* turn RTC on if it was not on */ + ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL2)); + if (ret < 0) + goto kfree_exit; + if (ret & (RS5C348_BIT_XSTP | RS5C348_BIT_VDET)) { + u8 buf[2]; + if (ret & RS5C348_BIT_VDET) + dev_warn(&spi->dev, "voltage-low detected.\n"); + buf[0] = RS5C348_CMD_W(RS5C348_REG_CTL2); + buf[1] = 0; + ret = spi_write_then_read(spi, buf, sizeof(buf), NULL, 0); + if (ret < 0) + goto kfree_exit; + } + + ret = spi_w8r8(spi, RS5C348_CMD_R(RS5C348_REG_CTL1)); + if (ret < 0) + goto kfree_exit; + if (ret & RS5C348_BIT_24H) + pdata->rtc_24h = 1; + + rtc = rtc_device_register(rs5c348_driver.driver.name, &spi->dev, + &rs5c348_rtc_ops, THIS_MODULE); + + if (IS_ERR(rtc)) { + ret = PTR_ERR(rtc); + goto kfree_exit; + } + + pdata->rtc = rtc; + + return 0; + kfree_exit: + kfree(pdata); + return ret; +} + +static int __devexit rs5c348_remove(struct spi_device *spi) +{ + struct rs5c348_plat_data *pdata = spi->dev.platform_data; + struct rtc_device *rtc = pdata->rtc; + + if (rtc) + rtc_device_unregister(rtc); + kfree(pdata); + return 0; +} + +static struct spi_driver rs5c348_driver = { + .driver = { + .name = "rs5c348", + .bus = &spi_bus_type, + .owner = THIS_MODULE, + }, + .probe = rs5c348_probe, + .remove = __devexit_p(rs5c348_remove), +}; + +static __init int rs5c348_init(void) +{ + return spi_register_driver(&rs5c348_driver); +} + +static __exit void rs5c348_exit(void) +{ + spi_unregister_driver(&rs5c348_driver); +} + +module_init(rs5c348_init); +module_exit(rs5c348_exit); + +MODULE_AUTHOR("Atsushi Nemoto "); +MODULE_DESCRIPTION("Ricoh RS5C348 RTC driver"); +MODULE_LICENSE("GPL"); +MODULE_VERSION(DRV_VERSION); diff --git a/trunk/drivers/s390/block/dasd.c b/trunk/drivers/s390/block/dasd.c index cfb1fff3787c..bafcd2f20ae2 100644 --- a/trunk/drivers/s390/block/dasd.c +++ b/trunk/drivers/s390/block/dasd.c @@ -95,7 +95,7 @@ dasd_alloc_device(void) spin_lock_init(&device->mem_lock); spin_lock_init(&device->request_queue_lock); atomic_set (&device->tasklet_scheduled, 0); - tasklet_init(&device->tasklet, + tasklet_init(&device->tasklet, (void (*)(unsigned long)) dasd_tasklet, (unsigned long) device); INIT_LIST_HEAD(&device->ccw_queue); @@ -128,7 +128,7 @@ dasd_state_new_to_known(struct dasd_device *device) int rc; /* - * As long as the device is not in state DASD_STATE_NEW we want to + * As long as the device is not in state DASD_STATE_NEW we want to * keep the reference count > 0. */ dasd_get_device(device); @@ -336,7 +336,7 @@ dasd_decrease_state(struct dasd_device *device) if (device->state == DASD_STATE_ONLINE && device->target <= DASD_STATE_READY) dasd_state_online_to_ready(device); - + if (device->state == DASD_STATE_READY && device->target <= DASD_STATE_BASIC) dasd_state_ready_to_basic(device); @@ -348,7 +348,7 @@ dasd_decrease_state(struct dasd_device *device) if (device->state == DASD_STATE_BASIC && device->target <= DASD_STATE_KNOWN) dasd_state_basic_to_known(device); - + if (device->state == DASD_STATE_KNOWN && device->target <= DASD_STATE_NEW) dasd_state_known_to_new(device); @@ -994,7 +994,7 @@ dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, ((irb->scsw.cstat << 8) | irb->scsw.dstat), cqr); /* Find out the appropriate era_action. */ - if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC) + if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC) era = dasd_era_fatal; else if (irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END) && irb->scsw.cstat == 0 && @@ -1004,7 +1004,7 @@ dasd_int_handler(struct ccw_device *cdev, unsigned long intparm, era = dasd_era_fatal; /* don't recover this request */ else if (irb->esw.esw0.erw.cons) era = device->discipline->examine_error(cqr, irb); - else + else era = dasd_era_recover; DBF_DEV_EVENT(DBF_DEBUG, device, "era_code %d", era); @@ -1287,7 +1287,7 @@ __dasd_start_head(struct dasd_device * device) } /* - * Remove requests from the ccw queue. + * Remove requests from the ccw queue. */ static void dasd_flush_ccw_queue(struct dasd_device * device, int all) @@ -1450,23 +1450,23 @@ dasd_sleep_on(struct dasd_ccw_req * cqr) wait_queue_head_t wait_q; struct dasd_device *device; int rc; - + device = cqr->device; spin_lock_irq(get_ccwdev_lock(device->cdev)); - + init_waitqueue_head (&wait_q); cqr->callback = dasd_wakeup_cb; cqr->callback_data = (void *) &wait_q; cqr->status = DASD_CQR_QUEUED; list_add_tail(&cqr->list, &device->ccw_queue); - + /* let the bh start the request to keep them in order */ dasd_schedule_bh(device); - + spin_unlock_irq(get_ccwdev_lock(device->cdev)); wait_event(wait_q, _wait_for_wakeup(cqr)); - + /* Request status is either done or failed. */ rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0; return rc; @@ -1568,7 +1568,7 @@ dasd_sleep_on_immediatly(struct dasd_ccw_req * cqr) wait_queue_head_t wait_q; struct dasd_device *device; int rc; - + device = cqr->device; spin_lock_irq(get_ccwdev_lock(device->cdev)); rc = _dasd_term_running_cqr(device); @@ -1576,20 +1576,20 @@ dasd_sleep_on_immediatly(struct dasd_ccw_req * cqr) spin_unlock_irq(get_ccwdev_lock(device->cdev)); return rc; } - + init_waitqueue_head (&wait_q); cqr->callback = dasd_wakeup_cb; cqr->callback_data = (void *) &wait_q; cqr->status = DASD_CQR_QUEUED; list_add(&cqr->list, &device->ccw_queue); - + /* let the bh start the request to keep them in order */ dasd_schedule_bh(device); - + spin_unlock_irq(get_ccwdev_lock(device->cdev)); wait_event(wait_q, _wait_for_wakeup(cqr)); - + /* Request status is either done or failed. */ rc = (cqr->status == DASD_CQR_FAILED) ? -EIO : 0; return rc; @@ -1725,7 +1725,7 @@ dasd_flush_request_queue(struct dasd_device * device) if (!device->request_queue) return; - + spin_lock_irq(&device->request_queue_lock); while (!list_empty(&device->request_queue->queue_head)) { req = elv_next_request(device->request_queue); @@ -1855,15 +1855,34 @@ dasd_generic_probe (struct ccw_device *cdev, { int ret; + ret = ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP); + if (ret) { + printk(KERN_WARNING + "dasd_generic_probe: could not set ccw-device options " + "for %s\n", cdev->dev.bus_id); + return ret; + } ret = dasd_add_sysfs_files(cdev); if (ret) { printk(KERN_WARNING "dasd_generic_probe: could not add sysfs entries " "for %s\n", cdev->dev.bus_id); - } else { - cdev->handler = &dasd_int_handler; + return ret; } + cdev->handler = &dasd_int_handler; + /* + * Automatically online either all dasd devices (dasd_autodetect) + * or all devices specified with dasd= parameters during + * initial probe. + */ + if ((dasd_get_feature(cdev, DASD_FEATURE_INITIAL_ONLINE) > 0 ) || + (dasd_autodetect && dasd_busid_known(cdev->dev.bus_id) != 0)) + ret = ccw_device_set_online(cdev); + if (ret) + printk(KERN_WARNING + "dasd_generic_probe: could not initially online " + "ccw-device %s\n", cdev->dev.bus_id); return ret; } @@ -1911,6 +1930,8 @@ dasd_generic_set_online (struct ccw_device *cdev, struct dasd_device *device; int rc; + /* first online clears initial online feature flag */ + dasd_set_feature(cdev, DASD_FEATURE_INITIAL_ONLINE, 0); device = dasd_create_device(cdev); if (IS_ERR(device)) return PTR_ERR(device); @@ -2065,31 +2086,6 @@ dasd_generic_notify(struct ccw_device *cdev, int event) return ret; } -/* - * Automatically online either all dasd devices (dasd_autodetect) or - * all devices specified with dasd= parameters. - */ -static int -__dasd_auto_online(struct device *dev, void *data) -{ - struct ccw_device *cdev; - - cdev = to_ccwdev(dev); - if (dasd_autodetect || dasd_busid_known(cdev->dev.bus_id) == 0) - ccw_device_set_online(cdev); - return 0; -} - -void -dasd_generic_auto_online (struct ccw_driver *dasd_discipline_driver) -{ - struct device_driver *drv; - - drv = get_driver(&dasd_discipline_driver->driver); - driver_for_each_device(drv, NULL, NULL, __dasd_auto_online); - put_driver(drv); -} - static int __init dasd_init(void) @@ -2170,23 +2166,4 @@ EXPORT_SYMBOL_GPL(dasd_generic_remove); EXPORT_SYMBOL_GPL(dasd_generic_notify); EXPORT_SYMBOL_GPL(dasd_generic_set_online); EXPORT_SYMBOL_GPL(dasd_generic_set_offline); -EXPORT_SYMBOL_GPL(dasd_generic_auto_online); -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-indent-level: 4 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -4 - * c-argdecl-indent: 4 - * c-label-offset: -4 - * c-continued-statement-offset: 4 - * c-continued-brace-offset: 0 - * indent-tabs-mode: 1 - * tab-width: 8 - * End: - */ diff --git a/trunk/drivers/s390/block/dasd_3370_erp.c b/trunk/drivers/s390/block/dasd_3370_erp.c index 1d11c2a9525d..1ddab8991d92 100644 --- a/trunk/drivers/s390/block/dasd_3370_erp.c +++ b/trunk/drivers/s390/block/dasd_3370_erp.c @@ -1,4 +1,4 @@ -/* +/* * File...........: linux/drivers/s390/block/dasd_3370_erp.c * Author(s)......: Holger Smolinski * Bugreports.to..: @@ -12,10 +12,10 @@ /* - * DASD_3370_ERP_EXAMINE + * DASD_3370_ERP_EXAMINE * * DESCRIPTION - * Checks only for fatal/no/recover error. + * Checks only for fatal/no/recover error. * A detailed examination of the sense data is done later outside * the interrupt handler. * @@ -23,7 +23,7 @@ * 'Chapter 7. 3370 Sense Data'. * * RETURN VALUES - * dasd_era_none no error + * dasd_era_none no error * dasd_era_fatal for all fatal (unrecoverable errors) * dasd_era_recover for all others. */ @@ -82,22 +82,3 @@ dasd_3370_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb) return dasd_era_recover; } /* END dasd_3370_erp_examine */ - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-indent-level: 4 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -4 - * c-argdecl-indent: 4 - * c-label-offset: -4 - * c-continued-statement-offset: 4 - * c-continued-brace-offset: 0 - * indent-tabs-mode: 1 - * tab-width: 8 - * End: - */ diff --git a/trunk/drivers/s390/block/dasd_3990_erp.c b/trunk/drivers/s390/block/dasd_3990_erp.c index 2ed51562319e..669805d4402d 100644 --- a/trunk/drivers/s390/block/dasd_3990_erp.c +++ b/trunk/drivers/s390/block/dasd_3990_erp.c @@ -1,6 +1,6 @@ -/* +/* * File...........: linux/drivers/s390/block/dasd_3990_erp.c - * Author(s)......: Horst Hummel + * Author(s)......: Horst Hummel * Holger Smolinski * Bugreports.to..: * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000, 2001 @@ -25,23 +25,23 @@ struct DCTL_data { } __attribute__ ((packed)); /* - ***************************************************************************** + ***************************************************************************** * SECTION ERP EXAMINATION - ***************************************************************************** + ***************************************************************************** */ /* - * DASD_3990_ERP_EXAMINE_24 + * DASD_3990_ERP_EXAMINE_24 * * DESCRIPTION - * Checks only for fatal (unrecoverable) error. + * Checks only for fatal (unrecoverable) error. * A detailed examination of the sense data is done later outside * the interrupt handler. * * Each bit configuration leading to an action code 2 (Exit with * programming error or unusual condition indication) * are handled as fatal error´s. - * + * * All other configurations are handled as recoverable errors. * * RETURN VALUES @@ -93,15 +93,15 @@ dasd_3990_erp_examine_24(struct dasd_ccw_req * cqr, char *sense) } /* END dasd_3990_erp_examine_24 */ /* - * DASD_3990_ERP_EXAMINE_32 + * DASD_3990_ERP_EXAMINE_32 * * DESCRIPTION - * Checks only for fatal/no/recoverable error. + * Checks only for fatal/no/recoverable error. * A detailed examination of the sense data is done later outside * the interrupt handler. * * RETURN VALUES - * dasd_era_none no error + * dasd_era_none no error * dasd_era_fatal for all fatal (unrecoverable errors) * dasd_era_recover for recoverable others. */ @@ -128,10 +128,10 @@ dasd_3990_erp_examine_32(struct dasd_ccw_req * cqr, char *sense) } /* end dasd_3990_erp_examine_32 */ /* - * DASD_3990_ERP_EXAMINE + * DASD_3990_ERP_EXAMINE * * DESCRIPTION - * Checks only for fatal/no/recover error. + * Checks only for fatal/no/recover error. * A detailed examination of the sense data is done later outside * the interrupt handler. * @@ -139,7 +139,7 @@ dasd_3990_erp_examine_32(struct dasd_ccw_req * cqr, char *sense) * 'Chapter 7. Error Recovery Procedures'. * * RETURN VALUES - * dasd_era_none no error + * dasd_era_none no error * dasd_era_fatal for all fatal (unrecoverable errors) * dasd_era_recover for all others. */ @@ -178,18 +178,18 @@ dasd_3990_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb) } /* END dasd_3990_erp_examine */ /* - ***************************************************************************** + ***************************************************************************** * SECTION ERP HANDLING - ***************************************************************************** + ***************************************************************************** */ /* - ***************************************************************************** + ***************************************************************************** * 24 and 32 byte sense ERP functions - ***************************************************************************** + ***************************************************************************** */ /* - * DASD_3990_ERP_CLEANUP + * DASD_3990_ERP_CLEANUP * * DESCRIPTION * Removes the already build but not necessary ERP request and sets @@ -197,10 +197,10 @@ dasd_3990_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb) * * PARAMETER * erp request to be blocked - * final_status either DASD_CQR_DONE or DASD_CQR_FAILED + * final_status either DASD_CQR_DONE or DASD_CQR_FAILED * * RETURN VALUES - * cqr original cqr + * cqr original cqr */ static struct dasd_ccw_req * dasd_3990_erp_cleanup(struct dasd_ccw_req * erp, char final_status) @@ -214,7 +214,7 @@ dasd_3990_erp_cleanup(struct dasd_ccw_req * erp, char final_status) } /* end dasd_3990_erp_cleanup */ /* - * DASD_3990_ERP_BLOCK_QUEUE + * DASD_3990_ERP_BLOCK_QUEUE * * DESCRIPTION * Block the given device request queue to prevent from further @@ -237,7 +237,7 @@ dasd_3990_erp_block_queue(struct dasd_ccw_req * erp, int expires) } /* - * DASD_3990_ERP_INT_REQ + * DASD_3990_ERP_INT_REQ * * DESCRIPTION * Handles 'Intervention Required' error. @@ -277,7 +277,7 @@ dasd_3990_erp_int_req(struct dasd_ccw_req * erp) } /* end dasd_3990_erp_int_req */ /* - * DASD_3990_ERP_ALTERNATE_PATH + * DASD_3990_ERP_ALTERNATE_PATH * * DESCRIPTION * Repeat the operation on a different channel path. @@ -330,15 +330,15 @@ dasd_3990_erp_alternate_path(struct dasd_ccw_req * erp) * DASD_3990_ERP_DCTL * * DESCRIPTION - * Setup cqr to do the Diagnostic Control (DCTL) command with an + * Setup cqr to do the Diagnostic Control (DCTL) command with an * Inhibit Write subcommand (0x20) and the given modifier. * * PARAMETER * erp pointer to the current (failed) ERP * modifier subcommand modifier - * + * * RETURN VALUES - * dctl_cqr pointer to NEW dctl_cqr + * dctl_cqr pointer to NEW dctl_cqr * */ static struct dasd_ccw_req * @@ -386,7 +386,7 @@ dasd_3990_erp_DCTL(struct dasd_ccw_req * erp, char modifier) } /* end dasd_3990_erp_DCTL */ /* - * DASD_3990_ERP_ACTION_1 + * DASD_3990_ERP_ACTION_1 * * DESCRIPTION * Setup ERP to do the ERP action 1 (see Reference manual). @@ -415,7 +415,7 @@ dasd_3990_erp_action_1(struct dasd_ccw_req * erp) } /* end dasd_3990_erp_action_1 */ /* - * DASD_3990_ERP_ACTION_4 + * DASD_3990_ERP_ACTION_4 * * DESCRIPTION * Setup ERP to do the ERP action 4 (see Reference manual). @@ -453,11 +453,11 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense) if (sense[25] == 0x1D) { /* state change pending */ - DEV_MESSAGE(KERN_INFO, device, + DEV_MESSAGE(KERN_INFO, device, "waiting for state change pending " "interrupt, %d retries left", erp->retries); - + dasd_3990_erp_block_queue(erp, 30*HZ); } else if (sense[25] == 0x1E) { /* busy */ @@ -469,9 +469,9 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense) } else { /* no state change pending - retry */ - DEV_MESSAGE (KERN_INFO, device, + DEV_MESSAGE (KERN_INFO, device, "redriving request immediately, " - "%d retries left", + "%d retries left", erp->retries); erp->status = DASD_CQR_QUEUED; } @@ -482,13 +482,13 @@ dasd_3990_erp_action_4(struct dasd_ccw_req * erp, char *sense) } /* end dasd_3990_erp_action_4 */ /* - ***************************************************************************** + ***************************************************************************** * 24 byte sense ERP functions (only) - ***************************************************************************** + ***************************************************************************** */ /* - * DASD_3990_ERP_ACTION_5 + * DASD_3990_ERP_ACTION_5 * * DESCRIPTION * Setup ERP to do the ERP action 5 (see Reference manual). @@ -523,7 +523,7 @@ dasd_3990_erp_action_5(struct dasd_ccw_req * erp) * * PARAMETER * sense current sense data - * + * * RETURN VALUES * void */ @@ -1150,9 +1150,9 @@ dasd_3990_handle_env_data(struct dasd_ccw_req * erp, char *sense) * PARAMETER * erp current erp_head * sense current sense data - * + * * RETURN VALUES - * erp 'new' erp_head - pointer to new ERP + * erp 'new' erp_head - pointer to new ERP */ static struct dasd_ccw_req * dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense) @@ -1185,7 +1185,7 @@ dasd_3990_erp_com_rej(struct dasd_ccw_req * erp, char *sense) } /* end dasd_3990_erp_com_rej */ /* - * DASD_3990_ERP_BUS_OUT + * DASD_3990_ERP_BUS_OUT * * DESCRIPTION * Handles 24 byte 'Bus Out Parity Check' error. @@ -1483,7 +1483,7 @@ dasd_3990_erp_env_data(struct dasd_ccw_req * erp, char *sense) * * PARAMETER * erp already added default ERP - * + * * RETURN VALUES * erp new erp_head - pointer to new ERP */ @@ -1527,11 +1527,11 @@ dasd_3990_erp_file_prot(struct dasd_ccw_req * erp) } /* end dasd_3990_erp_file_prot */ /* - * DASD_3990_ERP_INSPECT_24 + * DASD_3990_ERP_INSPECT_24 * * DESCRIPTION * Does a detailed inspection of the 24 byte sense data - * and sets up a related error recovery action. + * and sets up a related error recovery action. * * PARAMETER * sense sense data of the actual error @@ -1602,13 +1602,13 @@ dasd_3990_erp_inspect_24(struct dasd_ccw_req * erp, char *sense) } /* END dasd_3990_erp_inspect_24 */ /* - ***************************************************************************** + ***************************************************************************** * 32 byte sense ERP functions (only) - ***************************************************************************** + ***************************************************************************** */ /* - * DASD_3990_ERPACTION_10_32 + * DASD_3990_ERPACTION_10_32 * * DESCRIPTION * Handles 32 byte 'Action 10' of Single Program Action Codes. @@ -1616,7 +1616,7 @@ dasd_3990_erp_inspect_24(struct dasd_ccw_req * erp, char *sense) * * PARAMETER * erp current erp_head - * sense current sense data + * sense current sense data * RETURN VALUES * erp modified erp_head */ @@ -1640,18 +1640,18 @@ dasd_3990_erp_action_10_32(struct dasd_ccw_req * erp, char *sense) * * DESCRIPTION * Handles 32 byte 'Action 1B' of Single Program Action Codes. - * A write operation could not be finished because of an unexpected + * A write operation could not be finished because of an unexpected * condition. - * The already created 'default erp' is used to get the link to - * the erp chain, but it can not be used for this recovery + * The already created 'default erp' is used to get the link to + * the erp chain, but it can not be used for this recovery * action because it contains no DE/LO data space. * * PARAMETER * default_erp already added default erp. - * sense current sense data + * sense current sense data * * RETURN VALUES - * erp new erp or + * erp new erp or * default_erp in case of imprecise ending or error */ static struct dasd_ccw_req * @@ -1789,16 +1789,16 @@ dasd_3990_erp_action_1B_32(struct dasd_ccw_req * default_erp, char *sense) * DASD_3990_UPDATE_1B * * DESCRIPTION - * Handles the update to the 32 byte 'Action 1B' of Single Program + * Handles the update to the 32 byte 'Action 1B' of Single Program * Action Codes in case the first action was not successful. * The already created 'previous_erp' is the currently not successful - * ERP. + * ERP. * * PARAMETER * previous_erp already created previous erp. - * sense current sense data + * sense current sense data * RETURN VALUES - * erp modified erp + * erp modified erp */ static struct dasd_ccw_req * dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense) @@ -1897,7 +1897,7 @@ dasd_3990_update_1B(struct dasd_ccw_req * previous_erp, char *sense) } /* end dasd_3990_update_1B */ /* - * DASD_3990_ERP_COMPOUND_RETRY + * DASD_3990_ERP_COMPOUND_RETRY * * DESCRIPTION * Handles the compound ERP action retry code. @@ -1943,7 +1943,7 @@ dasd_3990_erp_compound_retry(struct dasd_ccw_req * erp, char *sense) } /* end dasd_3990_erp_compound_retry */ /* - * DASD_3990_ERP_COMPOUND_PATH + * DASD_3990_ERP_COMPOUND_PATH * * DESCRIPTION * Handles the compound ERP action for retry on alternate @@ -1965,7 +1965,7 @@ dasd_3990_erp_compound_path(struct dasd_ccw_req * erp, char *sense) dasd_3990_erp_alternate_path(erp); if (erp->status == DASD_CQR_FAILED) { - /* reset the lpm and the status to be able to + /* reset the lpm and the status to be able to * try further actions. */ erp->lpm = 0; @@ -1980,7 +1980,7 @@ dasd_3990_erp_compound_path(struct dasd_ccw_req * erp, char *sense) } /* end dasd_3990_erp_compound_path */ /* - * DASD_3990_ERP_COMPOUND_CODE + * DASD_3990_ERP_COMPOUND_CODE * * DESCRIPTION * Handles the compound ERP action for retry code. @@ -2001,18 +2001,18 @@ dasd_3990_erp_compound_code(struct dasd_ccw_req * erp, char *sense) switch (sense[28]) { case 0x17: - /* issue a Diagnostic Control command with an + /* issue a Diagnostic Control command with an * Inhibit Write subcommand and controler modifier */ erp = dasd_3990_erp_DCTL(erp, 0x20); break; - + case 0x25: /* wait for 5 seconds and retry again */ erp->retries = 1; - + dasd_3990_erp_block_queue (erp, 5*HZ); break; - + default: /* should not happen - continue */ break; @@ -2026,7 +2026,7 @@ dasd_3990_erp_compound_code(struct dasd_ccw_req * erp, char *sense) } /* end dasd_3990_erp_compound_code */ /* - * DASD_3990_ERP_COMPOUND_CONFIG + * DASD_3990_ERP_COMPOUND_CONFIG * * DESCRIPTION * Handles the compound ERP action for configruation @@ -2063,10 +2063,10 @@ dasd_3990_erp_compound_config(struct dasd_ccw_req * erp, char *sense) } /* end dasd_3990_erp_compound_config */ /* - * DASD_3990_ERP_COMPOUND + * DASD_3990_ERP_COMPOUND * * DESCRIPTION - * Does the further compound program action if + * Does the further compound program action if * compound retry was not successful. * * PARAMETER @@ -2110,11 +2110,11 @@ dasd_3990_erp_compound(struct dasd_ccw_req * erp, char *sense) } /* end dasd_3990_erp_compound */ /* - * DASD_3990_ERP_INSPECT_32 + * DASD_3990_ERP_INSPECT_32 * * DESCRIPTION * Does a detailed inspection of the 32 byte sense data - * and sets up a related error recovery action. + * and sets up a related error recovery action. * * PARAMETER * sense sense data of the actual error @@ -2228,9 +2228,9 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense) } /* end dasd_3990_erp_inspect_32 */ /* - ***************************************************************************** + ***************************************************************************** * main ERP control fuctions (24 and 32 byte sense) - ***************************************************************************** + ***************************************************************************** */ /* @@ -2243,7 +2243,7 @@ dasd_3990_erp_inspect_32(struct dasd_ccw_req * erp, char *sense) * PARAMETER * erp pointer to the currently created default ERP * RETURN VALUES - * erp_new contens was possibly modified + * erp_new contens was possibly modified */ static struct dasd_ccw_req * dasd_3990_erp_inspect(struct dasd_ccw_req * erp) @@ -2272,14 +2272,14 @@ dasd_3990_erp_inspect(struct dasd_ccw_req * erp) /* * DASD_3990_ERP_ADD_ERP - * + * * DESCRIPTION * This funtion adds an additional request block (ERP) to the head of * the given cqr (or erp). * This erp is initialized as an default erp (retry TIC) * * PARAMETER - * cqr head of the current ERP-chain (or single cqr if + * cqr head of the current ERP-chain (or single cqr if * first error) * RETURN VALUES * erp pointer to new ERP-chain head @@ -2332,15 +2332,15 @@ dasd_3990_erp_add_erp(struct dasd_ccw_req * cqr) } /* - * DASD_3990_ERP_ADDITIONAL_ERP - * + * DASD_3990_ERP_ADDITIONAL_ERP + * * DESCRIPTION * An additional ERP is needed to handle the current error. * Add ERP to the head of the ERP-chain containing the ERP processing * determined based on the sense data. * * PARAMETER - * cqr head of the current ERP-chain (or single cqr if + * cqr head of the current ERP-chain (or single cqr if * first error) * * RETURN VALUES @@ -2376,7 +2376,7 @@ dasd_3990_erp_additional_erp(struct dasd_ccw_req * cqr) * 24 byte sense byte 25 and 27 is set as well. * * PARAMETER - * cqr1 first cqr, which will be compared with the + * cqr1 first cqr, which will be compared with the * cqr2 second cqr. * * RETURN VALUES @@ -2415,7 +2415,7 @@ dasd_3990_erp_error_match(struct dasd_ccw_req *cqr1, struct dasd_ccw_req *cqr2) * cqr failed cqr (either original cqr or already an erp) * * RETURN VALUES - * erp erp-pointer to the already defined error + * erp erp-pointer to the already defined error * recovery procedure OR * NULL if a 'new' error occurred. */ @@ -2451,10 +2451,10 @@ dasd_3990_erp_in_erp(struct dasd_ccw_req *cqr) * DASD_3990_ERP_FURTHER_ERP (24 & 32 byte sense) * * DESCRIPTION - * No retry is left for the current ERP. Check what has to be done + * No retry is left for the current ERP. Check what has to be done * with the ERP. * - do further defined ERP action or - * - wait for interrupt or + * - wait for interrupt or * - exit with permanent error * * PARAMETER @@ -2485,7 +2485,7 @@ dasd_3990_erp_further_erp(struct dasd_ccw_req *erp) if (!(sense[2] & DASD_SENSE_BIT_0)) { - /* issue a Diagnostic Control command with an + /* issue a Diagnostic Control command with an * Inhibit Write subcommand */ switch (sense[25]) { @@ -2535,14 +2535,14 @@ dasd_3990_erp_further_erp(struct dasd_ccw_req *erp) } /* end dasd_3990_erp_further_erp */ /* - * DASD_3990_ERP_HANDLE_MATCH_ERP + * DASD_3990_ERP_HANDLE_MATCH_ERP * * DESCRIPTION * An error occurred again and an ERP has been detected which is already - * used to handle this error (e.g. retries). + * used to handle this error (e.g. retries). * All prior ERP's are asumed to be successful and therefore removed * from queue. - * If retry counter of matching erp is already 0, it is checked if further + * If retry counter of matching erp is already 0, it is checked if further * action is needed (besides retry) or if the ERP has failed. * * PARAMETER @@ -2631,7 +2631,7 @@ dasd_3990_erp_handle_match_erp(struct dasd_ccw_req *erp_head, * erp erp-pointer to the head of the ERP action chain. * This means: * - either a ptr to an additional ERP cqr or - * - the original given cqr (which's status might + * - the original given cqr (which's status might * be modified) */ struct dasd_ccw_req * @@ -2723,22 +2723,3 @@ dasd_3990_erp_action(struct dasd_ccw_req * cqr) return erp; } /* end dasd_3990_erp_action */ - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-indent-level: 4 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -4 - * c-argdecl-indent: 4 - * c-label-offset: -4 - * c-continued-statement-offset: 4 - * c-continued-brace-offset: 0 - * indent-tabs-mode: 1 - * tab-width: 8 - * End: - */ diff --git a/trunk/drivers/s390/block/dasd_9336_erp.c b/trunk/drivers/s390/block/dasd_9336_erp.c index dc861446d056..6e082688475a 100644 --- a/trunk/drivers/s390/block/dasd_9336_erp.c +++ b/trunk/drivers/s390/block/dasd_9336_erp.c @@ -1,4 +1,4 @@ -/* +/* * File...........: linux/drivers/s390/block/dasd_9336_erp.c * Author(s)......: Holger Smolinski * Bugreports.to..: @@ -12,10 +12,10 @@ /* - * DASD_9336_ERP_EXAMINE + * DASD_9336_ERP_EXAMINE * * DESCRIPTION - * Checks only for fatal/no/recover error. + * Checks only for fatal/no/recover error. * A detailed examination of the sense data is done later outside * the interrupt handler. * @@ -23,7 +23,7 @@ * 'Chapter 7. 9336 Sense Data'. * * RETURN VALUES - * dasd_era_none no error + * dasd_era_none no error * dasd_era_fatal for all fatal (unrecoverable errors) * dasd_era_recover for all others. */ @@ -39,22 +39,3 @@ dasd_9336_erp_examine(struct dasd_ccw_req * cqr, struct irb * irb) return dasd_era_recover; } /* END dasd_9336_erp_examine */ - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-indent-level: 4 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -4 - * c-argdecl-indent: 4 - * c-label-offset: -4 - * c-continued-statement-offset: 4 - * c-continued-brace-offset: 0 - * indent-tabs-mode: 1 - * tab-width: 8 - * End: - */ diff --git a/trunk/drivers/s390/block/dasd_9343_erp.c b/trunk/drivers/s390/block/dasd_9343_erp.c index 4a5b79569aaa..ddecb9808ed4 100644 --- a/trunk/drivers/s390/block/dasd_9343_erp.c +++ b/trunk/drivers/s390/block/dasd_9343_erp.c @@ -1,4 +1,4 @@ -/* +/* * File...........: linux/drivers/s390/block/dasd_9345_erp.c * Author(s)......: Holger Smolinski * Bugreports.to..: diff --git a/trunk/drivers/s390/block/dasd_devmap.c b/trunk/drivers/s390/block/dasd_devmap.c index 216bc4fba199..9e9ae7179602 100644 --- a/trunk/drivers/s390/block/dasd_devmap.c +++ b/trunk/drivers/s390/block/dasd_devmap.c @@ -27,7 +27,7 @@ #include "dasd_int.h" kmem_cache_t *dasd_page_cache; -EXPORT_SYMBOL(dasd_page_cache); +EXPORT_SYMBOL_GPL(dasd_page_cache); /* * dasd_devmap_t is used to store the features and the relation @@ -48,6 +48,20 @@ struct dasd_devmap { struct dasd_uid uid; }; +/* + * dasd_servermap is used to store the server_id of all storage servers + * accessed by DASD device driver. + */ +struct dasd_servermap { + struct list_head list; + struct server_id { + char vendor[4]; + char serial[15]; + } sid; +}; + +static struct list_head dasd_serverlist; + /* * Parameter parsing functions for dasd= parameter. The syntax is: * : (0x)?[0-9a-fA-F]+ @@ -64,6 +78,8 @@ struct dasd_devmap { int dasd_probeonly = 0; /* is true, when probeonly mode is active */ int dasd_autodetect = 0; /* is true, when autodetection is active */ +int dasd_nopav = 0; /* is true, when PAV is disabled */ +EXPORT_SYMBOL_GPL(dasd_nopav); /* * char *dasd[] is intended to hold the ranges supplied by the dasd= statement @@ -123,7 +139,7 @@ static inline int dasd_busid(char **str, int *id0, int *id1, int *devno) { int val, old_style; - + /* check for leading '0x' */ old_style = 0; if ((*str)[0] == '0' && (*str)[1] == 'x') { @@ -179,7 +195,7 @@ dasd_feature_list(char *str, char **endp) features = 0; while (1) { - for (len = 0; + for (len = 0; str[len] && str[len] != ':' && str[len] != ')'; len++); if (len == 2 && !strncmp(str, "ro", 2)) features |= DASD_FEATURE_READONLY; @@ -228,19 +244,24 @@ dasd_parse_keyword( char *parsestring ) { length = strlen(parsestring); residual_str = parsestring + length; } - if (strncmp ("autodetect", parsestring, length) == 0) { + if (strncmp("autodetect", parsestring, length) == 0) { dasd_autodetect = 1; MESSAGE (KERN_INFO, "%s", "turning to autodetection mode"); return residual_str; } - if (strncmp ("probeonly", parsestring, length) == 0) { + if (strncmp("probeonly", parsestring, length) == 0) { dasd_probeonly = 1; MESSAGE(KERN_INFO, "%s", "turning to probeonly mode"); return residual_str; } - if (strncmp ("fixedbuffers", parsestring, length) == 0) { + if (strncmp("nopav", parsestring, length) == 0) { + dasd_nopav = 1; + MESSAGE(KERN_INFO, "%s", "disable PAV mode"); + return residual_str; + } + if (strncmp("fixedbuffers", parsestring, length) == 0) { if (dasd_page_cache) return residual_str; dasd_page_cache = @@ -294,6 +315,8 @@ dasd_parse_range( char *parsestring ) { features = dasd_feature_list(str, &str); if (features < 0) return ERR_PTR(-EINVAL); + /* each device in dasd= parameter should be set initially online */ + features |= DASD_FEATURE_INITIAL_ONLINE; while (from <= to) { sprintf(bus_id, "%01x.%01x.%04x", from_id0, from_id1, from++); @@ -359,7 +382,7 @@ dasd_parse(void) * Add a devmap for the device specified by busid. It is possible that * the devmap already exists (dasd= parameter). The order of the devices * added through this function will define the kdevs for the individual - * devices. + * devices. */ static struct dasd_devmap * dasd_add_busid(char *bus_id, int features) @@ -368,7 +391,7 @@ dasd_add_busid(char *bus_id, int features) int hash; new = (struct dasd_devmap *) - kmalloc(sizeof(struct dasd_devmap), GFP_KERNEL); + kzalloc(sizeof(struct dasd_devmap), GFP_KERNEL); if (!new) return ERR_PTR(-ENOMEM); spin_lock(&dasd_devmap_lock); @@ -630,7 +653,8 @@ dasd_ro_show(struct device *dev, struct device_attribute *attr, char *buf) } static ssize_t -dasd_ro_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +dasd_ro_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct dasd_devmap *devmap; int ro_flag; @@ -658,7 +682,7 @@ static DEVICE_ATTR(readonly, 0644, dasd_ro_show, dasd_ro_store); * use_diag controls whether the driver should use diag rather than ssch * to talk to the device */ -static ssize_t +static ssize_t dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf) { struct dasd_devmap *devmap; @@ -673,7 +697,8 @@ dasd_use_diag_show(struct device *dev, struct device_attribute *attr, char *buf) } static ssize_t -dasd_use_diag_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) +dasd_use_diag_store(struct device *dev, struct device_attribute *attr, + const char *buf, size_t count) { struct dasd_devmap *devmap; ssize_t rc; @@ -697,11 +722,11 @@ dasd_use_diag_store(struct device *dev, struct device_attribute *attr, const cha return rc; } -static -DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store); +static DEVICE_ATTR(use_diag, 0644, dasd_use_diag_show, dasd_use_diag_store); static ssize_t -dasd_discipline_show(struct device *dev, struct device_attribute *attr, char *buf) +dasd_discipline_show(struct device *dev, struct device_attribute *attr, + char *buf) { struct dasd_devmap *devmap; char *dname; @@ -834,6 +859,38 @@ static struct attribute_group dasd_attr_group = { .attrs = dasd_attrs, }; +/* + * Check if the related storage server is already contained in the + * dasd_serverlist. If server is not contained, create new entry. + * Return 0 if server was already in serverlist, + * 1 if the server was added successfully + * <0 in case of error. + */ +static int +dasd_add_server(struct dasd_uid *uid) +{ + struct dasd_servermap *new, *tmp; + + /* check if server is already contained */ + list_for_each_entry(tmp, &dasd_serverlist, list) + // normale cmp? + if (strncmp(tmp->sid.vendor, uid->vendor, + sizeof(tmp->sid.vendor)) == 0 + && strncmp(tmp->sid.serial, uid->serial, + sizeof(tmp->sid.serial)) == 0) + return 0; + + new = (struct dasd_servermap *) + kzalloc(sizeof(struct dasd_servermap), GFP_KERNEL); + if (!new) + return -ENOMEM; + + strncpy(new->sid.vendor, uid->vendor, sizeof(new->sid.vendor)); + strncpy(new->sid.serial, uid->serial, sizeof(new->sid.serial)); + list_add(&new->list, &dasd_serverlist); + return 1; +} + /* * Return copy of the device unique identifier. @@ -854,21 +911,26 @@ dasd_get_uid(struct ccw_device *cdev, struct dasd_uid *uid) /* * Register the given device unique identifier into devmap struct. + * Return 0 if server was already in serverlist, + * 1 if the server was added successful + * <0 in case of error. */ int dasd_set_uid(struct ccw_device *cdev, struct dasd_uid *uid) { struct dasd_devmap *devmap; + int rc; devmap = dasd_find_busid(cdev->dev.bus_id); if (IS_ERR(devmap)) return PTR_ERR(devmap); spin_lock(&dasd_devmap_lock); devmap->uid = *uid; + rc = dasd_add_server(uid); spin_unlock(&dasd_devmap_lock); - return 0; + return rc; } -EXPORT_SYMBOL(dasd_set_uid); +EXPORT_SYMBOL_GPL(dasd_set_uid); /* * Return value of the specified feature. @@ -880,7 +942,7 @@ dasd_get_feature(struct ccw_device *cdev, int feature) devmap = dasd_find_busid(cdev->dev.bus_id); if (IS_ERR(devmap)) - return (int) PTR_ERR(devmap); + return PTR_ERR(devmap); return ((devmap->features & feature) != 0); } @@ -896,7 +958,7 @@ dasd_set_feature(struct ccw_device *cdev, int feature, int flag) devmap = dasd_find_busid(cdev->dev.bus_id); if (IS_ERR(devmap)) - return (int) PTR_ERR(devmap); + return PTR_ERR(devmap); spin_lock(&dasd_devmap_lock); if (flag) @@ -932,8 +994,10 @@ dasd_devmap_init(void) dasd_max_devindex = 0; for (i = 0; i < 256; i++) INIT_LIST_HEAD(&dasd_hashlists[i]); - return 0; + /* Initialize servermap structure. */ + INIT_LIST_HEAD(&dasd_serverlist); + return 0; } void diff --git a/trunk/drivers/s390/block/dasd_diag.c b/trunk/drivers/s390/block/dasd_diag.c index 3f9d704d2657..4002f6c1c1b3 100644 --- a/trunk/drivers/s390/block/dasd_diag.c +++ b/trunk/drivers/s390/block/dasd_diag.c @@ -1,4 +1,4 @@ -/* +/* * File...........: linux/drivers/s390/block/dasd_diag.c * Author(s)......: Holger Smolinski * Based on.......: linux/drivers/s390/block/mdisk.c @@ -336,7 +336,7 @@ dasd_diag_check_device(struct dasd_device *device) private = (struct dasd_diag_private *) device->private; if (private == NULL) { - private = kmalloc(sizeof(struct dasd_diag_private),GFP_KERNEL); + private = kzalloc(sizeof(struct dasd_diag_private),GFP_KERNEL); if (private == NULL) { DEV_MESSAGE(KERN_WARNING, device, "%s", "memory allocation failed for private data"); @@ -527,7 +527,7 @@ dasd_diag_build_cp(struct dasd_device * device, struct request *req) datasize, device); if (IS_ERR(cqr)) return cqr; - + dreq = (struct dasd_diag_req *) cqr->data; dreq->block_count = count; dbio = dreq->bio; diff --git a/trunk/drivers/s390/block/dasd_diag.h b/trunk/drivers/s390/block/dasd_diag.h index 38a4e55f8953..b8c78267ff3e 100644 --- a/trunk/drivers/s390/block/dasd_diag.h +++ b/trunk/drivers/s390/block/dasd_diag.h @@ -1,4 +1,4 @@ -/* +/* * File...........: linux/drivers/s390/block/dasd_diag.h * Author(s)......: Holger Smolinski * Based on.......: linux/drivers/s390/block/mdisk.h diff --git a/trunk/drivers/s390/block/dasd_eckd.c b/trunk/drivers/s390/block/dasd_eckd.c index 7d5a6cee4bd8..0dfab30e8089 100644 --- a/trunk/drivers/s390/block/dasd_eckd.c +++ b/trunk/drivers/s390/block/dasd_eckd.c @@ -1,7 +1,7 @@ -/* +/* * File...........: linux/drivers/s390/block/dasd_eckd.c * Author(s)......: Holger Smolinski - * Horst Hummel + * Horst Hummel * Carsten Otte * Martin Schwidefsky * Bugreports.to..: @@ -24,6 +24,7 @@ #include #include #include +#include #include #include "dasd_int.h" @@ -89,17 +90,22 @@ dasd_eckd_probe (struct ccw_device *cdev) { int ret; - ret = dasd_generic_probe (cdev, &dasd_eckd_discipline); - if (ret) + /* set ECKD specific ccw-device options */ + ret = ccw_device_set_options(cdev, CCWDEV_ALLOW_FORCE); + if (ret) { + printk(KERN_WARNING + "dasd_eckd_probe: could not set ccw-device options " + "for %s\n", cdev->dev.bus_id); return ret; - ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP | CCWDEV_ALLOW_FORCE); - return 0; + } + ret = dasd_generic_probe(cdev, &dasd_eckd_discipline); + return ret; } static int dasd_eckd_set_online(struct ccw_device *cdev) { - return dasd_generic_set_online (cdev, &dasd_eckd_discipline); + return dasd_generic_set_online(cdev, &dasd_eckd_discipline); } static struct ccw_driver dasd_eckd_driver = { @@ -210,14 +216,14 @@ check_XRC (struct ccw1 *de_ccw, /* switch on System Time Stamp - needed for XRC Support */ if (private->rdc_data.facilities.XRC_supported) { - + data->ga_extended |= 0x08; /* switch on 'Time Stamp Valid' */ data->ga_extended |= 0x02; /* switch on 'Extended Parameter' */ - + data->ep_sys_time = get_clock (); - + de_ccw->count = sizeof (struct DE_eckd_data); - de_ccw->flags |= CCW_FLAG_SLI; + de_ccw->flags |= CCW_FLAG_SLI; } return; @@ -296,8 +302,8 @@ define_extent(struct ccw1 * ccw, struct DE_eckd_data * data, int trk, /* check for sequential prestage - enhance cylinder range */ if (data->attributes.operation == DASD_SEQ_PRESTAGE || data->attributes.operation == DASD_SEQ_ACCESS) { - - if (end.cyl + private->attrib.nr_cyl < geo.cyl) + + if (end.cyl + private->attrib.nr_cyl < geo.cyl) end.cyl += private->attrib.nr_cyl; else end.cyl = (geo.cyl - 1); @@ -317,7 +323,7 @@ locate_record(struct ccw1 *ccw, struct LO_eckd_data *data, int trk, struct dasd_eckd_private *private; int sector; int dn, d; - + private = (struct dasd_eckd_private *) device->private; DBF_DEV_EVENT(DBF_INFO, device, @@ -540,6 +546,86 @@ dasd_eckd_read_conf(struct dasd_device *device) return 0; } +/* + * Build CP for Perform Subsystem Function - SSC. + */ +struct dasd_ccw_req * +dasd_eckd_build_psf_ssc(struct dasd_device *device) +{ + struct dasd_ccw_req *cqr; + struct dasd_psf_ssc_data *psf_ssc_data; + struct ccw1 *ccw; + + cqr = dasd_smalloc_request("ECKD", 1 /* PSF */ , + sizeof(struct dasd_psf_ssc_data), + device); + + if (IS_ERR(cqr)) { + DEV_MESSAGE(KERN_WARNING, device, "%s", + "Could not allocate PSF-SSC request"); + return cqr; + } + psf_ssc_data = (struct dasd_psf_ssc_data *)cqr->data; + psf_ssc_data->order = PSF_ORDER_SSC; + psf_ssc_data->suborder = 0x08; + + ccw = cqr->cpaddr; + ccw->cmd_code = DASD_ECKD_CCW_PSF; + ccw->cda = (__u32)(addr_t)psf_ssc_data; + ccw->count = 66; + + cqr->device = device; + cqr->expires = 10*HZ; + cqr->buildclk = get_clock(); + cqr->status = DASD_CQR_FILLED; + return cqr; +} + +/* + * Perform Subsystem Function. + * It is necessary to trigger CIO for channel revalidation since this + * call might change behaviour of DASD devices. + */ +static int +dasd_eckd_psf_ssc(struct dasd_device *device) +{ + struct dasd_ccw_req *cqr; + int rc; + + cqr = dasd_eckd_build_psf_ssc(device); + if (IS_ERR(cqr)) + return PTR_ERR(cqr); + + rc = dasd_sleep_on(cqr); + if (!rc) + /* trigger CIO to reprobe devices */ + css_schedule_reprobe(); + dasd_sfree_request(cqr, cqr->device); + return rc; +} + +/* + * Valide storage server of current device. + */ +static int +dasd_eckd_validate_server(struct dasd_device *device) +{ + int rc; + + /* Currently PAV is the only reason to 'validate' server on LPAR */ + if (dasd_nopav || MACHINE_IS_VM) + return 0; + + rc = dasd_eckd_psf_ssc(device); + if (rc) + /* may be requested feature is not available on server, + * therefore just report error and go ahead */ + DEV_MESSAGE(KERN_INFO, device, + "Perform Subsystem Function returned rc=%d", rc); + /* RE-Read Configuration Data */ + return dasd_eckd_read_conf(device); +} + /* * Check device characteristics. * If the device is accessible using ECKD discipline, the device is enabled. @@ -554,7 +640,7 @@ dasd_eckd_check_characteristics(struct dasd_device *device) private = (struct dasd_eckd_private *) device->private; if (private == NULL) { - private = kmalloc(sizeof(struct dasd_eckd_private), + private = kzalloc(sizeof(struct dasd_eckd_private), GFP_KERNEL | GFP_DMA); if (private == NULL) { DEV_MESSAGE(KERN_WARNING, device, "%s", @@ -562,7 +648,6 @@ dasd_eckd_check_characteristics(struct dasd_device *device) "data"); return -ENOMEM; } - memset(private, 0, sizeof(struct dasd_eckd_private)); device->private = (void *) private; } /* Invalidate status of initial analysis. */ @@ -571,16 +656,29 @@ dasd_eckd_check_characteristics(struct dasd_device *device) private->attrib.operation = DASD_NORMAL_CACHE; private->attrib.nr_cyl = 0; + /* Read Configuration Data */ + rc = dasd_eckd_read_conf(device); + if (rc) + return rc; + + /* Generate device unique id and register in devmap */ + rc = dasd_eckd_generate_uid(device, &uid); + if (rc) + return rc; + rc = dasd_set_uid(device->cdev, &uid); + if (rc == 1) /* new server found */ + rc = dasd_eckd_validate_server(device); + if (rc) + return rc; + /* Read Device Characteristics */ rdc_data = (void *) &(private->rdc_data); memset(rdc_data, 0, sizeof(rdc_data)); rc = read_dev_chars(device->cdev, &rdc_data, 64); - if (rc) { + if (rc) DEV_MESSAGE(KERN_WARNING, device, - "Read device characteristics returned error %d", - rc); - return rc; - } + "Read device characteristics returned " + "rc=%d", rc); DEV_MESSAGE(KERN_INFO, device, "%04X/%02X(CU:%04X/%02X) Cyl:%d Head:%d Sec:%d", @@ -591,19 +689,6 @@ dasd_eckd_check_characteristics(struct dasd_device *device) private->rdc_data.no_cyl, private->rdc_data.trk_per_cyl, private->rdc_data.sec_per_trk); - - /* Read Configuration Data */ - rc = dasd_eckd_read_conf (device); - if (rc) - return rc; - - /* Generate device unique id and register in devmap */ - rc = dasd_eckd_generate_uid(device, &uid); - if (rc) - return rc; - - rc = dasd_set_uid(device->cdev, &uid); - return rc; } @@ -773,7 +858,7 @@ dasd_eckd_end_analysis(struct dasd_device *device) ((private->rdc_data.no_cyl * private->rdc_data.trk_per_cyl * blk_per_trk * (device->bp_block >> 9)) >> 1), - ((blk_per_trk * device->bp_block) >> 10), + ((blk_per_trk * device->bp_block) >> 10), private->uses_cdl ? "compatible disk layout" : "linux disk layout"); @@ -970,7 +1055,7 @@ dasd_eckd_format_device(struct dasd_device * device, if (i < 3) { ect->kl = 4; ect->dl = sizes_trk0[i] - 4; - } + } } if ((fdata->intensity & 0x08) && fdata->start_unit == 1) { @@ -1270,7 +1355,7 @@ dasd_eckd_fill_info(struct dasd_device * device, /* * Release device ioctl. - * Buils a channel programm to releases a prior reserved + * Buils a channel programm to releases a prior reserved * (see dasd_eckd_reserve) device. */ static int @@ -1310,8 +1395,8 @@ dasd_eckd_release(struct dasd_device *device) /* * Reserve device ioctl. * Options are set to 'synchronous wait for interrupt' and - * 'timeout the request'. This leads to a terminate IO if - * the interrupt is outstanding for a certain time. + * 'timeout the request'. This leads to a terminate IO if + * the interrupt is outstanding for a certain time. */ static int dasd_eckd_reserve(struct dasd_device *device) @@ -1349,7 +1434,7 @@ dasd_eckd_reserve(struct dasd_device *device) /* * Steal lock ioctl - unconditional reserve device. - * Buils a channel programm to break a device's reservation. + * Buils a channel programm to break a device's reservation. * (unconditional reserve) */ static int @@ -1521,6 +1606,40 @@ dasd_eckd_ioctl(struct dasd_device *device, unsigned int cmd, void __user *argp) } } +/* + * Dump the range of CCWs into 'page' buffer + * and return number of printed chars. + */ +static inline int +dasd_eckd_dump_ccw_range(struct ccw1 *from, struct ccw1 *to, char *page) +{ + int len, count; + char *datap; + + len = 0; + while (from <= to) { + len += sprintf(page + len, KERN_ERR PRINTK_HEADER + " CCW %p: %08X %08X DAT:", + from, ((int *) from)[0], ((int *) from)[1]); + + /* get pointer to data (consider IDALs) */ + if (from->flags & CCW_FLAG_IDA) + datap = (char *) *((addr_t *) (addr_t) from->cda); + else + datap = (char *) ((addr_t) from->cda); + + /* dump data (max 32 bytes) */ + for (count = 0; count < from->count && count < 32; count++) { + if (count % 8 == 0) len += sprintf(page + len, " "); + if (count % 4 == 0) len += sprintf(page + len, " "); + len += sprintf(page + len, "%02x", datap[count]); + } + len += sprintf(page + len, "\n"); + from++; + } + return len; +} + /* * Print sense data and related channel program. * Parts are printed because printk buffer is only 1024 bytes. @@ -1530,8 +1649,8 @@ dasd_eckd_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req, struct irb *irb) { char *page; - struct ccw1 *act, *end, *last; - int len, sl, sct, count; + struct ccw1 *first, *last, *fail, *from, *to; + int len, sl, sct; page = (char *) get_zeroed_page(GFP_ATOMIC); if (page == NULL) { @@ -1539,7 +1658,8 @@ dasd_eckd_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req, "No memory to dump sense data"); return; } - len = sprintf(page, KERN_ERR PRINTK_HEADER + /* dump the sense data */ + len = sprintf(page, KERN_ERR PRINTK_HEADER " I/O status report for device %s:\n", device->cdev->dev.bus_id); len += sprintf(page + len, KERN_ERR PRINTK_HEADER @@ -1564,87 +1684,55 @@ dasd_eckd_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req, if (irb->ecw[27] & DASD_SENSE_BIT_0) { /* 24 Byte Sense Data */ - len += sprintf(page + len, KERN_ERR PRINTK_HEADER - " 24 Byte: %x MSG %x, " - "%s MSGb to SYSOP\n", - irb->ecw[7] >> 4, irb->ecw[7] & 0x0f, - irb->ecw[1] & 0x10 ? "" : "no"); + sprintf(page + len, KERN_ERR PRINTK_HEADER + " 24 Byte: %x MSG %x, " + "%s MSGb to SYSOP\n", + irb->ecw[7] >> 4, irb->ecw[7] & 0x0f, + irb->ecw[1] & 0x10 ? "" : "no"); } else { /* 32 Byte Sense Data */ - len += sprintf(page + len, KERN_ERR PRINTK_HEADER - " 32 Byte: Format: %x " - "Exception class %x\n", - irb->ecw[6] & 0x0f, irb->ecw[22] >> 4); + sprintf(page + len, KERN_ERR PRINTK_HEADER + " 32 Byte: Format: %x " + "Exception class %x\n", + irb->ecw[6] & 0x0f, irb->ecw[22] >> 4); } } else { - len += sprintf(page + len, KERN_ERR PRINTK_HEADER - " SORRY - NO VALID SENSE AVAILABLE\n"); + sprintf(page + len, KERN_ERR PRINTK_HEADER + " SORRY - NO VALID SENSE AVAILABLE\n"); } - MESSAGE_LOG(KERN_ERR, "%s", - page + sizeof(KERN_ERR PRINTK_HEADER)); - - /* dump the Channel Program */ - /* print first CCWs (maximum 8) */ - act = req->cpaddr; - for (last = act; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++); - end = min(act + 8, last); - len = sprintf(page, KERN_ERR PRINTK_HEADER + printk("%s", page); + + /* dump the Channel Program (max 140 Bytes per line) */ + /* Count CCW and print first CCWs (maximum 1024 % 140 = 7) */ + first = req->cpaddr; + for (last = first; last->flags & (CCW_FLAG_CC | CCW_FLAG_DC); last++); + to = min(first + 6, last); + len = sprintf(page, KERN_ERR PRINTK_HEADER " Related CP in req: %p\n", req); - while (act <= end) { - len += sprintf(page + len, KERN_ERR PRINTK_HEADER - " CCW %p: %08X %08X DAT:", - act, ((int *) act)[0], ((int *) act)[1]); - for (count = 0; count < 32 && count < act->count; - count += sizeof(int)) - len += sprintf(page + len, " %08X", - ((int *) (addr_t) act->cda) - [(count>>2)]); - len += sprintf(page + len, "\n"); - act++; - } - MESSAGE_LOG(KERN_ERR, "%s", - page + sizeof(KERN_ERR PRINTK_HEADER)); + dasd_eckd_dump_ccw_range(first, to, page + len); + printk("%s", page); - /* print failing CCW area */ + /* print failing CCW area (maximum 4) */ + /* scsw->cda is either valid or zero */ len = 0; - if (act < ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2) { - act = ((struct ccw1 *)(addr_t) irb->scsw.cpa) - 2; - len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n"); - } - end = min((struct ccw1 *)(addr_t) irb->scsw.cpa + 2, last); - while (act <= end) { - len += sprintf(page + len, KERN_ERR PRINTK_HEADER - " CCW %p: %08X %08X DAT:", - act, ((int *) act)[0], ((int *) act)[1]); - for (count = 0; count < 32 && count < act->count; - count += sizeof(int)) - len += sprintf(page + len, " %08X", - ((int *) (addr_t) act->cda) - [(count>>2)]); - len += sprintf(page + len, "\n"); - act++; + from = ++to; + fail = (struct ccw1 *)(addr_t) irb->scsw.cpa; /* failing CCW */ + if (from < fail - 2) { + from = fail - 2; /* there is a gap - print header */ + len += sprintf(page, KERN_ERR PRINTK_HEADER "......\n"); } + to = min(fail + 1, last); + len += dasd_eckd_dump_ccw_range(from, to, page + len); - /* print last CCWs */ - if (act < last - 2) { - act = last - 2; + /* print last CCWs (maximum 2) */ + from = max(from, ++to); + if (from < last - 1) { + from = last - 1; /* there is a gap - print header */ len += sprintf(page + len, KERN_ERR PRINTK_HEADER "......\n"); } - while (act <= last) { - len += sprintf(page + len, KERN_ERR PRINTK_HEADER - " CCW %p: %08X %08X DAT:", - act, ((int *) act)[0], ((int *) act)[1]); - for (count = 0; count < 32 && count < act->count; - count += sizeof(int)) - len += sprintf(page + len, " %08X", - ((int *) (addr_t) act->cda) - [(count>>2)]); - len += sprintf(page + len, "\n"); - act++; - } + len += dasd_eckd_dump_ccw_range(from, last, page + len); if (len > 0) - MESSAGE_LOG(KERN_ERR, "%s", - page + sizeof(KERN_ERR PRINTK_HEADER)); + printk("%s", page); free_page((unsigned long) page); } @@ -1685,14 +1773,8 @@ static struct dasd_discipline dasd_eckd_discipline = { static int __init dasd_eckd_init(void) { - int ret; - ASCEBC(dasd_eckd_discipline.ebcname, 4); - - ret = ccw_driver_register(&dasd_eckd_driver); - if (!ret) - dasd_generic_auto_online(&dasd_eckd_driver); - return ret; + return ccw_driver_register(&dasd_eckd_driver); } static void __exit @@ -1703,22 +1785,3 @@ dasd_eckd_cleanup(void) module_init(dasd_eckd_init); module_exit(dasd_eckd_cleanup); - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-indent-level: 4 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -4 - * c-argdecl-indent: 4 - * c-label-offset: -4 - * c-continued-statement-offset: 4 - * c-continued-brace-offset: 0 - * indent-tabs-mode: 1 - * tab-width: 8 - * End: - */ diff --git a/trunk/drivers/s390/block/dasd_eckd.h b/trunk/drivers/s390/block/dasd_eckd.h index d5734e976e1c..712ff1650134 100644 --- a/trunk/drivers/s390/block/dasd_eckd.h +++ b/trunk/drivers/s390/block/dasd_eckd.h @@ -1,7 +1,7 @@ -/* +/* * File...........: linux/drivers/s390/block/dasd_eckd.h * Author(s)......: Holger Smolinski - * Horst Hummel + * Horst Hummel * Bugreports.to..: * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 * @@ -41,9 +41,10 @@ #define DASD_ECKD_CCW_RESERVE 0xB4 /* - *Perform Subsystem Function / Sub-Orders + * Perform Subsystem Function / Sub-Orders */ -#define PSF_ORDER_PRSSD 0x18 +#define PSF_ORDER_PRSSD 0x18 +#define PSF_ORDER_SSC 0x1D /***************************************************************************** * SECTION: Type Definitions @@ -155,7 +156,7 @@ struct dasd_eckd_characteristics { unsigned char reserved2:4; unsigned char reserved3:8; unsigned char defect_wr:1; - unsigned char XRC_supported:1; + unsigned char XRC_supported:1; unsigned char reserved4:1; unsigned char striping:1; unsigned char reserved5:4; @@ -343,7 +344,7 @@ struct dasd_eckd_path { }; /* - * Perform Subsystem Function - Prepare for Read Subsystem Data + * Perform Subsystem Function - Prepare for Read Subsystem Data */ struct dasd_psf_prssd_data { unsigned char order; @@ -353,4 +354,15 @@ struct dasd_psf_prssd_data { unsigned char varies[9]; } __attribute__ ((packed)); +/* + * Perform Subsystem Function - Set Subsystem Characteristics + */ +struct dasd_psf_ssc_data { + unsigned char order; + unsigned char flags; + unsigned char cu_type[4]; + unsigned char suborder; + unsigned char reserved[59]; +} __attribute__((packed)); + #endif /* DASD_ECKD_H */ diff --git a/trunk/drivers/s390/block/dasd_eer.c b/trunk/drivers/s390/block/dasd_eer.c index 2d8af709947f..da65f1b032f5 100644 --- a/trunk/drivers/s390/block/dasd_eer.c +++ b/trunk/drivers/s390/block/dasd_eer.c @@ -276,7 +276,7 @@ struct dasd_eer_header { __u64 tv_sec; __u64 tv_usec; char busid[DASD_EER_BUSID_SIZE]; -}; +} __attribute__ ((packed)); /* * The following function can be used for those triggers that have @@ -521,6 +521,8 @@ static int dasd_eer_open(struct inode *inp, struct file *filp) unsigned long flags; eerb = kzalloc(sizeof(struct eerbuffer), GFP_KERNEL); + if (!eerb) + return -ENOMEM; eerb->buffer_page_count = eer_pages; if (eerb->buffer_page_count < 1 || eerb->buffer_page_count > INT_MAX / PAGE_SIZE) { diff --git a/trunk/drivers/s390/block/dasd_erp.c b/trunk/drivers/s390/block/dasd_erp.c index b842377cb0c6..4108d96f6a5a 100644 --- a/trunk/drivers/s390/block/dasd_erp.c +++ b/trunk/drivers/s390/block/dasd_erp.c @@ -90,7 +90,7 @@ dasd_default_erp_action(struct dasd_ccw_req * cqr) /* just retry - there is nothing to save ... I got no sense data.... */ if (cqr->retries > 0) { - DEV_MESSAGE (KERN_DEBUG, device, + DEV_MESSAGE (KERN_DEBUG, device, "default ERP called (%i retries left)", cqr->retries); cqr->lpm = LPM_ANYPATH; @@ -155,7 +155,7 @@ dasd_default_erp_postaction(struct dasd_ccw_req * cqr) /* * Print the hex dump of the memory used by a request. This includes - * all error recovery ccws that have been chained in from of the + * all error recovery ccws that have been chained in from of the * real request. */ static inline void @@ -227,12 +227,12 @@ dasd_log_ccw(struct dasd_ccw_req * cqr, int caller, __u32 cpa) /* * Log bytes arround failed CCW but only if we did * not log the whole CP of the CCW is outside the - * logged CP. + * logged CP. */ if (cplength > 40 || ((addr_t) cpa < (addr_t) lcqr->cpaddr && (addr_t) cpa > (addr_t) (lcqr->cpaddr + cplength + 4))) { - + DEV_MESSAGE(KERN_ERR, device, "Failed CCW (%p) (area):", (void *) (long) cpa); diff --git a/trunk/drivers/s390/block/dasd_fba.c b/trunk/drivers/s390/block/dasd_fba.c index 91145698f8e9..bb7755b9b19d 100644 --- a/trunk/drivers/s390/block/dasd_fba.c +++ b/trunk/drivers/s390/block/dasd_fba.c @@ -1,4 +1,4 @@ -/* +/* * File...........: linux/drivers/s390/block/dasd_fba.c * Author(s)......: Holger Smolinski * Bugreports.to..: @@ -56,19 +56,13 @@ static struct ccw_driver dasd_fba_driver; /* see below */ static int dasd_fba_probe(struct ccw_device *cdev) { - int ret; - - ret = dasd_generic_probe (cdev, &dasd_fba_discipline); - if (ret) - return ret; - ccw_device_set_options(cdev, CCWDEV_DO_PATHGROUP); - return 0; + return dasd_generic_probe(cdev, &dasd_fba_discipline); } static int dasd_fba_set_online(struct ccw_device *cdev) { - return dasd_generic_set_online (cdev, &dasd_fba_discipline); + return dasd_generic_set_online(cdev, &dasd_fba_discipline); } static struct ccw_driver dasd_fba_driver = { @@ -125,13 +119,13 @@ static int dasd_fba_check_characteristics(struct dasd_device *device) { struct dasd_fba_private *private; - struct ccw_device *cdev = device->cdev; + struct ccw_device *cdev = device->cdev; void *rdc_data; int rc; private = (struct dasd_fba_private *) device->private; if (private == NULL) { - private = kmalloc(sizeof(struct dasd_fba_private), GFP_KERNEL); + private = kzalloc(sizeof(struct dasd_fba_private), GFP_KERNEL); if (private == NULL) { DEV_MESSAGE(KERN_WARNING, device, "%s", "memory allocation failed for private " @@ -204,7 +198,7 @@ dasd_fba_examine_error(struct dasd_ccw_req * cqr, struct irb * irb) if (irb->scsw.cstat == 0x00 && irb->scsw.dstat == (DEV_STAT_CHN_END | DEV_STAT_DEV_END)) return dasd_era_none; - + cdev = device->cdev; switch (cdev->id.dev_type) { case 0x3370: @@ -539,7 +533,7 @@ dasd_fba_dump_sense(struct dasd_device *device, struct dasd_ccw_req * req, * 8192 bytes (=2 pages). For 64 bit one dasd_mchunkt_t structure has * 24 bytes, the struct dasd_ccw_req has 136 bytes and each block can use * up to 16 bytes (8 for the ccw and 8 for the idal pointer). In - * addition we have one define extent ccw + 16 bytes of data and a + * addition we have one define extent ccw + 16 bytes of data and a * locate record ccw for each block (stupid devices!) + 16 bytes of data. * That makes: * (8192 - 24 - 136 - 8 - 16) / 40 = 200.2 blocks at maximum. @@ -569,16 +563,8 @@ static struct dasd_discipline dasd_fba_discipline = { static int __init dasd_fba_init(void) { - int ret; - ASCEBC(dasd_fba_discipline.ebcname, 4); - - ret = ccw_driver_register(&dasd_fba_driver); - if (ret) - return ret; - - dasd_generic_auto_online(&dasd_fba_driver); - return 0; + return ccw_driver_register(&dasd_fba_driver); } static void __exit @@ -589,22 +575,3 @@ dasd_fba_cleanup(void) module_init(dasd_fba_init); module_exit(dasd_fba_cleanup); - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-indent-level: 4 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -4 - * c-argdecl-indent: 4 - * c-label-offset: -4 - * c-continued-statement-offset: 4 - * c-continued-brace-offset: 0 - * indent-tabs-mode: 1 - * tab-width: 8 - * End: - */ diff --git a/trunk/drivers/s390/block/dasd_fba.h b/trunk/drivers/s390/block/dasd_fba.h index da1fa91fc01d..14c910baa5fe 100644 --- a/trunk/drivers/s390/block/dasd_fba.h +++ b/trunk/drivers/s390/block/dasd_fba.h @@ -1,4 +1,4 @@ -/* +/* * File...........: linux/drivers/s390/block/dasd_fba.h * Author(s)......: Holger Smolinski * Bugreports.to..: diff --git a/trunk/drivers/s390/block/dasd_int.h b/trunk/drivers/s390/block/dasd_int.h index d4b13e300a76..03a83efc34c4 100644 --- a/trunk/drivers/s390/block/dasd_int.h +++ b/trunk/drivers/s390/block/dasd_int.h @@ -1,7 +1,7 @@ -/* +/* * File...........: linux/drivers/s390/block/dasd_int.h * Author(s)......: Holger Smolinski - * Horst Hummel + * Horst Hummel * Martin Schwidefsky * Bugreports.to..: * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 @@ -186,7 +186,7 @@ struct dasd_ccw_req { void *callback_data; }; -/* +/* * dasd_ccw_req -> status can be: */ #define DASD_CQR_FILLED 0x00 /* request is ready to be processed */ @@ -248,7 +248,7 @@ struct dasd_discipline { /* * Error recovery functions. examine_error() returns a value that * indicates what to do for an error condition. If examine_error() - * returns 'dasd_era_recover' erp_action() is called to create a + * returns 'dasd_era_recover' erp_action() is called to create a * special error recovery ccw. erp_postaction() is called after * an error recovery ccw has finished its execution. dump_sense * is called for every error condition to print the sense data @@ -302,11 +302,11 @@ struct dasd_device { spinlock_t request_queue_lock; struct block_device *bdev; unsigned int devindex; - unsigned long blocks; /* size of volume in blocks */ - unsigned int bp_block; /* bytes per block */ - unsigned int s2b_shift; /* log2 (bp_block/512) */ - unsigned long flags; /* per device flags */ - unsigned short features; /* copy of devmap-features (read-only!) */ + unsigned long blocks; /* size of volume in blocks */ + unsigned int bp_block; /* bytes per block */ + unsigned int s2b_shift; /* log2 (bp_block/512) */ + unsigned long flags; /* per device flags */ + unsigned short features; /* copy of devmap-features (read-only!) */ /* extended error reporting stuff (eer) */ struct dasd_ccw_req *eer_cqr; @@ -513,12 +513,12 @@ void dasd_generic_remove (struct ccw_device *cdev); int dasd_generic_set_online(struct ccw_device *, struct dasd_discipline *); int dasd_generic_set_offline (struct ccw_device *cdev); int dasd_generic_notify(struct ccw_device *, int); -void dasd_generic_auto_online (struct ccw_driver *); /* externals in dasd_devmap.c */ extern int dasd_max_devindex; extern int dasd_probeonly; extern int dasd_autodetect; +extern int dasd_nopav; int dasd_devmap_init(void); void dasd_devmap_exit(void); @@ -606,22 +606,3 @@ static inline int dasd_eer_enabled(struct dasd_device *device) #endif /* __KERNEL__ */ #endif /* DASD_H */ - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-indent-level: 4 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -4 - * c-argdecl-indent: 4 - * c-label-offset: -4 - * c-continued-statement-offset: 4 - * c-continued-brace-offset: 0 - * indent-tabs-mode: 1 - * tab-width: 8 - * End: - */ diff --git a/trunk/drivers/s390/block/dasd_ioctl.c b/trunk/drivers/s390/block/dasd_ioctl.c index b8c80d28df41..302bcd0f28be 100644 --- a/trunk/drivers/s390/block/dasd_ioctl.c +++ b/trunk/drivers/s390/block/dasd_ioctl.c @@ -90,10 +90,10 @@ static int dasd_ioctl_quiesce(struct dasd_device *device) { unsigned long flags; - + if (!capable (CAP_SYS_ADMIN)) return -EACCES; - + DEV_MESSAGE (KERN_DEBUG, device, "%s", "Quiesce IO on device"); spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); @@ -110,13 +110,13 @@ static int dasd_ioctl_resume(struct dasd_device *device) { unsigned long flags; - - if (!capable (CAP_SYS_ADMIN)) + + if (!capable (CAP_SYS_ADMIN)) return -EACCES; DEV_MESSAGE (KERN_DEBUG, device, "%s", "resume IO on device"); - + spin_lock_irqsave(get_ccwdev_lock(device->cdev), flags); device->stopped &= ~DASD_STOPPED_QUIESCE; spin_unlock_irqrestore(get_ccwdev_lock(device->cdev), flags); @@ -287,7 +287,7 @@ dasd_ioctl_information(struct dasd_device *device, dasd_info->open_count = atomic_read(&device->open_count); if (!device->bdev) dasd_info->open_count++; - + /* * check if device is really formatted * LDL / CDL was returned by 'fill_info' diff --git a/trunk/drivers/s390/char/raw3270.c b/trunk/drivers/s390/char/raw3270.c index eecb2afad5c2..3c1314b7391b 100644 --- a/trunk/drivers/s390/char/raw3270.c +++ b/trunk/drivers/s390/char/raw3270.c @@ -50,6 +50,9 @@ struct raw3270 { unsigned char *ascebc; /* ascii -> ebcdic table */ struct class_device *clttydev; /* 3270-class tty device ptr */ struct class_device *cltubdev; /* 3270-class tub device ptr */ + + struct raw3270_request init_request; + unsigned char init_data[256]; }; /* raw3270->flags */ @@ -484,8 +487,6 @@ struct raw3270_ua { /* Query Reply structure for Usable Area */ } __attribute__ ((packed)) aua; } __attribute__ ((packed)); -static unsigned char raw3270_init_data[256]; -static struct raw3270_request raw3270_init_request; static struct diag210 raw3270_init_diag210; static DECLARE_MUTEX(raw3270_init_sem); @@ -644,17 +645,17 @@ __raw3270_size_device(struct raw3270 *rp) * required (3270 device switched to 'stand-by') and command * rejects (old devices that can't do 'read partition'). */ - memset(&raw3270_init_request, 0, sizeof(raw3270_init_request)); - memset(raw3270_init_data, 0, sizeof(raw3270_init_data)); - /* Store 'read partition' data stream to raw3270_init_data */ - memcpy(raw3270_init_data, wbuf, sizeof(wbuf)); - INIT_LIST_HEAD(&raw3270_init_request.list); - raw3270_init_request.ccw.cmd_code = TC_WRITESF; - raw3270_init_request.ccw.flags = CCW_FLAG_SLI; - raw3270_init_request.ccw.count = sizeof(wbuf); - raw3270_init_request.ccw.cda = (__u32) __pa(raw3270_init_data); - - rc = raw3270_start_init(rp, &raw3270_init_view, &raw3270_init_request); + memset(&rp->init_request, 0, sizeof(rp->init_request)); + memset(&rp->init_data, 0, 256); + /* Store 'read partition' data stream to init_data */ + memcpy(&rp->init_data, wbuf, sizeof(wbuf)); + INIT_LIST_HEAD(&rp->init_request.list); + rp->init_request.ccw.cmd_code = TC_WRITESF; + rp->init_request.ccw.flags = CCW_FLAG_SLI; + rp->init_request.ccw.count = sizeof(wbuf); + rp->init_request.ccw.cda = (__u32) __pa(&rp->init_data); + + rc = raw3270_start_init(rp, &raw3270_init_view, &rp->init_request); if (rc) /* Check error cases: -ERESTARTSYS, -EIO and -EOPNOTSUPP */ return rc; @@ -679,18 +680,18 @@ __raw3270_size_device(struct raw3270 *rp) * The device accepted the 'read partition' command. Now * set up a read ccw and issue it. */ - raw3270_init_request.ccw.cmd_code = TC_READMOD; - raw3270_init_request.ccw.flags = CCW_FLAG_SLI; - raw3270_init_request.ccw.count = sizeof(raw3270_init_data); - raw3270_init_request.ccw.cda = (__u32) __pa(raw3270_init_data); - rc = raw3270_start_init(rp, &raw3270_init_view, &raw3270_init_request); + rp->init_request.ccw.cmd_code = TC_READMOD; + rp->init_request.ccw.flags = CCW_FLAG_SLI; + rp->init_request.ccw.count = sizeof(rp->init_data); + rp->init_request.ccw.cda = (__u32) __pa(rp->init_data); + rc = raw3270_start_init(rp, &raw3270_init_view, &rp->init_request); if (rc) return rc; /* Got a Query Reply */ - count = sizeof(raw3270_init_data) - raw3270_init_request.rescnt; - uap = (struct raw3270_ua *) (raw3270_init_data + 1); + count = sizeof(rp->init_data) - rp->init_request.rescnt; + uap = (struct raw3270_ua *) (rp->init_data + 1); /* Paranoia check. */ - if (raw3270_init_data[0] != 0x88 || uap->uab.qcode != 0x81) + if (rp->init_data[0] != 0x88 || uap->uab.qcode != 0x81) return -EOPNOTSUPP; /* Copy rows/columns of default Usable Area */ rp->rows = uap->uab.h; @@ -749,18 +750,18 @@ raw3270_reset_device(struct raw3270 *rp) int rc; down(&raw3270_init_sem); - memset(&raw3270_init_request, 0, sizeof(raw3270_init_request)); - memset(raw3270_init_data, 0, sizeof(raw3270_init_data)); - /* Store reset data stream to raw3270_init_data/raw3270_init_request */ - raw3270_init_data[0] = TW_KR; - INIT_LIST_HEAD(&raw3270_init_request.list); - raw3270_init_request.ccw.cmd_code = TC_EWRITEA; - raw3270_init_request.ccw.flags = CCW_FLAG_SLI; - raw3270_init_request.ccw.count = 1; - raw3270_init_request.ccw.cda = (__u32) __pa(raw3270_init_data); + memset(&rp->init_request, 0, sizeof(rp->init_request)); + memset(&rp->init_data, 0, sizeof(rp->init_data)); + /* Store reset data stream to init_data/init_request */ + rp->init_data[0] = TW_KR; + INIT_LIST_HEAD(&rp->init_request.list); + rp->init_request.ccw.cmd_code = TC_EWRITEA; + rp->init_request.ccw.flags = CCW_FLAG_SLI; + rp->init_request.ccw.count = 1; + rp->init_request.ccw.cda = (__u32) __pa(rp->init_data); rp->view = &raw3270_init_view; raw3270_init_view.dev = rp; - rc = raw3270_start_init(rp, &raw3270_init_view, &raw3270_init_request); + rc = raw3270_start_init(rp, &raw3270_init_view, &rp->init_request); raw3270_init_view.dev = 0; rp->view = 0; up(&raw3270_init_sem); @@ -854,7 +855,7 @@ raw3270_setup_console(struct ccw_device *cdev) char *ascebc; int rc; - rp = (struct raw3270 *) alloc_bootmem(sizeof(struct raw3270)); + rp = (struct raw3270 *) alloc_bootmem_low(sizeof(struct raw3270)); ascebc = (char *) alloc_bootmem(256); rc = raw3270_setup_device(cdev, rp, ascebc); if (rc) @@ -895,7 +896,7 @@ raw3270_create_device(struct ccw_device *cdev) char *ascebc; int rc; - rp = kmalloc(sizeof(struct raw3270), GFP_KERNEL); + rp = kmalloc(sizeof(struct raw3270), GFP_KERNEL | GFP_DMA); if (!rp) return ERR_PTR(-ENOMEM); ascebc = kmalloc(256, GFP_KERNEL); diff --git a/trunk/drivers/s390/cio/blacklist.c b/trunk/drivers/s390/cio/blacklist.c index 0960bef7b199..15b895496a45 100644 --- a/trunk/drivers/s390/cio/blacklist.c +++ b/trunk/drivers/s390/cio/blacklist.c @@ -224,39 +224,6 @@ is_blacklisted (int ssid, int devno) } #ifdef CONFIG_PROC_FS -static int -__s390_redo_validation(struct subchannel_id schid, void *data) -{ - int ret; - struct subchannel *sch; - - sch = get_subchannel_by_schid(schid); - if (sch) { - /* Already known. */ - put_device(&sch->dev); - return 0; - } - ret = css_probe_device(schid); - if (ret == -ENXIO) - return ret; /* We're through. */ - if (ret == -ENOMEM) - /* Stop validation for now. Bad, but no need for a panic. */ - return ret; - return 0; -} - -/* - * Function: s390_redo_validation - * Look for no longer blacklisted devices - * FIXME: there must be a better way to do this */ -static inline void -s390_redo_validation (void) -{ - CIO_TRACE_EVENT (0, "redoval"); - - for_each_subchannel(__s390_redo_validation, NULL); -} - /* * Function: blacklist_parse_proc_parameters * parse the stuff which is piped to /proc/cio_ignore @@ -281,7 +248,7 @@ blacklist_parse_proc_parameters (char *buf) return; } - s390_redo_validation (); + css_schedule_reprobe(); } /* Iterator struct for all devices. */ diff --git a/trunk/drivers/s390/cio/ccwgroup.c b/trunk/drivers/s390/cio/ccwgroup.c index bdfee7fbaa2e..c7319a07ba35 100644 --- a/trunk/drivers/s390/cio/ccwgroup.c +++ b/trunk/drivers/s390/cio/ccwgroup.c @@ -404,21 +404,24 @@ ccwgroup_driver_register (struct ccwgroup_driver *cdriver) } static int -__ccwgroup_driver_unregister_device(struct device *dev, void *data) +__ccwgroup_match_all(struct device *dev, void *data) { - __ccwgroup_remove_symlinks(to_ccwgroupdev(dev)); - device_unregister(dev); - put_device(dev); - return 0; + return 1; } void ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver) { + struct device *dev; + /* We don't want ccwgroup devices to live longer than their driver. */ get_driver(&cdriver->driver); - driver_for_each_device(&cdriver->driver, NULL, NULL, - __ccwgroup_driver_unregister_device); + while ((dev = driver_find_device(&cdriver->driver, NULL, NULL, + __ccwgroup_match_all))) { + __ccwgroup_remove_symlinks(to_ccwgroupdev(dev)); + device_unregister(dev); + put_device(dev); + } put_driver(&cdriver->driver); driver_unregister(&cdriver->driver); } diff --git a/trunk/drivers/s390/cio/chsc.c b/trunk/drivers/s390/cio/chsc.c index 72187e54dcac..b00f3ed051a0 100644 --- a/trunk/drivers/s390/cio/chsc.c +++ b/trunk/drivers/s390/cio/chsc.c @@ -244,8 +244,7 @@ s390_subchannel_remove_chpid(struct device *dev, void *data) if ((sch->schib.scsw.actl & SCSW_ACTL_DEVACT) && (sch->schib.scsw.actl & SCSW_ACTL_SCHACT) && - (sch->schib.pmcw.lpum == mask) && - (sch->vpm == 0)) { + (sch->schib.pmcw.lpum == mask)) { int cc; cc = cio_clear(sch); @@ -918,12 +917,13 @@ chp_measurement_read(struct kobject *kobj, char *buf, loff_t off, size_t count) chp = to_channelpath(container_of(kobj, struct device, kobj)); css = to_css(chp->dev.parent); - size = sizeof(struct cmg_chars); + size = sizeof(struct cmg_entry); /* Only allow single reads. */ if (off || count < size) return 0; chp_measurement_copy_block((struct cmg_entry *)buf, css, chp->id); + count = size; return count; } diff --git a/trunk/drivers/s390/cio/cmf.c b/trunk/drivers/s390/cio/cmf.c index 07ef3f640f4a..1c3e8e9012b0 100644 --- a/trunk/drivers/s390/cio/cmf.c +++ b/trunk/drivers/s390/cio/cmf.c @@ -3,9 +3,10 @@ * * Linux on zSeries Channel Measurement Facility support * - * Copyright 2000,2003 IBM Corporation + * Copyright 2000,2006 IBM Corporation * - * Author: Arnd Bergmann + * Authors: Arnd Bergmann + * Cornelia Huck * * original idea from Natarajan Krishnaswami * @@ -96,9 +97,9 @@ module_param(format, bool, 0444); /** * struct cmb_operations - functions to use depending on cmb_format * - * all these functions operate on a struct cmf_device. There is only - * one instance of struct cmb_operations because all cmf_device - * objects are guaranteed to be of the same type. + * Most of these functions operate on a struct ccw_device. There is only + * one instance of struct cmb_operations because the format of the measurement + * data is guaranteed to be the same for every ccw_device. * * @alloc: allocate memory for a channel measurement block, * either with the help of a special pool or with kmalloc @@ -107,6 +108,7 @@ module_param(format, bool, 0444); * @readall: read a measurement block in a common format * @reset: clear the data in the associated measurement block and * reset its time stamp + * @align: align an allocated block so that the hardware can use it */ struct cmb_operations { int (*alloc) (struct ccw_device*); @@ -115,11 +117,19 @@ struct cmb_operations { u64 (*read) (struct ccw_device*, int); int (*readall)(struct ccw_device*, struct cmbdata *); void (*reset) (struct ccw_device*); + void * (*align) (void *); struct attribute_group *attr_group; }; static struct cmb_operations *cmbops; +struct cmb_data { + void *hw_block; /* Pointer to block updated by hardware */ + void *last_block; /* Last changed block copied from hardware block */ + int size; /* Size of hw_block and last_block */ + unsigned long long last_update; /* when last_block was updated */ +}; + /* our user interface is designed in terms of nanoseconds, * while the hardware measures total times in its own * unit.*/ @@ -226,63 +236,229 @@ struct set_schib_struct { unsigned long address; wait_queue_head_t wait; int ret; + struct kref kref; }; +static void cmf_set_schib_release(struct kref *kref) +{ + struct set_schib_struct *set_data; + + set_data = container_of(kref, struct set_schib_struct, kref); + kfree(set_data); +} + +#define CMF_PENDING 1 + static int set_schib_wait(struct ccw_device *cdev, u32 mme, int mbfc, unsigned long address) { - struct set_schib_struct s = { - .mme = mme, - .mbfc = mbfc, - .address = address, - .wait = __WAIT_QUEUE_HEAD_INITIALIZER(s.wait), - }; + struct set_schib_struct *set_data; + int ret; spin_lock_irq(cdev->ccwlock); - s.ret = set_schib(cdev, mme, mbfc, address); - if (s.ret != -EBUSY) { - goto out_nowait; + if (!cdev->private->cmb) { + ret = -ENODEV; + goto out; } + set_data = kzalloc(sizeof(struct set_schib_struct), GFP_ATOMIC); + if (!set_data) { + ret = -ENOMEM; + goto out; + } + init_waitqueue_head(&set_data->wait); + kref_init(&set_data->kref); + set_data->mme = mme; + set_data->mbfc = mbfc; + set_data->address = address; + + ret = set_schib(cdev, mme, mbfc, address); + if (ret != -EBUSY) + goto out_put; if (cdev->private->state != DEV_STATE_ONLINE) { - s.ret = -EBUSY; /* if the device is not online, don't even try again */ - goto out_nowait; + ret = -EBUSY; + goto out_put; } + cdev->private->state = DEV_STATE_CMFCHANGE; - cdev->private->cmb_wait = &s; - s.ret = 1; + set_data->ret = CMF_PENDING; + cdev->private->cmb_wait = set_data; spin_unlock_irq(cdev->ccwlock); - if (wait_event_interruptible(s.wait, s.ret != 1)) { + if (wait_event_interruptible(set_data->wait, + set_data->ret != CMF_PENDING)) { spin_lock_irq(cdev->ccwlock); - if (s.ret == 1) { - s.ret = -ERESTARTSYS; - cdev->private->cmb_wait = 0; + if (set_data->ret == CMF_PENDING) { + set_data->ret = -ERESTARTSYS; if (cdev->private->state == DEV_STATE_CMFCHANGE) cdev->private->state = DEV_STATE_ONLINE; } spin_unlock_irq(cdev->ccwlock); } - return s.ret; - -out_nowait: + spin_lock_irq(cdev->ccwlock); + cdev->private->cmb_wait = NULL; + ret = set_data->ret; +out_put: + kref_put(&set_data->kref, cmf_set_schib_release); +out: spin_unlock_irq(cdev->ccwlock); - return s.ret; + return ret; } void retry_set_schib(struct ccw_device *cdev) { - struct set_schib_struct *s; + struct set_schib_struct *set_data; + + set_data = cdev->private->cmb_wait; + if (!set_data) { + WARN_ON(1); + return; + } + kref_get(&set_data->kref); + set_data->ret = set_schib(cdev, set_data->mme, set_data->mbfc, + set_data->address); + wake_up(&set_data->wait); + kref_put(&set_data->kref, cmf_set_schib_release); +} + +static int cmf_copy_block(struct ccw_device *cdev) +{ + struct subchannel *sch; + void *reference_buf; + void *hw_block; + struct cmb_data *cmb_data; + + sch = to_subchannel(cdev->dev.parent); + + if (stsch(sch->schid, &sch->schib)) + return -ENODEV; + + if (sch->schib.scsw.fctl & SCSW_FCTL_START_FUNC) { + /* Don't copy if a start function is in progress. */ + if ((!sch->schib.scsw.actl & SCSW_ACTL_SUSPENDED) && + (sch->schib.scsw.actl & + (SCSW_ACTL_DEVACT | SCSW_ACTL_SCHACT)) && + (!sch->schib.scsw.stctl & SCSW_STCTL_SEC_STATUS)) + return -EBUSY; + } + cmb_data = cdev->private->cmb; + hw_block = cmbops->align(cmb_data->hw_block); + if (!memcmp(cmb_data->last_block, hw_block, cmb_data->size)) + /* No need to copy. */ + return 0; + reference_buf = kzalloc(cmb_data->size, GFP_ATOMIC); + if (!reference_buf) + return -ENOMEM; + /* Ensure consistency of block copied from hardware. */ + do { + memcpy(cmb_data->last_block, hw_block, cmb_data->size); + memcpy(reference_buf, hw_block, cmb_data->size); + } while (memcmp(cmb_data->last_block, reference_buf, cmb_data->size)); + cmb_data->last_update = get_clock(); + kfree(reference_buf); + return 0; +} + +struct copy_block_struct { + wait_queue_head_t wait; + int ret; + struct kref kref; +}; + +static void cmf_copy_block_release(struct kref *kref) +{ + struct copy_block_struct *copy_block; + + copy_block = container_of(kref, struct copy_block_struct, kref); + kfree(copy_block); +} + +static int cmf_cmb_copy_wait(struct ccw_device *cdev) +{ + struct copy_block_struct *copy_block; + int ret; + unsigned long flags; + + spin_lock_irqsave(cdev->ccwlock, flags); + if (!cdev->private->cmb) { + ret = -ENODEV; + goto out; + } + copy_block = kzalloc(sizeof(struct copy_block_struct), GFP_ATOMIC); + if (!copy_block) { + ret = -ENOMEM; + goto out; + } + init_waitqueue_head(©_block->wait); + kref_init(©_block->kref); + + ret = cmf_copy_block(cdev); + if (ret != -EBUSY) + goto out_put; + + if (cdev->private->state != DEV_STATE_ONLINE) { + ret = -EBUSY; + goto out_put; + } + + cdev->private->state = DEV_STATE_CMFUPDATE; + copy_block->ret = CMF_PENDING; + cdev->private->cmb_wait = copy_block; + + spin_unlock_irqrestore(cdev->ccwlock, flags); + if (wait_event_interruptible(copy_block->wait, + copy_block->ret != CMF_PENDING)) { + spin_lock_irqsave(cdev->ccwlock, flags); + if (copy_block->ret == CMF_PENDING) { + copy_block->ret = -ERESTARTSYS; + if (cdev->private->state == DEV_STATE_CMFUPDATE) + cdev->private->state = DEV_STATE_ONLINE; + } + spin_unlock_irqrestore(cdev->ccwlock, flags); + } + spin_lock_irqsave(cdev->ccwlock, flags); + cdev->private->cmb_wait = NULL; + ret = copy_block->ret; +out_put: + kref_put(©_block->kref, cmf_copy_block_release); +out: + spin_unlock_irqrestore(cdev->ccwlock, flags); + return ret; +} + +void cmf_retry_copy_block(struct ccw_device *cdev) +{ + struct copy_block_struct *copy_block; - s = cdev->private->cmb_wait; - cdev->private->cmb_wait = 0; - if (!s) { + copy_block = cdev->private->cmb_wait; + if (!copy_block) { WARN_ON(1); return; } - s->ret = set_schib(cdev, s->mme, s->mbfc, s->address); - wake_up(&s->wait); + kref_get(©_block->kref); + copy_block->ret = cmf_copy_block(cdev); + wake_up(©_block->wait); + kref_put(©_block->kref, cmf_copy_block_release); +} + +static void cmf_generic_reset(struct ccw_device *cdev) +{ + struct cmb_data *cmb_data; + + spin_lock_irq(cdev->ccwlock); + cmb_data = cdev->private->cmb; + if (cmb_data) { + memset(cmb_data->last_block, 0, cmb_data->size); + /* + * Need to reset hw block as well to make the hardware start + * from 0 again. + */ + memset(cmbops->align(cmb_data->hw_block), 0, cmb_data->size); + cmb_data->last_update = 0; + } + cdev->private->cmb_start_time = get_clock(); + spin_unlock_irq(cdev->ccwlock); } /** @@ -343,8 +519,8 @@ struct cmb { /* insert a single device into the cmb_area list * called with cmb_area.lock held from alloc_cmb */ -static inline int -alloc_cmb_single (struct ccw_device *cdev) +static inline int alloc_cmb_single (struct ccw_device *cdev, + struct cmb_data *cmb_data) { struct cmb *cmb; struct ccw_device_private *node; @@ -358,10 +534,12 @@ alloc_cmb_single (struct ccw_device *cdev) /* find first unused cmb in cmb_area.mem. * this is a little tricky: cmb_area.list - * remains sorted by ->cmb pointers */ + * remains sorted by ->cmb->hw_data pointers */ cmb = cmb_area.mem; list_for_each_entry(node, &cmb_area.list, cmb_list) { - if ((struct cmb*)node->cmb > cmb) + struct cmb_data *data; + data = node->cmb; + if ((struct cmb*)data->hw_block > cmb) break; cmb++; } @@ -372,7 +550,8 @@ alloc_cmb_single (struct ccw_device *cdev) /* insert new cmb */ list_add_tail(&cdev->private->cmb_list, &node->cmb_list); - cdev->private->cmb = cmb; + cmb_data->hw_block = cmb; + cdev->private->cmb = cmb_data; ret = 0; out: spin_unlock_irq(cdev->ccwlock); @@ -385,7 +564,19 @@ alloc_cmb (struct ccw_device *cdev) int ret; struct cmb *mem; ssize_t size; + struct cmb_data *cmb_data; + + /* Allocate private cmb_data. */ + cmb_data = kzalloc(sizeof(struct cmb_data), GFP_KERNEL); + if (!cmb_data) + return -ENOMEM; + cmb_data->last_block = kzalloc(sizeof(struct cmb), GFP_KERNEL); + if (!cmb_data->last_block) { + kfree(cmb_data); + return -ENOMEM; + } + cmb_data->size = sizeof(struct cmb); spin_lock(&cmb_area.lock); if (!cmb_area.mem) { @@ -414,29 +605,36 @@ alloc_cmb (struct ccw_device *cdev) } /* do the actual allocation */ - ret = alloc_cmb_single(cdev); + ret = alloc_cmb_single(cdev, cmb_data); out: spin_unlock(&cmb_area.lock); - + if (ret) { + kfree(cmb_data->last_block); + kfree(cmb_data); + } return ret; } -static void -free_cmb(struct ccw_device *cdev) +static void free_cmb(struct ccw_device *cdev) { struct ccw_device_private *priv; - - priv = cdev->private; + struct cmb_data *cmb_data; spin_lock(&cmb_area.lock); spin_lock_irq(cdev->ccwlock); + priv = cdev->private; + if (list_empty(&priv->cmb_list)) { /* already freed */ goto out; } + cmb_data = priv->cmb; priv->cmb = NULL; + if (cmb_data) + kfree(cmb_data->last_block); + kfree(cmb_data); list_del_init(&priv->cmb_list); if (list_empty(&cmb_area.list)) { @@ -451,83 +649,97 @@ free_cmb(struct ccw_device *cdev) spin_unlock(&cmb_area.lock); } -static int -set_cmb(struct ccw_device *cdev, u32 mme) +static int set_cmb(struct ccw_device *cdev, u32 mme) { u16 offset; + struct cmb_data *cmb_data; + unsigned long flags; - if (!cdev->private->cmb) + spin_lock_irqsave(cdev->ccwlock, flags); + if (!cdev->private->cmb) { + spin_unlock_irqrestore(cdev->ccwlock, flags); return -EINVAL; - - offset = mme ? (struct cmb *)cdev->private->cmb - cmb_area.mem : 0; + } + cmb_data = cdev->private->cmb; + offset = mme ? (struct cmb *)cmb_data->hw_block - cmb_area.mem : 0; + spin_unlock_irqrestore(cdev->ccwlock, flags); return set_schib_wait(cdev, mme, 0, offset); } -static u64 -read_cmb (struct ccw_device *cdev, int index) +static u64 read_cmb (struct ccw_device *cdev, int index) { - /* yes, we have to put it on the stack - * because the cmb must only be accessed - * atomically, e.g. with mvc */ - struct cmb cmb; - unsigned long flags; + struct cmb *cmb; u32 val; + int ret; + unsigned long flags; + + ret = cmf_cmb_copy_wait(cdev); + if (ret < 0) + return 0; spin_lock_irqsave(cdev->ccwlock, flags); if (!cdev->private->cmb) { - spin_unlock_irqrestore(cdev->ccwlock, flags); - return 0; + ret = 0; + goto out; } - - cmb = *(struct cmb*)cdev->private->cmb; - spin_unlock_irqrestore(cdev->ccwlock, flags); + cmb = ((struct cmb_data *)cdev->private->cmb)->last_block; switch (index) { case cmb_ssch_rsch_count: - return cmb.ssch_rsch_count; + ret = cmb->ssch_rsch_count; + goto out; case cmb_sample_count: - return cmb.sample_count; + ret = cmb->sample_count; + goto out; case cmb_device_connect_time: - val = cmb.device_connect_time; + val = cmb->device_connect_time; break; case cmb_function_pending_time: - val = cmb.function_pending_time; + val = cmb->function_pending_time; break; case cmb_device_disconnect_time: - val = cmb.device_disconnect_time; + val = cmb->device_disconnect_time; break; case cmb_control_unit_queuing_time: - val = cmb.control_unit_queuing_time; + val = cmb->control_unit_queuing_time; break; case cmb_device_active_only_time: - val = cmb.device_active_only_time; + val = cmb->device_active_only_time; break; default: - return 0; + ret = 0; + goto out; } - return time_to_avg_nsec(val, cmb.sample_count); + ret = time_to_avg_nsec(val, cmb->sample_count); +out: + spin_unlock_irqrestore(cdev->ccwlock, flags); + return ret; } -static int -readall_cmb (struct ccw_device *cdev, struct cmbdata *data) +static int readall_cmb (struct ccw_device *cdev, struct cmbdata *data) { - /* yes, we have to put it on the stack - * because the cmb must only be accessed - * atomically, e.g. with mvc */ - struct cmb cmb; - unsigned long flags; + struct cmb *cmb; + struct cmb_data *cmb_data; u64 time; + unsigned long flags; + int ret; + ret = cmf_cmb_copy_wait(cdev); + if (ret < 0) + return ret; spin_lock_irqsave(cdev->ccwlock, flags); - if (!cdev->private->cmb) { - spin_unlock_irqrestore(cdev->ccwlock, flags); - return -ENODEV; + cmb_data = cdev->private->cmb; + if (!cmb_data) { + ret = -ENODEV; + goto out; } - - cmb = *(struct cmb*)cdev->private->cmb; - time = get_clock() - cdev->private->cmb_start_time; - spin_unlock_irqrestore(cdev->ccwlock, flags); + if (cmb_data->last_update == 0) { + ret = -EAGAIN; + goto out; + } + cmb = cmb_data->last_block; + time = cmb_data->last_update - cdev->private->cmb_start_time; memset(data, 0, sizeof(struct cmbdata)); @@ -538,31 +750,32 @@ readall_cmb (struct ccw_device *cdev, struct cmbdata *data) data->elapsed_time = (time * 1000) >> 12; /* copy data to new structure */ - data->ssch_rsch_count = cmb.ssch_rsch_count; - data->sample_count = cmb.sample_count; + data->ssch_rsch_count = cmb->ssch_rsch_count; + data->sample_count = cmb->sample_count; /* time fields are converted to nanoseconds while copying */ - data->device_connect_time = time_to_nsec(cmb.device_connect_time); - data->function_pending_time = time_to_nsec(cmb.function_pending_time); - data->device_disconnect_time = time_to_nsec(cmb.device_disconnect_time); + data->device_connect_time = time_to_nsec(cmb->device_connect_time); + data->function_pending_time = time_to_nsec(cmb->function_pending_time); + data->device_disconnect_time = + time_to_nsec(cmb->device_disconnect_time); data->control_unit_queuing_time - = time_to_nsec(cmb.control_unit_queuing_time); + = time_to_nsec(cmb->control_unit_queuing_time); data->device_active_only_time - = time_to_nsec(cmb.device_active_only_time); + = time_to_nsec(cmb->device_active_only_time); + ret = 0; +out: + spin_unlock_irqrestore(cdev->ccwlock, flags); + return ret; +} - return 0; +static void reset_cmb(struct ccw_device *cdev) +{ + cmf_generic_reset(cdev); } -static void -reset_cmb(struct ccw_device *cdev) +static void * align_cmb(void *area) { - struct cmb *cmb; - spin_lock_irq(cdev->ccwlock); - cmb = cdev->private->cmb; - if (cmb) - memset (cmb, 0, sizeof (*cmb)); - cdev->private->cmb_start_time = get_clock(); - spin_unlock_irq(cdev->ccwlock); + return area; } static struct attribute_group cmf_attr_group; @@ -574,6 +787,7 @@ static struct cmb_operations cmbops_basic = { .read = read_cmb, .readall = readall_cmb, .reset = reset_cmb, + .align = align_cmb, .attr_group = &cmf_attr_group, }; @@ -610,22 +824,34 @@ static inline struct cmbe* cmbe_align(struct cmbe *c) return (struct cmbe*)addr; } -static int -alloc_cmbe (struct ccw_device *cdev) +static int alloc_cmbe (struct ccw_device *cdev) { struct cmbe *cmbe; - cmbe = kmalloc (sizeof (*cmbe) * 2, GFP_KERNEL); + struct cmb_data *cmb_data; + int ret; + + cmbe = kzalloc (sizeof (*cmbe) * 2, GFP_KERNEL); if (!cmbe) return -ENOMEM; - + cmb_data = kzalloc(sizeof(struct cmb_data), GFP_KERNEL); + if (!cmb_data) { + ret = -ENOMEM; + goto out_free; + } + cmb_data->last_block = kzalloc(sizeof(struct cmbe), GFP_KERNEL); + if (!cmb_data->last_block) { + ret = -ENOMEM; + goto out_free; + } + cmb_data->size = sizeof(struct cmbe); spin_lock_irq(cdev->ccwlock); if (cdev->private->cmb) { - kfree(cmbe); spin_unlock_irq(cdev->ccwlock); - return -EBUSY; + ret = -EBUSY; + goto out_free; } - - cdev->private->cmb = cmbe; + cmb_data->hw_block = cmbe; + cdev->private->cmb = cmb_data; spin_unlock_irq(cdev->ccwlock); /* activate global measurement if this is the first channel */ @@ -636,14 +862,24 @@ alloc_cmbe (struct ccw_device *cdev) spin_unlock(&cmb_area.lock); return 0; +out_free: + if (cmb_data) + kfree(cmb_data->last_block); + kfree(cmb_data); + kfree(cmbe); + return ret; } -static void -free_cmbe (struct ccw_device *cdev) +static void free_cmbe (struct ccw_device *cdev) { + struct cmb_data *cmb_data; + spin_lock_irq(cdev->ccwlock); - kfree(cdev->private->cmb); + cmb_data = cdev->private->cmb; cdev->private->cmb = NULL; + if (cmb_data) + kfree(cmb_data->last_block); + kfree(cmb_data); spin_unlock_irq(cdev->ccwlock); /* deactivate global measurement if this is the last channel */ @@ -654,89 +890,105 @@ free_cmbe (struct ccw_device *cdev) spin_unlock(&cmb_area.lock); } -static int -set_cmbe(struct ccw_device *cdev, u32 mme) +static int set_cmbe(struct ccw_device *cdev, u32 mme) { unsigned long mba; + struct cmb_data *cmb_data; + unsigned long flags; - if (!cdev->private->cmb) + spin_lock_irqsave(cdev->ccwlock, flags); + if (!cdev->private->cmb) { + spin_unlock_irqrestore(cdev->ccwlock, flags); return -EINVAL; - mba = mme ? (unsigned long) cmbe_align(cdev->private->cmb) : 0; + } + cmb_data = cdev->private->cmb; + mba = mme ? (unsigned long) cmbe_align(cmb_data->hw_block) : 0; + spin_unlock_irqrestore(cdev->ccwlock, flags); return set_schib_wait(cdev, mme, 1, mba); } -u64 -read_cmbe (struct ccw_device *cdev, int index) +static u64 read_cmbe (struct ccw_device *cdev, int index) { - /* yes, we have to put it on the stack - * because the cmb must only be accessed - * atomically, e.g. with mvc */ - struct cmbe cmb; - unsigned long flags; + struct cmbe *cmb; + struct cmb_data *cmb_data; u32 val; + int ret; + unsigned long flags; - spin_lock_irqsave(cdev->ccwlock, flags); - if (!cdev->private->cmb) { - spin_unlock_irqrestore(cdev->ccwlock, flags); + ret = cmf_cmb_copy_wait(cdev); + if (ret < 0) return 0; - } - cmb = *cmbe_align(cdev->private->cmb); - spin_unlock_irqrestore(cdev->ccwlock, flags); + spin_lock_irqsave(cdev->ccwlock, flags); + cmb_data = cdev->private->cmb; + if (!cmb_data) { + ret = 0; + goto out; + } + cmb = cmb_data->last_block; switch (index) { case cmb_ssch_rsch_count: - return cmb.ssch_rsch_count; + ret = cmb->ssch_rsch_count; + goto out; case cmb_sample_count: - return cmb.sample_count; + ret = cmb->sample_count; + goto out; case cmb_device_connect_time: - val = cmb.device_connect_time; + val = cmb->device_connect_time; break; case cmb_function_pending_time: - val = cmb.function_pending_time; + val = cmb->function_pending_time; break; case cmb_device_disconnect_time: - val = cmb.device_disconnect_time; + val = cmb->device_disconnect_time; break; case cmb_control_unit_queuing_time: - val = cmb.control_unit_queuing_time; + val = cmb->control_unit_queuing_time; break; case cmb_device_active_only_time: - val = cmb.device_active_only_time; + val = cmb->device_active_only_time; break; case cmb_device_busy_time: - val = cmb.device_busy_time; + val = cmb->device_busy_time; break; case cmb_initial_command_response_time: - val = cmb.initial_command_response_time; + val = cmb->initial_command_response_time; break; default: - return 0; + ret = 0; + goto out; } - return time_to_avg_nsec(val, cmb.sample_count); + ret = time_to_avg_nsec(val, cmb->sample_count); +out: + spin_unlock_irqrestore(cdev->ccwlock, flags); + return ret; } -static int -readall_cmbe (struct ccw_device *cdev, struct cmbdata *data) +static int readall_cmbe (struct ccw_device *cdev, struct cmbdata *data) { - /* yes, we have to put it on the stack - * because the cmb must only be accessed - * atomically, e.g. with mvc */ - struct cmbe cmb; - unsigned long flags; + struct cmbe *cmb; + struct cmb_data *cmb_data; u64 time; + unsigned long flags; + int ret; + ret = cmf_cmb_copy_wait(cdev); + if (ret < 0) + return ret; spin_lock_irqsave(cdev->ccwlock, flags); - if (!cdev->private->cmb) { - spin_unlock_irqrestore(cdev->ccwlock, flags); - return -ENODEV; + cmb_data = cdev->private->cmb; + if (!cmb_data) { + ret = -ENODEV; + goto out; } - - cmb = *cmbe_align(cdev->private->cmb); - time = get_clock() - cdev->private->cmb_start_time; - spin_unlock_irqrestore(cdev->ccwlock, flags); + if (cmb_data->last_update == 0) { + ret = -EAGAIN; + goto out; + } + time = cmb_data->last_update - cdev->private->cmb_start_time; memset (data, 0, sizeof(struct cmbdata)); @@ -746,35 +998,38 @@ readall_cmbe (struct ccw_device *cdev, struct cmbdata *data) /* conver to nanoseconds */ data->elapsed_time = (time * 1000) >> 12; + cmb = cmb_data->last_block; /* copy data to new structure */ - data->ssch_rsch_count = cmb.ssch_rsch_count; - data->sample_count = cmb.sample_count; + data->ssch_rsch_count = cmb->ssch_rsch_count; + data->sample_count = cmb->sample_count; /* time fields are converted to nanoseconds while copying */ - data->device_connect_time = time_to_nsec(cmb.device_connect_time); - data->function_pending_time = time_to_nsec(cmb.function_pending_time); - data->device_disconnect_time = time_to_nsec(cmb.device_disconnect_time); + data->device_connect_time = time_to_nsec(cmb->device_connect_time); + data->function_pending_time = time_to_nsec(cmb->function_pending_time); + data->device_disconnect_time = + time_to_nsec(cmb->device_disconnect_time); data->control_unit_queuing_time - = time_to_nsec(cmb.control_unit_queuing_time); + = time_to_nsec(cmb->control_unit_queuing_time); data->device_active_only_time - = time_to_nsec(cmb.device_active_only_time); - data->device_busy_time = time_to_nsec(cmb.device_busy_time); + = time_to_nsec(cmb->device_active_only_time); + data->device_busy_time = time_to_nsec(cmb->device_busy_time); data->initial_command_response_time - = time_to_nsec(cmb.initial_command_response_time); + = time_to_nsec(cmb->initial_command_response_time); - return 0; + ret = 0; +out: + spin_unlock_irqrestore(cdev->ccwlock, flags); + return ret; } -static void -reset_cmbe(struct ccw_device *cdev) +static void reset_cmbe(struct ccw_device *cdev) { - struct cmbe *cmb; - spin_lock_irq(cdev->ccwlock); - cmb = cmbe_align(cdev->private->cmb); - if (cmb) - memset (cmb, 0, sizeof (*cmb)); - cdev->private->cmb_start_time = get_clock(); - spin_unlock_irq(cdev->ccwlock); + cmf_generic_reset(cdev); +} + +static void * align_cmbe(void *area) +{ + return cmbe_align(area); } static struct attribute_group cmf_attr_group_ext; @@ -786,6 +1041,7 @@ static struct cmb_operations cmbops_extended = { .read = read_cmbe, .readall = readall_cmbe, .reset = reset_cmbe, + .align = align_cmbe, .attr_group = &cmf_attr_group_ext, }; @@ -803,14 +1059,19 @@ cmb_show_avg_sample_interval(struct device *dev, struct device_attribute *attr, struct ccw_device *cdev; long interval; unsigned long count; + struct cmb_data *cmb_data; cdev = to_ccwdev(dev); - interval = get_clock() - cdev->private->cmb_start_time; count = cmf_read(cdev, cmb_sample_count); - if (count) + spin_lock_irq(cdev->ccwlock); + cmb_data = cdev->private->cmb; + if (count) { + interval = cmb_data->last_update - + cdev->private->cmb_start_time; interval /= count; - else + } else interval = -1; + spin_unlock_irq(cdev->ccwlock); return sprintf(buf, "%ld\n", interval); } @@ -823,7 +1084,10 @@ cmb_show_avg_utilization(struct device *dev, struct device_attribute *attr, char int ret; ret = cmf_readall(to_ccwdev(dev), &data); - if (ret) + if (ret == -EAGAIN || ret == -ENODEV) + /* No data (yet/currently) available to use for calculation. */ + return sprintf(buf, "n/a\n"); + else if (ret) return ret; utilization = data.device_connect_time + @@ -982,6 +1246,13 @@ cmf_readall(struct ccw_device *cdev, struct cmbdata *data) return cmbops->readall(cdev, data); } +/* Reenable cmf when a disconnected device becomes available again. */ +int cmf_reenable(struct ccw_device *cdev) +{ + cmbops->reset(cdev); + return cmbops->set(cdev, 2); +} + static int __init init_cmf(void) { diff --git a/trunk/drivers/s390/cio/css.c b/trunk/drivers/s390/cio/css.c index 74ea8aac4b7d..1d3be80797f8 100644 --- a/trunk/drivers/s390/cio/css.c +++ b/trunk/drivers/s390/cio/css.c @@ -19,9 +19,11 @@ #include "cio_debug.h" #include "ioasm.h" #include "chsc.h" +#include "device.h" int need_rescan = 0; int css_init_done = 0; +static int need_reprobe = 0; static int max_ssid = 0; struct channel_subsystem *css[__MAX_CSSID + 1]; @@ -339,6 +341,67 @@ typedef void (*workfunc)(void *); DECLARE_WORK(slow_path_work, (workfunc)css_trigger_slow_path, NULL); struct workqueue_struct *slow_path_wq; +/* Reprobe subchannel if unregistered. */ +static int reprobe_subchannel(struct subchannel_id schid, void *data) +{ + struct subchannel *sch; + int ret; + + CIO_DEBUG(KERN_INFO, 6, "cio: reprobe 0.%x.%04x\n", + schid.ssid, schid.sch_no); + if (need_reprobe) + return -EAGAIN; + + sch = get_subchannel_by_schid(schid); + if (sch) { + /* Already known. */ + put_device(&sch->dev); + return 0; + } + + ret = css_probe_device(schid); + switch (ret) { + case 0: + break; + case -ENXIO: + case -ENOMEM: + /* These should abort looping */ + break; + default: + ret = 0; + } + + return ret; +} + +/* Work function used to reprobe all unregistered subchannels. */ +static void reprobe_all(void *data) +{ + int ret; + + CIO_MSG_EVENT(2, "reprobe start\n"); + + need_reprobe = 0; + /* Make sure initial subchannel scan is done. */ + wait_event(ccw_device_init_wq, + atomic_read(&ccw_device_init_count) == 0); + ret = for_each_subchannel(reprobe_subchannel, NULL); + + CIO_MSG_EVENT(2, "reprobe done (rc=%d, need_reprobe=%d)\n", ret, + need_reprobe); +} + +DECLARE_WORK(css_reprobe_work, reprobe_all, NULL); + +/* Schedule reprobing of all unregistered subchannels. */ +void css_schedule_reprobe(void) +{ + need_reprobe = 1; + queue_work(ccw_device_work, &css_reprobe_work); +} + +EXPORT_SYMBOL_GPL(css_schedule_reprobe); + /* * Rescan for new devices. FIXME: This is slow. * This function is called when we have lost CRWs due to overflows and we have diff --git a/trunk/drivers/s390/cio/device.c b/trunk/drivers/s390/cio/device.c index 8e3053c2a451..eafde43e8410 100644 --- a/trunk/drivers/s390/cio/device.c +++ b/trunk/drivers/s390/cio/device.c @@ -133,8 +133,8 @@ struct css_driver io_subchannel_driver = { struct workqueue_struct *ccw_device_work; struct workqueue_struct *ccw_device_notify_work; -static wait_queue_head_t ccw_device_init_wq; -static atomic_t ccw_device_init_count; +wait_queue_head_t ccw_device_init_wq; +atomic_t ccw_device_init_count; static int __init init_ccw_bus_type (void) diff --git a/trunk/drivers/s390/cio/device.h b/trunk/drivers/s390/cio/device.h index 11587ebb7289..00be9a5b4acd 100644 --- a/trunk/drivers/s390/cio/device.h +++ b/trunk/drivers/s390/cio/device.h @@ -1,6 +1,10 @@ #ifndef S390_DEVICE_H #define S390_DEVICE_H +#include +#include +#include + /* * states of the device statemachine */ @@ -23,6 +27,7 @@ enum dev_state { DEV_STATE_DISCONNECTED, DEV_STATE_DISCONNECTED_SENSE_ID, DEV_STATE_CMFCHANGE, + DEV_STATE_CMFUPDATE, /* last element! */ NR_DEV_STATES }; @@ -67,6 +72,8 @@ dev_fsm_final_state(struct ccw_device *cdev) extern struct workqueue_struct *ccw_device_work; extern struct workqueue_struct *ccw_device_notify_work; +extern wait_queue_head_t ccw_device_init_wq; +extern atomic_t ccw_device_init_count; void io_subchannel_recog_done(struct ccw_device *cdev); @@ -112,5 +119,8 @@ int ccw_device_stlck(struct ccw_device *); void ccw_device_set_timeout(struct ccw_device *, int); extern struct subchannel_id ccw_device_get_subchannel_id(struct ccw_device *); +/* Channel measurement facility related */ void retry_set_schib(struct ccw_device *cdev); +void cmf_retry_copy_block(struct ccw_device *); +int cmf_reenable(struct ccw_device *); #endif diff --git a/trunk/drivers/s390/cio/device_fsm.c b/trunk/drivers/s390/cio/device_fsm.c index 49ec562d7f60..7d0dd72635eb 100644 --- a/trunk/drivers/s390/cio/device_fsm.c +++ b/trunk/drivers/s390/cio/device_fsm.c @@ -336,8 +336,11 @@ ccw_device_oper_notify(void *data) if (!ret) /* Driver doesn't want device back. */ ccw_device_do_unreg_rereg((void *)cdev); - else + else { + /* Reenable channel measurements, if needed. */ + cmf_reenable(cdev); wake_up(&cdev->private->wait_q); + } } /* @@ -861,6 +864,8 @@ ccw_device_clear_verify(struct ccw_device *cdev, enum dev_event dev_event) irb = (struct irb *) __LC_IRB; /* Accumulate status. We don't do basic sense. */ ccw_device_accumulate_irb(cdev, irb); + /* Remember to clear irb to avoid residuals. */ + memset(&cdev->private->irb, 0, sizeof(struct irb)); /* Try to start delayed device verification. */ ccw_device_online_verify(cdev, 0); /* Note: Don't call handler for cio initiated clear! */ @@ -1093,6 +1098,13 @@ ccw_device_change_cmfstate(struct ccw_device *cdev, enum dev_event dev_event) dev_fsm_event(cdev, dev_event); } +static void ccw_device_update_cmfblock(struct ccw_device *cdev, + enum dev_event dev_event) +{ + cmf_retry_copy_block(cdev); + cdev->private->state = DEV_STATE_ONLINE; + dev_fsm_event(cdev, dev_event); +} static void ccw_device_quiesce_done(struct ccw_device *cdev, enum dev_event dev_event) @@ -1247,6 +1259,12 @@ fsm_func_t *dev_jumptable[NR_DEV_STATES][NR_DEV_EVENTS] = { [DEV_EVENT_TIMEOUT] = ccw_device_change_cmfstate, [DEV_EVENT_VERIFY] = ccw_device_change_cmfstate, }, + [DEV_STATE_CMFUPDATE] = { + [DEV_EVENT_NOTOPER] = ccw_device_update_cmfblock, + [DEV_EVENT_INTERRUPT] = ccw_device_update_cmfblock, + [DEV_EVENT_TIMEOUT] = ccw_device_update_cmfblock, + [DEV_EVENT_VERIFY] = ccw_device_update_cmfblock, + }, }; /* diff --git a/trunk/drivers/s390/cio/device_ops.c b/trunk/drivers/s390/cio/device_ops.c index 795abb5a65ba..b266ad8e14ff 100644 --- a/trunk/drivers/s390/cio/device_ops.c +++ b/trunk/drivers/s390/cio/device_ops.c @@ -78,7 +78,8 @@ ccw_device_start_key(struct ccw_device *cdev, struct ccw1 *cpa, return -ENODEV; if (cdev->private->state == DEV_STATE_NOT_OPER) return -ENODEV; - if (cdev->private->state == DEV_STATE_VERIFY) { + if (cdev->private->state == DEV_STATE_VERIFY || + cdev->private->state == DEV_STATE_CLEAR_VERIFY) { /* Remember to fake irb when finished. */ if (!cdev->private->flags.fake_irb) { cdev->private->flags.fake_irb = 1; @@ -270,7 +271,8 @@ ccw_device_wake_up(struct ccw_device *cdev, unsigned long ip, struct irb *irb) * We didn't get channel end / device end. Check if path * verification has been started; we can retry after it has * finished. We also retry unit checks except for command reject - * or intervention required. + * or intervention required. Also check for long busy + * conditions. */ if (cdev->private->flags.doverify || cdev->private->state == DEV_STATE_VERIFY) @@ -279,6 +281,10 @@ ccw_device_wake_up(struct ccw_device *cdev, unsigned long ip, struct irb *irb) !(irb->ecw[0] & (SNS0_CMD_REJECT | SNS0_INTERVENTION_REQ))) cdev->private->intparm = -EAGAIN; + else if ((irb->scsw.dstat & DEV_STAT_ATTENTION) && + (irb->scsw.dstat & DEV_STAT_DEV_END) && + (irb->scsw.dstat & DEV_STAT_UNIT_EXCEP)) + cdev->private->intparm = -EAGAIN; else cdev->private->intparm = -EIO; diff --git a/trunk/drivers/s390/s390mach.c b/trunk/drivers/s390/s390mach.c index f99e55308b32..8dc75002acbe 100644 --- a/trunk/drivers/s390/s390mach.c +++ b/trunk/drivers/s390/s390mach.c @@ -14,6 +14,7 @@ #include #include #include +#include #include @@ -56,8 +57,6 @@ s390_collect_crw_info(void *param) unsigned int chain; sem = (struct semaphore *)param; - /* Set a nice name. */ - daemonize("kmcheck"); repeat: down_interruptible(sem); slow = 0; @@ -516,7 +515,7 @@ arch_initcall(machine_check_init); static int __init machine_check_crw_init (void) { - kernel_thread(s390_collect_crw_info, &m_sem, CLONE_FS|CLONE_FILES); + kthread_run(s390_collect_crw_info, &m_sem, "kmcheck"); ctl_set_bit(14, 28); /* enable channel report MCH */ return 0; } diff --git a/trunk/drivers/scsi/sata_via.c b/trunk/drivers/scsi/sata_via.c index 67c3d2999775..501ce1791782 100644 --- a/trunk/drivers/scsi/sata_via.c +++ b/trunk/drivers/scsi/sata_via.c @@ -335,10 +335,10 @@ static int svia_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) if ((pci_resource_start(pdev, i) == 0) || (pci_resource_len(pdev, i) < bar_sizes[i])) { dev_printk(KERN_ERR, &pdev->dev, - "invalid PCI BAR %u (sz 0x%lx, val 0x%lx)\n", - i, - pci_resource_start(pdev, i), - pci_resource_len(pdev, i)); + "invalid PCI BAR %u (sz 0x%llx, val 0x%llx)\n", + i, + (unsigned long long)pci_resource_start(pdev, i), + (unsigned long long)pci_resource_len(pdev, i)); rc = -ENODEV; goto err_out_regions; } diff --git a/trunk/drivers/serial/68328serial.c b/trunk/drivers/serial/68328serial.c index b88a7c1158af..bff94541991c 100644 --- a/trunk/drivers/serial/68328serial.c +++ b/trunk/drivers/serial/68328serial.c @@ -131,17 +131,6 @@ static int m68328_console_baud = CONSOLE_BAUD_RATE; static int m68328_console_cbaud = DEFAULT_CBAUD; -/* - * tmp_buf is used as a temporary buffer by serial_write. We need to - * lock it in case the memcpy_fromfs blocks while swapping in a page, - * and some other program tries to do a serial write at the same time. - * Since the lock will only come under contention when the system is - * swapping and available memory is low, it makes sense to share one - * buffer across all the serial ports, since it significantly saves - * memory if large numbers of serial ports are open. - */ -static unsigned char tmp_buf[SERIAL_XMIT_SIZE]; /* This is cheating */ - static inline int serial_paranoia_check(struct m68k_serial *info, char *name, const char *routine) { @@ -211,16 +200,16 @@ static void rs_stop(struct tty_struct *tty) if (serial_paranoia_check(info, tty->name, "rs_stop")) return; - save_flags(flags); cli(); + local_irq_save(flags); uart->ustcnt &= ~USTCNT_TXEN; - restore_flags(flags); + local_irq_restore(flags); } static void rs_put_char(char ch) { int flags, loops = 0; - save_flags(flags); cli(); + local_irq_save(flags); while (!(UTX & UTX_TX_AVAIL) && (loops < 1000)) { loops++; @@ -229,7 +218,7 @@ static void rs_put_char(char ch) UTX_TXDATA = ch; udelay(5); - restore_flags(flags); + local_irq_restore(flags); } static void rs_start(struct tty_struct *tty) @@ -241,7 +230,7 @@ static void rs_start(struct tty_struct *tty) if (serial_paranoia_check(info, tty->name, "rs_start")) return; - save_flags(flags); cli(); + local_irq_save(flags); if (info->xmit_cnt && info->xmit_buf && !(uart->ustcnt & USTCNT_TXEN)) { #ifdef USE_INTS uart->ustcnt |= USTCNT_TXEN | USTCNT_TX_INTR_MASK; @@ -249,7 +238,7 @@ static void rs_start(struct tty_struct *tty) uart->ustcnt |= USTCNT_TXEN; #endif } - restore_flags(flags); + local_irq_restore(flags); } /* Drop into either the boot monitor or kadb upon receiving a break @@ -327,14 +316,6 @@ static void receive_chars(struct m68k_serial *info, struct pt_regs *regs, if(!tty) goto clear_and_exit; - /* - * Make sure that we do not overflow the buffer - */ - if (tty_request_buffer_room(tty, 1) == 0) { - tty_schedule_flip(tty); - return; - } - flag = TTY_NORMAL; if(rx & URX_PARITY_ERROR) { @@ -473,7 +454,7 @@ static int startup(struct m68k_serial * info) return -ENOMEM; } - save_flags(flags); cli(); + local_irq_save(flags); /* * Clear the FIFO buffers and disable them @@ -506,7 +487,7 @@ static int startup(struct m68k_serial * info) change_speed(info); info->flags |= S_INITIALIZED; - restore_flags(flags); + local_irq_restore(flags); return 0; } @@ -523,7 +504,7 @@ static void shutdown(struct m68k_serial * info) if (!(info->flags & S_INITIALIZED)) return; - save_flags(flags); cli(); /* Disable interrupts */ + local_irq_save(flags); if (info->xmit_buf) { free_page((unsigned long) info->xmit_buf); @@ -534,7 +515,7 @@ static void shutdown(struct m68k_serial * info) set_bit(TTY_IO_ERROR, &info->tty->flags); info->flags &= ~S_INITIALIZED; - restore_flags(flags); + local_irq_restore(flags); } struct { @@ -655,24 +636,24 @@ static void rs_fair_output(void) if (info == 0) return; if (info->xmit_buf == 0) return; - save_flags(flags); cli(); + local_irq_save(flags); left = info->xmit_cnt; while (left != 0) { c = info->xmit_buf[info->xmit_tail]; info->xmit_tail = (info->xmit_tail+1) & (SERIAL_XMIT_SIZE-1); info->xmit_cnt--; - restore_flags(flags); + local_irq_restore(flags); rs_put_char(c); - save_flags(flags); cli(); + local_irq_save(flags); left = min(info->xmit_cnt, left-1); } /* Last character is being transmitted now (hopefully). */ udelay(5); - restore_flags(flags); + local_irq_restore(flags); return; } @@ -720,11 +701,11 @@ static void rs_flush_chars(struct tty_struct *tty) #endif /* Enable transmitter */ - save_flags(flags); cli(); + local_irq_save(flags); if (info->xmit_cnt <= 0 || tty->stopped || tty->hw_stopped || !info->xmit_buf) { - restore_flags(flags); + local_irq_restore(flags); return; } @@ -749,7 +730,7 @@ static void rs_flush_chars(struct tty_struct *tty) while (!(uart->utx.w & UTX_TX_AVAIL)) udelay(5); } #endif - restore_flags(flags); + local_irq_restore(flags); } extern void console_printn(const char * b, int count); @@ -768,18 +749,22 @@ static int rs_write(struct tty_struct * tty, if (!tty || !info->xmit_buf) return 0; - save_flags(flags); + local_save_flags(flags); while (1) { - cli(); + local_irq_disable(); c = min_t(int, count, min(SERIAL_XMIT_SIZE - info->xmit_cnt - 1, SERIAL_XMIT_SIZE - info->xmit_head)); + local_irq_restore(flags); + if (c <= 0) break; memcpy(info->xmit_buf + info->xmit_head, buf, c); + + local_irq_disable(); info->xmit_head = (info->xmit_head + c) & (SERIAL_XMIT_SIZE-1); info->xmit_cnt += c; - restore_flags(flags); + local_irq_restore(flags); buf += c; count -= c; total += c; @@ -787,7 +772,7 @@ static int rs_write(struct tty_struct * tty, if (info->xmit_cnt && !tty->stopped && !tty->hw_stopped) { /* Enable transmitter */ - cli(); + local_irq_disable(); #ifndef USE_INTS while(info->xmit_cnt) { #endif @@ -807,9 +792,9 @@ static int rs_write(struct tty_struct * tty, #ifndef USE_INTS } #endif - restore_flags(flags); + local_irq_restore(flags); } - restore_flags(flags); + return total; } @@ -838,12 +823,13 @@ static int rs_chars_in_buffer(struct tty_struct *tty) static void rs_flush_buffer(struct tty_struct *tty) { struct m68k_serial *info = (struct m68k_serial *)tty->driver_data; + unsigned long flags; if (serial_paranoia_check(info, tty->name, "rs_flush_buffer")) return; - cli(); + local_irq_save(flags); info->xmit_cnt = info->xmit_head = info->xmit_tail = 0; - sti(); + local_irq_restore(flags); tty_wakeup(tty); } @@ -973,14 +959,15 @@ static int get_lsr_info(struct m68k_serial * info, unsigned int *value) m68328_uart *uart = &uart_addr[info->line]; #endif unsigned char status; + unsigned long flags; - cli(); + local_irq_save(flags); #ifdef CONFIG_SERIAL_68328_RTS_CTS status = (uart->utx.w & UTX_CTS_STAT) ? 1 : 0; #else status = 0; #endif - sti(); + local_irq_restore(flags); put_user(status,value); return 0; } @@ -994,14 +981,13 @@ static void send_break(struct m68k_serial * info, unsigned int duration) unsigned long flags; if (!info->port) return; - save_flags(flags); - cli(); + local_irq_save(flags); #ifdef USE_INTS uart->utx.w |= UTX_SEND_BREAK; msleep_interruptible(duration); uart->utx.w &= ~UTX_SEND_BREAK; #endif - restore_flags(flags); + local_irq_restore(flags); } static int rs_ioctl(struct tty_struct *tty, struct file * file, @@ -1060,7 +1046,7 @@ static int rs_ioctl(struct tty_struct *tty, struct file * file, (struct serial_struct *) arg); case TIOCSERGETLSR: /* Get line status register */ if (access_ok(VERIFY_WRITE, (void *) arg, - sizeof(unsigned int)); + sizeof(unsigned int))) return get_lsr_info(info, (unsigned int *) arg); return -EFAULT; case TIOCSERGSTRUCT: @@ -1113,10 +1099,10 @@ static void rs_close(struct tty_struct *tty, struct file * filp) if (!info || serial_paranoia_check(info, tty->name, "rs_close")) return; - save_flags(flags); cli(); + local_irq_save(flags); if (tty_hung_up_p(filp)) { - restore_flags(flags); + local_irq_restore(flags); return; } @@ -1138,7 +1124,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) info->count = 0; } if (info->count) { - restore_flags(flags); + local_irq_restore(flags); return; } info->flags |= S_CLOSING; @@ -1186,7 +1172,7 @@ static void rs_close(struct tty_struct *tty, struct file * filp) } info->flags &= ~(S_NORMAL_ACTIVE|S_CLOSING); wake_up_interruptible(&info->close_wait); - restore_flags(flags); + local_irq_restore(flags); } /* @@ -1262,9 +1248,9 @@ static int block_til_ready(struct tty_struct *tty, struct file * filp, info->count--; info->blocked_open++; while (1) { - cli(); + local_irq_disable(); m68k_rtsdtr(info, 1); - sti(); + local_irq_enable(); current->state = TASK_INTERRUPTIBLE; if (tty_hung_up_p(filp) || !(info->flags & S_INITIALIZED)) { @@ -1444,7 +1430,7 @@ rs68328_init(void) return -ENOMEM; } - save_flags(flags); cli(); + local_irq_save(flags); for(i=0;idata = info; #endif } - restore_flags(flags); + local_irq_restore(flags); return 0; } diff --git a/trunk/drivers/serial/8250_pci.c b/trunk/drivers/serial/8250_pci.c index 94886c000d2a..864ef859be56 100644 --- a/trunk/drivers/serial/8250_pci.c +++ b/trunk/drivers/serial/8250_pci.c @@ -594,8 +594,8 @@ pci_default_setup(struct serial_private *priv, struct pciserial_board *board, else offset += idx * board->uart_offset; - maxnr = (pci_resource_len(priv->dev, bar) - board->first_offset) / - (8 << board->reg_shift); + maxnr = (pci_resource_len(priv->dev, bar) - board->first_offset) >> + (board->reg_shift + 3); if (board->flags & FL_REGION_SZ_CAP && idx >= maxnr) return 1; diff --git a/trunk/drivers/serial/crisv10.c b/trunk/drivers/serial/crisv10.c index 89700141f87e..5cacc5e74a92 100644 --- a/trunk/drivers/serial/crisv10.c +++ b/trunk/drivers/serial/crisv10.c @@ -2573,12 +2573,6 @@ static void flush_to_flip_buffer(struct e100_serial *info) DFLIP( if (1) { - - if (test_bit(TTY_DONT_FLIP, &tty->flags)) { - DEBUG_LOG(info->line, "*** TTY_DONT_FLIP set flip.count %i ***\n", tty->flip.count); - DEBUG_LOG(info->line, "*** recv_cnt %i\n", info->recv_cnt); - } else { - } DEBUG_LOG(info->line, "*** rxtot %i\n", info->icount.rx); DEBUG_LOG(info->line, "ldisc %lu\n", tty->ldisc.chars_in_buffer(tty)); DEBUG_LOG(info->line, "room %lu\n", tty->ldisc.receive_room(tty)); diff --git a/trunk/drivers/serial/jsm/jsm_tty.c b/trunk/drivers/serial/jsm/jsm_tty.c index 7d823705193c..f8262e6ad8d3 100644 --- a/trunk/drivers/serial/jsm/jsm_tty.c +++ b/trunk/drivers/serial/jsm/jsm_tty.c @@ -588,13 +588,6 @@ void jsm_input(struct jsm_channel *ch) len = min(len, (N_TTY_BUF_SIZE - 1) - tp->read_cnt); ld = tty_ldisc_ref(tp); - /* - * If the DONT_FLIP flag is on, don't flush our buffer, and act - * like the ld doesn't have any space to put the data right now. - */ - if (test_bit(TTY_DONT_FLIP, &tp->flags)) - len = 0; - /* * If we were unable to get a reference to the ld, * don't flush our buffer, and act like the ld doesn't diff --git a/trunk/drivers/sn/ioc4.c b/trunk/drivers/sn/ioc4.c index 8256a97eb508..8562821e6498 100644 --- a/trunk/drivers/sn/ioc4.c +++ b/trunk/drivers/sn/ioc4.c @@ -438,7 +438,7 @@ static struct pci_device_id ioc4_id_table[] = { {0} }; -static struct pci_driver __devinitdata ioc4_driver = { +static struct pci_driver ioc4_driver = { .name = "IOC4", .id_table = ioc4_id_table, .probe = ioc4_probe, diff --git a/trunk/drivers/spi/spi.c b/trunk/drivers/spi/spi.c index 1cea4a6799fe..ed1cdf6ac8f3 100644 --- a/trunk/drivers/spi/spi.c +++ b/trunk/drivers/spi/spi.c @@ -210,6 +210,7 @@ spi_new_device(struct spi_master *master, struct spi_board_info *chip) proxy->master = master; proxy->chip_select = chip->chip_select; proxy->max_speed_hz = chip->max_speed_hz; + proxy->mode = chip->mode; proxy->irq = chip->irq; proxy->modalias = chip->modalias; diff --git a/trunk/drivers/usb/host/sl811-hcd.c b/trunk/drivers/usb/host/sl811-hcd.c index 6b4bc3f2bd86..89bcda5a3298 100644 --- a/trunk/drivers/usb/host/sl811-hcd.c +++ b/trunk/drivers/usb/host/sl811-hcd.c @@ -1684,9 +1684,13 @@ sl811h_probe(struct platform_device *dev) if (!addr || !data) return -ENODEV; ioaddr = 1; - - addr_reg = (void __iomem *) addr->start; - data_reg = (void __iomem *) data->start; + /* + * NOTE: 64-bit resource->start is getting truncated + * to avoid compiler warning, assuming that ->start + * is always 32-bit for this case + */ + addr_reg = (void __iomem *) (unsigned long) addr->start; + data_reg = (void __iomem *) (unsigned long) data->start; } else { addr_reg = ioremap(addr->start, 1); if (addr_reg == NULL) { diff --git a/trunk/drivers/usb/serial/ir-usb.c b/trunk/drivers/usb/serial/ir-usb.c index 9432c7302275..d7f3f736a692 100644 --- a/trunk/drivers/usb/serial/ir-usb.c +++ b/trunk/drivers/usb/serial/ir-usb.c @@ -453,8 +453,7 @@ static void ir_read_bulk_callback (struct urb *urb, struct pt_regs *regs) tty = port->tty; /* - * FIXME: must not do this in IRQ context, - * must honour TTY_DONT_FLIP + * FIXME: must not do this in IRQ context */ tty->ldisc.receive_buf( tty, diff --git a/trunk/drivers/video/aty/radeon_backlight.c b/trunk/drivers/video/aty/radeon_backlight.c index 7de66b855d4e..1755dddf1899 100644 --- a/trunk/drivers/video/aty/radeon_backlight.c +++ b/trunk/drivers/video/aty/radeon_backlight.c @@ -40,14 +40,14 @@ static int radeon_bl_get_level_brightness(struct radeon_bl_privdata *pdata, mutex_unlock(&info->bl_mutex); - if (pdata->negative) - rlevel = MAX_RADEON_LEVEL - rlevel; - if (rlevel < 0) rlevel = 0; else if (rlevel > MAX_RADEON_LEVEL) rlevel = MAX_RADEON_LEVEL; + if (pdata->negative) + rlevel = MAX_RADEON_LEVEL - rlevel; + return rlevel; } diff --git a/trunk/drivers/video/console/vgacon.c b/trunk/drivers/video/console/vgacon.c index f32b590730f2..01401cd63ac0 100644 --- a/trunk/drivers/video/console/vgacon.c +++ b/trunk/drivers/video/console/vgacon.c @@ -390,7 +390,7 @@ static const char *vgacon_startup(void) vga_video_port_val = VGA_CRT_DM; if ((ORIG_VIDEO_EGA_BX & 0xff) != 0x10) { static struct resource ega_console_resource = - { "ega", 0x3B0, 0x3BF }; + { .name = "ega", .start = 0x3B0, .end = 0x3BF }; vga_video_type = VIDEO_TYPE_EGAM; vga_vram_size = 0x8000; display_desc = "EGA+"; @@ -398,9 +398,9 @@ static const char *vgacon_startup(void) &ega_console_resource); } else { static struct resource mda1_console_resource = - { "mda", 0x3B0, 0x3BB }; + { .name = "mda", .start = 0x3B0, .end = 0x3BB }; static struct resource mda2_console_resource = - { "mda", 0x3BF, 0x3BF }; + { .name = "mda", .start = 0x3BF, .end = 0x3BF }; vga_video_type = VIDEO_TYPE_MDA; vga_vram_size = 0x2000; display_desc = "*MDA"; @@ -423,14 +423,14 @@ static const char *vgacon_startup(void) if (!ORIG_VIDEO_ISVGA) { static struct resource ega_console_resource - = { "ega", 0x3C0, 0x3DF }; + = { .name = "ega", .start = 0x3C0, .end = 0x3DF }; vga_video_type = VIDEO_TYPE_EGAC; display_desc = "EGA"; request_resource(&ioport_resource, &ega_console_resource); } else { static struct resource vga_console_resource - = { "vga+", 0x3C0, 0x3DF }; + = { .name = "vga+", .start = 0x3C0, .end = 0x3DF }; vga_video_type = VIDEO_TYPE_VGAC; display_desc = "VGA+"; request_resource(&ioport_resource, @@ -474,7 +474,7 @@ static const char *vgacon_startup(void) } } else { static struct resource cga_console_resource = - { "cga", 0x3D4, 0x3D5 }; + { .name = "cga", .start = 0x3D4, .end = 0x3D5 }; vga_video_type = VIDEO_TYPE_CGA; vga_vram_size = 0x2000; display_desc = "*CGA"; diff --git a/trunk/drivers/video/sgivwfb.c b/trunk/drivers/video/sgivwfb.c index 2e6df1fcb2b9..c0cc5e3ba7b5 100644 --- a/trunk/drivers/video/sgivwfb.c +++ b/trunk/drivers/video/sgivwfb.c @@ -23,6 +23,8 @@ #include #include +#include + #define INCLUDE_TIMING_TABLE_DATA #define DBE_REG_BASE par->regs #include