aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2006-12-05 12:01:28 -0500
committerDavid Howells <dhowells@warthog.cambridge.redhat.com>2006-12-05 12:01:28 -0500
commit9db73724453a9350e1c22dbe732d427e2939a5c9 (patch)
tree15e3ead6413ae97398a54292acc199bee0864d42
parent4c1ac1b49122b805adfa4efc620592f68dccf5db (diff)
parente62438630ca37539c8cc1553710bbfaa3cf960a7 (diff)
Merge branch 'master' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
Conflicts: drivers/ata/libata-scsi.c include/linux/libata.h Futher merge of Linus's head and compilation fixups. Signed-Off-By: David Howells <dhowells@redhat.com>
-rw-r--r--Documentation/powerpc/booting-without-of.txt39
-rw-r--r--Documentation/powerpc/mpc52xx-device-tree-bindings.txt189
-rw-r--r--Documentation/s390/CommonIO4
-rw-r--r--Documentation/s390/Debugging390.txt38
-rw-r--r--Documentation/s390/cds.txt12
-rw-r--r--Documentation/s390/crypto/crypto-API.txt6
-rw-r--r--Documentation/s390/s390dbf.txt8
-rw-r--r--MAINTAINERS7
-rw-r--r--arch/i386/kernel/acpi/cstate.c1
-rw-r--r--arch/i386/kernel/alternative.c1
-rw-r--r--arch/i386/kernel/cpu/mcheck/therm_throt.c1
-rw-r--r--arch/m68knommu/Kconfig12
-rw-r--r--arch/m68knommu/kernel/process.c34
-rw-r--r--arch/m68knommu/kernel/setup.c3
-rw-r--r--arch/m68knommu/kernel/sys_m68k.c23
-rw-r--r--arch/m68knommu/kernel/traps.c13
-rw-r--r--arch/m68knommu/platform/5307/head.S20
-rw-r--r--arch/m68knommu/platform/68360/head-ram.S3
-rw-r--r--arch/mips/Kconfig18
-rw-r--r--arch/mips/kernel/linux32.c578
-rw-r--r--arch/mips/kernel/scall64-n32.S14
-rw-r--r--arch/mips/kernel/smp.c6
-rw-r--r--arch/mips/lib-32/Makefile2
-rw-r--r--arch/mips/lib-32/csum_partial.S240
-rw-r--r--arch/mips/lib-64/Makefile2
-rw-r--r--arch/mips/lib-64/csum_partial.S242
-rw-r--r--arch/mips/lib/Makefile4
-rw-r--r--arch/mips/lib/csum_partial.S258
-rw-r--r--arch/mips/sibyte/swarm/setup.c8
-rw-r--r--arch/powerpc/.gitignore1
-rw-r--r--arch/powerpc/Kconfig105
-rw-r--r--arch/powerpc/Kconfig.debug13
-rw-r--r--arch/powerpc/boot/.gitignore13
-rw-r--r--arch/powerpc/boot/Makefile15
-rw-r--r--arch/powerpc/boot/dts/kuroboxHG.dts148
-rw-r--r--arch/powerpc/boot/dts/lite5200.dts313
-rw-r--r--arch/powerpc/boot/dts/lite5200b.dts318
-rw-r--r--arch/powerpc/boot/dts/mpc7448hpc2.dts44
-rw-r--r--arch/powerpc/boot/flatdevtree.c880
-rw-r--r--arch/powerpc/boot/flatdevtree.h62
-rw-r--r--arch/powerpc/boot/flatdevtree_env.h47
-rw-r--r--arch/powerpc/boot/flatdevtree_misc.c51
-rw-r--r--arch/powerpc/boot/io.h53
-rw-r--r--arch/powerpc/boot/main.c57
-rw-r--r--arch/powerpc/boot/mktree.c152
-rw-r--r--arch/powerpc/boot/ns16550.c74
-rw-r--r--arch/powerpc/boot/of.c8
-rw-r--r--arch/powerpc/boot/ops.h26
-rw-r--r--arch/powerpc/boot/serial.c142
-rw-r--r--arch/powerpc/boot/simple_alloc.c149
-rw-r--r--arch/powerpc/boot/stdio.c3
-rw-r--r--arch/powerpc/boot/util.S88
-rwxr-xr-xarch/powerpc/boot/wrapper3
-rw-r--r--arch/powerpc/boot/zImage.coff.lds.S4
-rw-r--r--arch/powerpc/configs/cell_defconfig50
-rw-r--r--arch/powerpc/configs/linkstation_defconfig1583
-rw-r--r--arch/powerpc/configs/lite5200_defconfig931
-rw-r--r--arch/powerpc/configs/ppc64_defconfig4
-rw-r--r--arch/powerpc/configs/ps3_defconfig837
-rw-r--r--arch/powerpc/kernel/Makefile15
-rw-r--r--arch/powerpc/kernel/asm-offsets.c3
-rw-r--r--arch/powerpc/kernel/cpu_setup_ppc970.S16
-rw-r--r--arch/powerpc/kernel/cputable.c62
-rw-r--r--arch/powerpc/kernel/crash.c4
-rw-r--r--arch/powerpc/kernel/dma_64.c249
-rw-r--r--arch/powerpc/kernel/entry_64.S51
-rw-r--r--arch/powerpc/kernel/head_64.S163
-rw-r--r--arch/powerpc/kernel/ibmebus.c9
-rw-r--r--arch/powerpc/kernel/idle.c7
-rw-r--r--arch/powerpc/kernel/idle_power4.S8
-rw-r--r--arch/powerpc/kernel/io.c105
-rw-r--r--arch/powerpc/kernel/iomap.c2
-rw-r--r--arch/powerpc/kernel/iommu.c6
-rw-r--r--arch/powerpc/kernel/irq.c80
-rw-r--r--arch/powerpc/kernel/of_device.c173
-rw-r--r--arch/powerpc/kernel/of_platform.c489
-rw-r--r--arch/powerpc/kernel/pci_32.c96
-rw-r--r--arch/powerpc/kernel/pci_64.c70
-rw-r--r--arch/powerpc/kernel/pci_direct_iommu.c98
-rw-r--r--arch/powerpc/kernel/pci_iommu.c164
-rw-r--r--arch/powerpc/kernel/ppc_ksyms.c4
-rw-r--r--arch/powerpc/kernel/prom.c111
-rw-r--r--arch/powerpc/kernel/prom_init.c18
-rw-r--r--arch/powerpc/kernel/prom_parse.c290
-rw-r--r--arch/powerpc/kernel/rtas.c5
-rw-r--r--arch/powerpc/kernel/rtas_flash.c4
-rw-r--r--arch/powerpc/kernel/rtas_pci.c35
-rw-r--r--arch/powerpc/kernel/setup_32.c6
-rw-r--r--arch/powerpc/kernel/setup_64.c18
-rw-r--r--arch/powerpc/kernel/smp-tbsync.c5
-rw-r--r--arch/powerpc/kernel/smp.c1
-rw-r--r--arch/powerpc/kernel/sys_ppc32.c1
-rw-r--r--arch/powerpc/kernel/sysfs.c76
-rw-r--r--arch/powerpc/kernel/time.c7
-rw-r--r--arch/powerpc/kernel/traps.c8
-rw-r--r--arch/powerpc/kernel/vio.c94
-rw-r--r--arch/powerpc/mm/Makefile2
-rw-r--r--arch/powerpc/mm/fault.c25
-rw-r--r--arch/powerpc/mm/hash_native_64.c2
-rw-r--r--arch/powerpc/mm/hash_utils_64.c2
-rw-r--r--arch/powerpc/mm/init_64.c2
-rw-r--r--arch/powerpc/mm/pgtable_32.c33
-rw-r--r--arch/powerpc/mm/pgtable_64.c52
-rw-r--r--arch/powerpc/mm/slb.c13
-rw-r--r--arch/powerpc/oprofile/Makefile1
-rw-r--r--arch/powerpc/oprofile/common.c15
-rw-r--r--arch/powerpc/oprofile/op_model_cell.c724
-rw-r--r--arch/powerpc/platforms/52xx/Makefile9
-rw-r--r--arch/powerpc/platforms/52xx/efika-pci.c119
-rw-r--r--arch/powerpc/platforms/52xx/efika-setup.c150
-rw-r--r--arch/powerpc/platforms/52xx/efika.h19
-rw-r--r--arch/powerpc/platforms/52xx/lite5200.c162
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_common.c126
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pic.c473
-rw-r--r--arch/powerpc/platforms/52xx/mpc52xx_pic.h53
-rw-r--r--arch/powerpc/platforms/82xx/mpc82xx_ads.c13
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_mds.c2
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_itx.c3
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_sys.c3
-rw-r--r--arch/powerpc/platforms/83xx/mpc8360e_pb.c2
-rw-r--r--arch/powerpc/platforms/83xx/mpc83xx.h1
-rw-r--r--arch/powerpc/platforms/83xx/pci.c9
-rw-r--r--arch/powerpc/platforms/85xx/misc.c8
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ads.c11
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx_hpcn.c10
-rw-r--r--arch/powerpc/platforms/Makefile4
-rw-r--r--arch/powerpc/platforms/cell/Kconfig14
-rw-r--r--arch/powerpc/platforms/cell/Makefile7
-rw-r--r--arch/powerpc/platforms/cell/cbe_cpufreq.c248
-rw-r--r--arch/powerpc/platforms/cell/cbe_regs.c71
-rw-r--r--arch/powerpc/platforms/cell/cbe_regs.h203
-rw-r--r--arch/powerpc/platforms/cell/cbe_thermal.c226
-rw-r--r--arch/powerpc/platforms/cell/interrupt.c16
-rw-r--r--arch/powerpc/platforms/cell/interrupt.h2
-rw-r--r--arch/powerpc/platforms/cell/io-workarounds.c346
-rw-r--r--arch/powerpc/platforms/cell/iommu.c1049
-rw-r--r--arch/powerpc/platforms/cell/iommu.h65
-rw-r--r--arch/powerpc/platforms/cell/pervasive.c101
-rw-r--r--arch/powerpc/platforms/cell/pmu.c429
-rw-r--r--arch/powerpc/platforms/cell/setup.c78
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c415
-rw-r--r--arch/powerpc/platforms/cell/spu_coredump.c81
-rw-r--r--arch/powerpc/platforms/cell/spu_priv1_mmio.c428
-rw-r--r--arch/powerpc/platforms/cell/spu_priv1_mmio.h26
-rw-r--r--arch/powerpc/platforms/cell/spufs/Makefile2
-rw-r--r--arch/powerpc/platforms/cell/spufs/backing_ops.c31
-rw-r--r--arch/powerpc/platforms/cell/spufs/context.c27
-rw-r--r--arch/powerpc/platforms/cell/spufs/coredump.c238
-rw-r--r--arch/powerpc/platforms/cell/spufs/file.c536
-rw-r--r--arch/powerpc/platforms/cell/spufs/hw_ops.c51
-rw-r--r--arch/powerpc/platforms/cell/spufs/inode.c58
-rw-r--r--arch/powerpc/platforms/cell/spufs/run.c149
-rw-r--r--arch/powerpc/platforms/cell/spufs/spufs.h33
-rw-r--r--arch/powerpc/platforms/cell/spufs/switch.c63
-rw-r--r--arch/powerpc/platforms/chrp/chrp.h1
-rw-r--r--arch/powerpc/platforms/chrp/pci.c9
-rw-r--r--arch/powerpc/platforms/chrp/setup.c2
-rw-r--r--arch/powerpc/platforms/embedded6xx/Kconfig30
-rw-r--r--arch/powerpc/platforms/embedded6xx/Makefile1
-rw-r--r--arch/powerpc/platforms/embedded6xx/linkstation.c211
-rw-r--r--arch/powerpc/platforms/embedded6xx/ls_uart.c131
-rw-r--r--arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c94
-rw-r--r--arch/powerpc/platforms/iseries/Makefile8
-rw-r--r--arch/powerpc/platforms/iseries/dt.c15
-rw-r--r--arch/powerpc/platforms/iseries/iommu.c16
-rw-r--r--arch/powerpc/platforms/iseries/ksyms.c6
-rw-r--r--arch/powerpc/platforms/iseries/misc.S35
-rw-r--r--arch/powerpc/platforms/iseries/pci.c372
-rw-r--r--arch/powerpc/platforms/iseries/setup.c48
-rw-r--r--arch/powerpc/platforms/iseries/viopath.c3
-rw-r--r--arch/powerpc/platforms/maple/maple.h2
-rw-r--r--arch/powerpc/platforms/maple/pci.c47
-rw-r--r--arch/powerpc/platforms/maple/setup.c2
-rw-r--r--arch/powerpc/platforms/pasemi/pasemi.h1
-rw-r--r--arch/powerpc/platforms/pasemi/pci.c8
-rw-r--r--arch/powerpc/platforms/pasemi/setup.c17
-rw-r--r--arch/powerpc/platforms/powermac/feature.c8
-rw-r--r--arch/powerpc/platforms/powermac/pci.c35
-rw-r--r--arch/powerpc/platforms/powermac/pmac.h2
-rw-r--r--arch/powerpc/platforms/powermac/setup.c7
-rw-r--r--arch/powerpc/platforms/ps3/Kconfig43
-rw-r--r--arch/powerpc/platforms/ps3/Makefile4
-rw-r--r--arch/powerpc/platforms/ps3/exports.c27
-rw-r--r--arch/powerpc/platforms/ps3/htab.c277
-rw-r--r--arch/powerpc/platforms/ps3/hvcall.S804
-rw-r--r--arch/powerpc/platforms/ps3/interrupt.c575
-rw-r--r--arch/powerpc/platforms/ps3/mm.c831
-rw-r--r--arch/powerpc/platforms/ps3/os-area.c259
-rw-r--r--arch/powerpc/platforms/ps3/platform.h68
-rw-r--r--arch/powerpc/platforms/ps3/repository.c840
-rw-r--r--arch/powerpc/platforms/ps3/setup.c173
-rw-r--r--arch/powerpc/platforms/ps3/smp.c158
-rw-r--r--arch/powerpc/platforms/ps3/spu.c613
-rw-r--r--arch/powerpc/platforms/ps3/time.c104
-rw-r--r--arch/powerpc/platforms/pseries/iommu.c90
-rw-r--r--arch/powerpc/platforms/pseries/lpar.c4
-rw-r--r--arch/powerpc/platforms/pseries/pci.c35
-rw-r--r--arch/powerpc/platforms/pseries/pci_dlpar.c6
-rw-r--r--arch/powerpc/platforms/pseries/reconfig.c3
-rw-r--r--arch/powerpc/platforms/pseries/setup.c5
-rw-r--r--arch/powerpc/platforms/pseries/xics.c68
-rw-r--r--arch/powerpc/sysdev/Makefile5
-rw-r--r--arch/powerpc/sysdev/dart_iommu.c34
-rw-r--r--arch/powerpc/sysdev/dcr-low.S39
-rw-r--r--arch/powerpc/sysdev/dcr.c137
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c28
-rw-r--r--arch/powerpc/sysdev/mpic.c172
-rw-r--r--arch/powerpc/sysdev/qe_lib/qe.c3
-rw-r--r--arch/powerpc/sysdev/qe_lib/ucc_fast.c4
-rw-r--r--arch/powerpc/sysdev/qe_lib/ucc_slow.c4
-rw-r--r--arch/powerpc/sysdev/rom.c31
-rw-r--r--arch/powerpc/sysdev/todc.c392
-rw-r--r--arch/powerpc/sysdev/tsi108_pci.c48
-rw-r--r--arch/powerpc/xmon/Makefile9
-rw-r--r--arch/powerpc/xmon/dis-asm.h31
-rw-r--r--arch/powerpc/xmon/ppc-dis.c29
-rw-r--r--arch/powerpc/xmon/ppc-opc.c778
-rw-r--r--arch/powerpc/xmon/ppc.h39
-rw-r--r--arch/powerpc/xmon/spu-dis.c248
-rw-r--r--arch/powerpc/xmon/spu-insns.h410
-rw-r--r--arch/powerpc/xmon/spu-opc.c44
-rw-r--r--arch/powerpc/xmon/spu.h126
-rw-r--r--arch/powerpc/xmon/xmon.c356
-rw-r--r--arch/ppc/.gitignore1
-rw-r--r--arch/ppc/Kconfig11
-rw-r--r--arch/ppc/boot/images/.gitignore6
-rw-r--r--arch/ppc/boot/lib/.gitignore3
-rw-r--r--arch/ppc/boot/utils/.gitignore3
-rw-r--r--arch/ppc/kernel/setup.c2
-rw-r--r--arch/ppc/kernel/traps.c2
-rw-r--r--arch/ppc/platforms/4xx/bubinga.c2
-rw-r--r--arch/ppc/platforms/4xx/cpci405.c2
-rw-r--r--arch/ppc/platforms/4xx/ep405.c2
-rw-r--r--arch/ppc/platforms/83xx/mpc834x_sys.c4
-rw-r--r--arch/ppc/platforms/85xx/mpc8540_ads.c4
-rw-r--r--arch/ppc/platforms/85xx/mpc8560_ads.c4
-rw-r--r--arch/ppc/platforms/85xx/mpc85xx_cds_common.c6
-rw-r--r--arch/ppc/platforms/85xx/sbc8560.c2
-rw-r--r--arch/ppc/platforms/85xx/stx_gp3.c2
-rw-r--r--arch/ppc/platforms/85xx/tqm85xx.c4
-rw-r--r--arch/ppc/platforms/mpc8272ads_setup.c6
-rw-r--r--arch/ppc/platforms/mpc866ads_setup.c4
-rw-r--r--arch/ppc/syslib/mpc8xx_devices.c8
-rw-r--r--arch/s390/Kconfig5
-rw-r--r--arch/s390/Makefile3
-rw-r--r--arch/s390/kernel/Makefile2
-rw-r--r--arch/s390/kernel/cpcmd.c18
-rw-r--r--arch/s390/kernel/head.S21
-rw-r--r--arch/s390/kernel/head31.S8
-rw-r--r--arch/s390/kernel/head64.S17
-rw-r--r--arch/s390/kernel/ipl.c185
-rw-r--r--arch/s390/kernel/machine_kexec.c78
-rw-r--r--arch/s390/kernel/reipl.S17
-rw-r--r--arch/s390/kernel/reipl64.S16
-rw-r--r--arch/s390/kernel/relocate_kernel.S5
-rw-r--r--arch/s390/kernel/relocate_kernel64.S5
-rw-r--r--arch/s390/kernel/reset.S48
-rw-r--r--arch/s390/kernel/setup.c66
-rw-r--r--arch/s390/kernel/smp.c117
-rw-r--r--arch/s390/kernel/traps.c30
-rw-r--r--arch/s390/lib/Makefile2
-rw-r--r--arch/s390/lib/uaccess_mvcos.c27
-rw-r--r--arch/s390/lib/uaccess_pt.c153
-rw-r--r--arch/s390/lib/uaccess_std.c67
-rw-r--r--arch/s390/mm/extmem.c38
-rw-r--r--arch/s390/mm/fault.c28
-rw-r--r--block/Kconfig6
-rw-r--r--block/blktrace.c35
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/acpi/dock.c1
-rw-r--r--drivers/ata/Kconfig35
-rw-r--r--drivers/ata/Makefile4
-rw-r--r--drivers/ata/ahci.c229
-rw-r--r--drivers/ata/ata_generic.c11
-rw-r--r--drivers/ata/ata_piix.c194
-rw-r--r--drivers/ata/libata-core.c536
-rw-r--r--drivers/ata/libata-eh.c108
-rw-r--r--drivers/ata/libata-scsi.c328
-rw-r--r--drivers/ata/libata-sff.c43
-rw-r--r--drivers/ata/libata.h24
-rw-r--r--drivers/ata/pata_ali.c140
-rw-r--r--drivers/ata/pata_amd.c26
-rw-r--r--drivers/ata/pata_artop.c1
-rw-r--r--drivers/ata/pata_atiixp.c9
-rw-r--r--drivers/ata/pata_cmd64x.c23
-rw-r--r--drivers/ata/pata_cs5520.c25
-rw-r--r--drivers/ata/pata_cs5530.c100
-rw-r--r--drivers/ata/pata_cs5535.c9
-rw-r--r--drivers/ata/pata_cypress.c9
-rw-r--r--drivers/ata/pata_efar.c7
-rw-r--r--drivers/ata/pata_hpt366.c58
-rw-r--r--drivers/ata/pata_hpt37x.c1
-rw-r--r--drivers/ata/pata_hpt3x2n.c1
-rw-r--r--drivers/ata/pata_hpt3x3.c47
-rw-r--r--drivers/ata/pata_isapnp.c1
-rw-r--r--drivers/ata/pata_it821x.c19
-rw-r--r--drivers/ata/pata_ixp4xx_cf.c271
-rw-r--r--drivers/ata/pata_jmicron.c36
-rw-r--r--drivers/ata/pata_legacy.c1
-rw-r--r--drivers/ata/pata_marvell.c224
-rw-r--r--drivers/ata/pata_mpiix.c9
-rw-r--r--drivers/ata/pata_netcell.c8
-rw-r--r--drivers/ata/pata_ns87410.c9
-rw-r--r--drivers/ata/pata_oldpiix.c5
-rw-r--r--drivers/ata/pata_opti.c34
-rw-r--r--drivers/ata/pata_optidma.c9
-rw-r--r--drivers/ata/pata_pcmcia.c1
-rw-r--r--drivers/ata/pata_pdc2027x.c3
-rw-r--r--drivers/ata/pata_pdc202xx_old.c65
-rw-r--r--drivers/ata/pata_platform.c295
-rw-r--r--drivers/ata/pata_qdi.c1
-rw-r--r--drivers/ata/pata_radisys.c5
-rw-r--r--drivers/ata/pata_rz1000.c49
-rw-r--r--drivers/ata/pata_sc1200.c9
-rw-r--r--drivers/ata/pata_serverworks.c33
-rw-r--r--drivers/ata/pata_sil680.c83
-rw-r--r--drivers/ata/pata_sis.c7
-rw-r--r--drivers/ata/pata_sl82c105.c1
-rw-r--r--drivers/ata/pata_triflex.c9
-rw-r--r--drivers/ata/pata_via.c109
-rw-r--r--drivers/ata/pata_winbond.c306
-rw-r--r--drivers/ata/sata_nv.c1044
-rw-r--r--drivers/ata/sata_promise.c46
-rw-r--r--drivers/ata/sata_sil.c16
-rw-r--r--drivers/ata/sata_sil24.c18
-rw-r--r--drivers/ata/sata_sis.c17
-rw-r--r--drivers/base/cpu.c1
-rw-r--r--drivers/block/viodasd.c49
-rw-r--r--drivers/char/hpet.c1
-rw-r--r--drivers/char/hw_random/core.c1
-rw-r--r--drivers/char/tpm/tpm.h1
-rw-r--r--drivers/hwmon/abituguru.c1
-rw-r--r--drivers/hwmon/hdaps.c1
-rw-r--r--drivers/ide/pci/via82cxxx.c4
-rw-r--r--drivers/infiniband/ulp/iser/iser_memory.c1
-rw-r--r--drivers/isdn/divert/isdn_divert.c2
-rw-r--r--drivers/leds/ledtrig-ide-disk.c1
-rw-r--r--drivers/leds/ledtrig-timer.c1
-rw-r--r--drivers/macintosh/Kconfig7
-rw-r--r--drivers/macintosh/Makefile1
-rw-r--r--drivers/macintosh/rack-meter.c612
-rw-r--r--drivers/macintosh/smu.c3
-rw-r--r--drivers/macintosh/therm_adt746x.c2
-rw-r--r--drivers/macintosh/therm_pm72.c5
-rw-r--r--drivers/macintosh/therm_windtunnel.c7
-rw-r--r--drivers/media/dvb/cinergyT2/cinergyT2.c1
-rw-r--r--drivers/net/ehea/ehea_qmr.c1
-rw-r--r--drivers/net/ibm_emac/ibm_emac_mal.h6
-rw-r--r--drivers/net/ibmveth.c4
-rw-r--r--drivers/net/ibmveth.h1
-rw-r--r--drivers/net/lance.c1
-rw-r--r--drivers/net/ne3210.c1
-rw-r--r--drivers/net/phy/fixed.c2
-rw-r--r--drivers/net/sk98lin/skge.c1
-rw-r--r--drivers/net/spider_net.c18
-rw-r--r--drivers/net/starfire.c1
-rw-r--r--drivers/net/sun3lance.c1
-rw-r--r--drivers/net/sungem.c1
-rw-r--r--drivers/net/sunhme.c6
-rw-r--r--drivers/net/tokenring/ibmtr.c2
-rw-r--r--drivers/net/tulip/de4x5.c8
-rw-r--r--drivers/net/typhoon.c1
-rw-r--r--drivers/pci/access.c1
-rw-r--r--drivers/ps3/Makefile1
-rw-r--r--drivers/ps3/system-bus.c362
-rw-r--r--drivers/s390/block/dasd.c16
-rw-r--r--drivers/s390/block/dasd_devmap.c36
-rw-r--r--drivers/s390/char/con3215.c50
-rw-r--r--drivers/s390/char/sclp_quiesce.c37
-rw-r--r--drivers/s390/cio/chsc.c82
-rw-r--r--drivers/s390/cio/cio.c128
-rw-r--r--drivers/s390/cio/css.h3
-rw-r--r--drivers/s390/cio/device.c17
-rw-r--r--drivers/s390/cio/device_fsm.c27
-rw-r--r--drivers/s390/cio/device_id.c10
-rw-r--r--drivers/s390/cio/device_pgid.c30
-rw-r--r--drivers/s390/cio/device_status.c3
-rw-r--r--drivers/s390/cio/qdio.c8
-rw-r--r--drivers/s390/cio/qdio.h4
-rw-r--r--drivers/s390/crypto/ap_bus.c10
-rw-r--r--drivers/s390/net/lcs.c78
-rw-r--r--drivers/s390/net/lcs.h25
-rw-r--r--drivers/s390/net/qeth.h2
-rw-r--r--drivers/s390/net/qeth_main.c6
-rw-r--r--drivers/scsi/scsi_transport_sas.c1
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm2.c2
-rw-r--r--drivers/serial/mpc52xx_uart.c469
-rw-r--r--drivers/spi/spi_butterfly.c1
-rw-r--r--drivers/video/platinumfb.c5
-rw-r--r--drivers/w1/slaves/w1_therm.c1
-rw-r--r--fs/9p/conv.c1
-rw-r--r--fs/9p/fcall.c1
-rw-r--r--fs/9p/fid.c1
-rw-r--r--fs/9p/v9fs.c1
-rw-r--r--fs/9p/vfs_dir.c1
-rw-r--r--fs/9p/vfs_file.c1
-rw-r--r--fs/binfmt_elf.c8
-rw-r--r--fs/compat.c2
-rw-r--r--fs/configfs/dir.c9
-rw-r--r--fs/gfs2/locking/dlm/plock.c1
-rw-r--r--fs/inotify.c1
-rw-r--r--fs/jffs2/acl.c1
-rw-r--r--fs/jffs2/wbuf.c1
-rw-r--r--fs/jfs/ioctl.c1
-rw-r--r--fs/ocfs2/alloc.c90
-rw-r--r--fs/ocfs2/alloc.h2
-rw-r--r--fs/ocfs2/aops.c22
-rw-r--r--fs/ocfs2/aops.h2
-rw-r--r--fs/ocfs2/dir.c33
-rw-r--r--fs/ocfs2/dir.h2
-rw-r--r--fs/ocfs2/dlm/dlmdomain.c3
-rw-r--r--fs/ocfs2/dlmglue.c60
-rw-r--r--fs/ocfs2/dlmglue.h9
-rw-r--r--fs/ocfs2/export.c2
-rw-r--r--fs/ocfs2/file.c343
-rw-r--r--fs/ocfs2/file.h11
-rw-r--r--fs/ocfs2/inode.c33
-rw-r--r--fs/ocfs2/inode.h9
-rw-r--r--fs/ocfs2/ioctl.c10
-rw-r--r--fs/ocfs2/journal.c271
-rw-r--r--fs/ocfs2/journal.h78
-rw-r--r--fs/ocfs2/localalloc.c126
-rw-r--r--fs/ocfs2/localalloc.h3
-rw-r--r--fs/ocfs2/mmap.c11
-rw-r--r--fs/ocfs2/namei.c296
-rw-r--r--fs/ocfs2/namei.h2
-rw-r--r--fs/ocfs2/ocfs2.h4
-rw-r--r--fs/ocfs2/suballoc.c174
-rw-r--r--fs/ocfs2/suballoc.h16
-rw-r--r--fs/ocfs2/super.c32
-rw-r--r--fs/ocfs2/symlink.c4
-rw-r--r--fs/partitions/mac.c2
-rw-r--r--fs/proc/root.c1
-rw-r--r--fs/super.c18
-rw-r--r--fs/sync.c1
-rw-r--r--fs/utimes.c1
-rw-r--r--include/asm-arm/arch-ixp4xx/platform.h13
-rw-r--r--include/asm-avr32/types.h5
-rw-r--r--include/asm-h8300/types.h6
-rw-r--r--include/asm-i386/types.h10
-rw-r--r--include/asm-m68knommu/dma-mapping.h3
-rw-r--r--include/asm-m68knommu/m520xsim.h12
-rw-r--r--include/asm-m68knommu/scatterlist.h2
-rw-r--r--include/asm-mips/atomic.h39
-rw-r--r--include/asm-mips/barrier.h132
-rw-r--r--include/asm-mips/bitops.h27
-rw-r--r--include/asm-mips/compat.h68
-rw-r--r--include/asm-mips/futex.h22
-rw-r--r--include/asm-mips/sn/klconfig.h2
-rw-r--r--include/asm-mips/spinlock.h53
-rw-r--r--include/asm-mips/system.h156
-rw-r--r--include/asm-mips/types.h10
-rw-r--r--include/asm-powerpc/Kbuild1
-rw-r--r--include/asm-powerpc/cell-pmu.h113
-rw-r--r--include/asm-powerpc/cputable.h31
-rw-r--r--include/asm-powerpc/dbdma.h8
-rw-r--r--include/asm-powerpc/dcr-mmio.h51
-rw-r--r--include/asm-powerpc/dcr-native.h39
-rw-r--r--include/asm-powerpc/dcr.h42
-rw-r--r--include/asm-powerpc/device.h19
-rw-r--r--include/asm-powerpc/dma-mapping.h182
-rw-r--r--include/asm-powerpc/eeh.h213
-rw-r--r--include/asm-powerpc/elf.h13
-rw-r--r--include/asm-powerpc/firmware.h17
-rw-r--r--include/asm-powerpc/hw_irq.h44
-rw-r--r--include/asm-powerpc/ibmebus.h1
-rw-r--r--include/asm-powerpc/ide.h8
-rw-r--r--include/asm-powerpc/immap_qe.h17
-rw-r--r--include/asm-powerpc/io-defs.h59
-rw-r--r--include/asm-powerpc/io.h845
-rw-r--r--include/asm-powerpc/iommu.h34
-rw-r--r--include/asm-powerpc/irq.h4
-rw-r--r--include/asm-powerpc/iseries/iommu.h4
-rw-r--r--include/asm-powerpc/lv1call.h345
-rw-r--r--include/asm-powerpc/machdep.h18
-rw-r--r--include/asm-powerpc/mmu.h15
-rw-r--r--include/asm-powerpc/mpc52xx.h254
-rw-r--r--include/asm-powerpc/mpc85xx.h8
-rw-r--r--include/asm-powerpc/mpic.h39
-rw-r--r--include/asm-powerpc/of_device.h36
-rw-r--r--include/asm-powerpc/of_platform.h60
-rw-r--r--include/asm-powerpc/oprofile_impl.h3
-rw-r--r--include/asm-powerpc/paca.h3
-rw-r--r--include/asm-powerpc/pci-bridge.h1
-rw-r--r--include/asm-powerpc/pci.h10
-rw-r--r--include/asm-powerpc/ppc-pci.h13
-rw-r--r--include/asm-powerpc/processor.h4
-rw-r--r--include/asm-powerpc/prom.h15
-rw-r--r--include/asm-powerpc/ps3.h462
-rw-r--r--include/asm-powerpc/rtas.h2
-rw-r--r--include/asm-powerpc/sparsemem.h6
-rw-r--r--include/asm-powerpc/spu.h30
-rw-r--r--include/asm-powerpc/spu_csa.h1
-rw-r--r--include/asm-powerpc/spu_info.h54
-rw-r--r--include/asm-powerpc/spu_priv1.h46
-rw-r--r--include/asm-powerpc/todc.h487
-rw-r--r--include/asm-powerpc/topology.h7
-rw-r--r--include/asm-powerpc/tsi108.h4
-rw-r--r--include/asm-powerpc/types.h10
-rw-r--r--include/asm-powerpc/uaccess.h4
-rw-r--r--include/asm-powerpc/unistd.h12
-rw-r--r--include/asm-powerpc/vio.h1
-rw-r--r--include/asm-powerpc/xmon.h2
-rw-r--r--include/asm-ppc/io.h28
-rw-r--r--include/asm-ppc/m48t35.h2
-rw-r--r--include/asm-ppc/mpc52xx.h11
-rw-r--r--include/asm-ppc/mpc83xx.h8
-rw-r--r--include/asm-ppc/mpc85xx.h8
-rw-r--r--include/asm-ppc/pci-bridge.h1
-rw-r--r--include/asm-s390/cio.h9
-rw-r--r--include/asm-s390/cpcmd.h10
-rw-r--r--include/asm-s390/kexec.h2
-rw-r--r--include/asm-s390/lowcore.h8
-rw-r--r--include/asm-s390/pgtable.h15
-rw-r--r--include/asm-s390/reset.h23
-rw-r--r--include/asm-s390/setup.h15
-rw-r--r--include/asm-s390/smp.h8
-rw-r--r--include/asm-s390/system.h10
-rw-r--r--include/asm-s390/termios.h34
-rw-r--r--include/asm-s390/types.h10
-rw-r--r--include/asm-s390/uaccess.h18
-rw-r--r--include/asm-s390/zcrypt.h91
-rw-r--r--include/asm-sh/types.h10
-rw-r--r--include/asm-x86_64/elf.h1
-rw-r--r--include/asm-x86_64/types.h3
-rw-r--r--include/asm-x86_64/uaccess.h1
-rw-r--r--include/linux/acct.h1
-rw-r--r--include/linux/ata.h14
-rw-r--r--include/linux/cpu.h8
-rw-r--r--include/linux/elf.h7
-rw-r--r--include/linux/fs.h37
-rw-r--r--include/linux/igmp.h1
-rw-r--r--include/linux/kernelcapi.h2
-rw-r--r--include/linux/libata.h52
-rw-r--r--include/linux/module.h13
-rw-r--r--include/linux/netdevice.h1
-rw-r--r--include/linux/netfilter_ipv4/ip_conntrack.h1
-rw-r--r--include/linux/pata_platform.h13
-rw-r--r--include/linux/poll.h3
-rw-r--r--include/linux/radix-tree.h1
-rw-r--r--include/linux/skbuff.h22
-rw-r--r--include/linux/types.h14
-rw-r--r--include/net/inet_connection_sock.h1
-rw-r--r--include/net/irda/timer.h1
-rw-r--r--include/net/netfilter/nf_conntrack.h1
-rw-r--r--include/net/netlink.h1
-rw-r--r--include/net/sock.h1
-rw-r--r--include/net/udp.h1
-rw-r--r--include/scsi/libiscsi.h2
-rw-r--r--include/sound/pcm.h1
-rw-r--r--kernel/auditsc.c1
-rw-r--r--kernel/latency.c1
-rw-r--r--kernel/module.c15
-rw-r--r--lib/iomap.c32
-rw-r--r--lib/random32.c1
-rw-r--r--mm/filemap.c1
-rw-r--r--net/appletalk/ddp.c1
-rw-r--r--net/core/kmap_skb.h19
-rw-r--r--net/core/skbuff.c3
-rw-r--r--net/core/sock.c1
-rw-r--r--net/dccp/ccids/Kconfig33
-rw-r--r--net/dccp/ccids/ccid3.c119
-rw-r--r--net/dccp/ccids/ccid3.h2
-rw-r--r--net/dccp/ccids/lib/tfrc_equation.c222
-rw-r--r--net/ieee80211/ieee80211_crypt_tkip.c1
-rw-r--r--net/ieee80211/ieee80211_crypt_wep.c1
-rw-r--r--net/ipv4/ip_output.c1
-rw-r--r--net/ipv4/ipvs/ip_vs_lblc.c1
-rw-r--r--net/ipv4/ipvs/ip_vs_lblcr.c1
-rw-r--r--net/irda/discovery.c1
-rw-r--r--net/irda/iriap.c1
-rw-r--r--net/irda/irttp.c1
-rw-r--r--net/netfilter/nf_conntrack_core.c1
-rw-r--r--net/netfilter/x_tables.c1
-rw-r--r--net/netfilter/xt_hashlimit.c1
-rw-r--r--net/packet/af_packet.c1
-rw-r--r--net/xfrm/xfrm_user.c50
-rw-r--r--security/selinux/avc.c2
-rw-r--r--security/selinux/hooks.c2
-rw-r--r--security/selinux/include/avc.h8
-rw-r--r--sound/oss/cs46xx.c1
-rw-r--r--sound/oss/dmabuf.c1
-rw-r--r--sound/oss/emu10k1/audio.c1
-rw-r--r--sound/oss/es1371.c1
-rw-r--r--sound/oss/i810_audio.c1
-rw-r--r--sound/oss/soundcard.c1
-rw-r--r--sound/oss/sscape.c1
-rw-r--r--sound/oss/trident.c1
588 files changed, 32298 insertions, 9297 deletions
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index 4ac2d641fcb6..b3bd36668db3 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -6,6 +6,8 @@
6 IBM Corp. 6 IBM Corp.
7(c) 2005 Becky Bruce <becky.bruce at freescale.com>, 7(c) 2005 Becky Bruce <becky.bruce at freescale.com>,
8 Freescale Semiconductor, FSL SOC and 32-bit additions 8 Freescale Semiconductor, FSL SOC and 32-bit additions
9(c) 2006 MontaVista Software, Inc.
10 Flash chip node definition
9 11
10 May 18, 2005: Rev 0.1 - Initial draft, no chapter III yet. 12 May 18, 2005: Rev 0.1 - Initial draft, no chapter III yet.
11 13
@@ -1693,6 +1695,43 @@ platforms are moved over to use the flattened-device-tree model.
1693 }; 1695 };
1694 }; 1696 };
1695 1697
1698 g) Flash chip nodes
1699
1700 Flash chips (Memory Technology Devices) are often used for solid state
1701 file systems on embedded devices.
1702
1703 Required properties:
1704
1705 - device_type : has to be "rom"
1706 - compatible : Should specify what this ROM device is compatible with
1707 (i.e. "onenand"). Currently, this is most likely to be "direct-mapped"
1708 (which corresponds to the MTD physmap mapping driver).
1709 - regs : Offset and length of the register set (or memory mapping) for
1710 the device.
1711
1712 Recommended properties :
1713
1714 - bank-width : Width of the flash data bus in bytes. Required
1715 for the NOR flashes (compatible == "direct-mapped" and others) ONLY.
1716 - partitions : Several pairs of 32-bit values where the first value is
1717 partition's offset from the start of the device and the second one is
1718 partition size in bytes with LSB used to signify a read only
1719 partititon (so, the parition size should always be an even number).
1720 - partition-names : The list of concatenated zero terminated strings
1721 representing the partition names.
1722
1723 Example:
1724
1725 flash@ff000000 {
1726 device_type = "rom";
1727 compatible = "direct-mapped";
1728 regs = <ff000000 01000000>;
1729 bank-width = <4>;
1730 partitions = <00000000 00f80000
1731 00f80000 00080001>;
1732 partition-names = "fs\0firmware";
1733 };
1734
1696 More devices will be defined as this spec matures. 1735 More devices will be defined as this spec matures.
1697 1736
1698 1737
diff --git a/Documentation/powerpc/mpc52xx-device-tree-bindings.txt b/Documentation/powerpc/mpc52xx-device-tree-bindings.txt
new file mode 100644
index 000000000000..d077d764f82b
--- /dev/null
+++ b/Documentation/powerpc/mpc52xx-device-tree-bindings.txt
@@ -0,0 +1,189 @@
1MPC52xx Device Tree Bindings
2----------------------------
3
4(c) 2006 Secret Lab Technologies Ltd
5Grant Likely <grant.likely at secretlab.ca>
6
7I - Introduction
8================
9Boards supported by the arch/powerpc architecture require device tree be
10passed by the boot loader to the kernel at boot time. The device tree
11describes what devices are present on the board and how they are
12connected. The device tree can either be passed as a binary blob (as
13described in Documentation/powerpc/booting-without-of.txt), or passed
14by Open Firmare (IEEE 1275) compatible firmware using an OF compatible
15client interface API.
16
17This document specifies the requirements on the device-tree for mpc52xx
18based boards. These requirements are above and beyond the details
19specified in either the OpenFirmware spec or booting-without-of.txt
20
21All new mpc52xx-based boards are expected to match this document. In
22cases where this document is not sufficient to support a new board port,
23this document should be updated as part of adding the new board support.
24
25II - Philosophy
26===============
27The core of this document is naming convention. The whole point of
28defining this convention is to reduce or eliminate the number of
29special cases required to support a 52xx board. If all 52xx boards
30follow the same convention, then generic 52xx support code will work
31rather than coding special cases for each new board.
32
33This section tries to capture the thought process behind why the naming
34convention is what it is.
35
361. Node names
37-------------
38There is strong convention/requirements already established for children
39of the root node. 'cpus' describes the processor cores, 'memory'
40describes memory, and 'chosen' provides boot configuration. Other nodes
41are added to describe devices attached to the processor local bus.
42Following convention already established with other system-on-chip
43processors, MPC52xx boards must have an 'soc5200' node as a child of the
44root node.
45
46The soc5200 node holds child nodes for all on chip devices. Child nodes
47are typically named after the configured function. ie. the FEC node is
48named 'ethernet', and a PSC in uart mode is named 'serial'.
49
502. device_type property
51-----------------------
52similar to the node name convention above; the device_type reflects the
53configured function of a device. ie. 'serial' for a uart and 'spi' for
54an spi controller. However, while node names *should* reflect the
55configured function, device_type *must* match the configured function
56exactly.
57
583. compatible property
59----------------------
60Since device_type isn't enough to match devices to drivers, there also
61needs to be a naming convention for the compatible property. Compatible
62is an list of device descriptions sorted from specific to generic. For
63the mpc52xx, the required format for each compatible value is
64<chip>-<device>[-<mode>]. At the minimum, the list shall contain two
65items; the first specifying the exact chip, and the second specifying
66mpc52xx for the chip.
67
68ie. ethernet on mpc5200b: compatible = "mpc5200b-ethernet\0mpc52xx-ethernet"
69
70The idea here is that most drivers will match to the most generic field
71in the compatible list (mpc52xx-*), but can also test the more specific
72field for enabling bug fixes or extra features.
73
74Modal devices, like PSCs, also append the configured function to the
75end of the compatible field. ie. A PSC in i2s mode would specify
76"mpc52xx-psc-i2s", not "mpc52xx-i2s". This convention is chosen to
77avoid naming conflicts with non-psc devices providing the same
78function. For example, "mpc52xx-spi" and "mpc52xx-psc-spi" describe
79the mpc5200 simple spi device and a PSC spi mode respectively.
80
81If the soc device is more generic and present on other SOCs, the
82compatible property can specify the more generic device type also.
83
84ie. mscan: compatible = "mpc5200-mscan\0mpc52xx-mscan\0fsl,mscan";
85
86At the time of writing, exact chip may be either 'mpc5200' or
87'mpc5200b'.
88
89Device drivers should always try to match as generically as possible.
90
91III - Structure
92===============
93The device tree for an mpc52xx board follows the structure defined in
94booting-without-of.txt with the following additional notes:
95
960) the root node
97----------------
98Typical root description node; see booting-without-of
99
1001) The cpus node
101----------------
102The cpus node follows the basic layout described in booting-without-of.
103The bus-frequency property holds the XLB bus frequency
104The clock-frequency property holds the core frequency
105
1062) The memory node
107------------------
108Typical memory description node; see booting-without-of.
109
1103) The soc5200 node
111-------------------
112This node describes the on chip SOC peripherals. Every mpc52xx based
113board will have this node, and as such there is a common naming
114convention for SOC devices.
115
116Required properties:
117name type description
118---- ---- -----------
119device_type string must be "soc"
120ranges int should be <0 baseaddr baseaddr+10000>
121reg int must be <baseaddr 10000>
122
123Recommended properties:
124name type description
125---- ---- -----------
126compatible string should be "<chip>-soc\0mpc52xx-soc"
127 ie. "mpc5200b-soc\0mpc52xx-soc"
128#interrupt-cells int must be <3>. If it is not defined
129 here then it must be defined in every
130 soc device node.
131bus-frequency int IPB bus frequency in HZ. Clock rate
132 used by most of the soc devices.
133 Defining it here avoids needing it
134 added to every device node.
135
1364) soc5200 child nodes
137----------------------
138Any on chip SOC devices available to Linux must appear as soc5200 child nodes.
139
140Note: in the tables below, '*' matches all <chip> values. ie.
141*-pic would translate to "mpc5200-pic\0mpc52xx-pic"
142
143Required soc5200 child nodes:
144name device_type compatible Description
145---- ----------- ---------- -----------
146cdm@<addr> cdm *-cmd Clock Distribution
147pic@<addr> interrupt-controller *-pic need an interrupt
148 controller to boot
149bestcomm@<addr> dma-controller *-bestcomm 52xx pic also requires
150 the bestcomm device
151
152Recommended soc5200 child nodes; populate as needed for your board
153name device_type compatible Description
154---- ----------- ---------- -----------
155gpt@<addr> gpt *-gpt General purpose timers
156rtc@<addr> rtc *-rtc Real time clock
157mscan@<addr> mscan *-mscan CAN bus controller
158pci@<addr> pci *-pci PCI bridge
159serial@<addr> serial *-psc-uart PSC in serial mode
160i2s@<addr> i2s *-psc-i2s PSC in i2s mode
161ac97@<addr> ac97 *-psc-ac97 PSC in ac97 mode
162spi@<addr> spi *-psc-spi PSC in spi mode
163irda@<addr> irda *-psc-irda PSC in IrDA mode
164spi@<addr> spi *-spi MPC52xx spi device
165ethernet@<addr> network *-fec MPC52xx ethernet device
166ata@<addr> ata *-ata IDE ATA interface
167i2c@<addr> i2c *-i2c I2C controller
168usb@<addr> usb-ohci-be *-ohci,ohci-be USB controller
169xlb@<addr> xlb *-xlb XLB arbritrator
170
171IV - Extra Notes
172================
173
1741. Interrupt mapping
175--------------------
176The mpc52xx pic driver splits hardware IRQ numbers into two levels. The
177split reflects the layout of the PIC hardware itself, which groups
178interrupts into one of three groups; CRIT, MAIN or PERP. Also, the
179Bestcomm dma engine has it's own set of interrupt sources which are
180cascaded off of peripheral interrupt 0, which the driver interprets as a
181fourth group, SDMA.
182
183The interrupts property for device nodes using the mpc52xx pic consists
184of three cells; <L1 L2 level>
185
186 L1 := [CRIT=0, MAIN=1, PERP=2, SDMA=3]
187 L2 := interrupt number; directly mapped from the value in the
188 "ICTL PerStat, MainStat, CritStat Encoded Register"
189 level := [LEVEL_HIGH=0, EDGE_RISING=1, EDGE_FALLING=2, LEVEL_LOW=3]
diff --git a/Documentation/s390/CommonIO b/Documentation/s390/CommonIO
index d684a6ac69a8..22f82f21bc60 100644
--- a/Documentation/s390/CommonIO
+++ b/Documentation/s390/CommonIO
@@ -74,7 +74,7 @@ Command line parameters
74 74
75 Note: While already known devices can be added to the list of devices to be 75 Note: While already known devices can be added to the list of devices to be
76 ignored, there will be no effect on then. However, if such a device 76 ignored, there will be no effect on then. However, if such a device
77 disappears and then reappeares, it will then be ignored. 77 disappears and then reappears, it will then be ignored.
78 78
79 For example, 79 For example,
80 "echo add 0.0.a000-0.0.accc, 0.0.af00-0.0.afff > /proc/cio_ignore" 80 "echo add 0.0.a000-0.0.accc, 0.0.af00-0.0.afff > /proc/cio_ignore"
@@ -82,7 +82,7 @@ Command line parameters
82 devices. 82 devices.
83 83
84 The devices can be specified either by bus id (0.0.abcd) or, for 2.4 backward 84 The devices can be specified either by bus id (0.0.abcd) or, for 2.4 backward
85 compatibilty, by the device number in hexadecimal (0xabcd or abcd). 85 compatibility, by the device number in hexadecimal (0xabcd or abcd).
86 86
87 87
88* /proc/s390dbf/cio_*/ (S/390 debug feature) 88* /proc/s390dbf/cio_*/ (S/390 debug feature)
diff --git a/Documentation/s390/Debugging390.txt b/Documentation/s390/Debugging390.txt
index 4dd25ee549e9..3f9ddbc23b27 100644
--- a/Documentation/s390/Debugging390.txt
+++ b/Documentation/s390/Debugging390.txt
@@ -7,7 +7,7 @@
7 7
8Overview of Document: 8Overview of Document:
9===================== 9=====================
10This document is intended to give an good overview of how to debug 10This document is intended to give a good overview of how to debug
11Linux for s/390 & z/Architecture. It isn't intended as a complete reference & not a 11Linux for s/390 & z/Architecture. It isn't intended as a complete reference & not a
12tutorial on the fundamentals of C & assembly. It doesn't go into 12tutorial on the fundamentals of C & assembly. It doesn't go into
13390 IO in any detail. It is intended to complement the documents in the 13390 IO in any detail. It is intended to complement the documents in the
@@ -300,7 +300,7 @@ On z/Architecture our page indexes are now 2k in size
300but only mess with 2 segment indices each time we mess with 300but only mess with 2 segment indices each time we mess with
301a PMD. 301a PMD.
302 302
3033) As z/Architecture supports upto a massive 5-level page table lookup we 3033) As z/Architecture supports up to a massive 5-level page table lookup we
304can only use 3 currently on Linux ( as this is all the generic kernel 304can only use 3 currently on Linux ( as this is all the generic kernel
305currently supports ) however this may change in future 305currently supports ) however this may change in future
306this allows us to access ( according to my sums ) 306this allows us to access ( according to my sums )
@@ -502,7 +502,7 @@ Notes:
502------ 502------
5031) The only requirement is that registers which are used 5031) The only requirement is that registers which are used
504by the callee are saved, e.g. the compiler is perfectly 504by the callee are saved, e.g. the compiler is perfectly
505capible of using r11 for purposes other than a frame a 505capable of using r11 for purposes other than a frame a
506frame pointer if a frame pointer is not needed. 506frame pointer if a frame pointer is not needed.
5072) In functions with variable arguments e.g. printf the calling procedure 5072) In functions with variable arguments e.g. printf the calling procedure
508is identical to one without variable arguments & the same number of 508is identical to one without variable arguments & the same number of
@@ -846,7 +846,7 @@ of time searching for debugging info. The following self explanatory line should
846instead if the code isn't compiled -g, as it is much faster: 846instead if the code isn't compiled -g, as it is much faster:
847objdump --disassemble-all --syms vmlinux > vmlinux.lst 847objdump --disassemble-all --syms vmlinux > vmlinux.lst
848 848
849As hard drive space is valuble most of us use the following approach. 849As hard drive space is valuable most of us use the following approach.
8501) Look at the emitted psw on the console to find the crash address in the kernel. 8501) Look at the emitted psw on the console to find the crash address in the kernel.
8512) Look at the file System.map ( in the linux directory ) produced when building 8512) Look at the file System.map ( in the linux directory ) produced when building
852the kernel to find the closest address less than the current PSW to find the 852the kernel to find the closest address less than the current PSW to find the
@@ -902,7 +902,7 @@ A. It is a tool for intercepting calls to the kernel & logging them
902to a file & on the screen. 902to a file & on the screen.
903 903
904Q. What use is it ? 904Q. What use is it ?
905A. You can used it to find out what files a particular program opens. 905A. You can use it to find out what files a particular program opens.
906 906
907 907
908 908
@@ -911,7 +911,7 @@ Example 1
911If you wanted to know does ping work but didn't have the source 911If you wanted to know does ping work but didn't have the source
912strace ping -c 1 127.0.0.1 912strace ping -c 1 127.0.0.1
913& then look at the man pages for each of the syscalls below, 913& then look at the man pages for each of the syscalls below,
914( In fact this is sometimes easier than looking at some spagetti 914( In fact this is sometimes easier than looking at some spaghetti
915source which conditionally compiles for several architectures ). 915source which conditionally compiles for several architectures ).
916Not everything that it throws out needs to make sense immediately. 916Not everything that it throws out needs to make sense immediately.
917 917
@@ -1037,7 +1037,7 @@ e.g. man strace, man alarm, man socket.
1037 1037
1038Performance Debugging 1038Performance Debugging
1039===================== 1039=====================
1040gcc is capible of compiling in profiling code just add the -p option 1040gcc is capable of compiling in profiling code just add the -p option
1041to the CFLAGS, this obviously affects program size & performance. 1041to the CFLAGS, this obviously affects program size & performance.
1042This can be used by the gprof gnu profiling tool or the 1042This can be used by the gprof gnu profiling tool or the
1043gcov the gnu code coverage tool ( code coverage is a means of testing 1043gcov the gnu code coverage tool ( code coverage is a means of testing
@@ -1419,7 +1419,7 @@ On a SMP guest issue a command to all CPUs try prefixing the command with cpu al
1419To issue a command to a particular cpu try cpu <cpu number> e.g. 1419To issue a command to a particular cpu try cpu <cpu number> e.g.
1420CPU 01 TR I R 2000.3000 1420CPU 01 TR I R 2000.3000
1421If you are running on a guest with several cpus & you have a IO related problem 1421If you are running on a guest with several cpus & you have a IO related problem
1422& cannot follow the flow of code but you know it isnt smp related. 1422& cannot follow the flow of code but you know it isn't smp related.
1423from the bash prompt issue 1423from the bash prompt issue
1424shutdown -h now or halt. 1424shutdown -h now or halt.
1425do a Q CPUS to find out how many cpus you have 1425do a Q CPUS to find out how many cpus you have
@@ -1602,7 +1602,7 @@ V000FFFD0 00010400 80010802 8001085A 000FFFA0
1602our 3rd return address is 8001085A 1602our 3rd return address is 8001085A
1603 1603
1604as the 04B52002 looks suspiciously like rubbish it is fair to assume that the kernel entry routines 1604as the 04B52002 looks suspiciously like rubbish it is fair to assume that the kernel entry routines
1605for the sake of optimisation dont set up a backchain. 1605for the sake of optimisation don't set up a backchain.
1606 1606
1607now look at System.map to see if the addresses make any sense. 1607now look at System.map to see if the addresses make any sense.
1608 1608
@@ -1638,11 +1638,11 @@ more useful information.
1638 1638
1639Unlike other bus architectures modern 390 systems do their IO using mostly 1639Unlike other bus architectures modern 390 systems do their IO using mostly
1640fibre optics & devices such as tapes & disks can be shared between several mainframes, 1640fibre optics & devices such as tapes & disks can be shared between several mainframes,
1641also S390 can support upto 65536 devices while a high end PC based system might be choking 1641also S390 can support up to 65536 devices while a high end PC based system might be choking
1642with around 64. Here is some of the common IO terminology 1642with around 64. Here is some of the common IO terminology
1643 1643
1644Subchannel: 1644Subchannel:
1645This is the logical number most IO commands use to talk to an IO device there can be upto 1645This is the logical number most IO commands use to talk to an IO device there can be up to
16460x10000 (65536) of these in a configuration typically there is a few hundred. Under VM 16460x10000 (65536) of these in a configuration typically there is a few hundred. Under VM
1647for simplicity they are allocated contiguously, however on the native hardware they are not 1647for simplicity they are allocated contiguously, however on the native hardware they are not
1648they typically stay consistent between boots provided no new hardware is inserted or removed. 1648they typically stay consistent between boots provided no new hardware is inserted or removed.
@@ -1651,7 +1651,7 @@ HALT SUBCHANNEL,MODIFY SUBCHANNEL,RESUME SUBCHANNEL,START SUBCHANNEL,STORE SUBCH
1651TEST SUBCHANNEL ) we use this as the ID of the device we wish to talk to, the most 1651TEST SUBCHANNEL ) we use this as the ID of the device we wish to talk to, the most
1652important of these instructions are START SUBCHANNEL ( to start IO ), TEST SUBCHANNEL ( to check 1652important of these instructions are START SUBCHANNEL ( to start IO ), TEST SUBCHANNEL ( to check
1653whether the IO completed successfully ), & HALT SUBCHANNEL ( to kill IO ), a subchannel 1653whether the IO completed successfully ), & HALT SUBCHANNEL ( to kill IO ), a subchannel
1654can have up to 8 channel paths to a device this offers redunancy if one is not available. 1654can have up to 8 channel paths to a device this offers redundancy if one is not available.
1655 1655
1656 1656
1657Device Number: 1657Device Number:
@@ -1659,7 +1659,7 @@ This number remains static & Is closely tied to the hardware, there are 65536 of
1659also they are made up of a CHPID ( Channel Path ID, the most significant 8 bits ) 1659also they are made up of a CHPID ( Channel Path ID, the most significant 8 bits )
1660& another lsb 8 bits. These remain static even if more devices are inserted or removed 1660& another lsb 8 bits. These remain static even if more devices are inserted or removed
1661from the hardware, there is a 1 to 1 mapping between Subchannels & Device Numbers provided 1661from the hardware, there is a 1 to 1 mapping between Subchannels & Device Numbers provided
1662devices arent inserted or removed. 1662devices aren't inserted or removed.
1663 1663
1664Channel Control Words: 1664Channel Control Words:
1665CCWS are linked lists of instructions initially pointed to by an operation request block (ORB), 1665CCWS are linked lists of instructions initially pointed to by an operation request block (ORB),
@@ -1674,7 +1674,7 @@ concurrently, you check how the IO went on by issuing a TEST SUBCHANNEL at each
1674from which you receive an Interruption response block (IRB). If you get channel & device end 1674from which you receive an Interruption response block (IRB). If you get channel & device end
1675status in the IRB without channel checks etc. your IO probably went okay. If you didn't you 1675status in the IRB without channel checks etc. your IO probably went okay. If you didn't you
1676probably need a doctor to examine the IRB & extended status word etc. 1676probably need a doctor to examine the IRB & extended status word etc.
1677If an error occurs, more sophistocated control units have a facitity known as 1677If an error occurs, more sophisticated control units have a facility known as
1678concurrent sense this means that if an error occurs Extended sense information will 1678concurrent sense this means that if an error occurs Extended sense information will
1679be presented in the Extended status word in the IRB if not you have to issue a 1679be presented in the Extended status word in the IRB if not you have to issue a
1680subsequent SENSE CCW command after the test subchannel. 1680subsequent SENSE CCW command after the test subchannel.
@@ -1749,7 +1749,7 @@ Interface (OEMI).
1749This byte wide Parallel channel path/bus has parity & data on the "Bus" cable 1749This byte wide Parallel channel path/bus has parity & data on the "Bus" cable
1750& control lines on the "Tag" cable. These can operate in byte multiplex mode for 1750& control lines on the "Tag" cable. These can operate in byte multiplex mode for
1751sharing between several slow devices or burst mode & monopolize the channel for the 1751sharing between several slow devices or burst mode & monopolize the channel for the
1752whole burst. Upto 256 devices can be addressed on one of these cables. These cables are 1752whole burst. Up to 256 devices can be addressed on one of these cables. These cables are
1753about one inch in diameter. The maximum unextended length supported by these cables is 1753about one inch in diameter. The maximum unextended length supported by these cables is
1754125 Meters but this can be extended up to 2km with a fibre optic channel extended 1754125 Meters but this can be extended up to 2km with a fibre optic channel extended
1755such as a 3044. The maximum burst speed supported is 4.5 megabytes per second however 1755such as a 3044. The maximum burst speed supported is 4.5 megabytes per second however
@@ -1759,7 +1759,7 @@ One of these paths can be daisy chained to up to 8 control units.
1759 1759
1760ESCON if fibre optic it is also called FICON 1760ESCON if fibre optic it is also called FICON
1761Was introduced by IBM in 1990. Has 2 fibre optic cables & uses either leds or lasers 1761Was introduced by IBM in 1990. Has 2 fibre optic cables & uses either leds or lasers
1762for communication at a signaling rate of upto 200 megabits/sec. As 10bits are transferred 1762for communication at a signaling rate of up to 200 megabits/sec. As 10bits are transferred
1763for every 8 bits info this drops to 160 megabits/sec & to 18.6 Megabytes/sec once 1763for every 8 bits info this drops to 160 megabits/sec & to 18.6 Megabytes/sec once
1764control info & CRC are added. ESCON only operates in burst mode. 1764control info & CRC are added. ESCON only operates in burst mode.
1765 1765
@@ -1767,7 +1767,7 @@ ESCONs typical max cable length is 3km for the led version & 20km for the laser
1767known as XDF ( extended distance facility ). This can be further extended by using an 1767known as XDF ( extended distance facility ). This can be further extended by using an
1768ESCON director which triples the above mentioned ranges. Unlike Bus & Tag as ESCON is 1768ESCON director which triples the above mentioned ranges. Unlike Bus & Tag as ESCON is
1769serial it uses a packet switching architecture the standard Bus & Tag control protocol 1769serial it uses a packet switching architecture the standard Bus & Tag control protocol
1770is however present within the packets. Upto 256 devices can be attached to each control 1770is however present within the packets. Up to 256 devices can be attached to each control
1771unit that uses one of these interfaces. 1771unit that uses one of these interfaces.
1772 1772
1773Common 390 Devices include: 1773Common 390 Devices include:
@@ -2050,7 +2050,7 @@ list test.c:1,10
2050 2050
2051directory: 2051directory:
2052Adds directories to be searched for source if gdb cannot find the source. 2052Adds directories to be searched for source if gdb cannot find the source.
2053(note it is a bit sensititive about slashes) 2053(note it is a bit sensitive about slashes)
2054e.g. To add the root of the filesystem to the searchpath do 2054e.g. To add the root of the filesystem to the searchpath do
2055directory // 2055directory //
2056 2056
@@ -2152,7 +2152,7 @@ program as if it just crashed on your system, it is usually called core & create
2152current working directory. 2152current working directory.
2153This is very useful in that a customer can mail a core dump to a technical support department 2153This is very useful in that a customer can mail a core dump to a technical support department
2154& the technical support department can reconstruct what happened. 2154& the technical support department can reconstruct what happened.
2155Provided the have an identical copy of this program with debugging symbols compiled in & 2155Provided they have an identical copy of this program with debugging symbols compiled in &
2156the source base of this build is available. 2156the source base of this build is available.
2157In short it is far more useful than something like a crash log could ever hope to be. 2157In short it is far more useful than something like a crash log could ever hope to be.
2158 2158
diff --git a/Documentation/s390/cds.txt b/Documentation/s390/cds.txt
index 32a96cc39215..05a2b4f7e38f 100644
--- a/Documentation/s390/cds.txt
+++ b/Documentation/s390/cds.txt
@@ -98,7 +98,7 @@ The following chapters describe the I/O related interface routines the
98Linux/390 common device support (CDS) provides to allow for device specific 98Linux/390 common device support (CDS) provides to allow for device specific
99driver implementations on the IBM ESA/390 hardware platform. Those interfaces 99driver implementations on the IBM ESA/390 hardware platform. Those interfaces
100intend to provide the functionality required by every device driver 100intend to provide the functionality required by every device driver
101implementaion to allow to drive a specific hardware device on the ESA/390 101implementation to allow to drive a specific hardware device on the ESA/390
102platform. Some of the interface routines are specific to Linux/390 and some 102platform. Some of the interface routines are specific to Linux/390 and some
103of them can be found on other Linux platforms implementations too. 103of them can be found on other Linux platforms implementations too.
104Miscellaneous function prototypes, data declarations, and macro definitions 104Miscellaneous function prototypes, data declarations, and macro definitions
@@ -114,7 +114,7 @@ the ESA/390 architecture has implemented a so called channel subsystem, that
114provides a unified view of the devices physically attached to the systems. 114provides a unified view of the devices physically attached to the systems.
115Though the ESA/390 hardware platform knows about a huge variety of different 115Though the ESA/390 hardware platform knows about a huge variety of different
116peripheral attachments like disk devices (aka. DASDs), tapes, communication 116peripheral attachments like disk devices (aka. DASDs), tapes, communication
117controllers, etc. they can all by accessed by a well defined access method and 117controllers, etc. they can all be accessed by a well defined access method and
118they are presenting I/O completion a unified way : I/O interruptions. Every 118they are presenting I/O completion a unified way : I/O interruptions. Every
119single device is uniquely identified to the system by a so called subchannel, 119single device is uniquely identified to the system by a so called subchannel,
120where the ESA/390 architecture allows for 64k devices be attached. 120where the ESA/390 architecture allows for 64k devices be attached.
@@ -338,7 +338,7 @@ DOIO_REPORT_ALL - report all interrupt conditions
338The ccw_device_start() function returns : 338The ccw_device_start() function returns :
339 339
340 0 - successful completion or request successfully initiated 340 0 - successful completion or request successfully initiated
341-EBUSY - The device is currently processing a previous I/O request, or ther is 341-EBUSY - The device is currently processing a previous I/O request, or there is
342 a status pending at the device. 342 a status pending at the device.
343-ENODEV - cdev is invalid, the device is not operational or the ccw_device is 343-ENODEV - cdev is invalid, the device is not operational or the ccw_device is
344 not online. 344 not online.
@@ -361,7 +361,7 @@ first:
361-EIO: the common I/O layer terminated the request due to an error state 361-EIO: the common I/O layer terminated the request due to an error state
362 362
363If the concurrent sense flag in the extended status word in the irb is set, the 363If the concurrent sense flag in the extended status word in the irb is set, the
364field irb->scsw.count describes the numer of device specific sense bytes 364field irb->scsw.count describes the number of device specific sense bytes
365available in the extended control word irb->scsw.ecw[0]. No device sensing by 365available in the extended control word irb->scsw.ecw[0]. No device sensing by
366the device driver itself is required. 366the device driver itself is required.
367 367
@@ -410,7 +410,7 @@ ccw_device_start() must be called disabled and with the ccw device lock held.
410 410
411The device driver is allowed to issue the next ccw_device_start() call from 411The device driver is allowed to issue the next ccw_device_start() call from
412within its interrupt handler already. It is not required to schedule a 412within its interrupt handler already. It is not required to schedule a
413bottom-half, unless an non deterministically long running error recovery procedure 413bottom-half, unless a non deterministically long running error recovery procedure
414or similar needs to be scheduled. During I/O processing the Linux/390 generic 414or similar needs to be scheduled. During I/O processing the Linux/390 generic
415I/O device driver support has already obtained the IRQ lock, i.e. the handler 415I/O device driver support has already obtained the IRQ lock, i.e. the handler
416must not try to obtain it again when calling ccw_device_start() or we end in a 416must not try to obtain it again when calling ccw_device_start() or we end in a
@@ -431,7 +431,7 @@ information prior to device-end the device driver urgently relies on. In this
431case all I/O interruptions are presented to the device driver until final 431case all I/O interruptions are presented to the device driver until final
432status is recognized. 432status is recognized.
433 433
434If a device is able to recover from asynchronosly presented I/O errors, it can 434If a device is able to recover from asynchronously presented I/O errors, it can
435perform overlapping I/O using the DOIO_EARLY_NOTIFICATION flag. While some 435perform overlapping I/O using the DOIO_EARLY_NOTIFICATION flag. While some
436devices always report channel-end and device-end together, with a single 436devices always report channel-end and device-end together, with a single
437interrupt, others present primary status (channel-end) when the channel is 437interrupt, others present primary status (channel-end) when the channel is
diff --git a/Documentation/s390/crypto/crypto-API.txt b/Documentation/s390/crypto/crypto-API.txt
index 41a8b07da05a..71ae6ca9f2c2 100644
--- a/Documentation/s390/crypto/crypto-API.txt
+++ b/Documentation/s390/crypto/crypto-API.txt
@@ -17,8 +17,8 @@ arch/s390/crypto directory.
172. Probing for availability of MSA 172. Probing for availability of MSA
18~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 18~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
19It should be possible to use Kernels with the z990 crypto implementations both 19It should be possible to use Kernels with the z990 crypto implementations both
20on machines with MSA available an on those without MSA (pre z990 or z990 20on machines with MSA available and on those without MSA (pre z990 or z990
21without MSA). Therefore a simple probing mechanisms has been implemented: 21without MSA). Therefore a simple probing mechanism has been implemented:
22In the init function of each crypto module the availability of MSA and of the 22In the init function of each crypto module the availability of MSA and of the
23respective crypto algorithm in particular will be tested. If the algorithm is 23respective crypto algorithm in particular will be tested. If the algorithm is
24available the module will load and register its algorithm with the crypto API. 24available the module will load and register its algorithm with the crypto API.
@@ -26,7 +26,7 @@ available the module will load and register its algorithm with the crypto API.
26If the respective crypto algorithm is not available, the init function will 26If the respective crypto algorithm is not available, the init function will
27return -ENOSYS. In that case a fallback to the standard software implementation 27return -ENOSYS. In that case a fallback to the standard software implementation
28of the crypto algorithm must be taken ( -> the standard crypto modules are 28of the crypto algorithm must be taken ( -> the standard crypto modules are
29also build when compiling the kernel). 29also built when compiling the kernel).
30 30
31 31
323. Ensuring z990 crypto module preference 323. Ensuring z990 crypto module preference
diff --git a/Documentation/s390/s390dbf.txt b/Documentation/s390/s390dbf.txt
index 000230cd26db..0eb7c58916de 100644
--- a/Documentation/s390/s390dbf.txt
+++ b/Documentation/s390/s390dbf.txt
@@ -36,7 +36,7 @@ switches to the next debug area. This is done in order to be sure
36that the records which describe the origin of the exception are not 36that the records which describe the origin of the exception are not
37overwritten when a wrap around for the current area occurs. 37overwritten when a wrap around for the current area occurs.
38 38
39The debug areas itselve are also ordered in form of a ring buffer. 39The debug areas themselves are also ordered in form of a ring buffer.
40When an exception is thrown in the last debug area, the following debug 40When an exception is thrown in the last debug area, the following debug
41entries are then written again in the very first area. 41entries are then written again in the very first area.
42 42
@@ -55,7 +55,7 @@ The debug logs can be inspected in a live system through entries in
55the debugfs-filesystem. Under the toplevel directory "s390dbf" there is 55the debugfs-filesystem. Under the toplevel directory "s390dbf" there is
56a directory for each registered component, which is named like the 56a directory for each registered component, which is named like the
57corresponding component. The debugfs normally should be mounted to 57corresponding component. The debugfs normally should be mounted to
58/sys/kernel/debug therefore the debug feature can be accessed unter 58/sys/kernel/debug therefore the debug feature can be accessed under
59/sys/kernel/debug/s390dbf. 59/sys/kernel/debug/s390dbf.
60 60
61The content of the directories are files which represent different views 61The content of the directories are files which represent different views
@@ -87,11 +87,11 @@ There are currently 2 possible triggers, which stop the debug feature
87globally. The first possibility is to use the "debug_active" sysctl. If 87globally. The first possibility is to use the "debug_active" sysctl. If
88set to 1 the debug feature is running. If "debug_active" is set to 0 the 88set to 1 the debug feature is running. If "debug_active" is set to 0 the
89debug feature is turned off. 89debug feature is turned off.
90The second trigger which stops the debug feature is an kernel oops. 90The second trigger which stops the debug feature is a kernel oops.
91That prevents the debug feature from overwriting debug information that 91That prevents the debug feature from overwriting debug information that
92happened before the oops. After an oops you can reactivate the debug feature 92happened before the oops. After an oops you can reactivate the debug feature
93by piping 1 to /proc/sys/s390dbf/debug_active. Nevertheless, its not 93by piping 1 to /proc/sys/s390dbf/debug_active. Nevertheless, its not
94suggested to use an oopsed kernel in an production environment. 94suggested to use an oopsed kernel in a production environment.
95If you want to disallow the deactivation of the debug feature, you can use 95If you want to disallow the deactivation of the debug feature, you can use
96the "debug_stoppable" sysctl. If you set "debug_stoppable" to 0 the debug 96the "debug_stoppable" sysctl. If you set "debug_stoppable" to 0 the debug
97feature cannot be stopped. If the debug feature is already stopped, it 97feature cannot be stopped. If the debug feature is already stopped, it
diff --git a/MAINTAINERS b/MAINTAINERS
index 8385a69138a8..5dff26814a06 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -2438,6 +2438,13 @@ M: promise@pnd-pc.demon.co.uk
2438W: http://www.pnd-pc.demon.co.uk/promise/ 2438W: http://www.pnd-pc.demon.co.uk/promise/
2439S: Maintained 2439S: Maintained
2440 2440
2441PS3 PLATFORM SUPPORT
2442P: Geoff Levand
2443M: geoffrey.levand@am.sony.com
2444L: linuxppc-dev@ozlabs.org
2445L: cbe-oss-dev@ozlabs.org
2446S: Supported
2447
2441PVRUSB2 VIDEO4LINUX DRIVER 2448PVRUSB2 VIDEO4LINUX DRIVER
2442P: Mike Isely 2449P: Mike Isely
2443M: isely@pobox.com 2450M: isely@pobox.com
diff --git a/arch/i386/kernel/acpi/cstate.c b/arch/i386/kernel/acpi/cstate.c
index 20563e52c622..4664b55f623e 100644
--- a/arch/i386/kernel/acpi/cstate.c
+++ b/arch/i386/kernel/acpi/cstate.c
@@ -11,6 +11,7 @@
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/acpi.h> 12#include <linux/acpi.h>
13#include <linux/cpu.h> 13#include <linux/cpu.h>
14#include <linux/sched.h>
14 15
15#include <acpi/processor.h> 16#include <acpi/processor.h>
16#include <asm/acpi.h> 17#include <asm/acpi.h>
diff --git a/arch/i386/kernel/alternative.c b/arch/i386/kernel/alternative.c
index 583c238e17fb..535f9794fba1 100644
--- a/arch/i386/kernel/alternative.c
+++ b/arch/i386/kernel/alternative.c
@@ -1,4 +1,5 @@
1#include <linux/module.h> 1#include <linux/module.h>
2#include <linux/sched.h>
2#include <linux/spinlock.h> 3#include <linux/spinlock.h>
3#include <linux/list.h> 4#include <linux/list.h>
4#include <asm/alternative.h> 5#include <asm/alternative.h>
diff --git a/arch/i386/kernel/cpu/mcheck/therm_throt.c b/arch/i386/kernel/cpu/mcheck/therm_throt.c
index 2d8703b7ce65..bad8b4420709 100644
--- a/arch/i386/kernel/cpu/mcheck/therm_throt.c
+++ b/arch/i386/kernel/cpu/mcheck/therm_throt.c
@@ -20,6 +20,7 @@
20#include <linux/cpu.h> 20#include <linux/cpu.h>
21#include <asm/cpu.h> 21#include <asm/cpu.h>
22#include <linux/notifier.h> 22#include <linux/notifier.h>
23#include <linux/jiffies.h>
23#include <asm/therm_throt.h> 24#include <asm/therm_throt.h>
24 25
25/* How long to wait between reporting thermal events */ 26/* How long to wait between reporting thermal events */
diff --git a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
index c1bc22c6d0d8..aa70dde54228 100644
--- a/arch/m68knommu/Kconfig
+++ b/arch/m68knommu/Kconfig
@@ -173,7 +173,7 @@ config CLOCK_DIV
173 On many SoC style CPUs the master CPU clock is also used to drive 173 On many SoC style CPUs the master CPU clock is also used to drive
174 on-chip peripherals. The clock that is distributed to these 174 on-chip peripherals. The clock that is distributed to these
175 peripherals is sometimes a fixed ratio of the master clock 175 peripherals is sometimes a fixed ratio of the master clock
176 frequency. If so then set this to the divider ration of the 176 frequency. If so then set this to the divider ratio of the
177 master clock to the peripheral clock. If not sure then select 1. 177 master clock to the peripheral clock. If not sure then select 1.
178 178
179config OLDMASK 179config OLDMASK
@@ -192,7 +192,7 @@ config PILOT3
192 Support for the Palm Pilot 1000/5000, Personal/Pro and PalmIII. 192 Support for the Palm Pilot 1000/5000, Personal/Pro and PalmIII.
193 193
194config XCOPILOT_BUGS 194config XCOPILOT_BUGS
195 bool " (X)Copilot support" 195 bool "(X)Copilot support"
196 depends on PILOT3 196 depends on PILOT3
197 help 197 help
198 Support the bugs of Xcopilot. 198 Support the bugs of Xcopilot.
@@ -216,20 +216,20 @@ config DRAGEN2
216 Support for the DragenEngine II board. 216 Support for the DragenEngine II board.
217 217
218config DIRECT_IO_ACCESS 218config DIRECT_IO_ACCESS
219 bool " Allow user to access IO directly" 219 bool "Allow user to access IO directly"
220 depends on (UCSIMM || UCDIMM || DRAGEN2) 220 depends on (UCSIMM || UCDIMM || DRAGEN2)
221 help 221 help
222 Disable the CPU internal registers protection in user mode, 222 Disable the CPU internal registers protection in user mode,
223 to allow a user application to read/write them. 223 to allow a user application to read/write them.
224 224
225config INIT_LCD 225config INIT_LCD
226 bool " Initialize LCD" 226 bool "Initialize LCD"
227 depends on (UCSIMM || UCDIMM || DRAGEN2) 227 depends on (UCSIMM || UCDIMM || DRAGEN2)
228 help 228 help
229 Initialize the LCD controller of the 68x328 processor. 229 Initialize the LCD controller of the 68x328 processor.
230 230
231config MEMORY_RESERVE 231config MEMORY_RESERVE
232 int " Memory reservation (MiB)" 232 int "Memory reservation (MiB)"
233 depends on (UCSIMM || UCDIMM) 233 depends on (UCSIMM || UCDIMM)
234 help 234 help
235 Reserve certain memory regions on 68x328 based boards. 235 Reserve certain memory regions on 68x328 based boards.
@@ -409,7 +409,7 @@ config MOD5272
409 Support for the Netburner MOD-5272 board. 409 Support for the Netburner MOD-5272 board.
410 410
411config ROMFS_FROM_ROM 411config ROMFS_FROM_ROM
412 bool " ROMFS image not RAM resident" 412 bool "ROMFS image not RAM resident"
413 depends on (NETtel || SNAPGEAR) 413 depends on (NETtel || SNAPGEAR)
414 help 414 help
415 The ROMfs filesystem will stay resident in the FLASH/ROM, not be 415 The ROMfs filesystem will stay resident in the FLASH/ROM, not be
diff --git a/arch/m68knommu/kernel/process.c b/arch/m68knommu/kernel/process.c
index c18a83306953..941955dc3b7c 100644
--- a/arch/m68knommu/kernel/process.c
+++ b/arch/m68knommu/kernel/process.c
@@ -290,7 +290,7 @@ void dump(struct pt_regs *fp)
290 unsigned char *tp; 290 unsigned char *tp;
291 int i; 291 int i;
292 292
293 printk(KERN_EMERG "\nCURRENT PROCESS:\n\n"); 293 printk(KERN_EMERG "\n" KERN_EMERG "CURRENT PROCESS:\n" KERN_EMERG "\n");
294 printk(KERN_EMERG "COMM=%s PID=%d\n", current->comm, current->pid); 294 printk(KERN_EMERG "COMM=%s PID=%d\n", current->comm, current->pid);
295 295
296 if (current->mm) { 296 if (current->mm) {
@@ -301,7 +301,8 @@ void dump(struct pt_regs *fp)
301 (int) current->mm->end_data, 301 (int) current->mm->end_data,
302 (int) current->mm->end_data, 302 (int) current->mm->end_data,
303 (int) current->mm->brk); 303 (int) current->mm->brk);
304 printk(KERN_EMERG "USER-STACK=%08x KERNEL-STACK=%08x\n\n", 304 printk(KERN_EMERG "USER-STACK=%08x KERNEL-STACK=%08x\n"
305 KERN_EMERG "\n",
305 (int) current->mm->start_stack, 306 (int) current->mm->start_stack,
306 (int)(((unsigned long) current) + THREAD_SIZE)); 307 (int)(((unsigned long) current) + THREAD_SIZE));
307 } 308 }
@@ -312,36 +313,35 @@ void dump(struct pt_regs *fp)
312 fp->d0, fp->d1, fp->d2, fp->d3); 313 fp->d0, fp->d1, fp->d2, fp->d3);
313 printk(KERN_EMERG "d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n", 314 printk(KERN_EMERG "d4: %08lx d5: %08lx a0: %08lx a1: %08lx\n",
314 fp->d4, fp->d5, fp->a0, fp->a1); 315 fp->d4, fp->d5, fp->a0, fp->a1);
315 printk(KERN_EMERG "\nUSP: %08x TRAPFRAME: %08x\n", (unsigned int) rdusp(), 316 printk(KERN_EMERG "\n" KERN_EMERG "USP: %08x TRAPFRAME: %08x\n",
316 (unsigned int) fp); 317 (unsigned int) rdusp(), (unsigned int) fp);
317 318
318 printk(KERN_EMERG "\nCODE:"); 319 printk(KERN_EMERG "\n" KERN_EMERG "CODE:");
319 tp = ((unsigned char *) fp->pc) - 0x20; 320 tp = ((unsigned char *) fp->pc) - 0x20;
320 for (sp = (unsigned long *) tp, i = 0; (i < 0x40); i += 4) { 321 for (sp = (unsigned long *) tp, i = 0; (i < 0x40); i += 4) {
321 if ((i % 0x10) == 0) 322 if ((i % 0x10) == 0)
322 printk(KERN_EMERG "\n%08x: ", (int) (tp + i)); 323 printk("\n" KERN_EMERG "%08x: ", (int) (tp + i));
323 printk(KERN_EMERG "%08x ", (int) *sp++); 324 printk("%08x ", (int) *sp++);
324 } 325 }
325 printk(KERN_EMERG "\n"); 326 printk("\n" KERN_EMERG "\n");
326 327
327 printk(KERN_EMERG "\nKERNEL STACK:"); 328 printk(KERN_EMERG "KERNEL STACK:");
328 tp = ((unsigned char *) fp) - 0x40; 329 tp = ((unsigned char *) fp) - 0x40;
329 for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) { 330 for (sp = (unsigned long *) tp, i = 0; (i < 0xc0); i += 4) {
330 if ((i % 0x10) == 0) 331 if ((i % 0x10) == 0)
331 printk(KERN_EMERG "\n%08x: ", (int) (tp + i)); 332 printk("\n" KERN_EMERG "%08x: ", (int) (tp + i));
332 printk(KERN_EMERG "%08x ", (int) *sp++); 333 printk("%08x ", (int) *sp++);
333 } 334 }
334 printk(KERN_EMERG "\n"); 335 printk("\n" KERN_EMERG "\n");
335 printk(KERN_EMERG "\n");
336 336
337 printk(KERN_EMERG "\nUSER STACK:"); 337 printk(KERN_EMERG "USER STACK:");
338 tp = (unsigned char *) (rdusp() - 0x10); 338 tp = (unsigned char *) (rdusp() - 0x10);
339 for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) { 339 for (sp = (unsigned long *) tp, i = 0; (i < 0x80); i += 4) {
340 if ((i % 0x10) == 0) 340 if ((i % 0x10) == 0)
341 printk(KERN_EMERG "\n%08x: ", (int) (tp + i)); 341 printk("\n" KERN_EMERG "%08x: ", (int) (tp + i));
342 printk(KERN_EMERG "%08x ", (int) *sp++); 342 printk("%08x ", (int) *sp++);
343 } 343 }
344 printk(KERN_EMERG "\n\n"); 344 printk("\n" KERN_EMERG "\n");
345} 345}
346 346
347/* 347/*
diff --git a/arch/m68knommu/kernel/setup.c b/arch/m68knommu/kernel/setup.c
index 7b21959eaeae..9cf2e4d1fc77 100644
--- a/arch/m68knommu/kernel/setup.c
+++ b/arch/m68knommu/kernel/setup.c
@@ -36,10 +36,7 @@
36#include <asm/setup.h> 36#include <asm/setup.h>
37#include <asm/irq.h> 37#include <asm/irq.h>
38#include <asm/machdep.h> 38#include <asm/machdep.h>
39
40#ifdef CONFIG_BLK_DEV_INITRD
41#include <asm/pgtable.h> 39#include <asm/pgtable.h>
42#endif
43 40
44unsigned long memory_start; 41unsigned long memory_start;
45unsigned long memory_end; 42unsigned long memory_end;
diff --git a/arch/m68knommu/kernel/sys_m68k.c b/arch/m68knommu/kernel/sys_m68k.c
index c3494b8447d1..3265b2d734db 100644
--- a/arch/m68knommu/kernel/sys_m68k.c
+++ b/arch/m68knommu/kernel/sys_m68k.c
@@ -137,7 +137,7 @@ asmlinkage int old_select(struct sel_arg_struct *arg)
137asmlinkage int sys_ipc (uint call, int first, int second, 137asmlinkage int sys_ipc (uint call, int first, int second,
138 int third, void *ptr, long fifth) 138 int third, void *ptr, long fifth)
139{ 139{
140 int version; 140 int version, ret;
141 141
142 version = call >> 16; /* hack for backward compatibility */ 142 version = call >> 16; /* hack for backward compatibility */
143 call &= 0xffff; 143 call &= 0xffff;
@@ -190,6 +190,27 @@ asmlinkage int sys_ipc (uint call, int first, int second,
190 default: 190 default:
191 return -EINVAL; 191 return -EINVAL;
192 } 192 }
193 if (call <= SHMCTL)
194 switch (call) {
195 case SHMAT:
196 switch (version) {
197 default: {
198 ulong raddr;
199 ret = do_shmat (first, ptr, second, &raddr);
200 if (ret)
201 return ret;
202 return put_user (raddr, (ulong __user *) third);
203 }
204 }
205 case SHMDT:
206 return sys_shmdt (ptr);
207 case SHMGET:
208 return sys_shmget (first, second, third);
209 case SHMCTL:
210 return sys_shmctl (first, second, ptr);
211 default:
212 return -ENOSYS;
213 }
193 214
194 return -EINVAL; 215 return -EINVAL;
195} 216}
diff --git a/arch/m68knommu/kernel/traps.c b/arch/m68knommu/kernel/traps.c
index 17649d2543ef..9129b3a5258b 100644
--- a/arch/m68knommu/kernel/traps.c
+++ b/arch/m68knommu/kernel/traps.c
@@ -127,11 +127,12 @@ void show_stack(struct task_struct *task, unsigned long *stack)
127 if (stack + 1 > endstack) 127 if (stack + 1 > endstack)
128 break; 128 break;
129 if (i % 8 == 0) 129 if (i % 8 == 0)
130 printk(KERN_EMERG "\n "); 130 printk("\n" KERN_EMERG " ");
131 printk(KERN_EMERG " %08lx", *stack++); 131 printk(" %08lx", *stack++);
132 } 132 }
133 printk("\n");
133 134
134 printk(KERN_EMERG "\nCall Trace:"); 135 printk(KERN_EMERG "Call Trace:");
135 i = 0; 136 i = 0;
136 while (stack + 1 <= endstack) { 137 while (stack + 1 <= endstack) {
137 addr = *stack++; 138 addr = *stack++;
@@ -146,12 +147,12 @@ void show_stack(struct task_struct *task, unsigned long *stack)
146 if (((addr >= (unsigned long) &_start) && 147 if (((addr >= (unsigned long) &_start) &&
147 (addr <= (unsigned long) &_etext))) { 148 (addr <= (unsigned long) &_etext))) {
148 if (i % 4 == 0) 149 if (i % 4 == 0)
149 printk(KERN_EMERG "\n "); 150 printk("\n" KERN_EMERG " ");
150 printk(KERN_EMERG " [<%08lx>]", addr); 151 printk(" [<%08lx>]", addr);
151 i++; 152 i++;
152 } 153 }
153 } 154 }
154 printk(KERN_EMERG "\n"); 155 printk("\n");
155} 156}
156 157
157void bad_super_trap(struct frame *fp) 158void bad_super_trap(struct frame *fp)
diff --git a/arch/m68knommu/platform/5307/head.S b/arch/m68knommu/platform/5307/head.S
index f2edb6498cd9..b9aa0ca29bfb 100644
--- a/arch/m68knommu/platform/5307/head.S
+++ b/arch/m68knommu/platform/5307/head.S
@@ -64,6 +64,26 @@
64 negl %d0 /* negate bits */ 64 negl %d0 /* negate bits */
65.endm 65.endm
66 66
67#elif defined(CONFIG_M520x)
68.macro GET_MEM_SIZE
69 clrl %d0
70 movel MCF_MBAR+MCFSIM_SDCS0, %d2 /* Get SDRAM chip select 0 config */
71 andl #0x1f, %d2 /* Get only the chip select size */
72 beq 3f /* Check if it is enabled */
73 addql #1, %d2 /* Form exponent */
74 moveql #1, %d0
75 lsll %d2, %d0 /* 2 ^ exponent */
763:
77 movel MCF_MBAR+MCFSIM_SDCS1, %d2 /* Get SDRAM chip select 1 config */
78 andl #0x1f, %d2 /* Get only the chip select size */
79 beq 4f /* Check if it is enabled */
80 addql #1, %d2 /* Form exponent */
81 moveql #1, %d1
82 lsll %d2, %d1 /* 2 ^ exponent */
83 addl %d1, %d0 /* Total size of SDRAM in d0 */
844:
85.endm
86
67#else 87#else
68#error "ERROR: I don't know how to probe your boards memory size?" 88#error "ERROR: I don't know how to probe your boards memory size?"
69#endif 89#endif
diff --git a/arch/m68knommu/platform/68360/head-ram.S b/arch/m68knommu/platform/68360/head-ram.S
index 2ea51479f13a..2ef06242398b 100644
--- a/arch/m68knommu/platform/68360/head-ram.S
+++ b/arch/m68knommu/platform/68360/head-ram.S
@@ -25,6 +25,7 @@
25.global _periph_base 25.global _periph_base
26 26
27#define RAMEND (CONFIG_RAMBASE + CONFIG_RAMSIZE) 27#define RAMEND (CONFIG_RAMBASE + CONFIG_RAMSIZE)
28#define ROMEND (CONFIG_ROMBASE + CONFIG_ROMSIZE)
28 29
29#define REGB 0x1000 30#define REGB 0x1000
30#define PEPAR (_dprbase + REGB + 0x0016) 31#define PEPAR (_dprbase + REGB + 0x0016)
@@ -175,7 +176,7 @@ configure_chip_select_0:
175 move.l %d0, BR0 176 move.l %d0, BR0
176 177
177configure_chip_select_1: 178configure_chip_select_1:
178 move.l #__rom_end, %d0 179 move.l #ROMEND, %d0
179 subi.l #__rom_start, %d0 180 subi.l #__rom_start, %d0
180 subq.l #0x01, %d0 181 subq.l #0x01, %d0
181 eori.l #SIM_OR_MASK, %d0 182 eori.l #SIM_OR_MASK, %d0
diff --git a/arch/mips/Kconfig b/arch/mips/Kconfig
index 27f83e642968..4d64960be035 100644
--- a/arch/mips/Kconfig
+++ b/arch/mips/Kconfig
@@ -16,6 +16,7 @@ config MIPS_MTX1
16 bool "4G Systems MTX-1 board" 16 bool "4G Systems MTX-1 board"
17 select DMA_NONCOHERENT 17 select DMA_NONCOHERENT
18 select HW_HAS_PCI 18 select HW_HAS_PCI
19 select RESOURCES_64BIT if PCI
19 select SOC_AU1500 20 select SOC_AU1500
20 select SYS_HAS_CPU_MIPS32_R1 21 select SYS_HAS_CPU_MIPS32_R1
21 select SYS_SUPPORTS_LITTLE_ENDIAN 22 select SYS_SUPPORTS_LITTLE_ENDIAN
@@ -32,6 +33,7 @@ config MIPS_PB1000
32 select SOC_AU1000 33 select SOC_AU1000
33 select DMA_NONCOHERENT 34 select DMA_NONCOHERENT
34 select HW_HAS_PCI 35 select HW_HAS_PCI
36 select RESOURCES_64BIT if PCI
35 select SWAP_IO_SPACE 37 select SWAP_IO_SPACE
36 select SYS_HAS_CPU_MIPS32_R1 38 select SYS_HAS_CPU_MIPS32_R1
37 select SYS_SUPPORTS_LITTLE_ENDIAN 39 select SYS_SUPPORTS_LITTLE_ENDIAN
@@ -41,6 +43,7 @@ config MIPS_PB1100
41 select SOC_AU1100 43 select SOC_AU1100
42 select DMA_NONCOHERENT 44 select DMA_NONCOHERENT
43 select HW_HAS_PCI 45 select HW_HAS_PCI
46 select RESOURCES_64BIT if PCI
44 select SWAP_IO_SPACE 47 select SWAP_IO_SPACE
45 select SYS_HAS_CPU_MIPS32_R1 48 select SYS_HAS_CPU_MIPS32_R1
46 select SYS_SUPPORTS_LITTLE_ENDIAN 49 select SYS_SUPPORTS_LITTLE_ENDIAN
@@ -50,6 +53,7 @@ config MIPS_PB1500
50 select SOC_AU1500 53 select SOC_AU1500
51 select DMA_NONCOHERENT 54 select DMA_NONCOHERENT
52 select HW_HAS_PCI 55 select HW_HAS_PCI
56 select RESOURCES_64BIT if PCI
53 select SYS_HAS_CPU_MIPS32_R1 57 select SYS_HAS_CPU_MIPS32_R1
54 select SYS_SUPPORTS_LITTLE_ENDIAN 58 select SYS_SUPPORTS_LITTLE_ENDIAN
55 59
@@ -59,6 +63,7 @@ config MIPS_PB1550
59 select DMA_NONCOHERENT 63 select DMA_NONCOHERENT
60 select HW_HAS_PCI 64 select HW_HAS_PCI
61 select MIPS_DISABLE_OBSOLETE_IDE 65 select MIPS_DISABLE_OBSOLETE_IDE
66 select RESOURCES_64BIT if PCI
62 select SYS_HAS_CPU_MIPS32_R1 67 select SYS_HAS_CPU_MIPS32_R1
63 select SYS_SUPPORTS_LITTLE_ENDIAN 68 select SYS_SUPPORTS_LITTLE_ENDIAN
64 69
@@ -67,6 +72,7 @@ config MIPS_PB1200
67 select SOC_AU1200 72 select SOC_AU1200
68 select DMA_NONCOHERENT 73 select DMA_NONCOHERENT
69 select MIPS_DISABLE_OBSOLETE_IDE 74 select MIPS_DISABLE_OBSOLETE_IDE
75 select RESOURCES_64BIT if PCI
70 select SYS_HAS_CPU_MIPS32_R1 76 select SYS_HAS_CPU_MIPS32_R1
71 select SYS_SUPPORTS_LITTLE_ENDIAN 77 select SYS_SUPPORTS_LITTLE_ENDIAN
72 78
@@ -75,6 +81,7 @@ config MIPS_DB1000
75 select SOC_AU1000 81 select SOC_AU1000
76 select DMA_NONCOHERENT 82 select DMA_NONCOHERENT
77 select HW_HAS_PCI 83 select HW_HAS_PCI
84 select RESOURCES_64BIT if PCI
78 select SYS_HAS_CPU_MIPS32_R1 85 select SYS_HAS_CPU_MIPS32_R1
79 select SYS_SUPPORTS_LITTLE_ENDIAN 86 select SYS_SUPPORTS_LITTLE_ENDIAN
80 87
@@ -91,6 +98,7 @@ config MIPS_DB1500
91 select DMA_NONCOHERENT 98 select DMA_NONCOHERENT
92 select HW_HAS_PCI 99 select HW_HAS_PCI
93 select MIPS_DISABLE_OBSOLETE_IDE 100 select MIPS_DISABLE_OBSOLETE_IDE
101 select RESOURCES_64BIT if PCI
94 select SYS_HAS_CPU_MIPS32_R1 102 select SYS_HAS_CPU_MIPS32_R1
95 select SYS_SUPPORTS_BIG_ENDIAN 103 select SYS_SUPPORTS_BIG_ENDIAN
96 select SYS_SUPPORTS_LITTLE_ENDIAN 104 select SYS_SUPPORTS_LITTLE_ENDIAN
@@ -101,6 +109,7 @@ config MIPS_DB1550
101 select HW_HAS_PCI 109 select HW_HAS_PCI
102 select DMA_NONCOHERENT 110 select DMA_NONCOHERENT
103 select MIPS_DISABLE_OBSOLETE_IDE 111 select MIPS_DISABLE_OBSOLETE_IDE
112 select RESOURCES_64BIT if PCI
104 select SYS_HAS_CPU_MIPS32_R1 113 select SYS_HAS_CPU_MIPS32_R1
105 select SYS_SUPPORTS_LITTLE_ENDIAN 114 select SYS_SUPPORTS_LITTLE_ENDIAN
106 115
@@ -1268,6 +1277,7 @@ config CPU_RM9000
1268 select CPU_SUPPORTS_32BIT_KERNEL 1277 select CPU_SUPPORTS_32BIT_KERNEL
1269 select CPU_SUPPORTS_64BIT_KERNEL 1278 select CPU_SUPPORTS_64BIT_KERNEL
1270 select CPU_SUPPORTS_HIGHMEM 1279 select CPU_SUPPORTS_HIGHMEM
1280 select WEAK_ORDERING
1271 1281
1272config CPU_SB1 1282config CPU_SB1
1273 bool "SB1" 1283 bool "SB1"
@@ -1276,6 +1286,7 @@ config CPU_SB1
1276 select CPU_SUPPORTS_32BIT_KERNEL 1286 select CPU_SUPPORTS_32BIT_KERNEL
1277 select CPU_SUPPORTS_64BIT_KERNEL 1287 select CPU_SUPPORTS_64BIT_KERNEL
1278 select CPU_SUPPORTS_HIGHMEM 1288 select CPU_SUPPORTS_HIGHMEM
1289 select WEAK_ORDERING
1279 1290
1280endchoice 1291endchoice
1281 1292
@@ -1336,6 +1347,8 @@ config SYS_HAS_CPU_RM9000
1336config SYS_HAS_CPU_SB1 1347config SYS_HAS_CPU_SB1
1337 bool 1348 bool
1338 1349
1350config WEAK_ORDERING
1351 bool
1339endmenu 1352endmenu
1340 1353
1341# 1354#
@@ -1940,6 +1953,11 @@ config COMPAT
1940 depends on MIPS32_COMPAT 1953 depends on MIPS32_COMPAT
1941 default y 1954 default y
1942 1955
1956config SYSVIPC_COMPAT
1957 bool
1958 depends on COMPAT && SYSVIPC
1959 default y
1960
1943config MIPS32_O32 1961config MIPS32_O32
1944 bool "Kernel support for o32 binaries" 1962 bool "Kernel support for o32 binaries"
1945 depends on MIPS32_COMPAT 1963 depends on MIPS32_COMPAT
diff --git a/arch/mips/kernel/linux32.c b/arch/mips/kernel/linux32.c
index 7a3ebbeba1f3..b061c9aa6302 100644
--- a/arch/mips/kernel/linux32.c
+++ b/arch/mips/kernel/linux32.c
@@ -382,531 +382,6 @@ asmlinkage int sys32_sched_rr_get_interval(compat_pid_t pid,
382 return ret; 382 return ret;
383} 383}
384 384
385struct msgbuf32 { s32 mtype; char mtext[1]; };
386
387struct ipc_perm32
388{
389 key_t key;
390 __compat_uid_t uid;
391 __compat_gid_t gid;
392 __compat_uid_t cuid;
393 __compat_gid_t cgid;
394 compat_mode_t mode;
395 unsigned short seq;
396};
397
398struct ipc64_perm32 {
399 key_t key;
400 __compat_uid_t uid;
401 __compat_gid_t gid;
402 __compat_uid_t cuid;
403 __compat_gid_t cgid;
404 compat_mode_t mode;
405 unsigned short seq;
406 unsigned short __pad1;
407 unsigned int __unused1;
408 unsigned int __unused2;
409};
410
411struct semid_ds32 {
412 struct ipc_perm32 sem_perm; /* permissions .. see ipc.h */
413 compat_time_t sem_otime; /* last semop time */
414 compat_time_t sem_ctime; /* last change time */
415 u32 sem_base; /* ptr to first semaphore in array */
416 u32 sem_pending; /* pending operations to be processed */
417 u32 sem_pending_last; /* last pending operation */
418 u32 undo; /* undo requests on this array */
419 unsigned short sem_nsems; /* no. of semaphores in array */
420};
421
422struct semid64_ds32 {
423 struct ipc64_perm32 sem_perm;
424 compat_time_t sem_otime;
425 compat_time_t sem_ctime;
426 unsigned int sem_nsems;
427 unsigned int __unused1;
428 unsigned int __unused2;
429};
430
431struct msqid_ds32
432{
433 struct ipc_perm32 msg_perm;
434 u32 msg_first;
435 u32 msg_last;
436 compat_time_t msg_stime;
437 compat_time_t msg_rtime;
438 compat_time_t msg_ctime;
439 u32 wwait;
440 u32 rwait;
441 unsigned short msg_cbytes;
442 unsigned short msg_qnum;
443 unsigned short msg_qbytes;
444 compat_ipc_pid_t msg_lspid;
445 compat_ipc_pid_t msg_lrpid;
446};
447
448struct msqid64_ds32 {
449 struct ipc64_perm32 msg_perm;
450 compat_time_t msg_stime;
451 unsigned int __unused1;
452 compat_time_t msg_rtime;
453 unsigned int __unused2;
454 compat_time_t msg_ctime;
455 unsigned int __unused3;
456 unsigned int msg_cbytes;
457 unsigned int msg_qnum;
458 unsigned int msg_qbytes;
459 compat_pid_t msg_lspid;
460 compat_pid_t msg_lrpid;
461 unsigned int __unused4;
462 unsigned int __unused5;
463};
464
465struct shmid_ds32 {
466 struct ipc_perm32 shm_perm;
467 int shm_segsz;
468 compat_time_t shm_atime;
469 compat_time_t shm_dtime;
470 compat_time_t shm_ctime;
471 compat_ipc_pid_t shm_cpid;
472 compat_ipc_pid_t shm_lpid;
473 unsigned short shm_nattch;
474};
475
476struct shmid64_ds32 {
477 struct ipc64_perm32 shm_perm;
478 compat_size_t shm_segsz;
479 compat_time_t shm_atime;
480 compat_time_t shm_dtime;
481 compat_time_t shm_ctime;
482 compat_pid_t shm_cpid;
483 compat_pid_t shm_lpid;
484 unsigned int shm_nattch;
485 unsigned int __unused1;
486 unsigned int __unused2;
487};
488
489struct ipc_kludge32 {
490 u32 msgp;
491 s32 msgtyp;
492};
493
494static int
495do_sys32_semctl(int first, int second, int third, void __user *uptr)
496{
497 union semun fourth;
498 u32 pad;
499 int err, err2;
500 struct semid64_ds s;
501 mm_segment_t old_fs;
502
503 if (!uptr)
504 return -EINVAL;
505 err = -EFAULT;
506 if (get_user (pad, (u32 __user *)uptr))
507 return err;
508 if ((third & ~IPC_64) == SETVAL)
509 fourth.val = (int)pad;
510 else
511 fourth.__pad = (void __user *)A(pad);
512 switch (third & ~IPC_64) {
513 case IPC_INFO:
514 case IPC_RMID:
515 case IPC_SET:
516 case SEM_INFO:
517 case GETVAL:
518 case GETPID:
519 case GETNCNT:
520 case GETZCNT:
521 case GETALL:
522 case SETVAL:
523 case SETALL:
524 err = sys_semctl (first, second, third, fourth);
525 break;
526
527 case IPC_STAT:
528 case SEM_STAT:
529 fourth.__pad = (struct semid64_ds __user *)&s;
530 old_fs = get_fs();
531 set_fs(KERNEL_DS);
532 err = sys_semctl(first, second, third | IPC_64, fourth);
533 set_fs(old_fs);
534
535 if (third & IPC_64) {
536 struct semid64_ds32 __user *usp64 = (struct semid64_ds32 __user *) A(pad);
537
538 if (!access_ok(VERIFY_WRITE, usp64, sizeof(*usp64))) {
539 err = -EFAULT;
540 break;
541 }
542 err2 = __put_user(s.sem_perm.key, &usp64->sem_perm.key);
543 err2 |= __put_user(s.sem_perm.uid, &usp64->sem_perm.uid);
544 err2 |= __put_user(s.sem_perm.gid, &usp64->sem_perm.gid);
545 err2 |= __put_user(s.sem_perm.cuid, &usp64->sem_perm.cuid);
546 err2 |= __put_user(s.sem_perm.cgid, &usp64->sem_perm.cgid);
547 err2 |= __put_user(s.sem_perm.mode, &usp64->sem_perm.mode);
548 err2 |= __put_user(s.sem_perm.seq, &usp64->sem_perm.seq);
549 err2 |= __put_user(s.sem_otime, &usp64->sem_otime);
550 err2 |= __put_user(s.sem_ctime, &usp64->sem_ctime);
551 err2 |= __put_user(s.sem_nsems, &usp64->sem_nsems);
552 } else {
553 struct semid_ds32 __user *usp32 = (struct semid_ds32 __user *) A(pad);
554
555 if (!access_ok(VERIFY_WRITE, usp32, sizeof(*usp32))) {
556 err = -EFAULT;
557 break;
558 }
559 err2 = __put_user(s.sem_perm.key, &usp32->sem_perm.key);
560 err2 |= __put_user(s.sem_perm.uid, &usp32->sem_perm.uid);
561 err2 |= __put_user(s.sem_perm.gid, &usp32->sem_perm.gid);
562 err2 |= __put_user(s.sem_perm.cuid, &usp32->sem_perm.cuid);
563 err2 |= __put_user(s.sem_perm.cgid, &usp32->sem_perm.cgid);
564 err2 |= __put_user(s.sem_perm.mode, &usp32->sem_perm.mode);
565 err2 |= __put_user(s.sem_perm.seq, &usp32->sem_perm.seq);
566 err2 |= __put_user(s.sem_otime, &usp32->sem_otime);
567 err2 |= __put_user(s.sem_ctime, &usp32->sem_ctime);
568 err2 |= __put_user(s.sem_nsems, &usp32->sem_nsems);
569 }
570 if (err2)
571 err = -EFAULT;
572 break;
573
574 default:
575 err = - EINVAL;
576 break;
577 }
578
579 return err;
580}
581
582static int
583do_sys32_msgsnd (int first, int second, int third, void __user *uptr)
584{
585 struct msgbuf32 __user *up = (struct msgbuf32 __user *)uptr;
586 struct msgbuf *p;
587 mm_segment_t old_fs;
588 int err;
589
590 if (second < 0)
591 return -EINVAL;
592 p = kmalloc (second + sizeof (struct msgbuf)
593 + 4, GFP_USER);
594 if (!p)
595 return -ENOMEM;
596 err = get_user (p->mtype, &up->mtype);
597 if (err)
598 goto out;
599 err |= __copy_from_user (p->mtext, &up->mtext, second);
600 if (err)
601 goto out;
602 old_fs = get_fs ();
603 set_fs (KERNEL_DS);
604 err = sys_msgsnd (first, (struct msgbuf __user *)p, second, third);
605 set_fs (old_fs);
606out:
607 kfree (p);
608
609 return err;
610}
611
612static int
613do_sys32_msgrcv (int first, int second, int msgtyp, int third,
614 int version, void __user *uptr)
615{
616 struct msgbuf32 __user *up;
617 struct msgbuf *p;
618 mm_segment_t old_fs;
619 int err;
620
621 if (!version) {
622 struct ipc_kludge32 __user *uipck = (struct ipc_kludge32 __user *)uptr;
623 struct ipc_kludge32 ipck;
624
625 err = -EINVAL;
626 if (!uptr)
627 goto out;
628 err = -EFAULT;
629 if (copy_from_user (&ipck, uipck, sizeof (struct ipc_kludge32)))
630 goto out;
631 uptr = (void __user *)AA(ipck.msgp);
632 msgtyp = ipck.msgtyp;
633 }
634
635 if (second < 0)
636 return -EINVAL;
637 err = -ENOMEM;
638 p = kmalloc (second + sizeof (struct msgbuf) + 4, GFP_USER);
639 if (!p)
640 goto out;
641 old_fs = get_fs ();
642 set_fs (KERNEL_DS);
643 err = sys_msgrcv (first, (struct msgbuf __user *)p, second + 4, msgtyp, third);
644 set_fs (old_fs);
645 if (err < 0)
646 goto free_then_out;
647 up = (struct msgbuf32 __user *)uptr;
648 if (put_user (p->mtype, &up->mtype) ||
649 __copy_to_user (&up->mtext, p->mtext, err))
650 err = -EFAULT;
651free_then_out:
652 kfree (p);
653out:
654 return err;
655}
656
657static int
658do_sys32_msgctl (int first, int second, void __user *uptr)
659{
660 int err = -EINVAL, err2;
661 struct msqid64_ds m;
662 struct msqid_ds32 __user *up32 = (struct msqid_ds32 __user *)uptr;
663 struct msqid64_ds32 __user *up64 = (struct msqid64_ds32 __user *)uptr;
664 mm_segment_t old_fs;
665
666 switch (second & ~IPC_64) {
667 case IPC_INFO:
668 case IPC_RMID:
669 case MSG_INFO:
670 err = sys_msgctl (first, second, (struct msqid_ds __user *)uptr);
671 break;
672
673 case IPC_SET:
674 if (second & IPC_64) {
675 if (!access_ok(VERIFY_READ, up64, sizeof(*up64))) {
676 err = -EFAULT;
677 break;
678 }
679 err = __get_user(m.msg_perm.uid, &up64->msg_perm.uid);
680 err |= __get_user(m.msg_perm.gid, &up64->msg_perm.gid);
681 err |= __get_user(m.msg_perm.mode, &up64->msg_perm.mode);
682 err |= __get_user(m.msg_qbytes, &up64->msg_qbytes);
683 } else {
684 if (!access_ok(VERIFY_READ, up32, sizeof(*up32))) {
685 err = -EFAULT;
686 break;
687 }
688 err = __get_user(m.msg_perm.uid, &up32->msg_perm.uid);
689 err |= __get_user(m.msg_perm.gid, &up32->msg_perm.gid);
690 err |= __get_user(m.msg_perm.mode, &up32->msg_perm.mode);
691 err |= __get_user(m.msg_qbytes, &up32->msg_qbytes);
692 }
693 if (err)
694 break;
695 old_fs = get_fs();
696 set_fs(KERNEL_DS);
697 err = sys_msgctl(first, second | IPC_64, (struct msqid_ds __user *)&m);
698 set_fs(old_fs);
699 break;
700
701 case IPC_STAT:
702 case MSG_STAT:
703 old_fs = get_fs();
704 set_fs(KERNEL_DS);
705 err = sys_msgctl(first, second | IPC_64, (struct msqid_ds __user *)&m);
706 set_fs(old_fs);
707 if (second & IPC_64) {
708 if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) {
709 err = -EFAULT;
710 break;
711 }
712 err2 = __put_user(m.msg_perm.key, &up64->msg_perm.key);
713 err2 |= __put_user(m.msg_perm.uid, &up64->msg_perm.uid);
714 err2 |= __put_user(m.msg_perm.gid, &up64->msg_perm.gid);
715 err2 |= __put_user(m.msg_perm.cuid, &up64->msg_perm.cuid);
716 err2 |= __put_user(m.msg_perm.cgid, &up64->msg_perm.cgid);
717 err2 |= __put_user(m.msg_perm.mode, &up64->msg_perm.mode);
718 err2 |= __put_user(m.msg_perm.seq, &up64->msg_perm.seq);
719 err2 |= __put_user(m.msg_stime, &up64->msg_stime);
720 err2 |= __put_user(m.msg_rtime, &up64->msg_rtime);
721 err2 |= __put_user(m.msg_ctime, &up64->msg_ctime);
722 err2 |= __put_user(m.msg_cbytes, &up64->msg_cbytes);
723 err2 |= __put_user(m.msg_qnum, &up64->msg_qnum);
724 err2 |= __put_user(m.msg_qbytes, &up64->msg_qbytes);
725 err2 |= __put_user(m.msg_lspid, &up64->msg_lspid);
726 err2 |= __put_user(m.msg_lrpid, &up64->msg_lrpid);
727 if (err2)
728 err = -EFAULT;
729 } else {
730 if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) {
731 err = -EFAULT;
732 break;
733 }
734 err2 = __put_user(m.msg_perm.key, &up32->msg_perm.key);
735 err2 |= __put_user(m.msg_perm.uid, &up32->msg_perm.uid);
736 err2 |= __put_user(m.msg_perm.gid, &up32->msg_perm.gid);
737 err2 |= __put_user(m.msg_perm.cuid, &up32->msg_perm.cuid);
738 err2 |= __put_user(m.msg_perm.cgid, &up32->msg_perm.cgid);
739 err2 |= __put_user(m.msg_perm.mode, &up32->msg_perm.mode);
740 err2 |= __put_user(m.msg_perm.seq, &up32->msg_perm.seq);
741 err2 |= __put_user(m.msg_stime, &up32->msg_stime);
742 err2 |= __put_user(m.msg_rtime, &up32->msg_rtime);
743 err2 |= __put_user(m.msg_ctime, &up32->msg_ctime);
744 err2 |= __put_user(m.msg_cbytes, &up32->msg_cbytes);
745 err2 |= __put_user(m.msg_qnum, &up32->msg_qnum);
746 err2 |= __put_user(m.msg_qbytes, &up32->msg_qbytes);
747 err2 |= __put_user(m.msg_lspid, &up32->msg_lspid);
748 err2 |= __put_user(m.msg_lrpid, &up32->msg_lrpid);
749 if (err2)
750 err = -EFAULT;
751 }
752 break;
753 }
754
755 return err;
756}
757
758static int
759do_sys32_shmat (int first, int second, int third, int version, void __user *uptr)
760{
761 unsigned long raddr;
762 u32 __user *uaddr = (u32 __user *)A((u32)third);
763 int err = -EINVAL;
764
765 if (version == 1)
766 return err;
767 err = do_shmat (first, uptr, second, &raddr);
768 if (err)
769 return err;
770 err = put_user (raddr, uaddr);
771 return err;
772}
773
774struct shm_info32 {
775 int used_ids;
776 u32 shm_tot, shm_rss, shm_swp;
777 u32 swap_attempts, swap_successes;
778};
779
780static int
781do_sys32_shmctl (int first, int second, void __user *uptr)
782{
783 struct shmid64_ds32 __user *up64 = (struct shmid64_ds32 __user *)uptr;
784 struct shmid_ds32 __user *up32 = (struct shmid_ds32 __user *)uptr;
785 struct shm_info32 __user *uip = (struct shm_info32 __user *)uptr;
786 int err = -EFAULT, err2;
787 struct shmid64_ds s64;
788 mm_segment_t old_fs;
789 struct shm_info si;
790 struct shmid_ds s;
791
792 switch (second & ~IPC_64) {
793 case IPC_INFO:
794 second = IPC_INFO; /* So that we don't have to translate it */
795 case IPC_RMID:
796 case SHM_LOCK:
797 case SHM_UNLOCK:
798 err = sys_shmctl(first, second, (struct shmid_ds __user *)uptr);
799 break;
800 case IPC_SET:
801 if (second & IPC_64) {
802 err = get_user(s.shm_perm.uid, &up64->shm_perm.uid);
803 err |= get_user(s.shm_perm.gid, &up64->shm_perm.gid);
804 err |= get_user(s.shm_perm.mode, &up64->shm_perm.mode);
805 } else {
806 err = get_user(s.shm_perm.uid, &up32->shm_perm.uid);
807 err |= get_user(s.shm_perm.gid, &up32->shm_perm.gid);
808 err |= get_user(s.shm_perm.mode, &up32->shm_perm.mode);
809 }
810 if (err)
811 break;
812 old_fs = get_fs();
813 set_fs(KERNEL_DS);
814 err = sys_shmctl(first, second & ~IPC_64, (struct shmid_ds __user *)&s);
815 set_fs(old_fs);
816 break;
817
818 case IPC_STAT:
819 case SHM_STAT:
820 old_fs = get_fs();
821 set_fs(KERNEL_DS);
822 err = sys_shmctl(first, second | IPC_64, (void __user *) &s64);
823 set_fs(old_fs);
824 if (err < 0)
825 break;
826 if (second & IPC_64) {
827 if (!access_ok(VERIFY_WRITE, up64, sizeof(*up64))) {
828 err = -EFAULT;
829 break;
830 }
831 err2 = __put_user(s64.shm_perm.key, &up64->shm_perm.key);
832 err2 |= __put_user(s64.shm_perm.uid, &up64->shm_perm.uid);
833 err2 |= __put_user(s64.shm_perm.gid, &up64->shm_perm.gid);
834 err2 |= __put_user(s64.shm_perm.cuid, &up64->shm_perm.cuid);
835 err2 |= __put_user(s64.shm_perm.cgid, &up64->shm_perm.cgid);
836 err2 |= __put_user(s64.shm_perm.mode, &up64->shm_perm.mode);
837 err2 |= __put_user(s64.shm_perm.seq, &up64->shm_perm.seq);
838 err2 |= __put_user(s64.shm_atime, &up64->shm_atime);
839 err2 |= __put_user(s64.shm_dtime, &up64->shm_dtime);
840 err2 |= __put_user(s64.shm_ctime, &up64->shm_ctime);
841 err2 |= __put_user(s64.shm_segsz, &up64->shm_segsz);
842 err2 |= __put_user(s64.shm_nattch, &up64->shm_nattch);
843 err2 |= __put_user(s64.shm_cpid, &up64->shm_cpid);
844 err2 |= __put_user(s64.shm_lpid, &up64->shm_lpid);
845 } else {
846 if (!access_ok(VERIFY_WRITE, up32, sizeof(*up32))) {
847 err = -EFAULT;
848 break;
849 }
850 err2 = __put_user(s64.shm_perm.key, &up32->shm_perm.key);
851 err2 |= __put_user(s64.shm_perm.uid, &up32->shm_perm.uid);
852 err2 |= __put_user(s64.shm_perm.gid, &up32->shm_perm.gid);
853 err2 |= __put_user(s64.shm_perm.cuid, &up32->shm_perm.cuid);
854 err2 |= __put_user(s64.shm_perm.cgid, &up32->shm_perm.cgid);
855 err2 |= __put_user(s64.shm_perm.mode, &up32->shm_perm.mode);
856 err2 |= __put_user(s64.shm_perm.seq, &up32->shm_perm.seq);
857 err2 |= __put_user(s64.shm_atime, &up32->shm_atime);
858 err2 |= __put_user(s64.shm_dtime, &up32->shm_dtime);
859 err2 |= __put_user(s64.shm_ctime, &up32->shm_ctime);
860 err2 |= __put_user(s64.shm_segsz, &up32->shm_segsz);
861 err2 |= __put_user(s64.shm_nattch, &up32->shm_nattch);
862 err2 |= __put_user(s64.shm_cpid, &up32->shm_cpid);
863 err2 |= __put_user(s64.shm_lpid, &up32->shm_lpid);
864 }
865 if (err2)
866 err = -EFAULT;
867 break;
868
869 case SHM_INFO:
870 old_fs = get_fs();
871 set_fs(KERNEL_DS);
872 err = sys_shmctl(first, second, (void __user *)&si);
873 set_fs(old_fs);
874 if (err < 0)
875 break;
876 err2 = put_user(si.used_ids, &uip->used_ids);
877 err2 |= __put_user(si.shm_tot, &uip->shm_tot);
878 err2 |= __put_user(si.shm_rss, &uip->shm_rss);
879 err2 |= __put_user(si.shm_swp, &uip->shm_swp);
880 err2 |= __put_user(si.swap_attempts, &uip->swap_attempts);
881 err2 |= __put_user (si.swap_successes, &uip->swap_successes);
882 if (err2)
883 err = -EFAULT;
884 break;
885
886 default:
887 err = -EINVAL;
888 break;
889 }
890
891 return err;
892}
893
894static int sys32_semtimedop(int semid, struct sembuf __user *tsems, int nsems,
895 const struct compat_timespec __user *timeout32)
896{
897 struct compat_timespec t32;
898 struct timespec __user *t64 = compat_alloc_user_space(sizeof(*t64));
899
900 if (copy_from_user(&t32, timeout32, sizeof(t32)))
901 return -EFAULT;
902
903 if (put_user(t32.tv_sec, &t64->tv_sec) ||
904 put_user(t32.tv_nsec, &t64->tv_nsec))
905 return -EFAULT;
906
907 return sys_semtimedop(semid, tsems, nsems, t64);
908}
909
910asmlinkage long 385asmlinkage long
911sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth) 386sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
912{ 387{
@@ -918,48 +393,43 @@ sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
918 switch (call) { 393 switch (call) {
919 case SEMOP: 394 case SEMOP:
920 /* struct sembuf is the same on 32 and 64bit :)) */ 395 /* struct sembuf is the same on 32 and 64bit :)) */
921 err = sys_semtimedop (first, (struct sembuf __user *)AA(ptr), second, 396 err = sys_semtimedop(first, compat_ptr(ptr), second, NULL);
922 NULL);
923 break; 397 break;
924 case SEMTIMEDOP: 398 case SEMTIMEDOP:
925 err = sys32_semtimedop (first, (struct sembuf __user *)AA(ptr), second, 399 err = compat_sys_semtimedop(first, compat_ptr(ptr), second,
926 (const struct compat_timespec __user *)AA(fifth)); 400 compat_ptr(fifth));
927 break; 401 break;
928 case SEMGET: 402 case SEMGET:
929 err = sys_semget (first, second, third); 403 err = sys_semget(first, second, third);
930 break; 404 break;
931 case SEMCTL: 405 case SEMCTL:
932 err = do_sys32_semctl (first, second, third, 406 err = compat_sys_semctl(first, second, third, compat_ptr(ptr));
933 (void __user *)AA(ptr));
934 break; 407 break;
935
936 case MSGSND: 408 case MSGSND:
937 err = do_sys32_msgsnd (first, second, third, 409 err = compat_sys_msgsnd(first, second, third, compat_ptr(ptr));
938 (void __user *)AA(ptr));
939 break; 410 break;
940 case MSGRCV: 411 case MSGRCV:
941 err = do_sys32_msgrcv (first, second, fifth, third, 412 err = compat_sys_msgrcv(first, second, fifth, third,
942 version, (void __user *)AA(ptr)); 413 version, compat_ptr(ptr));
943 break; 414 break;
944 case MSGGET: 415 case MSGGET:
945 err = sys_msgget ((key_t) first, second); 416 err = sys_msgget((key_t) first, second);
946 break; 417 break;
947 case MSGCTL: 418 case MSGCTL:
948 err = do_sys32_msgctl (first, second, (void __user *)AA(ptr)); 419 err = compat_sys_msgctl(first, second, compat_ptr(ptr));
949 break; 420 break;
950
951 case SHMAT: 421 case SHMAT:
952 err = do_sys32_shmat (first, second, third, 422 err = compat_sys_shmat(first, second, third, version,
953 version, (void __user *)AA(ptr)); 423 compat_ptr(ptr));
954 break; 424 break;
955 case SHMDT: 425 case SHMDT:
956 err = sys_shmdt ((char __user *)A(ptr)); 426 err = sys_shmdt(compat_ptr(ptr));
957 break; 427 break;
958 case SHMGET: 428 case SHMGET:
959 err = sys_shmget (first, (unsigned)second, third); 429 err = sys_shmget(first, (unsigned)second, third);
960 break; 430 break;
961 case SHMCTL: 431 case SHMCTL:
962 err = do_sys32_shmctl (first, second, (void __user *)AA(ptr)); 432 err = compat_sys_shmctl(first, second, compat_ptr(ptr));
963 break; 433 break;
964 default: 434 default:
965 err = -EINVAL; 435 err = -EINVAL;
@@ -969,18 +439,16 @@ sys32_ipc (u32 call, int first, int second, int third, u32 ptr, u32 fifth)
969 return err; 439 return err;
970} 440}
971 441
972asmlinkage long sys32_shmat(int shmid, char __user *shmaddr, 442#ifdef CONFIG_MIPS32_N32
973 int shmflg, int32_t __user *addr) 443asmlinkage long sysn32_semctl(int semid, int semnum, int cmd, union semun arg)
974{ 444{
975 unsigned long raddr; 445 /* compat_sys_semctl expects a pointer to union semun */
976 int err; 446 u32 __user *uptr = compat_alloc_user_space(sizeof(u32));
977 447 if (put_user(ptr_to_compat(arg.__pad), uptr))
978 err = do_shmat(shmid, shmaddr, shmflg, &raddr); 448 return -EFAULT;
979 if (err) 449 return compat_sys_semctl(semid, semnum, cmd, uptr);
980 return err;
981
982 return put_user(raddr, addr);
983} 450}
451#endif
984 452
985struct sysctl_args32 453struct sysctl_args32
986{ 454{
diff --git a/arch/mips/kernel/scall64-n32.S b/arch/mips/kernel/scall64-n32.S
index 5b18f265d75b..34567d81f940 100644
--- a/arch/mips/kernel/scall64-n32.S
+++ b/arch/mips/kernel/scall64-n32.S
@@ -149,8 +149,8 @@ EXPORT(sysn32_call_table)
149 PTR sys_mincore 149 PTR sys_mincore
150 PTR sys_madvise 150 PTR sys_madvise
151 PTR sys_shmget 151 PTR sys_shmget
152 PTR sys32_shmat 152 PTR sys_shmat
153 PTR sys_shmctl /* 6030 */ 153 PTR compat_sys_shmctl /* 6030 */
154 PTR sys_dup 154 PTR sys_dup
155 PTR sys_dup2 155 PTR sys_dup2
156 PTR sys_pause 156 PTR sys_pause
@@ -184,12 +184,12 @@ EXPORT(sysn32_call_table)
184 PTR sys32_newuname 184 PTR sys32_newuname
185 PTR sys_semget 185 PTR sys_semget
186 PTR sys_semop 186 PTR sys_semop
187 PTR sys_semctl 187 PTR sysn32_semctl
188 PTR sys_shmdt /* 6065 */ 188 PTR sys_shmdt /* 6065 */
189 PTR sys_msgget 189 PTR sys_msgget
190 PTR sys_msgsnd 190 PTR compat_sys_msgsnd
191 PTR sys_msgrcv 191 PTR compat_sys_msgrcv
192 PTR sys_msgctl 192 PTR compat_sys_msgctl
193 PTR compat_sys_fcntl /* 6070 */ 193 PTR compat_sys_fcntl /* 6070 */
194 PTR sys_flock 194 PTR sys_flock
195 PTR sys_fsync 195 PTR sys_fsync
@@ -335,7 +335,7 @@ EXPORT(sysn32_call_table)
335 PTR compat_sys_fcntl64 335 PTR compat_sys_fcntl64
336 PTR sys_set_tid_address 336 PTR sys_set_tid_address
337 PTR sys_restart_syscall 337 PTR sys_restart_syscall
338 PTR sys_semtimedop /* 6215 */ 338 PTR compat_sys_semtimedop /* 6215 */
339 PTR sys_fadvise64_64 339 PTR sys_fadvise64_64
340 PTR compat_sys_statfs64 340 PTR compat_sys_statfs64
341 PTR compat_sys_fstatfs64 341 PTR compat_sys_fstatfs64
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c
index 49db516789e0..f2a8701e414d 100644
--- a/arch/mips/kernel/smp.c
+++ b/arch/mips/kernel/smp.c
@@ -172,7 +172,7 @@ int smp_call_function (void (*func) (void *info), void *info, int retry,
172 172
173 spin_lock(&smp_call_lock); 173 spin_lock(&smp_call_lock);
174 call_data = &data; 174 call_data = &data;
175 mb(); 175 smp_mb();
176 176
177 /* Send a message to all other CPUs and wait for them to respond */ 177 /* Send a message to all other CPUs and wait for them to respond */
178 for_each_online_cpu(i) 178 for_each_online_cpu(i)
@@ -204,7 +204,7 @@ void smp_call_function_interrupt(void)
204 * Notify initiating CPU that I've grabbed the data and am 204 * Notify initiating CPU that I've grabbed the data and am
205 * about to execute the function. 205 * about to execute the function.
206 */ 206 */
207 mb(); 207 smp_mb();
208 atomic_inc(&call_data->started); 208 atomic_inc(&call_data->started);
209 209
210 /* 210 /*
@@ -215,7 +215,7 @@ void smp_call_function_interrupt(void)
215 irq_exit(); 215 irq_exit();
216 216
217 if (wait) { 217 if (wait) {
218 mb(); 218 smp_mb();
219 atomic_inc(&call_data->finished); 219 atomic_inc(&call_data->finished);
220 } 220 }
221} 221}
diff --git a/arch/mips/lib-32/Makefile b/arch/mips/lib-32/Makefile
index ad285786e74b..dcd4d2ed2ac4 100644
--- a/arch/mips/lib-32/Makefile
+++ b/arch/mips/lib-32/Makefile
@@ -2,7 +2,7 @@
2# Makefile for MIPS-specific library files.. 2# Makefile for MIPS-specific library files..
3# 3#
4 4
5lib-y += csum_partial.o memset.o watch.o 5lib-y += memset.o watch.o
6 6
7obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o 7obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o
8obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o 8obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o
diff --git a/arch/mips/lib-32/csum_partial.S b/arch/mips/lib-32/csum_partial.S
deleted file mode 100644
index ea257dbdcc40..000000000000
--- a/arch/mips/lib-32/csum_partial.S
+++ /dev/null
@@ -1,240 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 1998 Ralf Baechle
7 */
8#include <asm/asm.h>
9#include <asm/regdef.h>
10
11#define ADDC(sum,reg) \
12 addu sum, reg; \
13 sltu v1, sum, reg; \
14 addu sum, v1
15
16#define CSUM_BIGCHUNK(src, offset, sum, t0, t1, t2, t3) \
17 lw t0, (offset + 0x00)(src); \
18 lw t1, (offset + 0x04)(src); \
19 lw t2, (offset + 0x08)(src); \
20 lw t3, (offset + 0x0c)(src); \
21 ADDC(sum, t0); \
22 ADDC(sum, t1); \
23 ADDC(sum, t2); \
24 ADDC(sum, t3); \
25 lw t0, (offset + 0x10)(src); \
26 lw t1, (offset + 0x14)(src); \
27 lw t2, (offset + 0x18)(src); \
28 lw t3, (offset + 0x1c)(src); \
29 ADDC(sum, t0); \
30 ADDC(sum, t1); \
31 ADDC(sum, t2); \
32 ADDC(sum, t3); \
33
34/*
35 * a0: source address
36 * a1: length of the area to checksum
37 * a2: partial checksum
38 */
39
40#define src a0
41#define dest a1
42#define sum v0
43
44 .text
45 .set noreorder
46
47/* unknown src alignment and < 8 bytes to go */
48small_csumcpy:
49 move a1, t2
50
51 andi t0, a1, 4
52 beqz t0, 1f
53 andi t0, a1, 2
54
55 /* Still a full word to go */
56 ulw t1, (src)
57 addiu src, 4
58 ADDC(sum, t1)
59
601: move t1, zero
61 beqz t0, 1f
62 andi t0, a1, 1
63
64 /* Still a halfword to go */
65 ulhu t1, (src)
66 addiu src, 2
67
681: beqz t0, 1f
69 sll t1, t1, 16
70
71 lbu t2, (src)
72 nop
73
74#ifdef __MIPSEB__
75 sll t2, t2, 8
76#endif
77 or t1, t2
78
791: ADDC(sum, t1)
80
81 /* fold checksum */
82 sll v1, sum, 16
83 addu sum, v1
84 sltu v1, sum, v1
85 srl sum, sum, 16
86 addu sum, v1
87
88 /* odd buffer alignment? */
89 beqz t7, 1f
90 nop
91 sll v1, sum, 8
92 srl sum, sum, 8
93 or sum, v1
94 andi sum, 0xffff
951:
96 .set reorder
97 /* Add the passed partial csum. */
98 ADDC(sum, a2)
99 jr ra
100 .set noreorder
101
102/* ------------------------------------------------------------------------- */
103
104 .align 5
105LEAF(csum_partial)
106 move sum, zero
107 move t7, zero
108
109 sltiu t8, a1, 0x8
110 bnez t8, small_csumcpy /* < 8 bytes to copy */
111 move t2, a1
112
113 beqz a1, out
114 andi t7, src, 0x1 /* odd buffer? */
115
116hword_align:
117 beqz t7, word_align
118 andi t8, src, 0x2
119
120 lbu t0, (src)
121 subu a1, a1, 0x1
122#ifdef __MIPSEL__
123 sll t0, t0, 8
124#endif
125 ADDC(sum, t0)
126 addu src, src, 0x1
127 andi t8, src, 0x2
128
129word_align:
130 beqz t8, dword_align
131 sltiu t8, a1, 56
132
133 lhu t0, (src)
134 subu a1, a1, 0x2
135 ADDC(sum, t0)
136 sltiu t8, a1, 56
137 addu src, src, 0x2
138
139dword_align:
140 bnez t8, do_end_words
141 move t8, a1
142
143 andi t8, src, 0x4
144 beqz t8, qword_align
145 andi t8, src, 0x8
146
147 lw t0, 0x00(src)
148 subu a1, a1, 0x4
149 ADDC(sum, t0)
150 addu src, src, 0x4
151 andi t8, src, 0x8
152
153qword_align:
154 beqz t8, oword_align
155 andi t8, src, 0x10
156
157 lw t0, 0x00(src)
158 lw t1, 0x04(src)
159 subu a1, a1, 0x8
160 ADDC(sum, t0)
161 ADDC(sum, t1)
162 addu src, src, 0x8
163 andi t8, src, 0x10
164
165oword_align:
166 beqz t8, begin_movement
167 srl t8, a1, 0x7
168
169 lw t3, 0x08(src)
170 lw t4, 0x0c(src)
171 lw t0, 0x00(src)
172 lw t1, 0x04(src)
173 ADDC(sum, t3)
174 ADDC(sum, t4)
175 ADDC(sum, t0)
176 ADDC(sum, t1)
177 subu a1, a1, 0x10
178 addu src, src, 0x10
179 srl t8, a1, 0x7
180
181begin_movement:
182 beqz t8, 1f
183 andi t2, a1, 0x40
184
185move_128bytes:
186 CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
187 CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4)
188 CSUM_BIGCHUNK(src, 0x40, sum, t0, t1, t3, t4)
189 CSUM_BIGCHUNK(src, 0x60, sum, t0, t1, t3, t4)
190 subu t8, t8, 0x01
191 bnez t8, move_128bytes
192 addu src, src, 0x80
193
1941:
195 beqz t2, 1f
196 andi t2, a1, 0x20
197
198move_64bytes:
199 CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
200 CSUM_BIGCHUNK(src, 0x20, sum, t0, t1, t3, t4)
201 addu src, src, 0x40
202
2031:
204 beqz t2, do_end_words
205 andi t8, a1, 0x1c
206
207move_32bytes:
208 CSUM_BIGCHUNK(src, 0x00, sum, t0, t1, t3, t4)
209 andi t8, a1, 0x1c
210 addu src, src, 0x20
211
212do_end_words:
213 beqz t8, maybe_end_cruft
214 srl t8, t8, 0x2
215
216end_words:
217 lw t0, (src)
218 subu t8, t8, 0x1
219 ADDC(sum, t0)
220 bnez t8, end_words
221 addu src, src, 0x4
222
223maybe_end_cruft:
224 andi t2, a1, 0x3
225
226small_memcpy:
227 j small_csumcpy; move a1, t2
228 beqz t2, out
229 move a1, t2
230
231end_bytes:
232 lb t0, (src)
233 subu a1, a1, 0x1
234 bnez a2, end_bytes
235 addu src, src, 0x1
236
237out:
238 jr ra
239 move v0, sum
240 END(csum_partial)
diff --git a/arch/mips/lib-64/Makefile b/arch/mips/lib-64/Makefile
index ad285786e74b..dcd4d2ed2ac4 100644
--- a/arch/mips/lib-64/Makefile
+++ b/arch/mips/lib-64/Makefile
@@ -2,7 +2,7 @@
2# Makefile for MIPS-specific library files.. 2# Makefile for MIPS-specific library files..
3# 3#
4 4
5lib-y += csum_partial.o memset.o watch.o 5lib-y += memset.o watch.o
6 6
7obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o 7obj-$(CONFIG_CPU_MIPS32) += dump_tlb.o
8obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o 8obj-$(CONFIG_CPU_MIPS64) += dump_tlb.o
diff --git a/arch/mips/lib-64/csum_partial.S b/arch/mips/lib-64/csum_partial.S
deleted file mode 100644
index 25aba660cc9c..000000000000
--- a/arch/mips/lib-64/csum_partial.S
+++ /dev/null
@@ -1,242 +0,0 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Quick'n'dirty IP checksum ...
7 *
8 * Copyright (C) 1998, 1999 Ralf Baechle
9 * Copyright (C) 1999 Silicon Graphics, Inc.
10 */
11#include <asm/asm.h>
12#include <asm/regdef.h>
13
14#define ADDC(sum,reg) \
15 addu sum, reg; \
16 sltu v1, sum, reg; \
17 addu sum, v1
18
19#define CSUM_BIGCHUNK(src, offset, sum, t0, t1, t2, t3) \
20 lw t0, (offset + 0x00)(src); \
21 lw t1, (offset + 0x04)(src); \
22 lw t2, (offset + 0x08)(src); \
23 lw t3, (offset + 0x0c)(src); \
24 ADDC(sum, t0); \
25 ADDC(sum, t1); \
26 ADDC(sum, t2); \
27 ADDC(sum, t3); \
28 lw t0, (offset + 0x10)(src); \
29 lw t1, (offset + 0x14)(src); \
30 lw t2, (offset + 0x18)(src); \
31 lw t3, (offset + 0x1c)(src); \
32 ADDC(sum, t0); \
33 ADDC(sum, t1); \
34 ADDC(sum, t2); \
35 ADDC(sum, t3); \
36
37/*
38 * a0: source address
39 * a1: length of the area to checksum
40 * a2: partial checksum
41 */
42
43#define src a0
44#define sum v0
45
46 .text
47 .set noreorder
48
49/* unknown src alignment and < 8 bytes to go */
50small_csumcpy:
51 move a1, ta2
52
53 andi ta0, a1, 4
54 beqz ta0, 1f
55 andi ta0, a1, 2
56
57 /* Still a full word to go */
58 ulw ta1, (src)
59 daddiu src, 4
60 ADDC(sum, ta1)
61
621: move ta1, zero
63 beqz ta0, 1f
64 andi ta0, a1, 1
65
66 /* Still a halfword to go */
67 ulhu ta1, (src)
68 daddiu src, 2
69
701: beqz ta0, 1f
71 sll ta1, ta1, 16
72
73 lbu ta2, (src)
74 nop
75
76#ifdef __MIPSEB__
77 sll ta2, ta2, 8
78#endif
79 or ta1, ta2
80
811: ADDC(sum, ta1)
82
83 /* fold checksum */
84 sll v1, sum, 16
85 addu sum, v1
86 sltu v1, sum, v1
87 srl sum, sum, 16
88 addu sum, v1
89
90 /* odd buffer alignment? */
91 beqz t3, 1f
92 nop
93 sll v1, sum, 8
94 srl sum, sum, 8
95 or sum, v1
96 andi sum, 0xffff
971:
98 .set reorder
99 /* Add the passed partial csum. */
100 ADDC(sum, a2)
101 jr ra
102 .set noreorder
103
104/* ------------------------------------------------------------------------- */
105
106 .align 5
107LEAF(csum_partial)
108 move sum, zero
109 move t3, zero
110
111 sltiu t8, a1, 0x8
112 bnez t8, small_csumcpy /* < 8 bytes to copy */
113 move ta2, a1
114
115 beqz a1, out
116 andi t3, src, 0x1 /* odd buffer? */
117
118hword_align:
119 beqz t3, word_align
120 andi t8, src, 0x2
121
122 lbu ta0, (src)
123 dsubu a1, a1, 0x1
124#ifdef __MIPSEL__
125 sll ta0, ta0, 8
126#endif
127 ADDC(sum, ta0)
128 daddu src, src, 0x1
129 andi t8, src, 0x2
130
131word_align:
132 beqz t8, dword_align
133 sltiu t8, a1, 56
134
135 lhu ta0, (src)
136 dsubu a1, a1, 0x2
137 ADDC(sum, ta0)
138 sltiu t8, a1, 56
139 daddu src, src, 0x2
140
141dword_align:
142 bnez t8, do_end_words
143 move t8, a1
144
145 andi t8, src, 0x4
146 beqz t8, qword_align
147 andi t8, src, 0x8
148
149 lw ta0, 0x00(src)
150 dsubu a1, a1, 0x4
151 ADDC(sum, ta0)
152 daddu src, src, 0x4
153 andi t8, src, 0x8
154
155qword_align:
156 beqz t8, oword_align
157 andi t8, src, 0x10
158
159 lw ta0, 0x00(src)
160 lw ta1, 0x04(src)
161 dsubu a1, a1, 0x8
162 ADDC(sum, ta0)
163 ADDC(sum, ta1)
164 daddu src, src, 0x8
165 andi t8, src, 0x10
166
167oword_align:
168 beqz t8, begin_movement
169 dsrl t8, a1, 0x7
170
171 lw ta3, 0x08(src)
172 lw t0, 0x0c(src)
173 lw ta0, 0x00(src)
174 lw ta1, 0x04(src)
175 ADDC(sum, ta3)
176 ADDC(sum, t0)
177 ADDC(sum, ta0)
178 ADDC(sum, ta1)
179 dsubu a1, a1, 0x10
180 daddu src, src, 0x10
181 dsrl t8, a1, 0x7
182
183begin_movement:
184 beqz t8, 1f
185 andi ta2, a1, 0x40
186
187move_128bytes:
188 CSUM_BIGCHUNK(src, 0x00, sum, ta0, ta1, ta3, t0)
189 CSUM_BIGCHUNK(src, 0x20, sum, ta0, ta1, ta3, t0)
190 CSUM_BIGCHUNK(src, 0x40, sum, ta0, ta1, ta3, t0)
191 CSUM_BIGCHUNK(src, 0x60, sum, ta0, ta1, ta3, t0)
192 dsubu t8, t8, 0x01
193 bnez t8, move_128bytes
194 daddu src, src, 0x80
195
1961:
197 beqz ta2, 1f
198 andi ta2, a1, 0x20
199
200move_64bytes:
201 CSUM_BIGCHUNK(src, 0x00, sum, ta0, ta1, ta3, t0)
202 CSUM_BIGCHUNK(src, 0x20, sum, ta0, ta1, ta3, t0)
203 daddu src, src, 0x40
204
2051:
206 beqz ta2, do_end_words
207 andi t8, a1, 0x1c
208
209move_32bytes:
210 CSUM_BIGCHUNK(src, 0x00, sum, ta0, ta1, ta3, t0)
211 andi t8, a1, 0x1c
212 daddu src, src, 0x20
213
214do_end_words:
215 beqz t8, maybe_end_cruft
216 dsrl t8, t8, 0x2
217
218end_words:
219 lw ta0, (src)
220 dsubu t8, t8, 0x1
221 ADDC(sum, ta0)
222 bnez t8, end_words
223 daddu src, src, 0x4
224
225maybe_end_cruft:
226 andi ta2, a1, 0x3
227
228small_memcpy:
229 j small_csumcpy; move a1, ta2 /* XXX ??? */
230 beqz t2, out
231 move a1, ta2
232
233end_bytes:
234 lb ta0, (src)
235 dsubu a1, a1, 0x1
236 bnez a2, end_bytes
237 daddu src, src, 0x1
238
239out:
240 jr ra
241 move v0, sum
242 END(csum_partial)
diff --git a/arch/mips/lib/Makefile b/arch/mips/lib/Makefile
index b225543f5302..888b61ea12fe 100644
--- a/arch/mips/lib/Makefile
+++ b/arch/mips/lib/Makefile
@@ -2,8 +2,8 @@
2# Makefile for MIPS-specific library files.. 2# Makefile for MIPS-specific library files..
3# 3#
4 4
5lib-y += csum_partial_copy.o memcpy.o promlib.o strlen_user.o strncpy_user.o \ 5lib-y += csum_partial.o csum_partial_copy.o memcpy.o promlib.o \
6 strnlen_user.o uncached.o 6 strlen_user.o strncpy_user.o strnlen_user.o uncached.o
7 7
8obj-y += iomap.o 8obj-y += iomap.o
9 9
diff --git a/arch/mips/lib/csum_partial.S b/arch/mips/lib/csum_partial.S
new file mode 100644
index 000000000000..15611d9df7ac
--- /dev/null
+++ b/arch/mips/lib/csum_partial.S
@@ -0,0 +1,258 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Quick'n'dirty IP checksum ...
7 *
8 * Copyright (C) 1998, 1999 Ralf Baechle
9 * Copyright (C) 1999 Silicon Graphics, Inc.
10 */
11#include <asm/asm.h>
12#include <asm/regdef.h>
13
14#ifdef CONFIG_64BIT
15#define T0 ta0
16#define T1 ta1
17#define T2 ta2
18#define T3 ta3
19#define T4 t0
20#define T7 t3
21#else
22#define T0 t0
23#define T1 t1
24#define T2 t2
25#define T3 t3
26#define T4 t4
27#define T7 t7
28#endif
29
30#define ADDC(sum,reg) \
31 addu sum, reg; \
32 sltu v1, sum, reg; \
33 addu sum, v1
34
35#define CSUM_BIGCHUNK(src, offset, sum, _t0, _t1, _t2, _t3) \
36 lw _t0, (offset + 0x00)(src); \
37 lw _t1, (offset + 0x04)(src); \
38 lw _t2, (offset + 0x08)(src); \
39 lw _t3, (offset + 0x0c)(src); \
40 ADDC(sum, _t0); \
41 ADDC(sum, _t1); \
42 ADDC(sum, _t2); \
43 ADDC(sum, _t3); \
44 lw _t0, (offset + 0x10)(src); \
45 lw _t1, (offset + 0x14)(src); \
46 lw _t2, (offset + 0x18)(src); \
47 lw _t3, (offset + 0x1c)(src); \
48 ADDC(sum, _t0); \
49 ADDC(sum, _t1); \
50 ADDC(sum, _t2); \
51 ADDC(sum, _t3); \
52
53/*
54 * a0: source address
55 * a1: length of the area to checksum
56 * a2: partial checksum
57 */
58
59#define src a0
60#define sum v0
61
62 .text
63 .set noreorder
64
65/* unknown src alignment and < 8 bytes to go */
66small_csumcpy:
67 move a1, T2
68
69 andi T0, a1, 4
70 beqz T0, 1f
71 andi T0, a1, 2
72
73 /* Still a full word to go */
74 ulw T1, (src)
75 PTR_ADDIU src, 4
76 ADDC(sum, T1)
77
781: move T1, zero
79 beqz T0, 1f
80 andi T0, a1, 1
81
82 /* Still a halfword to go */
83 ulhu T1, (src)
84 PTR_ADDIU src, 2
85
861: beqz T0, 1f
87 sll T1, T1, 16
88
89 lbu T2, (src)
90 nop
91
92#ifdef __MIPSEB__
93 sll T2, T2, 8
94#endif
95 or T1, T2
96
971: ADDC(sum, T1)
98
99 /* fold checksum */
100 sll v1, sum, 16
101 addu sum, v1
102 sltu v1, sum, v1
103 srl sum, sum, 16
104 addu sum, v1
105
106 /* odd buffer alignment? */
107 beqz T7, 1f
108 nop
109 sll v1, sum, 8
110 srl sum, sum, 8
111 or sum, v1
112 andi sum, 0xffff
1131:
114 .set reorder
115 /* Add the passed partial csum. */
116 ADDC(sum, a2)
117 jr ra
118 .set noreorder
119
120/* ------------------------------------------------------------------------- */
121
122 .align 5
123LEAF(csum_partial)
124 move sum, zero
125 move T7, zero
126
127 sltiu t8, a1, 0x8
128 bnez t8, small_csumcpy /* < 8 bytes to copy */
129 move T2, a1
130
131 beqz a1, out
132 andi T7, src, 0x1 /* odd buffer? */
133
134hword_align:
135 beqz T7, word_align
136 andi t8, src, 0x2
137
138 lbu T0, (src)
139 LONG_SUBU a1, a1, 0x1
140#ifdef __MIPSEL__
141 sll T0, T0, 8
142#endif
143 ADDC(sum, T0)
144 PTR_ADDU src, src, 0x1
145 andi t8, src, 0x2
146
147word_align:
148 beqz t8, dword_align
149 sltiu t8, a1, 56
150
151 lhu T0, (src)
152 LONG_SUBU a1, a1, 0x2
153 ADDC(sum, T0)
154 sltiu t8, a1, 56
155 PTR_ADDU src, src, 0x2
156
157dword_align:
158 bnez t8, do_end_words
159 move t8, a1
160
161 andi t8, src, 0x4
162 beqz t8, qword_align
163 andi t8, src, 0x8
164
165 lw T0, 0x00(src)
166 LONG_SUBU a1, a1, 0x4
167 ADDC(sum, T0)
168 PTR_ADDU src, src, 0x4
169 andi t8, src, 0x8
170
171qword_align:
172 beqz t8, oword_align
173 andi t8, src, 0x10
174
175 lw T0, 0x00(src)
176 lw T1, 0x04(src)
177 LONG_SUBU a1, a1, 0x8
178 ADDC(sum, T0)
179 ADDC(sum, T1)
180 PTR_ADDU src, src, 0x8
181 andi t8, src, 0x10
182
183oword_align:
184 beqz t8, begin_movement
185 LONG_SRL t8, a1, 0x7
186
187 lw T3, 0x08(src)
188 lw T4, 0x0c(src)
189 lw T0, 0x00(src)
190 lw T1, 0x04(src)
191 ADDC(sum, T3)
192 ADDC(sum, T4)
193 ADDC(sum, T0)
194 ADDC(sum, T1)
195 LONG_SUBU a1, a1, 0x10
196 PTR_ADDU src, src, 0x10
197 LONG_SRL t8, a1, 0x7
198
199begin_movement:
200 beqz t8, 1f
201 andi T2, a1, 0x40
202
203move_128bytes:
204 CSUM_BIGCHUNK(src, 0x00, sum, T0, T1, T3, T4)
205 CSUM_BIGCHUNK(src, 0x20, sum, T0, T1, T3, T4)
206 CSUM_BIGCHUNK(src, 0x40, sum, T0, T1, T3, T4)
207 CSUM_BIGCHUNK(src, 0x60, sum, T0, T1, T3, T4)
208 LONG_SUBU t8, t8, 0x01
209 bnez t8, move_128bytes
210 PTR_ADDU src, src, 0x80
211
2121:
213 beqz T2, 1f
214 andi T2, a1, 0x20
215
216move_64bytes:
217 CSUM_BIGCHUNK(src, 0x00, sum, T0, T1, T3, T4)
218 CSUM_BIGCHUNK(src, 0x20, sum, T0, T1, T3, T4)
219 PTR_ADDU src, src, 0x40
220
2211:
222 beqz T2, do_end_words
223 andi t8, a1, 0x1c
224
225move_32bytes:
226 CSUM_BIGCHUNK(src, 0x00, sum, T0, T1, T3, T4)
227 andi t8, a1, 0x1c
228 PTR_ADDU src, src, 0x20
229
230do_end_words:
231 beqz t8, maybe_end_cruft
232 LONG_SRL t8, t8, 0x2
233
234end_words:
235 lw T0, (src)
236 LONG_SUBU t8, t8, 0x1
237 ADDC(sum, T0)
238 bnez t8, end_words
239 PTR_ADDU src, src, 0x4
240
241maybe_end_cruft:
242 andi T2, a1, 0x3
243
244small_memcpy:
245 j small_csumcpy; move a1, T2 /* XXX ??? */
246 beqz t2, out
247 move a1, T2
248
249end_bytes:
250 lb T0, (src)
251 LONG_SUBU a1, a1, 0x1
252 bnez a2, end_bytes
253 PTR_ADDU src, src, 0x1
254
255out:
256 jr ra
257 move v0, sum
258 END(csum_partial)
diff --git a/arch/mips/sibyte/swarm/setup.c b/arch/mips/sibyte/swarm/setup.c
index ac342f5643c9..defa1f1452ad 100644
--- a/arch/mips/sibyte/swarm/setup.c
+++ b/arch/mips/sibyte/swarm/setup.c
@@ -43,7 +43,7 @@
43#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) 43#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
44#include <asm/sibyte/sb1250_regs.h> 44#include <asm/sibyte/sb1250_regs.h>
45#else 45#else
46#error invalid SiByte board configuation 46#error invalid SiByte board configuration
47#endif 47#endif
48#include <asm/sibyte/sb1250_genbus.h> 48#include <asm/sibyte/sb1250_genbus.h>
49#include <asm/sibyte/board.h> 49#include <asm/sibyte/board.h>
@@ -53,7 +53,7 @@ extern void bcm1480_setup(void);
53#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) 53#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
54extern void sb1250_setup(void); 54extern void sb1250_setup(void);
55#else 55#else
56#error invalid SiByte board configuation 56#error invalid SiByte board configuration
57#endif 57#endif
58 58
59extern int xicor_probe(void); 59extern int xicor_probe(void);
@@ -90,7 +90,7 @@ void __init plat_timer_setup(struct irqaction *irq)
90#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) 90#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
91 sb1250_time_init(); 91 sb1250_time_init();
92#else 92#else
93#error invalid SiByte board configuation 93#error invalid SiByte board configuration
94#endif 94#endif
95} 95}
96 96
@@ -111,7 +111,7 @@ void __init plat_mem_setup(void)
111#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X) 111#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)
112 sb1250_setup(); 112 sb1250_setup();
113#else 113#else
114#error invalid SiByte board configuation 114#error invalid SiByte board configuration
115#endif 115#endif
116 116
117 panic_timeout = 5; /* For debug. */ 117 panic_timeout = 5; /* For debug. */
diff --git a/arch/powerpc/.gitignore b/arch/powerpc/.gitignore
new file mode 100644
index 000000000000..a1a869c8c840
--- /dev/null
+++ b/arch/powerpc/.gitignore
@@ -0,0 +1 @@
include
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 116d7d3683ed..291c95ac4b31 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -112,7 +112,7 @@ choice
112 default 6xx 112 default 6xx
113 113
114config CLASSIC32 114config CLASSIC32
115 bool "6xx/7xx/74xx" 115 bool "52xx/6xx/7xx/74xx"
116 select PPC_FPU 116 select PPC_FPU
117 select 6xx 117 select 6xx
118 help 118 help
@@ -121,16 +121,18 @@ config CLASSIC32
121 versions (821, 823, 850, 855, 860, 52xx, 82xx, 83xx), the AMCC 121 versions (821, 823, 850, 855, 860, 52xx, 82xx, 83xx), the AMCC
122 embedded versions (403 and 405) and the high end 64 bit Power 122 embedded versions (403 and 405) and the high end 64 bit Power
123 processors (POWER 3, POWER4, and IBM PPC970 also known as G5). 123 processors (POWER 3, POWER4, and IBM PPC970 also known as G5).
124
125 This option is the catch-all for 6xx types, including some of the
126 embedded versions. Unless there is see an option for the specific
127 chip family you are using, you want this option.
128
129 You do not want this if you are building a kernel for a 64 bit
130 IBM RS/6000 or an Apple G5, choose 6xx.
131
132 If unsure, select this option
124 133
125 Unless you are building a kernel for one of the embedded processor
126 systems, 64 bit IBM RS/6000 or an Apple G5, choose 6xx.
127 Note that the kernel runs in 32-bit mode even on 64-bit chips. 134 Note that the kernel runs in 32-bit mode even on 64-bit chips.
128 135
129config PPC_52xx
130 bool "Freescale 52xx"
131 select 6xx
132 select PPC_FPU
133
134config PPC_82xx 136config PPC_82xx
135 bool "Freescale 82xx" 137 bool "Freescale 82xx"
136 select 6xx 138 select 6xx
@@ -160,9 +162,11 @@ config PPC_86xx
160 162
161config 40x 163config 40x
162 bool "AMCC 40x" 164 bool "AMCC 40x"
165 select PPC_DCR_NATIVE
163 166
164config 44x 167config 44x
165 bool "AMCC 44x" 168 bool "AMCC 44x"
169 select PPC_DCR_NATIVE
166 170
167config 8xx 171config 8xx
168 bool "Freescale 8xx" 172 bool "Freescale 8xx"
@@ -208,6 +212,24 @@ config PPC_FPU
208 bool 212 bool
209 default y if PPC64 213 default y if PPC64
210 214
215config PPC_DCR_NATIVE
216 bool
217 default n
218
219config PPC_DCR_MMIO
220 bool
221 default n
222
223config PPC_DCR
224 bool
225 depends on PPC_DCR_NATIVE || PPC_DCR_MMIO
226 default y
227
228config PPC_OF_PLATFORM_PCI
229 bool
230 depends on PPC64 # not supported on 32 bits yet
231 default n
232
211config BOOKE 233config BOOKE
212 bool 234 bool
213 depends on E200 || E500 235 depends on E200 || E500
@@ -227,6 +249,7 @@ config PTE_64BIT
227config PHYS_64BIT 249config PHYS_64BIT
228 bool 'Large physical address support' if E500 250 bool 'Large physical address support' if E500
229 depends on 44x || E500 251 depends on 44x || E500
252 select RESOURCES_64BIT
230 default y if 44x 253 default y if 44x
231 ---help--- 254 ---help---
232 This option enables kernel support for larger than 32-bit physical 255 This option enables kernel support for larger than 32-bit physical
@@ -369,11 +392,13 @@ config PPC_PSERIES
369 select PPC_RTAS 392 select PPC_RTAS
370 select RTAS_ERROR_LOGGING 393 select RTAS_ERROR_LOGGING
371 select PPC_UDBG_16550 394 select PPC_UDBG_16550
395 select PPC_NATIVE
372 default y 396 default y
373 397
374config PPC_ISERIES 398config PPC_ISERIES
375 bool "IBM Legacy iSeries" 399 bool "IBM Legacy iSeries"
376 depends on PPC_MULTIPLATFORM && PPC64 400 depends on PPC_MULTIPLATFORM && PPC64
401 select PPC_INDIRECT_IO
377 402
378config PPC_CHRP 403config PPC_CHRP
379 bool "Common Hardware Reference Platform (CHRP) based machines" 404 bool "Common Hardware Reference Platform (CHRP) based machines"
@@ -384,14 +409,35 @@ config PPC_CHRP
384 select PPC_RTAS 409 select PPC_RTAS
385 select PPC_MPC106 410 select PPC_MPC106
386 select PPC_UDBG_16550 411 select PPC_UDBG_16550
412 select PPC_NATIVE
413 default y
414
415config PPC_MPC52xx
416 bool
417 default n
418
419config PPC_EFIKA
420 bool "bPlan Efika 5k2. MPC5200B based computer"
421 depends on PPC_MULTIPLATFORM && PPC32
422 select PPC_RTAS
423 select RTAS_PROC
424 select PPC_MPC52xx
425 select PPC_NATIVE
387 default y 426 default y
388 427
428config PPC_LITE5200
429 bool "Freescale Lite5200 Eval Board"
430 depends on PPC_MULTIPLATFORM && PPC32
431 select PPC_MPC52xx
432 default n
433
389config PPC_PMAC 434config PPC_PMAC
390 bool "Apple PowerMac based machines" 435 bool "Apple PowerMac based machines"
391 depends on PPC_MULTIPLATFORM 436 depends on PPC_MULTIPLATFORM
392 select MPIC 437 select MPIC
393 select PPC_INDIRECT_PCI if PPC32 438 select PPC_INDIRECT_PCI if PPC32
394 select PPC_MPC106 if PPC32 439 select PPC_MPC106 if PPC32
440 select PPC_NATIVE
395 default y 441 default y
396 442
397config PPC_PMAC64 443config PPC_PMAC64
@@ -411,6 +457,7 @@ config PPC_PREP
411 select PPC_I8259 457 select PPC_I8259
412 select PPC_INDIRECT_PCI 458 select PPC_INDIRECT_PCI
413 select PPC_UDBG_16550 459 select PPC_UDBG_16550
460 select PPC_NATIVE
414 default y 461 default y
415 462
416config PPC_MAPLE 463config PPC_MAPLE
@@ -422,6 +469,7 @@ config PPC_MAPLE
422 select GENERIC_TBSYNC 469 select GENERIC_TBSYNC
423 select PPC_UDBG_16550 470 select PPC_UDBG_16550
424 select PPC_970_NAP 471 select PPC_970_NAP
472 select PPC_NATIVE
425 default n 473 default n
426 help 474 help
427 This option enables support for the Maple 970FX Evaluation Board. 475 This option enables support for the Maple 970FX Evaluation Board.
@@ -434,6 +482,7 @@ config PPC_PASEMI
434 select MPIC 482 select MPIC
435 select PPC_UDBG_16550 483 select PPC_UDBG_16550
436 select GENERIC_TBSYNC 484 select GENERIC_TBSYNC
485 select PPC_NATIVE
437 help 486 help
438 This option enables support for PA Semi's PWRficient line 487 This option enables support for PA Semi's PWRficient line
439 of SoC processors, including PA6T-1682M 488 of SoC processors, including PA6T-1682M
@@ -445,6 +494,11 @@ config PPC_CELL
445config PPC_CELL_NATIVE 494config PPC_CELL_NATIVE
446 bool 495 bool
447 select PPC_CELL 496 select PPC_CELL
497 select PPC_DCR_MMIO
498 select PPC_OF_PLATFORM_PCI
499 select PPC_INDIRECT_IO
500 select PPC_NATIVE
501 select MPIC
448 default n 502 default n
449 503
450config PPC_IBM_CELL_BLADE 504config PPC_IBM_CELL_BLADE
@@ -456,6 +510,22 @@ config PPC_IBM_CELL_BLADE
456 select PPC_UDBG_16550 510 select PPC_UDBG_16550
457 select UDBG_RTAS_CONSOLE 511 select UDBG_RTAS_CONSOLE
458 512
513config PPC_PS3
514 bool "Sony PS3"
515 depends on PPC_MULTIPLATFORM && PPC64
516 select PPC_CELL
517 help
518 This option enables support for the Sony PS3 game console
519 and other platforms using the PS3 hypervisor.
520
521config PPC_NATIVE
522 bool
523 depends on PPC_MULTIPLATFORM
524 help
525 Support for running natively on the hardware, i.e. without
526 a hypervisor. This option is not user-selectable but should
527 be selected by all platforms that need it.
528
459config UDBG_RTAS_CONSOLE 529config UDBG_RTAS_CONSOLE
460 bool "RTAS based debug console" 530 bool "RTAS based debug console"
461 depends on PPC_RTAS 531 depends on PPC_RTAS
@@ -517,6 +587,15 @@ config PPC_970_NAP
517 bool 587 bool
518 default n 588 default n
519 589
590config PPC_INDIRECT_IO
591 bool
592 select GENERIC_IOMAP
593 default n
594
595config GENERIC_IOMAP
596 bool
597 default n
598
520source "drivers/cpufreq/Kconfig" 599source "drivers/cpufreq/Kconfig"
521 600
522config CPU_FREQ_PMAC 601config CPU_FREQ_PMAC
@@ -594,12 +673,6 @@ config TAU_AVERAGE
594 673
595 If in doubt, say N here. 674 If in doubt, say N here.
596 675
597config PPC_TODC
598 depends on EMBEDDED6xx
599 bool "Generic Time-of-day Clock (TODC) support"
600 ---help---
601 This adds support for many TODC/RTC chips.
602
603endmenu 676endmenu
604 677
605source arch/powerpc/platforms/embedded6xx/Kconfig 678source arch/powerpc/platforms/embedded6xx/Kconfig
@@ -610,6 +683,7 @@ source arch/powerpc/platforms/85xx/Kconfig
610source arch/powerpc/platforms/86xx/Kconfig 683source arch/powerpc/platforms/86xx/Kconfig
611source arch/powerpc/platforms/8xx/Kconfig 684source arch/powerpc/platforms/8xx/Kconfig
612source arch/powerpc/platforms/cell/Kconfig 685source arch/powerpc/platforms/cell/Kconfig
686source arch/powerpc/platforms/ps3/Kconfig
613 687
614menu "Kernel options" 688menu "Kernel options"
615 689
@@ -790,7 +864,6 @@ source "arch/powerpc/platforms/prep/Kconfig"
790 864
791config CMDLINE_BOOL 865config CMDLINE_BOOL
792 bool "Default bootloader kernel arguments" 866 bool "Default bootloader kernel arguments"
793 depends on !PPC_ISERIES
794 867
795config CMDLINE 868config CMDLINE
796 string "Initial kernel command string" 869 string "Initial kernel command string"
@@ -880,7 +953,7 @@ config MCA
880 953
881config PCI 954config PCI
882 bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx \ 955 bool "PCI support" if 40x || CPM2 || PPC_83xx || PPC_85xx || PPC_86xx \
883 || PPC_MPC52xx || (EMBEDDED && PPC_ISERIES) || MPC7448HPC2 956 || PPC_MPC52xx || (EMBEDDED && PPC_ISERIES) || MPC7448HPC2 || PPC_PS3
884 default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx \ 957 default y if !40x && !CPM2 && !8xx && !APUS && !PPC_83xx \
885 && !PPC_85xx && !PPC_86xx 958 && !PPC_85xx && !PPC_86xx
886 default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS 959 default PCI_PERMEDIA if !4xx && !CPM2 && !8xx && APUS
diff --git a/arch/powerpc/Kconfig.debug b/arch/powerpc/Kconfig.debug
index 5ad149b47e34..f0e51edde022 100644
--- a/arch/powerpc/Kconfig.debug
+++ b/arch/powerpc/Kconfig.debug
@@ -77,7 +77,7 @@ config KGDB_CONSOLE
77 77
78config XMON 78config XMON
79 bool "Include xmon kernel debugger" 79 bool "Include xmon kernel debugger"
80 depends on DEBUGGER && !PPC_ISERIES 80 depends on DEBUGGER
81 help 81 help
82 Include in-kernel hooks for the xmon kernel monitor/debugger. 82 Include in-kernel hooks for the xmon kernel monitor/debugger.
83 Unless you are intending to debug the kernel, say N here. 83 Unless you are intending to debug the kernel, say N here.
@@ -98,6 +98,15 @@ config XMON_DEFAULT
98 xmon is normally disabled unless booted with 'xmon=on'. 98 xmon is normally disabled unless booted with 'xmon=on'.
99 Use 'xmon=off' to disable xmon init during runtime. 99 Use 'xmon=off' to disable xmon init during runtime.
100 100
101config XMON_DISASSEMBLY
102 bool "Include disassembly support in xmon"
103 depends on XMON
104 default y
105 help
106 Include support for disassembling in xmon. You probably want
107 to say Y here, unless you're building for a memory-constrained
108 system.
109
101config IRQSTACKS 110config IRQSTACKS
102 bool "Use separate kernel stacks when processing interrupts" 111 bool "Use separate kernel stacks when processing interrupts"
103 depends on PPC64 112 depends on PPC64
@@ -116,7 +125,7 @@ config BDI_SWITCH
116 125
117config BOOTX_TEXT 126config BOOTX_TEXT
118 bool "Support for early boot text console (BootX or OpenFirmware only)" 127 bool "Support for early boot text console (BootX or OpenFirmware only)"
119 depends PPC_OF && !PPC_ISERIES 128 depends PPC_OF
120 help 129 help
121 Say Y here to see progress messages from the boot firmware in text 130 Say Y here to see progress messages from the boot firmware in text
122 mode. Requires either BootX or Open Firmware. 131 mode. Requires either BootX or Open Firmware.
diff --git a/arch/powerpc/boot/.gitignore b/arch/powerpc/boot/.gitignore
index 45c9ad23526e..0734b2fc1d95 100644
--- a/arch/powerpc/boot/.gitignore
+++ b/arch/powerpc/boot/.gitignore
@@ -1,19 +1,32 @@
1addnote 1addnote
2empty.c
3hack-coff
2infblock.c 4infblock.c
3infblock.h 5infblock.h
4infcodes.c 6infcodes.c
5infcodes.h 7infcodes.h
6inffast.c 8inffast.c
7inffast.h 9inffast.h
10inffixed.h
8inflate.c 11inflate.c
12inflate.h
9inftrees.c 13inftrees.c
10inftrees.h 14inftrees.h
11infutil.c 15infutil.c
12infutil.h 16infutil.h
13kernel-vmlinux.strip.c 17kernel-vmlinux.strip.c
14kernel-vmlinux.strip.gz 18kernel-vmlinux.strip.gz
19mktree
15uImage 20uImage
16zImage 21zImage
22zImage.chrp
23zImage.coff
24zImage.coff.lds
25zImage.lds
26zImage.miboot
27zImage.pmac
28zImage.pseries
29zImage.sandpoint
17zImage.vmode 30zImage.vmode
18zconf.h 31zconf.h
19zlib.h 32zlib.h
diff --git a/arch/powerpc/boot/Makefile b/arch/powerpc/boot/Makefile
index 4b2be611f77f..343dbcfdf08a 100644
--- a/arch/powerpc/boot/Makefile
+++ b/arch/powerpc/boot/Makefile
@@ -40,7 +40,8 @@ zliblinuxheader := zlib.h zconf.h zutil.h
40$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) \ 40$(addprefix $(obj)/,$(zlib) main.o): $(addprefix $(obj)/,$(zliblinuxheader)) \
41 $(addprefix $(obj)/,$(zlibheader)) 41 $(addprefix $(obj)/,$(zlibheader))
42 42
43src-wlib := string.S stdio.c main.c div64.S $(zlib) 43src-wlib := string.S stdio.c main.c flatdevtree.c flatdevtree_misc.c \
44 ns16550.c serial.c simple_alloc.c div64.S util.S $(zlib)
44src-plat := of.c 45src-plat := of.c
45src-boot := crt0.S $(src-wlib) $(src-plat) empty.c 46src-boot := crt0.S $(src-wlib) $(src-plat) empty.c
46 47
@@ -74,7 +75,7 @@ $(obj)/zImage.lds $(obj)/zImage.coff.lds: $(obj)/%: $(srctree)/$(src)/%.S
74 @cp $< $@ 75 @cp $< $@
75 76
76clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \ 77clean-files := $(zlib) $(zlibheader) $(zliblinuxheader) \
77 $(obj)/empty.c 78 empty.c zImage zImage.coff.lds zImage.lds zImage.sandpoint
78 79
79quiet_cmd_bootcc = BOOTCC $@ 80quiet_cmd_bootcc = BOOTCC $@
80 cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $< 81 cmd_bootcc = $(CROSS32CC) -Wp,-MD,$(depfile) $(BOOTCFLAGS) -c -o $@ $<
@@ -93,13 +94,13 @@ $(patsubst %.S,%.o, $(filter %.S, $(src-boot))): %.o: %.S
93$(obj)/wrapper.a: $(obj-wlib) 94$(obj)/wrapper.a: $(obj-wlib)
94 $(call cmd,bootar) 95 $(call cmd,bootar)
95 96
96hostprogs-y := addnote addRamDisk hack-coff 97hostprogs-y := addnote addRamDisk hack-coff mktree
97 98
98extra-y := $(obj)/crt0.o $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \ 99extra-y := $(obj)/crt0.o $(obj)/wrapper.a $(obj-plat) $(obj)/empty.o \
99 $(obj)/zImage.lds $(obj)/zImage.coff.lds 100 $(obj)/zImage.lds $(obj)/zImage.coff.lds
100 101
101wrapper :=$(srctree)/$(src)/wrapper 102wrapper :=$(srctree)/$(src)/wrapper
102wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff) 103wrapperbits := $(extra-y) $(addprefix $(obj)/,addnote hack-coff mktree)
103 104
104############# 105#############
105# Bits for building various flavours of zImage 106# Bits for building various flavours of zImage
@@ -148,13 +149,18 @@ $(obj)/zImage.miboot: vmlinux $(wrapperbits)
148$(obj)/zImage.initrd.miboot: vmlinux $(wrapperbits) 149$(obj)/zImage.initrd.miboot: vmlinux $(wrapperbits)
149 $(call cmd,wrap_initrd,miboot) 150 $(call cmd,wrap_initrd,miboot)
150 151
152$(obj)/zImage.ps3: vmlinux
153 $(STRIP) -s -R .comment $< -o $@
154
151$(obj)/uImage: vmlinux $(wrapperbits) 155$(obj)/uImage: vmlinux $(wrapperbits)
152 $(call cmd,wrap,uboot) 156 $(call cmd,wrap,uboot)
153 157
154image-$(CONFIG_PPC_PSERIES) += zImage.pseries 158image-$(CONFIG_PPC_PSERIES) += zImage.pseries
155image-$(CONFIG_PPC_MAPLE) += zImage.pseries 159image-$(CONFIG_PPC_MAPLE) += zImage.pseries
156image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries 160image-$(CONFIG_PPC_IBM_CELL_BLADE) += zImage.pseries
161image-$(CONFIG_PPC_PS3) += zImage.ps3
157image-$(CONFIG_PPC_CHRP) += zImage.chrp 162image-$(CONFIG_PPC_CHRP) += zImage.chrp
163image-$(CONFIG_PPC_EFIKA) += zImage.chrp
158image-$(CONFIG_PPC_PMAC) += zImage.pmac 164image-$(CONFIG_PPC_PMAC) += zImage.pmac
159image-$(CONFIG_DEFAULT_UIMAGE) += uImage 165image-$(CONFIG_DEFAULT_UIMAGE) += uImage
160 166
@@ -176,3 +182,4 @@ install: $(CONFIGURE) $(image-y)
176 182
177clean-files += $(addprefix $(objtree)/, $(obj-boot) vmlinux.strip.gz) 183clean-files += $(addprefix $(objtree)/, $(obj-boot) vmlinux.strip.gz)
178clean-files += $(addprefix $(objtree)/, $(obj-boot) vmlinux.bin.gz) 184clean-files += $(addprefix $(objtree)/, $(obj-boot) vmlinux.bin.gz)
185clean-files += $(image-)
diff --git a/arch/powerpc/boot/dts/kuroboxHG.dts b/arch/powerpc/boot/dts/kuroboxHG.dts
new file mode 100644
index 000000000000..d06b0b018899
--- /dev/null
+++ b/arch/powerpc/boot/dts/kuroboxHG.dts
@@ -0,0 +1,148 @@
1/*
2 * Device Tree Souce for Buffalo KuroboxHG
3 *
4 * Choose CONFIG_LINKSTATION to build a kernel for KuroboxHG, or use
5 * the default configuration linkstation_defconfig.
6 *
7 * Based on sandpoint.dts
8 *
9 * 2006 (c) G. Liakhovetski <g.liakhovetski@gmx.de>
10 *
11 * This file is licensed under
12 * the terms of the GNU General Public License version 2. This program
13 * is licensed "as is" without any warranty of any kind, whether express
14 * or implied.
15
16XXXX add flash parts, rtc, ??
17
18build with: "dtc -f -I dts -O dtb -o kuroboxHG.dtb -V 16 kuroboxHG.dts"
19
20
21 */
22
23/ {
24 linux,phandle = <1000>;
25 model = "KuroboxHG";
26 compatible = "linkstation";
27 #address-cells = <1>;
28 #size-cells = <1>;
29
30 cpus {
31 linux,phandle = <2000>;
32 #cpus = <1>;
33 #address-cells = <1>;
34 #size-cells = <0>;
35
36 PowerPC,603e { /* Really 8241 */
37 linux,phandle = <2100>;
38 linux,boot-cpu;
39 device_type = "cpu";
40 reg = <0>;
41 clock-frequency = <fdad680>; /* Fixed by bootwrapper */
42 timebase-frequency = <1F04000>; /* Fixed by bootwrapper */
43 bus-frequency = <0>; /* From bootloader */
44 /* Following required by dtc but not used */
45 i-cache-line-size = <0>;
46 d-cache-line-size = <0>;
47 i-cache-size = <4000>;
48 d-cache-size = <4000>;
49 };
50 };
51
52 memory {
53 linux,phandle = <3000>;
54 device_type = "memory";
55 reg = <00000000 08000000>;
56 };
57
58 soc10x { /* AFAICT need to make soc for 8245's uarts to be defined */
59 linux,phandle = <4000>;
60 #address-cells = <1>;
61 #size-cells = <1>;
62 #interrupt-cells = <2>;
63 device_type = "soc";
64 compatible = "mpc10x";
65 store-gathering = <0>; /* 0 == off, !0 == on */
66 reg = <80000000 00100000>;
67 ranges = <80000000 80000000 70000000 /* pci mem space */
68 fc000000 fc000000 00100000 /* EUMB */
69 fe000000 fe000000 00c00000 /* pci i/o space */
70 fec00000 fec00000 00300000 /* pci cfg regs */
71 fef00000 fef00000 00100000>; /* pci iack */
72
73 i2c@80003000 {
74 linux,phandle = <4300>;
75 device_type = "i2c";
76 compatible = "fsl-i2c";
77 reg = <80003000 1000>;
78 interrupts = <5 2>;
79 interrupt-parent = <4400>;
80 };
81
82 serial@80004500 {
83 linux,phandle = <4511>;
84 device_type = "serial";
85 compatible = "ns16550";
86 reg = <80004500 8>;
87 clock-frequency = <7c044a8>;
88 current-speed = <2580>;
89 interrupts = <9 2>;
90 interrupt-parent = <4400>;
91 };
92
93 serial@80004600 {
94 linux,phandle = <4512>;
95 device_type = "serial";
96 compatible = "ns16550";
97 reg = <80004600 8>;
98 clock-frequency = <7c044a8>;
99 current-speed = <e100>;
100 interrupts = <a 0>;
101 interrupt-parent = <4400>;
102 };
103
104 pic@80040000 {
105 linux,phandle = <4400>;
106 #interrupt-cells = <2>;
107 #address-cells = <0>;
108 device_type = "open-pic";
109 compatible = "chrp,open-pic";
110 interrupt-controller;
111 reg = <80040000 40000>;
112 built-in;
113 };
114
115 pci@fec00000 {
116 linux,phandle = <4500>;
117 #address-cells = <3>;
118 #size-cells = <2>;
119 #interrupt-cells = <1>;
120 device_type = "pci";
121 compatible = "mpc10x-pci";
122 reg = <fec00000 400000>;
123 ranges = <01000000 0 0 fe000000 0 00c00000
124 02000000 0 80000000 80000000 0 70000000>;
125 bus-range = <0 ff>;
126 clock-frequency = <7f28155>;
127 interrupt-parent = <4400>;
128 interrupt-map-mask = <f800 0 0 7>;
129 interrupt-map = <
130 /* IDSEL 0x11 - IRQ0 ETH */
131 5800 0 0 1 4400 0 1
132 5800 0 0 2 4400 1 1
133 5800 0 0 3 4400 2 1
134 5800 0 0 4 4400 3 1
135 /* IDSEL 0x12 - IRQ1 IDE0 */
136 6000 0 0 1 4400 1 1
137 6000 0 0 2 4400 2 1
138 6000 0 0 3 4400 3 1
139 6000 0 0 4 4400 0 1
140 /* IDSEL 0x14 - IRQ3 USB2.0 */
141 7000 0 0 1 4400 3 1
142 7000 0 0 2 4400 3 1
143 7000 0 0 3 4400 3 1
144 7000 0 0 4 4400 3 1
145 >;
146 };
147 };
148};
diff --git a/arch/powerpc/boot/dts/lite5200.dts b/arch/powerpc/boot/dts/lite5200.dts
new file mode 100644
index 000000000000..8bc0d259796d
--- /dev/null
+++ b/arch/powerpc/boot/dts/lite5200.dts
@@ -0,0 +1,313 @@
1/*
2 * Lite5200 board Device Tree Source
3 *
4 * Copyright 2006 Secret Lab Technologies Ltd.
5 * Grant Likely <grant.likely@secretlab.ca>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13/ {
14 model = "Lite5200";
15 compatible = "lite5200\0lite52xx\0mpc5200\0mpc52xx";
16 #address-cells = <1>;
17 #size-cells = <1>;
18
19 cpus {
20 #cpus = <1>;
21 #address-cells = <1>;
22 #size-cells = <0>;
23
24 PowerPC,5200@0 {
25 device_type = "cpu";
26 reg = <0>;
27 d-cache-line-size = <20>;
28 i-cache-line-size = <20>;
29 d-cache-size = <4000>; // L1, 16K
30 i-cache-size = <4000>; // L1, 16K
31 timebase-frequency = <0>; // from bootloader
32 bus-frequency = <0>; // from bootloader
33 clock-frequency = <0>; // from bootloader
34 32-bit;
35 };
36 };
37
38 memory {
39 device_type = "memory";
40 reg = <00000000 04000000>; // 64MB
41 };
42
43 soc5200@f0000000 {
44 #interrupt-cells = <3>;
45 device_type = "soc";
46 ranges = <0 f0000000 f0010000>;
47 reg = <f0000000 00010000>;
48 bus-frequency = <0>; // from bootloader
49
50 cdm@200 {
51 compatible = "mpc5200-cdm\0mpc52xx-cdm";
52 reg = <200 38>;
53 };
54
55 pic@500 {
56 // 5200 interrupts are encoded into two levels;
57 linux,phandle = <500>;
58 interrupt-controller;
59 #interrupt-cells = <3>;
60 device_type = "interrupt-controller";
61 compatible = "mpc5200-pic\0mpc52xx-pic";
62 reg = <500 80>;
63 built-in;
64 };
65
66 gpt@600 { // General Purpose Timer
67 compatible = "mpc5200-gpt\0mpc52xx-gpt";
68 device_type = "gpt";
69 reg = <600 10>;
70 interrupts = <1 9 0>;
71 interrupt-parent = <500>;
72 };
73
74 gpt@610 { // General Purpose Timer
75 compatible = "mpc5200-gpt\0mpc52xx-gpt";
76 device_type = "gpt";
77 reg = <610 10>;
78 interrupts = <1 a 0>;
79 interrupt-parent = <500>;
80 };
81
82 gpt@620 { // General Purpose Timer
83 compatible = "mpc5200-gpt\0mpc52xx-gpt";
84 device_type = "gpt";
85 reg = <620 10>;
86 interrupts = <1 b 0>;
87 interrupt-parent = <500>;
88 };
89
90 gpt@630 { // General Purpose Timer
91 compatible = "mpc5200-gpt\0mpc52xx-gpt";
92 device_type = "gpt";
93 reg = <630 10>;
94 interrupts = <1 c 0>;
95 interrupt-parent = <500>;
96 };
97
98 gpt@640 { // General Purpose Timer
99 compatible = "mpc5200-gpt\0mpc52xx-gpt";
100 device_type = "gpt";
101 reg = <640 10>;
102 interrupts = <1 d 0>;
103 interrupt-parent = <500>;
104 };
105
106 gpt@650 { // General Purpose Timer
107 compatible = "mpc5200-gpt\0mpc52xx-gpt";
108 device_type = "gpt";
109 reg = <650 10>;
110 interrupts = <1 e 0>;
111 interrupt-parent = <500>;
112 };
113
114 gpt@660 { // General Purpose Timer
115 compatible = "mpc5200-gpt\0mpc52xx-gpt";
116 device_type = "gpt";
117 reg = <660 10>;
118 interrupts = <1 f 0>;
119 interrupt-parent = <500>;
120 };
121
122 gpt@670 { // General Purpose Timer
123 compatible = "mpc5200-gpt\0mpc52xx-gpt";
124 device_type = "gpt";
125 reg = <670 10>;
126 interrupts = <1 10 0>;
127 interrupt-parent = <500>;
128 };
129
130 rtc@800 { // Real time clock
131 compatible = "mpc5200-rtc\0mpc52xx-rtc";
132 device_type = "rtc";
133 reg = <800 100>;
134 interrupts = <1 5 0 1 6 0>;
135 interrupt-parent = <500>;
136 };
137
138 mscan@900 {
139 device_type = "mscan";
140 compatible = "mpc5200-mscan\0mpc52xx-mscan";
141 interrupts = <2 11 0>;
142 interrupt-parent = <500>;
143 reg = <900 80>;
144 };
145
146 mscan@980 {
147 device_type = "mscan";
148 compatible = "mpc5200-mscan\0mpc52xx-mscan";
149 interrupts = <1 12 0>;
150 interrupt-parent = <500>;
151 reg = <980 80>;
152 };
153
154 gpio@b00 {
155 compatible = "mpc5200-gpio\0mpc52xx-gpio";
156 reg = <b00 40>;
157 interrupts = <1 7 0>;
158 interrupt-parent = <500>;
159 };
160
161 gpio-wkup@b00 {
162 compatible = "mpc5200-gpio-wkup\0mpc52xx-gpio-wkup";
163 reg = <c00 40>;
164 interrupts = <1 8 0 0 3 0>;
165 interrupt-parent = <500>;
166 };
167
168 pci@0d00 {
169 #interrupt-cells = <1>;
170 #size-cells = <2>;
171 #address-cells = <3>;
172 device_type = "pci";
173 compatible = "mpc5200-pci\0mpc52xx-pci";
174 reg = <d00 100>;
175 interrupt-map-mask = <f800 0 0 7>;
176 interrupt-map = <c000 0 0 1 500 0 0 3
177 c000 0 0 2 500 0 0 3
178 c000 0 0 3 500 0 0 3
179 c000 0 0 4 500 0 0 3>;
180 clock-frequency = <0>; // From boot loader
181 interrupts = <2 8 0 2 9 0 2 a 0>;
182 interrupt-parent = <500>;
183 bus-range = <0 0>;
184 ranges = <42000000 0 80000000 80000000 0 20000000
185 02000000 0 a0000000 a0000000 0 10000000
186 01000000 0 00000000 b0000000 0 01000000>;
187 };
188
189 spi@f00 {
190 device_type = "spi";
191 compatible = "mpc5200-spi\0mpc52xx-spi";
192 reg = <f00 20>;
193 interrupts = <2 d 0 2 e 0>;
194 interrupt-parent = <500>;
195 };
196
197 usb@1000 {
198 device_type = "usb-ohci-be";
199 compatible = "mpc5200-ohci\0mpc52xx-ohci\0ohci-be";
200 reg = <1000 ff>;
201 interrupts = <2 6 0>;
202 interrupt-parent = <500>;
203 };
204
205 bestcomm@1200 {
206 device_type = "dma-controller";
207 compatible = "mpc5200-bestcomm\0mpc52xx-bestcomm";
208 reg = <1200 80>;
209 interrupts = <3 0 0 3 1 0 3 2 0 3 3 0
210 3 4 0 3 5 0 3 6 0 3 7 0
211 3 8 0 3 9 0 3 a 0 3 b 0
212 3 c 0 3 d 0 3 e 0 3 f 0>;
213 interrupt-parent = <500>;
214 };
215
216 xlb@1f00 {
217 compatible = "mpc5200-xlb\0mpc52xx-xlb";
218 reg = <1f00 100>;
219 };
220
221 serial@2000 { // PSC1
222 device_type = "serial";
223 compatible = "mpc5200-psc-uart\0mpc52xx-psc-uart";
224 port-number = <0>; // Logical port assignment
225 reg = <2000 100>;
226 interrupts = <2 1 0>;
227 interrupt-parent = <500>;
228 };
229
230 // PSC2 in spi mode example
231 spi@2200 { // PSC2
232 device_type = "spi";
233 compatible = "mpc5200-psc-spi\0mpc52xx-psc-spi";
234 reg = <2200 100>;
235 interrupts = <2 2 0>;
236 interrupt-parent = <500>;
237 };
238
239 // PSC3 in CODEC mode example
240 i2s@2400 { // PSC3
241 device_type = "i2s";
242 compatible = "mpc5200-psc-i2s\0mpc52xx-psc-i2s";
243 reg = <2400 100>;
244 interrupts = <2 3 0>;
245 interrupt-parent = <500>;
246 };
247
248 // PSC4 unconfigured
249 //serial@2600 { // PSC4
250 // device_type = "serial";
251 // compatible = "mpc5200-psc-uart\0mpc52xx-psc-uart";
252 // reg = <2600 100>;
253 // interrupts = <2 b 0>;
254 // interrupt-parent = <500>;
255 //};
256
257 // PSC5 unconfigured
258 //serial@2800 { // PSC5
259 // device_type = "serial";
260 // compatible = "mpc5200-psc-uart\0mpc52xx-psc-uart";
261 // reg = <2800 100>;
262 // interrupts = <2 c 0>;
263 // interrupt-parent = <500>;
264 //};
265
266 // PSC6 in AC97 mode example
267 ac97@2c00 { // PSC6
268 device_type = "ac97";
269 compatible = "mpc5200-psc-ac97\0mpc52xx-psc-ac97";
270 reg = <2c00 100>;
271 interrupts = <2 4 0>;
272 interrupt-parent = <500>;
273 };
274
275 ethernet@3000 {
276 device_type = "network";
277 compatible = "mpc5200-fec\0mpc52xx-fec";
278 reg = <3000 800>;
279 mac-address = [ 02 03 04 05 06 07 ]; // Bad!
280 interrupts = <2 5 0>;
281 interrupt-parent = <500>;
282 };
283
284 ata@3a00 {
285 device_type = "ata";
286 compatible = "mpc5200-ata\0mpc52xx-ata";
287 reg = <3a00 100>;
288 interrupts = <2 7 0>;
289 interrupt-parent = <500>;
290 };
291
292 i2c@3d00 {
293 device_type = "i2c";
294 compatible = "mpc5200-i2c\0mpc52xx-i2c";
295 reg = <3d00 40>;
296 interrupts = <2 f 0>;
297 interrupt-parent = <500>;
298 };
299
300 i2c@3d40 {
301 device_type = "i2c";
302 compatible = "mpc5200-i2c\0mpc52xx-i2c";
303 reg = <3d40 40>;
304 interrupts = <2 10 0>;
305 interrupt-parent = <500>;
306 };
307 sram@8000 {
308 device_type = "sram";
309 compatible = "mpc5200-sram\0mpc52xx-sram\0sram";
310 reg = <8000 4000>;
311 };
312 };
313};
diff --git a/arch/powerpc/boot/dts/lite5200b.dts b/arch/powerpc/boot/dts/lite5200b.dts
new file mode 100644
index 000000000000..81cb76418a78
--- /dev/null
+++ b/arch/powerpc/boot/dts/lite5200b.dts
@@ -0,0 +1,318 @@
1/*
2 * Lite5200B board Device Tree Source
3 *
4 * Copyright 2006 Secret Lab Technologies Ltd.
5 * Grant Likely <grant.likely@secretlab.ca>
6 *
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2 of the License, or (at your
10 * option) any later version.
11 */
12
13/ {
14 model = "Lite5200b";
15 compatible = "lite5200b\0lite52xx\0mpc5200b\0mpc52xx";
16 #address-cells = <1>;
17 #size-cells = <1>;
18
19 cpus {
20 #cpus = <1>;
21 #address-cells = <1>;
22 #size-cells = <0>;
23
24 PowerPC,5200@0 {
25 device_type = "cpu";
26 reg = <0>;
27 d-cache-line-size = <20>;
28 i-cache-line-size = <20>;
29 d-cache-size = <4000>; // L1, 16K
30 i-cache-size = <4000>; // L1, 16K
31 timebase-frequency = <0>; // from bootloader
32 bus-frequency = <0>; // from bootloader
33 clock-frequency = <0>; // from bootloader
34 32-bit;
35 };
36 };
37
38 memory {
39 device_type = "memory";
40 reg = <00000000 10000000>; // 256MB
41 };
42
43 soc5200@f0000000 {
44 #interrupt-cells = <3>;
45 device_type = "soc";
46 ranges = <0 f0000000 f0010000>;
47 reg = <f0000000 00010000>;
48 bus-frequency = <0>; // from bootloader
49
50 cdm@200 {
51 compatible = "mpc5200b-cdm\0mpc52xx-cdm";
52 reg = <200 38>;
53 };
54
55 pic@500 {
56 // 5200 interrupts are encoded into two levels;
57 linux,phandle = <500>;
58 interrupt-controller;
59 #interrupt-cells = <3>;
60 device_type = "interrupt-controller";
61 compatible = "mpc5200b-pic\0mpc52xx-pic";
62 reg = <500 80>;
63 built-in;
64 };
65
66 gpt@600 { // General Purpose Timer
67 compatible = "mpc5200b-gpt\0mpc52xx-gpt";
68 device_type = "gpt";
69 reg = <600 10>;
70 interrupts = <1 9 0>;
71 interrupt-parent = <500>;
72 };
73
74 gpt@610 { // General Purpose Timer
75 compatible = "mpc5200b-gpt\0mpc52xx-gpt";
76 device_type = "gpt";
77 reg = <610 10>;
78 interrupts = <1 a 0>;
79 interrupt-parent = <500>;
80 };
81
82 gpt@620 { // General Purpose Timer
83 compatible = "mpc5200b-gpt\0mpc52xx-gpt";
84 device_type = "gpt";
85 reg = <620 10>;
86 interrupts = <1 b 0>;
87 interrupt-parent = <500>;
88 };
89
90 gpt@630 { // General Purpose Timer
91 compatible = "mpc5200b-gpt\0mpc52xx-gpt";
92 device_type = "gpt";
93 reg = <630 10>;
94 interrupts = <1 c 0>;
95 interrupt-parent = <500>;
96 };
97
98 gpt@640 { // General Purpose Timer
99 compatible = "mpc5200b-gpt\0mpc52xx-gpt";
100 device_type = "gpt";
101 reg = <640 10>;
102 interrupts = <1 d 0>;
103 interrupt-parent = <500>;
104 };
105
106 gpt@650 { // General Purpose Timer
107 compatible = "mpc5200b-gpt\0mpc52xx-gpt";
108 device_type = "gpt";
109 reg = <650 10>;
110 interrupts = <1 e 0>;
111 interrupt-parent = <500>;
112 };
113
114 gpt@660 { // General Purpose Timer
115 compatible = "mpc5200b-gpt\0mpc52xx-gpt";
116 device_type = "gpt";
117 reg = <660 10>;
118 interrupts = <1 f 0>;
119 interrupt-parent = <500>;
120 };
121
122 gpt@670 { // General Purpose Timer
123 compatible = "mpc5200b-gpt\0mpc52xx-gpt";
124 device_type = "gpt";
125 reg = <670 10>;
126 interrupts = <1 10 0>;
127 interrupt-parent = <500>;
128 };
129
130 rtc@800 { // Real time clock
131 compatible = "mpc5200b-rtc\0mpc52xx-rtc";
132 device_type = "rtc";
133 reg = <800 100>;
134 interrupts = <1 5 0 1 6 0>;
135 interrupt-parent = <500>;
136 };
137
138 mscan@900 {
139 device_type = "mscan";
140 compatible = "mpc5200b-mscan\0mpc52xx-mscan";
141 interrupts = <2 11 0>;
142 interrupt-parent = <500>;
143 reg = <900 80>;
144 };
145
146 mscan@980 {
147 device_type = "mscan";
148 compatible = "mpc5200b-mscan\0mpc52xx-mscan";
149 interrupts = <1 12 0>;
150 interrupt-parent = <500>;
151 reg = <980 80>;
152 };
153
154 gpio@b00 {
155 compatible = "mpc5200b-gpio\0mpc52xx-gpio";
156 reg = <b00 40>;
157 interrupts = <1 7 0>;
158 interrupt-parent = <500>;
159 };
160
161 gpio-wkup@b00 {
162 compatible = "mpc5200b-gpio-wkup\0mpc52xx-gpio-wkup";
163 reg = <c00 40>;
164 interrupts = <1 8 0 0 3 0>;
165 interrupt-parent = <500>;
166 };
167
168 pci@0d00 {
169 #interrupt-cells = <1>;
170 #size-cells = <2>;
171 #address-cells = <3>;
172 device_type = "pci";
173 compatible = "mpc5200b-pci\0mpc52xx-pci";
174 reg = <d00 100>;
175 interrupt-map-mask = <f800 0 0 7>;
176 interrupt-map = <c000 0 0 1 500 0 0 3 // 1st slot
177 c000 0 0 2 500 1 1 3
178 c000 0 0 3 500 1 2 3
179 c000 0 0 4 500 1 3 3
180
181 c800 0 0 1 500 1 1 3 // 2nd slot
182 c800 0 0 2 500 1 2 3
183 c800 0 0 3 500 1 3 3
184 c800 0 0 4 500 0 0 3>;
185 clock-frequency = <0>; // From boot loader
186 interrupts = <2 8 0 2 9 0 2 a 0>;
187 interrupt-parent = <500>;
188 bus-range = <0 0>;
189 ranges = <42000000 0 80000000 80000000 0 20000000
190 02000000 0 a0000000 a0000000 0 10000000
191 01000000 0 00000000 b0000000 0 01000000>;
192 };
193
194 spi@f00 {
195 device_type = "spi";
196 compatible = "mpc5200b-spi\0mpc52xx-spi";
197 reg = <f00 20>;
198 interrupts = <2 d 0 2 e 0>;
199 interrupt-parent = <500>;
200 };
201
202 usb@1000 {
203 device_type = "usb-ohci-be";
204 compatible = "mpc5200b-ohci\0mpc52xx-ohci\0ohci-be";
205 reg = <1000 ff>;
206 interrupts = <2 6 0>;
207 interrupt-parent = <500>;
208 };
209
210 bestcomm@1200 {
211 device_type = "dma-controller";
212 compatible = "mpc5200b-bestcomm\0mpc52xx-bestcomm";
213 reg = <1200 80>;
214 interrupts = <3 0 0 3 1 0 3 2 0 3 3 0
215 3 4 0 3 5 0 3 6 0 3 7 0
216 3 8 0 3 9 0 3 a 0 3 b 0
217 3 c 0 3 d 0 3 e 0 3 f 0>;
218 interrupt-parent = <500>;
219 };
220
221 xlb@1f00 {
222 compatible = "mpc5200b-xlb\0mpc52xx-xlb";
223 reg = <1f00 100>;
224 };
225
226 serial@2000 { // PSC1
227 device_type = "serial";
228 compatible = "mpc5200b-psc-uart\0mpc52xx-psc-uart";
229 port-number = <0>; // Logical port assignment
230 reg = <2000 100>;
231 interrupts = <2 1 0>;
232 interrupt-parent = <500>;
233 };
234
235 // PSC2 in spi mode example
236 spi@2200 { // PSC2
237 device_type = "spi";
238 compatible = "mpc5200b-psc-spi\0mpc52xx-psc-spi";
239 reg = <2200 100>;
240 interrupts = <2 2 0>;
241 interrupt-parent = <500>;
242 };
243
244 // PSC3 in CODEC mode example
245 i2s@2400 { // PSC3
246 device_type = "i2s";
247 compatible = "mpc5200b-psc-i2s\0mpc52xx-psc-i2s";
248 reg = <2400 100>;
249 interrupts = <2 3 0>;
250 interrupt-parent = <500>;
251 };
252
253 // PSC4 unconfigured
254 //serial@2600 { // PSC4
255 // device_type = "serial";
256 // compatible = "mpc5200b-psc-uart\0mpc52xx-psc-uart";
257 // reg = <2600 100>;
258 // interrupts = <2 b 0>;
259 // interrupt-parent = <500>;
260 //};
261
262 // PSC5 unconfigured
263 //serial@2800 { // PSC5
264 // device_type = "serial";
265 // compatible = "mpc5200b-psc-uart\0mpc52xx-psc-uart";
266 // reg = <2800 100>;
267 // interrupts = <2 c 0>;
268 // interrupt-parent = <500>;
269 //};
270
271 // PSC6 in AC97 mode example
272 ac97@2c00 { // PSC6
273 device_type = "ac97";
274 compatible = "mpc5200b-psc-ac97\0mpc52xx-psc-ac97";
275 reg = <2c00 100>;
276 interrupts = <2 4 0>;
277 interrupt-parent = <500>;
278 };
279
280 ethernet@3000 {
281 device_type = "network";
282 compatible = "mpc5200b-fec\0mpc52xx-fec";
283 reg = <3000 800>;
284 mac-address = [ 02 03 04 05 06 07 ]; // Bad!
285 interrupts = <2 5 0>;
286 interrupt-parent = <500>;
287 };
288
289 ata@3a00 {
290 device_type = "ata";
291 compatible = "mpc5200b-ata\0mpc52xx-ata";
292 reg = <3a00 100>;
293 interrupts = <2 7 0>;
294 interrupt-parent = <500>;
295 };
296
297 i2c@3d00 {
298 device_type = "i2c";
299 compatible = "mpc5200b-i2c\0mpc52xx-i2c";
300 reg = <3d00 40>;
301 interrupts = <2 f 0>;
302 interrupt-parent = <500>;
303 };
304
305 i2c@3d40 {
306 device_type = "i2c";
307 compatible = "mpc5200b-i2c\0mpc52xx-i2c";
308 reg = <3d40 40>;
309 interrupts = <2 10 0>;
310 interrupt-parent = <500>;
311 };
312 sram@8000 {
313 device_type = "sram";
314 compatible = "mpc5200b-sram\0mpc52xx-sram\0sram";
315 reg = <8000 4000>;
316 };
317 };
318};
diff --git a/arch/powerpc/boot/dts/mpc7448hpc2.dts b/arch/powerpc/boot/dts/mpc7448hpc2.dts
index d7b985e6bd2f..c4d9562cbaad 100644
--- a/arch/powerpc/boot/dts/mpc7448hpc2.dts
+++ b/arch/powerpc/boot/dts/mpc7448hpc2.dts
@@ -161,29 +161,41 @@
161 interrupt-map = < 161 interrupt-map = <
162 162
163 /* IDSEL 0x11 */ 163 /* IDSEL 0x11 */
164 0800 0 0 1 7400 24 0 164 0800 0 0 1 1180 24 0
165 0800 0 0 2 7400 25 0 165 0800 0 0 2 1180 25 0
166 0800 0 0 3 7400 26 0 166 0800 0 0 3 1180 26 0
167 0800 0 0 4 7400 27 0 167 0800 0 0 4 1180 27 0
168 168
169 /* IDSEL 0x12 */ 169 /* IDSEL 0x12 */
170 1000 0 0 1 7400 25 0 170 1000 0 0 1 1180 25 0
171 1000 0 0 2 7400 26 0 171 1000 0 0 2 1180 26 0
172 1000 0 0 3 7400 27 0 172 1000 0 0 3 1180 27 0
173 1000 0 0 4 7400 24 0 173 1000 0 0 4 1180 24 0
174 174
175 /* IDSEL 0x13 */ 175 /* IDSEL 0x13 */
176 1800 0 0 1 7400 26 0 176 1800 0 0 1 1180 26 0
177 1800 0 0 2 7400 27 0 177 1800 0 0 2 1180 27 0
178 1800 0 0 3 7400 24 0 178 1800 0 0 3 1180 24 0
179 1800 0 0 4 7400 25 0 179 1800 0 0 4 1180 25 0
180 180
181 /* IDSEL 0x14 */ 181 /* IDSEL 0x14 */
182 2000 0 0 1 7400 27 0 182 2000 0 0 1 1180 27 0
183 2000 0 0 2 7400 24 0 183 2000 0 0 2 1180 24 0
184 2000 0 0 3 7400 25 0 184 2000 0 0 3 1180 25 0
185 2000 0 0 4 7400 26 0 185 2000 0 0 4 1180 26 0
186 >; 186 >;
187 router@1180 {
188 linux,phandle = <1180>;
189 clock-frequency = <0>;
190 interrupt-controller;
191 device_type = "pic-router";
192 #address-cells = <0>;
193 #interrupt-cells = <2>;
194 built-in;
195 big-endian;
196 interrupts = <17 2>;
197 interrupt-parent = <7400>;
198 };
187 }; 199 };
188 }; 200 };
189 201
diff --git a/arch/powerpc/boot/flatdevtree.c b/arch/powerpc/boot/flatdevtree.c
new file mode 100644
index 000000000000..c76c194715b2
--- /dev/null
+++ b/arch/powerpc/boot/flatdevtree.c
@@ -0,0 +1,880 @@
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15 *
16 * Copyright Pantelis Antoniou 2006
17 * Copyright (C) IBM Corporation 2006
18 *
19 * Authors: Pantelis Antoniou <pantelis@embeddedalley.com>
20 * Hollis Blanchard <hollisb@us.ibm.com>
21 * Mark A. Greer <mgreer@mvista.com>
22 * Paul Mackerras <paulus@samba.org>
23 */
24
25#include <string.h>
26#include <stddef.h>
27#include "flatdevtree.h"
28#include "flatdevtree_env.h"
29
30#define _ALIGN(x, al) (((x) + (al) - 1) & ~((al) - 1))
31
32/* Routines for keeping node ptrs returned by ft_find_device current */
33/* First entry not used b/c it would return 0 and be taken as NULL/error */
34static void *ft_node_add(struct ft_cxt *cxt, char *node)
35{
36 unsigned int i;
37
38 for (i = 1; i < cxt->nodes_used; i++) /* already there? */
39 if (cxt->node_tbl[i] == node)
40 return (void *)i;
41
42 if (cxt->nodes_used < cxt->node_max) {
43 cxt->node_tbl[cxt->nodes_used] = node;
44 return (void *)cxt->nodes_used++;
45 }
46
47 return NULL;
48}
49
50static char *ft_node_ph2node(struct ft_cxt *cxt, const void *phandle)
51{
52 unsigned int i = (unsigned int)phandle;
53
54 if (i < cxt->nodes_used)
55 return cxt->node_tbl[i];
56 return NULL;
57}
58
59static void ft_node_update_before(struct ft_cxt *cxt, char *addr, int shift)
60{
61 unsigned int i;
62
63 if (shift == 0)
64 return;
65
66 for (i = 1; i < cxt->nodes_used; i++)
67 if (cxt->node_tbl[i] < addr)
68 cxt->node_tbl[i] += shift;
69}
70
71static void ft_node_update_after(struct ft_cxt *cxt, char *addr, int shift)
72{
73 unsigned int i;
74
75 if (shift == 0)
76 return;
77
78 for (i = 1; i < cxt->nodes_used; i++)
79 if (cxt->node_tbl[i] >= addr)
80 cxt->node_tbl[i] += shift;
81}
82
83/* Struct used to return info from ft_next() */
84struct ft_atom {
85 u32 tag;
86 const char *name;
87 void *data;
88 u32 size;
89};
90
91/* Set ptrs to current one's info; return addr of next one */
92static char *ft_next(struct ft_cxt *cxt, char *p, struct ft_atom *ret)
93{
94 u32 sz;
95
96 if (p >= cxt->rgn[FT_STRUCT].start + cxt->rgn[FT_STRUCT].size)
97 return NULL;
98
99 ret->tag = be32_to_cpu(*(u32 *) p);
100 p += 4;
101
102 switch (ret->tag) { /* Tag */
103 case OF_DT_BEGIN_NODE:
104 ret->name = p;
105 ret->data = (void *)(p - 4); /* start of node */
106 p += _ALIGN(strlen(p) + 1, 4);
107 break;
108 case OF_DT_PROP:
109 ret->size = sz = be32_to_cpu(*(u32 *) p);
110 ret->name = cxt->str_anchor + be32_to_cpu(*(u32 *) (p + 4));
111 ret->data = (void *)(p + 8);
112 p += 8 + _ALIGN(sz, 4);
113 break;
114 case OF_DT_END_NODE:
115 case OF_DT_NOP:
116 break;
117 case OF_DT_END:
118 default:
119 p = NULL;
120 break;
121 }
122
123 return p;
124}
125
126#define HDR_SIZE _ALIGN(sizeof(struct boot_param_header), 8)
127#define EXPAND_INCR 1024 /* alloc this much extra when expanding */
128
129/* See if the regions are in the standard order and non-overlapping */
130static int ft_ordered(struct ft_cxt *cxt)
131{
132 char *p = (char *)cxt->bph + HDR_SIZE;
133 enum ft_rgn_id r;
134
135 for (r = FT_RSVMAP; r <= FT_STRINGS; ++r) {
136 if (p > cxt->rgn[r].start)
137 return 0;
138 p = cxt->rgn[r].start + cxt->rgn[r].size;
139 }
140 return p <= (char *)cxt->bph + cxt->max_size;
141}
142
143/* Copy the tree to a newly-allocated region and put things in order */
144static int ft_reorder(struct ft_cxt *cxt, int nextra)
145{
146 unsigned long tot;
147 enum ft_rgn_id r;
148 char *p, *pend;
149 int stroff;
150
151 tot = HDR_SIZE + EXPAND_INCR;
152 for (r = FT_RSVMAP; r <= FT_STRINGS; ++r)
153 tot += cxt->rgn[r].size;
154 if (nextra > 0)
155 tot += nextra;
156 tot = _ALIGN(tot, 8);
157
158 if (!cxt->realloc)
159 return 0;
160 p = cxt->realloc(NULL, tot);
161 if (!p)
162 return 0;
163
164 memcpy(p, cxt->bph, sizeof(struct boot_param_header));
165 /* offsets get fixed up later */
166
167 cxt->bph = (struct boot_param_header *)p;
168 cxt->max_size = tot;
169 pend = p + tot;
170 p += HDR_SIZE;
171
172 memcpy(p, cxt->rgn[FT_RSVMAP].start, cxt->rgn[FT_RSVMAP].size);
173 cxt->rgn[FT_RSVMAP].start = p;
174 p += cxt->rgn[FT_RSVMAP].size;
175
176 memcpy(p, cxt->rgn[FT_STRUCT].start, cxt->rgn[FT_STRUCT].size);
177 ft_node_update_after(cxt, cxt->rgn[FT_STRUCT].start,
178 p - cxt->rgn[FT_STRUCT].start);
179 cxt->p += p - cxt->rgn[FT_STRUCT].start;
180 cxt->rgn[FT_STRUCT].start = p;
181
182 p = pend - cxt->rgn[FT_STRINGS].size;
183 memcpy(p, cxt->rgn[FT_STRINGS].start, cxt->rgn[FT_STRINGS].size);
184 stroff = cxt->str_anchor - cxt->rgn[FT_STRINGS].start;
185 cxt->rgn[FT_STRINGS].start = p;
186 cxt->str_anchor = p + stroff;
187
188 cxt->isordered = 1;
189 return 1;
190}
191
192static inline char *prev_end(struct ft_cxt *cxt, enum ft_rgn_id r)
193{
194 if (r > FT_RSVMAP)
195 return cxt->rgn[r - 1].start + cxt->rgn[r - 1].size;
196 return (char *)cxt->bph + HDR_SIZE;
197}
198
199static inline char *next_start(struct ft_cxt *cxt, enum ft_rgn_id r)
200{
201 if (r < FT_STRINGS)
202 return cxt->rgn[r + 1].start;
203 return (char *)cxt->bph + cxt->max_size;
204}
205
206/*
207 * See if we can expand region rgn by nextra bytes by using up
208 * free space after or before the region.
209 */
210static int ft_shuffle(struct ft_cxt *cxt, char **pp, enum ft_rgn_id rgn,
211 int nextra)
212{
213 char *p = *pp;
214 char *rgn_start, *rgn_end;
215
216 rgn_start = cxt->rgn[rgn].start;
217 rgn_end = rgn_start + cxt->rgn[rgn].size;
218 if (nextra <= 0 || rgn_end + nextra <= next_start(cxt, rgn)) {
219 /* move following stuff */
220 if (p < rgn_end) {
221 if (nextra < 0)
222 memmove(p, p - nextra, rgn_end - p + nextra);
223 else
224 memmove(p + nextra, p, rgn_end - p);
225 if (rgn == FT_STRUCT)
226 ft_node_update_after(cxt, p, nextra);
227 }
228 cxt->rgn[rgn].size += nextra;
229 if (rgn == FT_STRINGS)
230 /* assumes strings only added at beginning */
231 cxt->str_anchor += nextra;
232 return 1;
233 }
234 if (prev_end(cxt, rgn) <= rgn_start - nextra) {
235 /* move preceding stuff */
236 if (p > rgn_start) {
237 memmove(rgn_start - nextra, rgn_start, p - rgn_start);
238 if (rgn == FT_STRUCT)
239 ft_node_update_before(cxt, p, -nextra);
240 }
241 *p -= nextra;
242 cxt->rgn[rgn].start -= nextra;
243 cxt->rgn[rgn].size += nextra;
244 return 1;
245 }
246 return 0;
247}
248
249static int ft_make_space(struct ft_cxt *cxt, char **pp, enum ft_rgn_id rgn,
250 int nextra)
251{
252 unsigned long size, ssize, tot;
253 char *str, *next;
254 enum ft_rgn_id r;
255
256 if (!cxt->isordered && !ft_reorder(cxt, nextra))
257 return 0;
258 if (ft_shuffle(cxt, pp, rgn, nextra))
259 return 1;
260
261 /* See if there is space after the strings section */
262 ssize = cxt->rgn[FT_STRINGS].size;
263 if (cxt->rgn[FT_STRINGS].start + ssize
264 < (char *)cxt->bph + cxt->max_size) {
265 /* move strings up as far as possible */
266 str = (char *)cxt->bph + cxt->max_size - ssize;
267 cxt->str_anchor += str - cxt->rgn[FT_STRINGS].start;
268 memmove(str, cxt->rgn[FT_STRINGS].start, ssize);
269 cxt->rgn[FT_STRINGS].start = str;
270 /* enough space now? */
271 if (rgn >= FT_STRUCT && ft_shuffle(cxt, pp, rgn, nextra))
272 return 1;
273 }
274
275 /* how much total free space is there following this region? */
276 tot = 0;
277 for (r = rgn; r < FT_STRINGS; ++r) {
278 char *r_end = cxt->rgn[r].start + cxt->rgn[r].size;
279 tot += next_start(cxt, rgn) - r_end;
280 }
281
282 /* cast is to shut gcc up; we know nextra >= 0 */
283 if (tot < (unsigned int)nextra) {
284 /* have to reallocate */
285 char *newp, *new_start;
286 int shift;
287
288 if (!cxt->realloc)
289 return 0;
290 size = _ALIGN(cxt->max_size + (nextra - tot) + EXPAND_INCR, 8);
291 newp = cxt->realloc(cxt->bph, size);
292 if (!newp)
293 return 0;
294 cxt->max_size = size;
295 shift = newp - (char *)cxt->bph;
296
297 if (shift) { /* realloc can return same addr */
298 cxt->bph = (struct boot_param_header *)newp;
299 ft_node_update_after(cxt, cxt->rgn[FT_STRUCT].start,
300 shift);
301 for (r = FT_RSVMAP; r <= FT_STRINGS; ++r) {
302 new_start = cxt->rgn[r].start + shift;
303 cxt->rgn[r].start = new_start;
304 }
305 *pp += shift;
306 cxt->str_anchor += shift;
307 }
308
309 /* move strings up to the end */
310 str = newp + size - ssize;
311 cxt->str_anchor += str - cxt->rgn[FT_STRINGS].start;
312 memmove(str, cxt->rgn[FT_STRINGS].start, ssize);
313 cxt->rgn[FT_STRINGS].start = str;
314
315 if (ft_shuffle(cxt, pp, rgn, nextra))
316 return 1;
317 }
318
319 /* must be FT_RSVMAP and we need to move FT_STRUCT up */
320 if (rgn == FT_RSVMAP) {
321 next = cxt->rgn[FT_RSVMAP].start + cxt->rgn[FT_RSVMAP].size
322 + nextra;
323 ssize = cxt->rgn[FT_STRUCT].size;
324 if (next + ssize >= cxt->rgn[FT_STRINGS].start)
325 return 0; /* "can't happen" */
326 memmove(next, cxt->rgn[FT_STRUCT].start, ssize);
327 ft_node_update_after(cxt, cxt->rgn[FT_STRUCT].start, nextra);
328 cxt->rgn[FT_STRUCT].start = next;
329
330 if (ft_shuffle(cxt, pp, rgn, nextra))
331 return 1;
332 }
333
334 return 0; /* "can't happen" */
335}
336
337static void ft_put_word(struct ft_cxt *cxt, u32 v)
338{
339 *(u32 *) cxt->p = cpu_to_be32(v);
340 cxt->p += 4;
341}
342
343static void ft_put_bin(struct ft_cxt *cxt, const void *data, unsigned int sz)
344{
345 unsigned long sza = _ALIGN(sz, 4);
346
347 /* zero out the alignment gap if necessary */
348 if (sz < sza)
349 *(u32 *) (cxt->p + sza - 4) = 0;
350
351 /* copy in the data */
352 memcpy(cxt->p, data, sz);
353
354 cxt->p += sza;
355}
356
357int ft_begin_node(struct ft_cxt *cxt, const char *name)
358{
359 unsigned long nlen = strlen(name) + 1;
360 unsigned long len = 8 + _ALIGN(nlen, 4);
361
362 if (!ft_make_space(cxt, &cxt->p, FT_STRUCT, len))
363 return -1;
364 ft_put_word(cxt, OF_DT_BEGIN_NODE);
365 ft_put_bin(cxt, name, strlen(name) + 1);
366 return 0;
367}
368
369void ft_end_node(struct ft_cxt *cxt)
370{
371 ft_put_word(cxt, OF_DT_END_NODE);
372}
373
374void ft_nop(struct ft_cxt *cxt)
375{
376 if (ft_make_space(cxt, &cxt->p, FT_STRUCT, 4))
377 ft_put_word(cxt, OF_DT_NOP);
378}
379
380#define NO_STRING 0x7fffffff
381
382static int lookup_string(struct ft_cxt *cxt, const char *name)
383{
384 char *p, *end;
385
386 p = cxt->rgn[FT_STRINGS].start;
387 end = p + cxt->rgn[FT_STRINGS].size;
388 while (p < end) {
389 if (strcmp(p, (char *)name) == 0)
390 return p - cxt->str_anchor;
391 p += strlen(p) + 1;
392 }
393
394 return NO_STRING;
395}
396
397/* lookup string and insert if not found */
398static int map_string(struct ft_cxt *cxt, const char *name)
399{
400 int off;
401 char *p;
402
403 off = lookup_string(cxt, name);
404 if (off != NO_STRING)
405 return off;
406 p = cxt->rgn[FT_STRINGS].start;
407 if (!ft_make_space(cxt, &p, FT_STRINGS, strlen(name) + 1))
408 return NO_STRING;
409 strcpy(p, name);
410 return p - cxt->str_anchor;
411}
412
413int ft_prop(struct ft_cxt *cxt, const char *name, const void *data,
414 unsigned int sz)
415{
416 int off, len;
417
418 off = lookup_string(cxt, name);
419 if (off == NO_STRING)
420 return -1;
421
422 len = 12 + _ALIGN(sz, 4);
423 if (!ft_make_space(cxt, &cxt->p, FT_STRUCT, len))
424 return -1;
425
426 ft_put_word(cxt, OF_DT_PROP);
427 ft_put_word(cxt, sz);
428 ft_put_word(cxt, off);
429 ft_put_bin(cxt, data, sz);
430 return 0;
431}
432
433int ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str)
434{
435 return ft_prop(cxt, name, str, strlen(str) + 1);
436}
437
438int ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val)
439{
440 u32 v = cpu_to_be32((u32) val);
441
442 return ft_prop(cxt, name, &v, 4);
443}
444
445/* Calculate the size of the reserved map */
446static unsigned long rsvmap_size(struct ft_cxt *cxt)
447{
448 struct ft_reserve *res;
449
450 res = (struct ft_reserve *)cxt->rgn[FT_RSVMAP].start;
451 while (res->start || res->len)
452 ++res;
453 return (char *)(res + 1) - cxt->rgn[FT_RSVMAP].start;
454}
455
456/* Calculate the size of the struct region by stepping through it */
457static unsigned long struct_size(struct ft_cxt *cxt)
458{
459 char *p = cxt->rgn[FT_STRUCT].start;
460 char *next;
461 struct ft_atom atom;
462
463 /* make check in ft_next happy */
464 if (cxt->rgn[FT_STRUCT].size == 0)
465 cxt->rgn[FT_STRUCT].size = 0xfffffffful - (unsigned long)p;
466
467 while ((next = ft_next(cxt, p, &atom)) != NULL)
468 p = next;
469 return p + 4 - cxt->rgn[FT_STRUCT].start;
470}
471
472/* add `adj' on to all string offset values in the struct area */
473static void adjust_string_offsets(struct ft_cxt *cxt, int adj)
474{
475 char *p = cxt->rgn[FT_STRUCT].start;
476 char *next;
477 struct ft_atom atom;
478 int off;
479
480 while ((next = ft_next(cxt, p, &atom)) != NULL) {
481 if (atom.tag == OF_DT_PROP) {
482 off = be32_to_cpu(*(u32 *) (p + 8));
483 *(u32 *) (p + 8) = cpu_to_be32(off + adj);
484 }
485 p = next;
486 }
487}
488
489/* start construction of the flat OF tree from scratch */
490void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size,
491 void *(*realloc_fn) (void *, unsigned long))
492{
493 struct boot_param_header *bph = blob;
494 char *p;
495 struct ft_reserve *pres;
496
497 /* clear the cxt */
498 memset(cxt, 0, sizeof(*cxt));
499
500 cxt->bph = bph;
501 cxt->max_size = max_size;
502 cxt->realloc = realloc_fn;
503 cxt->isordered = 1;
504
505 /* zero everything in the header area */
506 memset(bph, 0, sizeof(*bph));
507
508 bph->magic = cpu_to_be32(OF_DT_HEADER);
509 bph->version = cpu_to_be32(0x10);
510 bph->last_comp_version = cpu_to_be32(0x10);
511
512 /* start pointers */
513 cxt->rgn[FT_RSVMAP].start = p = blob + HDR_SIZE;
514 cxt->rgn[FT_RSVMAP].size = sizeof(struct ft_reserve);
515 pres = (struct ft_reserve *)p;
516 cxt->rgn[FT_STRUCT].start = p += sizeof(struct ft_reserve);
517 cxt->rgn[FT_STRUCT].size = 4;
518 cxt->rgn[FT_STRINGS].start = blob + max_size;
519 cxt->rgn[FT_STRINGS].size = 0;
520
521 /* init rsvmap and struct */
522 pres->start = 0;
523 pres->len = 0;
524 *(u32 *) p = cpu_to_be32(OF_DT_END);
525
526 cxt->str_anchor = blob;
527}
528
529/* open up an existing blob to be examined or modified */
530int ft_open(struct ft_cxt *cxt, void *blob, unsigned int max_size,
531 unsigned int max_find_device,
532 void *(*realloc_fn) (void *, unsigned long))
533{
534 struct boot_param_header *bph = blob;
535
536 /* can't cope with version < 16 */
537 if (be32_to_cpu(bph->version) < 16)
538 return -1;
539
540 /* clear the cxt */
541 memset(cxt, 0, sizeof(*cxt));
542
543 /* alloc node_tbl to track node ptrs returned by ft_find_device */
544 ++max_find_device;
545 cxt->node_tbl = realloc_fn(NULL, max_find_device * sizeof(char *));
546 if (!cxt->node_tbl)
547 return -1;
548 memset(cxt->node_tbl, 0, max_find_device * sizeof(char *));
549 cxt->node_max = max_find_device;
550 cxt->nodes_used = 1; /* don't use idx 0 b/c looks like NULL */
551
552 cxt->bph = bph;
553 cxt->max_size = max_size;
554 cxt->realloc = realloc_fn;
555
556 cxt->rgn[FT_RSVMAP].start = blob + be32_to_cpu(bph->off_mem_rsvmap);
557 cxt->rgn[FT_RSVMAP].size = rsvmap_size(cxt);
558 cxt->rgn[FT_STRUCT].start = blob + be32_to_cpu(bph->off_dt_struct);
559 cxt->rgn[FT_STRUCT].size = struct_size(cxt);
560 cxt->rgn[FT_STRINGS].start = blob + be32_to_cpu(bph->off_dt_strings);
561 cxt->rgn[FT_STRINGS].size = be32_to_cpu(bph->dt_strings_size);
562 /* Leave as '0' to force first ft_make_space call to do a ft_reorder
563 * and move dt to an area allocated by realloc.
564 cxt->isordered = ft_ordered(cxt);
565 */
566
567 cxt->p = cxt->rgn[FT_STRUCT].start;
568 cxt->str_anchor = cxt->rgn[FT_STRINGS].start;
569
570 return 0;
571}
572
573/* add a reserver physical area to the rsvmap */
574int ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size)
575{
576 char *p;
577 struct ft_reserve *pres;
578
579 p = cxt->rgn[FT_RSVMAP].start + cxt->rgn[FT_RSVMAP].size
580 - sizeof(struct ft_reserve);
581 if (!ft_make_space(cxt, &p, FT_RSVMAP, sizeof(struct ft_reserve)))
582 return -1;
583
584 pres = (struct ft_reserve *)p;
585 pres->start = cpu_to_be64(physaddr);
586 pres->len = cpu_to_be64(size);
587
588 return 0;
589}
590
591void ft_begin_tree(struct ft_cxt *cxt)
592{
593 cxt->p = cxt->rgn[FT_STRUCT].start;
594}
595
596void ft_end_tree(struct ft_cxt *cxt)
597{
598 struct boot_param_header *bph = cxt->bph;
599 char *p, *oldstr, *str, *endp;
600 unsigned long ssize;
601 int adj;
602
603 if (!cxt->isordered)
604 return; /* we haven't touched anything */
605
606 /* adjust string offsets */
607 oldstr = cxt->rgn[FT_STRINGS].start;
608 adj = cxt->str_anchor - oldstr;
609 if (adj)
610 adjust_string_offsets(cxt, adj);
611
612 /* make strings end on 8-byte boundary */
613 ssize = cxt->rgn[FT_STRINGS].size;
614 endp = (char *)_ALIGN((unsigned long)cxt->rgn[FT_STRUCT].start
615 + cxt->rgn[FT_STRUCT].size + ssize, 8);
616 str = endp - ssize;
617
618 /* move strings down to end of structs */
619 memmove(str, oldstr, ssize);
620 cxt->str_anchor = str;
621 cxt->rgn[FT_STRINGS].start = str;
622
623 /* fill in header fields */
624 p = (char *)bph;
625 bph->totalsize = cpu_to_be32(endp - p);
626 bph->off_mem_rsvmap = cpu_to_be32(cxt->rgn[FT_RSVMAP].start - p);
627 bph->off_dt_struct = cpu_to_be32(cxt->rgn[FT_STRUCT].start - p);
628 bph->off_dt_strings = cpu_to_be32(cxt->rgn[FT_STRINGS].start - p);
629 bph->dt_strings_size = cpu_to_be32(ssize);
630}
631
632void *ft_find_device(struct ft_cxt *cxt, const char *srch_path)
633{
634 char *node;
635
636 /* require absolute path */
637 if (srch_path[0] != '/')
638 return NULL;
639 node = ft_find_descendent(cxt, cxt->rgn[FT_STRUCT].start, srch_path);
640 return ft_node_add(cxt, node);
641}
642
643void *ft_find_descendent(struct ft_cxt *cxt, void *top, const char *srch_path)
644{
645 struct ft_atom atom;
646 char *p;
647 const char *cp, *q;
648 int cl;
649 int depth = -1;
650 int dmatch = 0;
651 const char *path_comp[FT_MAX_DEPTH];
652
653 cp = srch_path;
654 cl = 0;
655 p = top;
656
657 while ((p = ft_next(cxt, p, &atom)) != NULL) {
658 switch (atom.tag) {
659 case OF_DT_BEGIN_NODE:
660 ++depth;
661 if (depth != dmatch)
662 break;
663 cxt->genealogy[depth] = atom.data;
664 cxt->genealogy[depth + 1] = NULL;
665 if (depth && !(strncmp(atom.name, cp, cl) == 0
666 && (atom.name[cl] == '/'
667 || atom.name[cl] == '\0'
668 || atom.name[cl] == '@')))
669 break;
670 path_comp[dmatch] = cp;
671 /* it matches so far, advance to next path component */
672 cp += cl;
673 /* skip slashes */
674 while (*cp == '/')
675 ++cp;
676 /* we're done if this is the end of the string */
677 if (*cp == 0)
678 return atom.data;
679 /* look for end of this component */
680 q = strchr(cp, '/');
681 if (q)
682 cl = q - cp;
683 else
684 cl = strlen(cp);
685 ++dmatch;
686 break;
687 case OF_DT_END_NODE:
688 if (depth == 0)
689 return NULL;
690 if (dmatch > depth) {
691 --dmatch;
692 cl = cp - path_comp[dmatch] - 1;
693 cp = path_comp[dmatch];
694 while (cl > 0 && cp[cl - 1] == '/')
695 --cl;
696 }
697 --depth;
698 break;
699 }
700 }
701 return NULL;
702}
703
704void *ft_get_parent(struct ft_cxt *cxt, const void *phandle)
705{
706 void *node;
707 int d;
708 struct ft_atom atom;
709 char *p;
710
711 node = ft_node_ph2node(cxt, phandle);
712 if (node == NULL)
713 return NULL;
714
715 for (d = 0; cxt->genealogy[d] != NULL; ++d)
716 if (cxt->genealogy[d] == node)
717 return cxt->genealogy[d > 0 ? d - 1 : 0];
718
719 /* have to do it the hard way... */
720 p = cxt->rgn[FT_STRUCT].start;
721 d = 0;
722 while ((p = ft_next(cxt, p, &atom)) != NULL) {
723 switch (atom.tag) {
724 case OF_DT_BEGIN_NODE:
725 cxt->genealogy[d] = atom.data;
726 if (node == atom.data) {
727 /* found it */
728 cxt->genealogy[d + 1] = NULL;
729 return d > 0 ? cxt->genealogy[d - 1] : node;
730 }
731 ++d;
732 break;
733 case OF_DT_END_NODE:
734 --d;
735 break;
736 }
737 }
738 return NULL;
739}
740
741int ft_get_prop(struct ft_cxt *cxt, const void *phandle, const char *propname,
742 void *buf, const unsigned int buflen)
743{
744 struct ft_atom atom;
745 void *node;
746 char *p;
747 int depth;
748 unsigned int size;
749
750 node = ft_node_ph2node(cxt, phandle);
751 if (node == NULL)
752 return -1;
753
754 depth = 0;
755 p = (char *)node;
756
757 while ((p = ft_next(cxt, p, &atom)) != NULL) {
758 switch (atom.tag) {
759 case OF_DT_BEGIN_NODE:
760 ++depth;
761 break;
762 case OF_DT_PROP:
763 if ((depth != 1) || strcmp(atom.name, propname))
764 break;
765 size = min(atom.size, buflen);
766 memcpy(buf, atom.data, size);
767 return atom.size;
768 case OF_DT_END_NODE:
769 if (--depth <= 0)
770 return -1;
771 }
772 }
773 return -1;
774}
775
776int ft_set_prop(struct ft_cxt *cxt, const void *phandle, const char *propname,
777 const void *buf, const unsigned int buflen)
778{
779 struct ft_atom atom;
780 void *node;
781 char *p, *next;
782 int nextra, depth;
783
784 node = ft_node_ph2node(cxt, phandle);
785 if (node == NULL)
786 return -1;
787
788 depth = 0;
789 p = node;
790
791 while ((next = ft_next(cxt, p, &atom)) != NULL) {
792 switch (atom.tag) {
793 case OF_DT_BEGIN_NODE:
794 ++depth;
795 break;
796 case OF_DT_END_NODE:
797 if (--depth > 0)
798 break;
799 /* haven't found the property, insert here */
800 cxt->p = p;
801 return ft_prop(cxt, propname, buf, buflen);
802 case OF_DT_PROP:
803 if ((depth != 1) || strcmp(atom.name, propname))
804 break;
805 /* found an existing property, overwrite it */
806 nextra = _ALIGN(buflen, 4) - _ALIGN(atom.size, 4);
807 cxt->p = atom.data;
808 if (nextra && !ft_make_space(cxt, &cxt->p, FT_STRUCT,
809 nextra))
810 return -1;
811 *(u32 *) (cxt->p - 8) = cpu_to_be32(buflen);
812 ft_put_bin(cxt, buf, buflen);
813 return 0;
814 }
815 p = next;
816 }
817 return -1;
818}
819
820int ft_del_prop(struct ft_cxt *cxt, const void *phandle, const char *propname)
821{
822 struct ft_atom atom;
823 void *node;
824 char *p, *next;
825 int size;
826
827 node = ft_node_ph2node(cxt, phandle);
828 if (node == NULL)
829 return -1;
830
831 p = node;
832 while ((next = ft_next(cxt, p, &atom)) != NULL) {
833 switch (atom.tag) {
834 case OF_DT_BEGIN_NODE:
835 case OF_DT_END_NODE:
836 return -1;
837 case OF_DT_PROP:
838 if (strcmp(atom.name, propname))
839 break;
840 /* found the property, remove it */
841 size = 12 + -_ALIGN(atom.size, 4);
842 cxt->p = p;
843 if (!ft_make_space(cxt, &cxt->p, FT_STRUCT, -size))
844 return -1;
845 return 0;
846 }
847 p = next;
848 }
849 return -1;
850}
851
852void *ft_create_node(struct ft_cxt *cxt, const void *parent, const char *path)
853{
854 struct ft_atom atom;
855 char *p, *next;
856 int depth = 0;
857
858 p = cxt->rgn[FT_STRUCT].start;
859 while ((next = ft_next(cxt, p, &atom)) != NULL) {
860 switch (atom.tag) {
861 case OF_DT_BEGIN_NODE:
862 ++depth;
863 if (depth == 1 && strcmp(atom.name, path) == 0)
864 /* duplicate node path, return error */
865 return NULL;
866 break;
867 case OF_DT_END_NODE:
868 --depth;
869 if (depth > 0)
870 break;
871 /* end of node, insert here */
872 cxt->p = p;
873 ft_begin_node(cxt, path);
874 ft_end_node(cxt);
875 return p;
876 }
877 p = next;
878 }
879 return NULL;
880}
diff --git a/arch/powerpc/boot/flatdevtree.h b/arch/powerpc/boot/flatdevtree.h
index 761c8dc84008..b9cd9f61f351 100644
--- a/arch/powerpc/boot/flatdevtree.h
+++ b/arch/powerpc/boot/flatdevtree.h
@@ -17,7 +17,7 @@
17#ifndef FLATDEVTREE_H 17#ifndef FLATDEVTREE_H
18#define FLATDEVTREE_H 18#define FLATDEVTREE_H
19 19
20#include "types.h" 20#include "flatdevtree_env.h"
21 21
22/* Definitions used by the flattened device tree */ 22/* Definitions used by the flattened device tree */
23#define OF_DT_HEADER 0xd00dfeed /* marker */ 23#define OF_DT_HEADER 0xd00dfeed /* marker */
@@ -43,4 +43,64 @@ struct boot_param_header {
43 u32 dt_strings_size; /* size of the DT strings block */ 43 u32 dt_strings_size; /* size of the DT strings block */
44}; 44};
45 45
46struct ft_reserve {
47 u64 start;
48 u64 len;
49};
50
51struct ft_region {
52 char *start;
53 unsigned long size;
54};
55
56enum ft_rgn_id {
57 FT_RSVMAP,
58 FT_STRUCT,
59 FT_STRINGS,
60 FT_N_REGION
61};
62
63#define FT_MAX_DEPTH 50
64
65struct ft_cxt {
66 struct boot_param_header *bph;
67 int max_size; /* maximum size of tree */
68 int isordered; /* everything in standard order */
69 void *(*realloc)(void *, unsigned long);
70 char *str_anchor;
71 char *p; /* current insertion point in structs */
72 struct ft_region rgn[FT_N_REGION];
73 void *genealogy[FT_MAX_DEPTH+1];
74 char **node_tbl;
75 unsigned int node_max;
76 unsigned int nodes_used;
77};
78
79int ft_begin_node(struct ft_cxt *cxt, const char *name);
80void ft_end_node(struct ft_cxt *cxt);
81
82void ft_begin_tree(struct ft_cxt *cxt);
83void ft_end_tree(struct ft_cxt *cxt);
84
85void ft_nop(struct ft_cxt *cxt);
86int ft_prop(struct ft_cxt *cxt, const char *name,
87 const void *data, unsigned int sz);
88int ft_prop_str(struct ft_cxt *cxt, const char *name, const char *str);
89int ft_prop_int(struct ft_cxt *cxt, const char *name, unsigned int val);
90void ft_begin(struct ft_cxt *cxt, void *blob, unsigned int max_size,
91 void *(*realloc_fn)(void *, unsigned long));
92int ft_open(struct ft_cxt *cxt, void *blob, unsigned int max_size,
93 unsigned int max_find_device,
94 void *(*realloc_fn)(void *, unsigned long));
95int ft_add_rsvmap(struct ft_cxt *cxt, u64 physaddr, u64 size);
96
97void ft_dump_blob(const void *bphp);
98void ft_merge_blob(struct ft_cxt *cxt, void *blob);
99void *ft_find_device(struct ft_cxt *cxt, const char *srch_path);
100void *ft_find_descendent(struct ft_cxt *cxt, void *top, const char *srch_path);
101int ft_get_prop(struct ft_cxt *cxt, const void *phandle, const char *propname,
102 void *buf, const unsigned int buflen);
103int ft_set_prop(struct ft_cxt *cxt, const void *phandle, const char *propname,
104 const void *buf, const unsigned int buflen);
105
46#endif /* FLATDEVTREE_H */ 106#endif /* FLATDEVTREE_H */
diff --git a/arch/powerpc/boot/flatdevtree_env.h b/arch/powerpc/boot/flatdevtree_env.h
new file mode 100644
index 000000000000..83bc1c718836
--- /dev/null
+++ b/arch/powerpc/boot/flatdevtree_env.h
@@ -0,0 +1,47 @@
1/*
2 * This file adds the header file glue so that the shared files
3 * flatdevicetree.[ch] can compile and work in the powerpc bootwrapper.
4 *
5 * strncmp & strchr copied from <file:lib/strings.c>
6 * Copyright (C) 1991, 1992 Linus Torvalds
7 *
8 * Maintained by: Mark A. Greer <mgreer@mvista.com>
9 */
10#ifndef _PPC_BOOT_FLATDEVTREE_ENV_H_
11#define _PPC_BOOT_FLATDEVTREE_ENV_H_
12
13#include <stdarg.h>
14#include <stddef.h>
15#include "types.h"
16#include "string.h"
17#include "stdio.h"
18#include "ops.h"
19
20#define be16_to_cpu(x) (x)
21#define cpu_to_be16(x) (x)
22#define be32_to_cpu(x) (x)
23#define cpu_to_be32(x) (x)
24#define be64_to_cpu(x) (x)
25#define cpu_to_be64(x) (x)
26
27static inline int strncmp(const char *cs, const char *ct, size_t count)
28{
29 signed char __res = 0;
30
31 while (count) {
32 if ((__res = *cs - *ct++) != 0 || !*cs++)
33 break;
34 count--;
35 }
36 return __res;
37}
38
39static inline char *strchr(const char *s, int c)
40{
41 for (; *s != (char)c; ++s)
42 if (*s == '\0')
43 return NULL;
44 return (char *)s;
45}
46
47#endif /* _PPC_BOOT_FLATDEVTREE_ENV_H_ */
diff --git a/arch/powerpc/boot/flatdevtree_misc.c b/arch/powerpc/boot/flatdevtree_misc.c
new file mode 100644
index 000000000000..04da38fa477f
--- /dev/null
+++ b/arch/powerpc/boot/flatdevtree_misc.c
@@ -0,0 +1,51 @@
1/*
2 * This file does the necessary interface mapping between the bootwrapper
3 * device tree operations and the interface provided by shared source
4 * files flatdevicetree.[ch].
5 *
6 * Author: Mark A. Greer <mgreer@mvista.com>
7 *
8 * 2006 (c) MontaVista Software, Inc. This file is licensed under
9 * the terms of the GNU General Public License version 2. This program
10 * is licensed "as is" without any warranty of any kind, whether express
11 * or implied.
12 */
13#include <stddef.h>
14#include "flatdevtree.h"
15#include "ops.h"
16
17static struct ft_cxt cxt;
18
19static void *ft_finddevice(const char *name)
20{
21 return ft_find_device(&cxt, name);
22}
23
24static int ft_getprop(const void *phandle, const char *propname, void *buf,
25 const int buflen)
26{
27 return ft_get_prop(&cxt, phandle, propname, buf, buflen);
28}
29
30static int ft_setprop(const void *phandle, const char *propname,
31 const void *buf, const int buflen)
32{
33 return ft_set_prop(&cxt, phandle, propname, buf, buflen);
34}
35
36static unsigned long ft_finalize(void)
37{
38 ft_end_tree(&cxt);
39 return (unsigned long)cxt.bph;
40}
41
42int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device)
43{
44 dt_ops.finddevice = ft_finddevice;
45 dt_ops.getprop = ft_getprop;
46 dt_ops.setprop = ft_setprop;
47 dt_ops.finalize = ft_finalize;
48
49 return ft_open(&cxt, dt_blob, max_size, max_find_device,
50 platform_ops.realloc);
51}
diff --git a/arch/powerpc/boot/io.h b/arch/powerpc/boot/io.h
new file mode 100644
index 000000000000..32974ed49e02
--- /dev/null
+++ b/arch/powerpc/boot/io.h
@@ -0,0 +1,53 @@
1#ifndef _IO_H
2#define __IO_H
3/*
4 * Low-level I/O routines.
5 *
6 * Copied from <file:include/asm-powerpc/io.h> (which has no copyright)
7 */
8static inline int in_8(const volatile unsigned char *addr)
9{
10 int ret;
11
12 __asm__ __volatile__("lbz%U1%X1 %0,%1; twi 0,%0,0; isync"
13 : "=r" (ret) : "m" (*addr));
14 return ret;
15}
16
17static inline void out_8(volatile unsigned char *addr, int val)
18{
19 __asm__ __volatile__("stb%U0%X0 %1,%0; sync"
20 : "=m" (*addr) : "r" (val));
21}
22
23static inline unsigned in_le32(const volatile unsigned *addr)
24{
25 unsigned ret;
26
27 __asm__ __volatile__("lwbrx %0,0,%1; twi 0,%0,0; isync"
28 : "=r" (ret) : "r" (addr), "m" (*addr));
29 return ret;
30}
31
32static inline unsigned in_be32(const volatile unsigned *addr)
33{
34 unsigned ret;
35
36 __asm__ __volatile__("lwz%U1%X1 %0,%1; twi 0,%0,0; isync"
37 : "=r" (ret) : "m" (*addr));
38 return ret;
39}
40
41static inline void out_le32(volatile unsigned *addr, int val)
42{
43 __asm__ __volatile__("stwbrx %1,0,%2; sync" : "=m" (*addr)
44 : "r" (val), "r" (addr));
45}
46
47static inline void out_be32(volatile unsigned *addr, int val)
48{
49 __asm__ __volatile__("stw%U0%X0 %1,%0; sync"
50 : "=m" (*addr) : "r" (val));
51}
52
53#endif /* _IO_H */
diff --git a/arch/powerpc/boot/main.c b/arch/powerpc/boot/main.c
index d719bb9333d1..6f6b50d238b6 100644
--- a/arch/powerpc/boot/main.c
+++ b/arch/powerpc/boot/main.c
@@ -27,6 +27,8 @@ extern char _vmlinux_start[];
27extern char _vmlinux_end[]; 27extern char _vmlinux_end[];
28extern char _initrd_start[]; 28extern char _initrd_start[];
29extern char _initrd_end[]; 29extern char _initrd_end[];
30extern char _dtb_start[];
31extern char _dtb_end[];
30 32
31struct addr_range { 33struct addr_range {
32 unsigned long addr; 34 unsigned long addr;
@@ -167,7 +169,7 @@ static int is_elf32(void *hdr)
167 return 1; 169 return 1;
168} 170}
169 171
170static void prep_kernel(unsigned long *a1, unsigned long *a2) 172static void prep_kernel(unsigned long a1, unsigned long a2)
171{ 173{
172 int len; 174 int len;
173 175
@@ -203,11 +205,14 @@ static void prep_kernel(unsigned long *a1, unsigned long *a2)
203 } 205 }
204 206
205 /* 207 /*
206 * Now we try to alloc memory for the initrd (and copy it there) 208 * Now find the initrd
209 *
210 * First see if we have an image attached to us. If so
211 * allocate memory for it and copy it there.
207 */ 212 */
208 initrd.size = (unsigned long)(_initrd_end - _initrd_start); 213 initrd.size = (unsigned long)(_initrd_end - _initrd_start);
209 initrd.memsize = initrd.size; 214 initrd.memsize = initrd.size;
210 if ( initrd.size > 0 ) { 215 if (initrd.size > 0) {
211 printf("Allocating 0x%lx bytes for initrd ...\n\r", 216 printf("Allocating 0x%lx bytes for initrd ...\n\r",
212 initrd.size); 217 initrd.size);
213 initrd.addr = (unsigned long)malloc((u32)initrd.size); 218 initrd.addr = (unsigned long)malloc((u32)initrd.size);
@@ -216,8 +221,6 @@ static void prep_kernel(unsigned long *a1, unsigned long *a2)
216 "ramdisk !\n\r"); 221 "ramdisk !\n\r");
217 exit(); 222 exit();
218 } 223 }
219 *a1 = initrd.addr;
220 *a2 = initrd.size;
221 printf("initial ramdisk moving 0x%lx <- 0x%lx " 224 printf("initial ramdisk moving 0x%lx <- 0x%lx "
222 "(0x%lx bytes)\n\r", initrd.addr, 225 "(0x%lx bytes)\n\r", initrd.addr,
223 (unsigned long)_initrd_start, initrd.size); 226 (unsigned long)_initrd_start, initrd.size);
@@ -225,6 +228,12 @@ static void prep_kernel(unsigned long *a1, unsigned long *a2)
225 initrd.size); 228 initrd.size);
226 printf("initrd head: 0x%lx\n\r", 229 printf("initrd head: 0x%lx\n\r",
227 *((unsigned long *)initrd.addr)); 230 *((unsigned long *)initrd.addr));
231 } else if (a2 != 0) {
232 /* Otherwise, see if yaboot or another loader gave us an initrd */
233 initrd.addr = a1;
234 initrd.memsize = initrd.size = a2;
235 printf("Using loader supplied initrd at 0x%lx (0x%lx bytes)\n\r",
236 initrd.addr, initrd.size);
228 } 237 }
229 238
230 /* Eventually gunzip the kernel */ 239 /* Eventually gunzip the kernel */
@@ -250,10 +259,6 @@ static void prep_kernel(unsigned long *a1, unsigned long *a2)
250 flush_cache((void *)vmlinux.addr, vmlinux.size); 259 flush_cache((void *)vmlinux.addr, vmlinux.size);
251} 260}
252 261
253void __attribute__ ((weak)) ft_init(void *dt_blob)
254{
255}
256
257/* A buffer that may be edited by tools operating on a zImage binary so as to 262/* A buffer that may be edited by tools operating on a zImage binary so as to
258 * edit the command line passed to vmlinux (by setting /chosen/bootargs). 263 * edit the command line passed to vmlinux (by setting /chosen/bootargs).
259 * The buffer is put in it's own section so that tools may locate it easier. 264 * The buffer is put in it's own section so that tools may locate it easier.
@@ -285,36 +290,22 @@ static void set_cmdline(char *buf)
285 setprop(devp, "bootargs", buf, strlen(buf) + 1); 290 setprop(devp, "bootargs", buf, strlen(buf) + 1);
286} 291}
287 292
288/* Section where ft can be tacked on after zImage is built */
289union blobspace {
290 struct boot_param_header hdr;
291 char space[8*1024];
292} dt_blob __attribute__((__section__("__builtin_ft")));
293
294struct platform_ops platform_ops; 293struct platform_ops platform_ops;
295struct dt_ops dt_ops; 294struct dt_ops dt_ops;
296struct console_ops console_ops; 295struct console_ops console_ops;
297 296
298void start(unsigned long a1, unsigned long a2, void *promptr, void *sp) 297void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
299{ 298{
300 int have_dt = 0;
301 kernel_entry_t kentry; 299 kernel_entry_t kentry;
302 char cmdline[COMMAND_LINE_SIZE]; 300 char cmdline[COMMAND_LINE_SIZE];
301 unsigned long ft_addr = 0;
303 302
304 memset(__bss_start, 0, _end - __bss_start); 303 memset(__bss_start, 0, _end - __bss_start);
305 memset(&platform_ops, 0, sizeof(platform_ops)); 304 memset(&platform_ops, 0, sizeof(platform_ops));
306 memset(&dt_ops, 0, sizeof(dt_ops)); 305 memset(&dt_ops, 0, sizeof(dt_ops));
307 memset(&console_ops, 0, sizeof(console_ops)); 306 memset(&console_ops, 0, sizeof(console_ops));
308 307
309 /* Override the dt_ops and device tree if there was an flat dev 308 if (platform_init(promptr, _dtb_start, _dtb_end))
310 * tree attached to the zImage.
311 */
312 if (dt_blob.hdr.magic == OF_DT_HEADER) {
313 have_dt = 1;
314 ft_init(&dt_blob);
315 }
316
317 if (platform_init(promptr))
318 exit(); 309 exit();
319 if (console_ops.open && (console_ops.open() < 0)) 310 if (console_ops.open && (console_ops.open() < 0))
320 exit(); 311 exit();
@@ -324,7 +315,7 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
324 printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r", 315 printf("\n\rzImage starting: loaded at 0x%p (sp: 0x%p)\n\r",
325 _start, sp); 316 _start, sp);
326 317
327 prep_kernel(&a1, &a2); 318 prep_kernel(a1, a2);
328 319
329 /* If cmdline came from zimage wrapper or if we can edit the one 320 /* If cmdline came from zimage wrapper or if we can edit the one
330 * in the dt, print it out and edit it, if possible. 321 * in the dt, print it out and edit it, if possible.
@@ -338,15 +329,23 @@ void start(unsigned long a1, unsigned long a2, void *promptr, void *sp)
338 set_cmdline(cmdline); 329 set_cmdline(cmdline);
339 } 330 }
340 331
332 printf("Finalizing device tree...");
333 if (dt_ops.finalize)
334 ft_addr = dt_ops.finalize();
335 if (ft_addr)
336 printf(" flat tree at 0x%lx\n\r", ft_addr);
337 else
338 printf(" using OF tree (promptr=%p)\n\r", promptr);
339
341 if (console_ops.close) 340 if (console_ops.close)
342 console_ops.close(); 341 console_ops.close();
343 342
344 kentry = (kernel_entry_t) vmlinux.addr; 343 kentry = (kernel_entry_t) vmlinux.addr;
345 if (have_dt) 344 if (ft_addr)
346 kentry(dt_ops.ft_addr(), 0, NULL); 345 kentry(ft_addr, 0, NULL);
347 else 346 else
348 /* XXX initrd addr/size should be passed in properties */ 347 /* XXX initrd addr/size should be passed in properties */
349 kentry(a1, a2, promptr); 348 kentry(initrd.addr, initrd.size, promptr);
350 349
351 /* console closed so printf below may not work */ 350 /* console closed so printf below may not work */
352 printf("Error: Linux kernel returned to zImage boot wrapper!\n\r"); 351 printf("Error: Linux kernel returned to zImage boot wrapper!\n\r");
diff --git a/arch/powerpc/boot/mktree.c b/arch/powerpc/boot/mktree.c
new file mode 100644
index 000000000000..4cb892993651
--- /dev/null
+++ b/arch/powerpc/boot/mktree.c
@@ -0,0 +1,152 @@
1/*
2 * Makes a tree bootable image for IBM Evaluation boards.
3 * Basically, just take a zImage, skip the ELF header, and stuff
4 * a 32 byte header on the front.
5 *
6 * We use htonl, which is a network macro, to make sure we're doing
7 * The Right Thing on an LE machine. It's non-obvious, but it should
8 * work on anything BSD'ish.
9 */
10
11#include <fcntl.h>
12#include <stdio.h>
13#include <stdlib.h>
14#include <string.h>
15#include <sys/stat.h>
16#include <unistd.h>
17#include <netinet/in.h>
18#ifdef __sun__
19#include <inttypes.h>
20#else
21#include <stdint.h>
22#endif
23
24/* This gets tacked on the front of the image. There are also a few
25 * bytes allocated after the _start label used by the boot rom (see
26 * head.S for details).
27 */
28typedef struct boot_block {
29 uint32_t bb_magic; /* 0x0052504F */
30 uint32_t bb_dest; /* Target address of the image */
31 uint32_t bb_num_512blocks; /* Size, rounded-up, in 512 byte blks */
32 uint32_t bb_debug_flag; /* Run debugger or image after load */
33 uint32_t bb_entry_point; /* The image address to start */
34 uint32_t bb_checksum; /* 32 bit checksum including header */
35 uint32_t reserved[2];
36} boot_block_t;
37
38#define IMGBLK 512
39char tmpbuf[IMGBLK];
40
41int main(int argc, char *argv[])
42{
43 int in_fd, out_fd;
44 int nblks, i;
45 uint cksum, *cp;
46 struct stat st;
47 boot_block_t bt;
48
49 if (argc < 3) {
50 fprintf(stderr, "usage: %s <zImage-file> <boot-image> [entry-point]\n",argv[0]);
51 exit(1);
52 }
53
54 if (stat(argv[1], &st) < 0) {
55 perror("stat");
56 exit(2);
57 }
58
59 nblks = (st.st_size + IMGBLK) / IMGBLK;
60
61 bt.bb_magic = htonl(0x0052504F);
62
63 /* If we have the optional entry point parameter, use it */
64 if (argc == 4)
65 bt.bb_dest = bt.bb_entry_point = htonl(strtoul(argv[3], NULL, 0));
66 else
67 bt.bb_dest = bt.bb_entry_point = htonl(0x500000);
68
69 /* We know these from the linker command.
70 * ...and then move it up into memory a little more so the
71 * relocation can happen.
72 */
73 bt.bb_num_512blocks = htonl(nblks);
74 bt.bb_debug_flag = 0;
75
76 bt.bb_checksum = 0;
77
78 /* To be neat and tidy :-).
79 */
80 bt.reserved[0] = 0;
81 bt.reserved[1] = 0;
82
83 if ((in_fd = open(argv[1], O_RDONLY)) < 0) {
84 perror("zImage open");
85 exit(3);
86 }
87
88 if ((out_fd = open(argv[2], (O_RDWR | O_CREAT | O_TRUNC), 0666)) < 0) {
89 perror("bootfile open");
90 exit(3);
91 }
92
93 cksum = 0;
94 cp = (void *)&bt;
95 for (i=0; i<sizeof(bt)/sizeof(uint); i++)
96 cksum += *cp++;
97
98 /* Assume zImage is an ELF file, and skip the 64K header.
99 */
100 if (read(in_fd, tmpbuf, IMGBLK) != IMGBLK) {
101 fprintf(stderr, "%s is too small to be an ELF image\n",
102 argv[1]);
103 exit(4);
104 }
105
106 if ((*(uint *)tmpbuf) != htonl(0x7f454c46)) {
107 fprintf(stderr, "%s is not an ELF image\n", argv[1]);
108 exit(4);
109 }
110
111 if (lseek(in_fd, (64 * 1024), SEEK_SET) < 0) {
112 fprintf(stderr, "%s failed to seek in ELF image\n", argv[1]);
113 exit(4);
114 }
115
116 nblks -= (64 * 1024) / IMGBLK;
117
118 /* And away we go......
119 */
120 if (write(out_fd, &bt, sizeof(bt)) != sizeof(bt)) {
121 perror("boot-image write");
122 exit(5);
123 }
124
125 while (nblks-- > 0) {
126 if (read(in_fd, tmpbuf, IMGBLK) < 0) {
127 perror("zImage read");
128 exit(5);
129 }
130 cp = (uint *)tmpbuf;
131 for (i=0; i<sizeof(tmpbuf)/sizeof(uint); i++)
132 cksum += *cp++;
133 if (write(out_fd, tmpbuf, sizeof(tmpbuf)) != sizeof(tmpbuf)) {
134 perror("boot-image write");
135 exit(5);
136 }
137 }
138
139 /* rewrite the header with the computed checksum.
140 */
141 bt.bb_checksum = htonl(cksum);
142 if (lseek(out_fd, 0, SEEK_SET) < 0) {
143 perror("rewrite seek");
144 exit(1);
145 }
146 if (write(out_fd, &bt, sizeof(bt)) != sizeof(bt)) {
147 perror("boot-image rewrite");
148 exit(1);
149 }
150
151 exit(0);
152}
diff --git a/arch/powerpc/boot/ns16550.c b/arch/powerpc/boot/ns16550.c
new file mode 100644
index 000000000000..1ffe72e35cdc
--- /dev/null
+++ b/arch/powerpc/boot/ns16550.c
@@ -0,0 +1,74 @@
1/*
2 * 16550 serial console support.
3 *
4 * Original copied from <file:arch/ppc/boot/common/ns16550.c>
5 * (which had no copyright)
6 * Modifications: 2006 (c) MontaVista Software, Inc.
7 *
8 * Modified by: Mark A. Greer <mgreer@mvista.com>
9 */
10#include <stdarg.h>
11#include <stddef.h>
12#include "types.h"
13#include "string.h"
14#include "stdio.h"
15#include "io.h"
16#include "ops.h"
17
18#define UART_DLL 0 /* Out: Divisor Latch Low */
19#define UART_DLM 1 /* Out: Divisor Latch High */
20#define UART_FCR 2 /* Out: FIFO Control Register */
21#define UART_LCR 3 /* Out: Line Control Register */
22#define UART_MCR 4 /* Out: Modem Control Register */
23#define UART_LSR 5 /* In: Line Status Register */
24#define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */
25#define UART_LSR_DR 0x01 /* Receiver data ready */
26#define UART_MSR 6 /* In: Modem Status Register */
27#define UART_SCR 7 /* I/O: Scratch Register */
28
29static unsigned char *reg_base;
30static u32 reg_shift;
31
32static int ns16550_open(void)
33{
34 out_8(reg_base + (UART_FCR << reg_shift), 0x06);
35 return 0;
36}
37
38static void ns16550_putc(unsigned char c)
39{
40 while ((in_8(reg_base + (UART_LSR << reg_shift)) & UART_LSR_THRE) == 0);
41 out_8(reg_base, c);
42}
43
44static unsigned char ns16550_getc(void)
45{
46 while ((in_8(reg_base + (UART_LSR << reg_shift)) & UART_LSR_DR) == 0);
47 return in_8(reg_base);
48}
49
50static u8 ns16550_tstc(void)
51{
52 return ((in_8(reg_base + (UART_LSR << reg_shift)) & UART_LSR_DR) != 0);
53}
54
55int ns16550_console_init(void *devp, struct serial_console_data *scdp)
56{
57 int n;
58
59 n = getprop(devp, "virtual-reg", &reg_base, sizeof(reg_base));
60 if (n != sizeof(reg_base))
61 return -1;
62
63 n = getprop(devp, "reg-shift", &reg_shift, sizeof(reg_shift));
64 if (n != sizeof(reg_shift))
65 reg_shift = 0;
66
67 scdp->open = ns16550_open;
68 scdp->putc = ns16550_putc;
69 scdp->getc = ns16550_getc;
70 scdp->tstc = ns16550_tstc;
71 scdp->close = NULL;
72
73 return 0;
74}
diff --git a/arch/powerpc/boot/of.c b/arch/powerpc/boot/of.c
index 3a71845afc6c..0182f384f3e6 100644
--- a/arch/powerpc/boot/of.c
+++ b/arch/powerpc/boot/of.c
@@ -256,24 +256,18 @@ static void of_console_write(char *buf, int len)
256 call_prom("write", 3, 1, of_stdout_handle, buf, len); 256 call_prom("write", 3, 1, of_stdout_handle, buf, len);
257} 257}
258 258
259int platform_init(void *promptr) 259int platform_init(void *promptr, char *dt_blob_start, char *dt_blob_end)
260{ 260{
261 platform_ops.fixups = NULL;
262 platform_ops.image_hdr = of_image_hdr; 261 platform_ops.image_hdr = of_image_hdr;
263 platform_ops.malloc = of_try_claim; 262 platform_ops.malloc = of_try_claim;
264 platform_ops.free = NULL;
265 platform_ops.exit = of_exit; 263 platform_ops.exit = of_exit;
266 264
267 dt_ops.finddevice = of_finddevice; 265 dt_ops.finddevice = of_finddevice;
268 dt_ops.getprop = of_getprop; 266 dt_ops.getprop = of_getprop;
269 dt_ops.setprop = of_setprop; 267 dt_ops.setprop = of_setprop;
270 dt_ops.translate_addr = NULL;
271 268
272 console_ops.open = of_console_open; 269 console_ops.open = of_console_open;
273 console_ops.write = of_console_write; 270 console_ops.write = of_console_write;
274 console_ops.edit_cmdline = NULL;
275 console_ops.close = NULL;
276 console_ops.data = NULL;
277 271
278 prom = (int (*)(void *))promptr; 272 prom = (int (*)(void *))promptr;
279 return 0; 273 return 0;
diff --git a/arch/powerpc/boot/ops.h b/arch/powerpc/boot/ops.h
index 135eb4bb03b4..8abb6516bb7c 100644
--- a/arch/powerpc/boot/ops.h
+++ b/arch/powerpc/boot/ops.h
@@ -22,7 +22,8 @@ struct platform_ops {
22 void (*fixups)(void); 22 void (*fixups)(void);
23 void (*image_hdr)(const void *); 23 void (*image_hdr)(const void *);
24 void * (*malloc)(u32 size); 24 void * (*malloc)(u32 size);
25 void (*free)(void *ptr, u32 size); 25 void (*free)(void *ptr);
26 void * (*realloc)(void *ptr, unsigned long size);
26 void (*exit)(void); 27 void (*exit)(void);
27}; 28};
28extern struct platform_ops platform_ops; 29extern struct platform_ops platform_ops;
@@ -30,13 +31,11 @@ extern struct platform_ops platform_ops;
30/* Device Tree operations */ 31/* Device Tree operations */
31struct dt_ops { 32struct dt_ops {
32 void * (*finddevice)(const char *name); 33 void * (*finddevice)(const char *name);
33 int (*getprop)(const void *node, const char *name, void *buf, 34 int (*getprop)(const void *phandle, const char *name, void *buf,
34 const int buflen); 35 const int buflen);
35 int (*setprop)(const void *node, const char *name, 36 int (*setprop)(const void *phandle, const char *name,
36 const void *buf, const int buflen); 37 const void *buf, const int buflen);
37 u64 (*translate_addr)(const char *path, const u32 *in_addr, 38 unsigned long (*finalize)(void);
38 const u32 addr_len);
39 unsigned long (*ft_addr)(void);
40}; 39};
41extern struct dt_ops dt_ops; 40extern struct dt_ops dt_ops;
42 41
@@ -59,10 +58,13 @@ struct serial_console_data {
59 void (*close)(void); 58 void (*close)(void);
60}; 59};
61 60
62extern int platform_init(void *promptr); 61int platform_init(void *promptr, char *dt_blob_start, char *dt_blob_end);
63extern void simple_alloc_init(void); 62int ft_init(void *dt_blob, unsigned int max_size, unsigned int max_find_device);
64extern void ft_init(void *dt_blob); 63int serial_console_init(void);
65extern int serial_console_init(void); 64int ns16550_console_init(void *devp, struct serial_console_data *scdp);
65void *simple_alloc_init(char *base, u32 heap_size, u32 granularity,
66 u32 max_allocs);
67
66 68
67static inline void *finddevice(const char *name) 69static inline void *finddevice(const char *name)
68{ 70{
@@ -84,10 +86,10 @@ static inline void *malloc(u32 size)
84 return (platform_ops.malloc) ? platform_ops.malloc(size) : NULL; 86 return (platform_ops.malloc) ? platform_ops.malloc(size) : NULL;
85} 87}
86 88
87static inline void free(void *ptr, u32 size) 89static inline void free(void *ptr)
88{ 90{
89 if (platform_ops.free) 91 if (platform_ops.free)
90 platform_ops.free(ptr, size); 92 platform_ops.free(ptr);
91} 93}
92 94
93static inline void exit(void) 95static inline void exit(void)
diff --git a/arch/powerpc/boot/serial.c b/arch/powerpc/boot/serial.c
new file mode 100644
index 000000000000..e8de4cf59be7
--- /dev/null
+++ b/arch/powerpc/boot/serial.c
@@ -0,0 +1,142 @@
1/*
2 * Generic serial console support
3 *
4 * Author: Mark A. Greer <mgreer@mvista.com>
5 *
6 * Code in serial_edit_cmdline() copied from <file:arch/ppc/boot/simple/misc.c>
7 * and was written by Matt Porter <mporter@kernel.crashing.org>.
8 *
9 * 2001,2006 (c) MontaVista Software, Inc. This file is licensed under
10 * the terms of the GNU General Public License version 2. This program
11 * is licensed "as is" without any warranty of any kind, whether express
12 * or implied.
13 */
14#include <stdarg.h>
15#include <stddef.h>
16#include "types.h"
17#include "string.h"
18#include "stdio.h"
19#include "io.h"
20#include "ops.h"
21
22extern void udelay(long delay);
23
24static int serial_open(void)
25{
26 struct serial_console_data *scdp = console_ops.data;
27 return scdp->open();
28}
29
30static void serial_write(char *buf, int len)
31{
32 struct serial_console_data *scdp = console_ops.data;
33
34 while (*buf != '\0')
35 scdp->putc(*buf++);
36}
37
38static void serial_edit_cmdline(char *buf, int len)
39{
40 int timer = 0, count;
41 char ch, *cp;
42 struct serial_console_data *scdp = console_ops.data;
43
44 cp = buf;
45 count = strlen(buf);
46 cp = &buf[count];
47 count++;
48
49 while (timer++ < 5*1000) {
50 if (scdp->tstc()) {
51 while (((ch = scdp->getc()) != '\n') && (ch != '\r')) {
52 /* Test for backspace/delete */
53 if ((ch == '\b') || (ch == '\177')) {
54 if (cp != buf) {
55 cp--;
56 count--;
57 printf("\b \b");
58 }
59 /* Test for ^x/^u (and wipe the line) */
60 } else if ((ch == '\030') || (ch == '\025')) {
61 while (cp != buf) {
62 cp--;
63 count--;
64 printf("\b \b");
65 }
66 } else if (count < len) {
67 *cp++ = ch;
68 count++;
69 scdp->putc(ch);
70 }
71 }
72 break; /* Exit 'timer' loop */
73 }
74 udelay(1000); /* 1 msec */
75 }
76 *cp = 0;
77}
78
79static void serial_close(void)
80{
81 struct serial_console_data *scdp = console_ops.data;
82
83 if (scdp->close)
84 scdp->close();
85}
86
87static void *serial_get_stdout_devp(void)
88{
89 void *devp;
90 char devtype[MAX_PROP_LEN];
91 char path[MAX_PATH_LEN];
92
93 devp = finddevice("/chosen");
94 if (devp == NULL)
95 goto err_out;
96
97 if (getprop(devp, "linux,stdout-path", path, MAX_PATH_LEN) > 0) {
98 devp = finddevice(path);
99 if (devp == NULL)
100 goto err_out;
101
102 if ((getprop(devp, "device_type", devtype, sizeof(devtype)) > 0)
103 && !strcmp(devtype, "serial"))
104 return devp;
105 }
106err_out:
107 return NULL;
108}
109
110static struct serial_console_data serial_cd;
111
112/* Node's "compatible" property determines which serial driver to use */
113int serial_console_init(void)
114{
115 void *devp;
116 int rc = -1;
117 char compat[MAX_PROP_LEN];
118
119 devp = serial_get_stdout_devp();
120 if (devp == NULL)
121 goto err_out;
122
123 if (getprop(devp, "compatible", compat, sizeof(compat)) < 0)
124 goto err_out;
125
126 if (!strcmp(compat, "ns16550"))
127 rc = ns16550_console_init(devp, &serial_cd);
128
129 /* Add other serial console driver calls here */
130
131 if (!rc) {
132 console_ops.open = serial_open;
133 console_ops.write = serial_write;
134 console_ops.edit_cmdline = serial_edit_cmdline;
135 console_ops.close = serial_close;
136 console_ops.data = &serial_cd;
137
138 return 0;
139 }
140err_out:
141 return -1;
142}
diff --git a/arch/powerpc/boot/simple_alloc.c b/arch/powerpc/boot/simple_alloc.c
new file mode 100644
index 000000000000..cfe3a7505ba0
--- /dev/null
+++ b/arch/powerpc/boot/simple_alloc.c
@@ -0,0 +1,149 @@
1/*
2 * Implement primitive realloc(3) functionality.
3 *
4 * Author: Mark A. Greer <mgreer@mvista.com>
5 *
6 * 2006 (c) MontaVista, Software, Inc. This file is licensed under
7 * the terms of the GNU General Public License version 2. This program
8 * is licensed "as is" without any warranty of any kind, whether express
9 * or implied.
10 */
11
12#include <stddef.h>
13#include "types.h"
14#include "page.h"
15#include "string.h"
16#include "ops.h"
17
18#define ENTRY_BEEN_USED 0x01
19#define ENTRY_IN_USE 0x02
20
21static struct alloc_info {
22 u32 flags;
23 u32 base;
24 u32 size;
25} *alloc_tbl;
26
27static u32 tbl_entries;
28static u32 alloc_min;
29static u32 next_base;
30static u32 space_left;
31
32/*
33 * First time an entry is used, its base and size are set.
34 * An entry can be freed and re-malloc'd but its base & size don't change.
35 * Should be smart enough for needs of bootwrapper.
36 */
37static void *simple_malloc(u32 size)
38{
39 u32 i;
40 struct alloc_info *p = alloc_tbl;
41
42 if (size == 0)
43 goto err_out;
44
45 size = _ALIGN_UP(size, alloc_min);
46
47 for (i=0; i<tbl_entries; i++, p++)
48 if (!(p->flags & ENTRY_BEEN_USED)) { /* never been used */
49 if (size <= space_left) {
50 p->base = next_base;
51 p->size = size;
52 p->flags = ENTRY_BEEN_USED | ENTRY_IN_USE;
53 next_base += size;
54 space_left -= size;
55 return (void *)p->base;
56 }
57 goto err_out; /* not enough space left */
58 }
59 /* reuse an entry keeping same base & size */
60 else if (!(p->flags & ENTRY_IN_USE) && (size <= p->size)) {
61 p->flags |= ENTRY_IN_USE;
62 return (void *)p->base;
63 }
64err_out:
65 return NULL;
66}
67
68static struct alloc_info *simple_find_entry(void *ptr)
69{
70 u32 i;
71 struct alloc_info *p = alloc_tbl;
72
73 for (i=0; i<tbl_entries; i++,p++) {
74 if (!(p->flags & ENTRY_BEEN_USED))
75 break;
76 if ((p->flags & ENTRY_IN_USE) && (p->base == (u32)ptr))
77 return p;
78 }
79 return NULL;
80}
81
82static void simple_free(void *ptr)
83{
84 struct alloc_info *p = simple_find_entry(ptr);
85
86 if (p != NULL)
87 p->flags &= ~ENTRY_IN_USE;
88}
89
90/*
91 * Change size of area pointed to by 'ptr' to 'size'.
92 * If 'ptr' is NULL, then its a malloc(). If 'size' is 0, then its a free().
93 * 'ptr' must be NULL or a pointer to a non-freed area previously returned by
94 * simple_realloc() or simple_malloc().
95 */
96static void *simple_realloc(void *ptr, unsigned long size)
97{
98 struct alloc_info *p;
99 void *new;
100
101 if (size == 0) {
102 simple_free(ptr);
103 return NULL;
104 }
105
106 if (ptr == NULL)
107 return simple_malloc(size);
108
109 p = simple_find_entry(ptr);
110 if (p == NULL) /* ptr not from simple_malloc/simple_realloc */
111 return NULL;
112 if (size <= p->size) /* fits in current block */
113 return ptr;
114
115 new = simple_malloc(size);
116 memcpy(new, ptr, p->size);
117 simple_free(ptr);
118 return new;
119}
120
121/*
122 * Returns addr of first byte after heap so caller can see if it took
123 * too much space. If so, change args & try again.
124 */
125void *simple_alloc_init(char *base, u32 heap_size, u32 granularity,
126 u32 max_allocs)
127{
128 u32 heap_base, tbl_size;
129
130 heap_size = _ALIGN_UP(heap_size, granularity);
131 alloc_min = granularity;
132 tbl_entries = max_allocs;
133
134 tbl_size = tbl_entries * sizeof(struct alloc_info);
135
136 alloc_tbl = (struct alloc_info *)_ALIGN_UP((unsigned long)base, 8);
137 memset(alloc_tbl, 0, tbl_size);
138
139 heap_base = _ALIGN_UP((u32)alloc_tbl + tbl_size, alloc_min);
140
141 next_base = heap_base;
142 space_left = heap_size;
143
144 platform_ops.malloc = simple_malloc;
145 platform_ops.free = simple_free;
146 platform_ops.realloc = simple_realloc;
147
148 return (void *)(heap_base + heap_size);
149}
diff --git a/arch/powerpc/boot/stdio.c b/arch/powerpc/boot/stdio.c
index 6d5f6382e1ce..0a9feeb98342 100644
--- a/arch/powerpc/boot/stdio.c
+++ b/arch/powerpc/boot/stdio.c
@@ -320,6 +320,7 @@ printf(const char *fmt, ...)
320 va_start(args, fmt); 320 va_start(args, fmt);
321 n = vsprintf(sprint_buf, fmt, args); 321 n = vsprintf(sprint_buf, fmt, args);
322 va_end(args); 322 va_end(args);
323 console_ops.write(sprint_buf, n); 323 if (console_ops.write)
324 console_ops.write(sprint_buf, n);
324 return n; 325 return n;
325} 326}
diff --git a/arch/powerpc/boot/util.S b/arch/powerpc/boot/util.S
new file mode 100644
index 000000000000..427ddfc11991
--- /dev/null
+++ b/arch/powerpc/boot/util.S
@@ -0,0 +1,88 @@
1/*
2 * Copied from <file:arch/powerpc/kernel/misc_32.S>
3 *
4 * This file contains miscellaneous low-level functions.
5 * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org)
6 *
7 * Largely rewritten by Cort Dougan (cort@cs.nmt.edu)
8 * and Paul Mackerras.
9 *
10 * kexec bits:
11 * Copyright (C) 2002-2003 Eric Biederman <ebiederm@xmission.com>
12 * GameCube/ppc32 port Copyright (C) 2004 Albert Herranz
13 *
14 * This program is free software; you can redistribute it and/or
15 * modify it under the terms of the GNU General Public License
16 * as published by the Free Software Foundation; either version
17 * 2 of the License, or (at your option) any later version.
18 *
19 */
20#include "ppc_asm.h"
21
22#define SPRN_PVR 0x11F /* Processor Version Register */
23
24 .text
25
26/* udelay (on non-601 processors) needs to know the period of the
27 * timebase in nanoseconds. This used to be hardcoded to be 60ns
28 * (period of 66MHz/4). Now a variable is used that is initialized to
29 * 60 for backward compatibility, but it can be overridden as necessary
30 * with code something like this:
31 * extern unsigned long timebase_period_ns;
32 * timebase_period_ns = 1000000000 / bd->bi_tbfreq;
33 */
34 .data
35 .globl timebase_period_ns
36timebase_period_ns:
37 .long 60
38
39 .text
40/*
41 * Delay for a number of microseconds
42 */
43 .globl udelay
44udelay:
45 mfspr r4,SPRN_PVR
46 srwi r4,r4,16
47 cmpwi 0,r4,1 /* 601 ? */
48 bne .udelay_not_601
4900: li r0,86 /* Instructions / microsecond? */
50 mtctr r0
5110: addi r0,r0,0 /* NOP */
52 bdnz 10b
53 subic. r3,r3,1
54 bne 00b
55 blr
56
57.udelay_not_601:
58 mulli r4,r3,1000 /* nanoseconds */
59 /* Change r4 to be the number of ticks using:
60 * (nanoseconds + (timebase_period_ns - 1 )) / timebase_period_ns
61 * timebase_period_ns defaults to 60 (16.6MHz) */
62 mflr r5
63 bl 0f
640: mflr r6
65 mtlr r5
66 lis r5,0b@ha
67 addi r5,r5,0b@l
68 subf r5,r5,r6 /* In case we're relocated */
69 addis r5,r5,timebase_period_ns@ha
70 lwz r5,timebase_period_ns@l(r5)
71 add r4,r4,r5
72 addi r4,r4,-1
73 divw r4,r4,r5 /* BUS ticks */
741: mftbu r5
75 mftb r6
76 mftbu r7
77 cmpw 0,r5,r7
78 bne 1b /* Get [synced] base time */
79 addc r9,r6,r4 /* Compute end time */
80 addze r8,r5
812: mftbu r5
82 cmpw 0,r5,r8
83 blt 2b
84 bgt 3f
85 mftb r6
86 cmpw 0,r6,r9
87 blt 2b
883: blr
diff --git a/arch/powerpc/boot/wrapper b/arch/powerpc/boot/wrapper
index b5fb1fee76f8..024e4d425c59 100755
--- a/arch/powerpc/boot/wrapper
+++ b/arch/powerpc/boot/wrapper
@@ -184,6 +184,9 @@ fi
184 184
185if [ -n "$dtb" ]; then 185if [ -n "$dtb" ]; then
186 addsec $tmp "$dtb" .kernel:dtb 186 addsec $tmp "$dtb" .kernel:dtb
187 if [ -n "$dts" ]; then
188 rm $dtb
189 fi
187fi 190fi
188 191
189if [ "$platform" != "miboot" ]; then 192if [ "$platform" != "miboot" ]; then
diff --git a/arch/powerpc/boot/zImage.coff.lds.S b/arch/powerpc/boot/zImage.coff.lds.S
index 05f32388b953..a360905e5428 100644
--- a/arch/powerpc/boot/zImage.coff.lds.S
+++ b/arch/powerpc/boot/zImage.coff.lds.S
@@ -21,6 +21,10 @@ SECTIONS
21 *(.got2) 21 *(.got2)
22 __got2_end = .; 22 __got2_end = .;
23 23
24 _dtb_start = .;
25 *(.kernel:dtb)
26 _dtb_end = .;
27
24 _vmlinux_start = .; 28 _vmlinux_start = .;
25 *(.kernel:vmlinux.strip) 29 *(.kernel:vmlinux.strip)
26 _vmlinux_end = .; 30 _vmlinux_end = .;
diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig
index 0aba06d7d2ec..a98c982c73ad 100644
--- a/arch/powerpc/configs/cell_defconfig
+++ b/arch/powerpc/configs/cell_defconfig
@@ -1,7 +1,7 @@
1# 1#
2# Automatically generated make config: don't edit 2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.18 3# Linux kernel version: 2.6.19-rc6
4# Wed Oct 4 15:30:50 2006 4# Wed Nov 22 15:33:04 2006
5# 5#
6CONFIG_PPC64=y 6CONFIG_PPC64=y
7CONFIG_64BIT=y 7CONFIG_64BIT=y
@@ -32,6 +32,10 @@ CONFIG_AUDIT_ARCH=y
32CONFIG_POWER3=y 32CONFIG_POWER3=y
33CONFIG_POWER4=y 33CONFIG_POWER4=y
34CONFIG_PPC_FPU=y 34CONFIG_PPC_FPU=y
35# CONFIG_PPC_DCR_NATIVE is not set
36CONFIG_PPC_DCR_MMIO=y
37CONFIG_PPC_DCR=y
38CONFIG_PPC_OF_PLATFORM_PCI=y
35CONFIG_ALTIVEC=y 39CONFIG_ALTIVEC=y
36CONFIG_PPC_STD_MMU=y 40CONFIG_PPC_STD_MMU=y
37CONFIG_VIRT_CPU_ACCOUNTING=y 41CONFIG_VIRT_CPU_ACCOUNTING=y
@@ -67,7 +71,7 @@ CONFIG_INITRAMFS_SOURCE=""
67CONFIG_CC_OPTIMIZE_FOR_SIZE=y 71CONFIG_CC_OPTIMIZE_FOR_SIZE=y
68CONFIG_SYSCTL=y 72CONFIG_SYSCTL=y
69# CONFIG_EMBEDDED is not set 73# CONFIG_EMBEDDED is not set
70# CONFIG_SYSCTL_SYSCALL is not set 74CONFIG_SYSCTL_SYSCALL=y
71CONFIG_KALLSYMS=y 75CONFIG_KALLSYMS=y
72# CONFIG_KALLSYMS_ALL is not set 76# CONFIG_KALLSYMS_ALL is not set
73# CONFIG_KALLSYMS_EXTRA_PASS is not set 77# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -131,6 +135,7 @@ CONFIG_PPC_CELL=y
131CONFIG_PPC_CELL_NATIVE=y 135CONFIG_PPC_CELL_NATIVE=y
132CONFIG_PPC_IBM_CELL_BLADE=y 136CONFIG_PPC_IBM_CELL_BLADE=y
133CONFIG_UDBG_RTAS_CONSOLE=y 137CONFIG_UDBG_RTAS_CONSOLE=y
138CONFIG_PPC_PS3=y
134# CONFIG_U3_DART is not set 139# CONFIG_U3_DART is not set
135CONFIG_PPC_RTAS=y 140CONFIG_PPC_RTAS=y
136# CONFIG_RTAS_ERROR_LOGGING is not set 141# CONFIG_RTAS_ERROR_LOGGING is not set
@@ -139,9 +144,23 @@ CONFIG_RTAS_FLASH=y
139CONFIG_MMIO_NVRAM=y 144CONFIG_MMIO_NVRAM=y
140# CONFIG_PPC_MPC106 is not set 145# CONFIG_PPC_MPC106 is not set
141# CONFIG_PPC_970_NAP is not set 146# CONFIG_PPC_970_NAP is not set
142# CONFIG_CPU_FREQ is not set 147CONFIG_PPC_INDIRECT_IO=y
148CONFIG_GENERIC_IOMAP=y
149CONFIG_CPU_FREQ=y
150CONFIG_CPU_FREQ_TABLE=y
151CONFIG_CPU_FREQ_DEBUG=y
152CONFIG_CPU_FREQ_STAT=y
153# CONFIG_CPU_FREQ_STAT_DETAILS is not set
154CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE=y
155# CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE is not set
156CONFIG_CPU_FREQ_GOV_PERFORMANCE=y
157CONFIG_CPU_FREQ_GOV_POWERSAVE=y
158CONFIG_CPU_FREQ_GOV_USERSPACE=y
159CONFIG_CPU_FREQ_GOV_ONDEMAND=y
160CONFIG_CPU_FREQ_GOV_CONSERVATIVE=y
161# CONFIG_CPU_FREQ_PMAC64 is not set
143# CONFIG_WANT_EARLY_SERIAL is not set 162# CONFIG_WANT_EARLY_SERIAL is not set
144# CONFIG_MPIC is not set 163CONFIG_MPIC=y
145 164
146# 165#
147# Cell Broadband Engine options 166# Cell Broadband Engine options
@@ -149,6 +168,15 @@ CONFIG_MMIO_NVRAM=y
149CONFIG_SPU_FS=m 168CONFIG_SPU_FS=m
150CONFIG_SPU_BASE=y 169CONFIG_SPU_BASE=y
151CONFIG_CBE_RAS=y 170CONFIG_CBE_RAS=y
171CONFIG_CBE_THERM=m
172CONFIG_CBE_CPUFREQ=m
173
174#
175# PS3 Platform Options
176#
177CONFIG_PS3_HTAB_SIZE=20
178# CONFIG_PS3_DYNAMIC_DMA is not set
179CONFIG_PS3_USE_LPAR_ADDR=y
152 180
153# 181#
154# Kernel options 182# Kernel options
@@ -166,13 +194,14 @@ CONFIG_BINFMT_MISC=m
166CONFIG_FORCE_MAX_ZONEORDER=9 194CONFIG_FORCE_MAX_ZONEORDER=9
167# CONFIG_IOMMU_VMERGE is not set 195# CONFIG_IOMMU_VMERGE is not set
168CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y 196CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
169CONFIG_KEXEC=y 197# CONFIG_KEXEC is not set
170# CONFIG_CRASH_DUMP is not set 198# CONFIG_CRASH_DUMP is not set
171CONFIG_IRQ_ALL_CPUS=y 199CONFIG_IRQ_ALL_CPUS=y
172CONFIG_NUMA=y 200CONFIG_NUMA=y
173CONFIG_NODES_SHIFT=4 201CONFIG_NODES_SHIFT=4
174CONFIG_ARCH_SELECT_MEMORY_MODEL=y 202CONFIG_ARCH_SELECT_MEMORY_MODEL=y
175CONFIG_ARCH_SPARSEMEM_ENABLE=y 203CONFIG_ARCH_SPARSEMEM_ENABLE=y
204CONFIG_ARCH_SPARSEMEM_DEFAULT=y
176CONFIG_ARCH_POPULATES_NODE_MAP=y 205CONFIG_ARCH_POPULATES_NODE_MAP=y
177CONFIG_SELECT_MEMORY_MODEL=y 206CONFIG_SELECT_MEMORY_MODEL=y
178# CONFIG_FLATMEM_MANUAL is not set 207# CONFIG_FLATMEM_MANUAL is not set
@@ -189,6 +218,7 @@ CONFIG_SPLIT_PTLOCK_CPUS=4
189CONFIG_MIGRATION=y 218CONFIG_MIGRATION=y
190CONFIG_RESOURCES_64BIT=y 219CONFIG_RESOURCES_64BIT=y
191CONFIG_ARCH_MEMORY_PROBE=y 220CONFIG_ARCH_MEMORY_PROBE=y
221CONFIG_NODES_SPAN_OTHER_NODES=y
192CONFIG_PPC_64K_PAGES=y 222CONFIG_PPC_64K_PAGES=y
193CONFIG_SCHED_SMT=y 223CONFIG_SCHED_SMT=y
194CONFIG_PROC_DEVICETREE=y 224CONFIG_PROC_DEVICETREE=y
@@ -207,7 +237,6 @@ CONFIG_GENERIC_ISA_DMA=y
207CONFIG_PCI=y 237CONFIG_PCI=y
208CONFIG_PCI_DOMAINS=y 238CONFIG_PCI_DOMAINS=y
209CONFIG_PCIEPORTBUS=y 239CONFIG_PCIEPORTBUS=y
210# CONFIG_PCI_MULTITHREAD_PROBE is not set
211# CONFIG_PCI_DEBUG is not set 240# CONFIG_PCI_DEBUG is not set
212 241
213# 242#
@@ -280,7 +309,6 @@ CONFIG_INET6_XFRM_MODE_TUNNEL=y
280# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set 309# CONFIG_INET6_XFRM_MODE_ROUTEOPTIMIZATION is not set
281# CONFIG_IPV6_SIT is not set 310# CONFIG_IPV6_SIT is not set
282CONFIG_IPV6_TUNNEL=m 311CONFIG_IPV6_TUNNEL=m
283# CONFIG_IPV6_SUBTREES is not set
284# CONFIG_IPV6_MULTIPLE_TABLES is not set 312# CONFIG_IPV6_MULTIPLE_TABLES is not set
285# CONFIG_NETWORK_SECMARK is not set 313# CONFIG_NETWORK_SECMARK is not set
286CONFIG_NETFILTER=y 314CONFIG_NETFILTER=y
@@ -1107,7 +1135,8 @@ CONFIG_PLIST=y
1107# 1135#
1108# Instrumentation Support 1136# Instrumentation Support
1109# 1137#
1110# CONFIG_PROFILING is not set 1138CONFIG_PROFILING=y
1139CONFIG_OPROFILE=y
1111# CONFIG_KPROBES is not set 1140# CONFIG_KPROBES is not set
1112 1141
1113# 1142#
@@ -1142,6 +1171,7 @@ CONFIG_DEBUG_FS=y
1142CONFIG_DEBUGGER=y 1171CONFIG_DEBUGGER=y
1143CONFIG_XMON=y 1172CONFIG_XMON=y
1144CONFIG_XMON_DEFAULT=y 1173CONFIG_XMON_DEFAULT=y
1174CONFIG_XMON_DISASSEMBLY=y
1145CONFIG_IRQSTACKS=y 1175CONFIG_IRQSTACKS=y
1146# CONFIG_BOOTX_TEXT is not set 1176# CONFIG_BOOTX_TEXT is not set
1147# CONFIG_PPC_EARLY_DEBUG is not set 1177# CONFIG_PPC_EARLY_DEBUG is not set
@@ -1159,7 +1189,7 @@ CONFIG_CRYPTO=y
1159CONFIG_CRYPTO_ALGAPI=y 1189CONFIG_CRYPTO_ALGAPI=y
1160CONFIG_CRYPTO_BLKCIPHER=m 1190CONFIG_CRYPTO_BLKCIPHER=m
1161CONFIG_CRYPTO_HASH=y 1191CONFIG_CRYPTO_HASH=y
1162# CONFIG_CRYPTO_MANAGER is not set 1192CONFIG_CRYPTO_MANAGER=y
1163CONFIG_CRYPTO_HMAC=y 1193CONFIG_CRYPTO_HMAC=y
1164# CONFIG_CRYPTO_NULL is not set 1194# CONFIG_CRYPTO_NULL is not set
1165# CONFIG_CRYPTO_MD4 is not set 1195# CONFIG_CRYPTO_MD4 is not set
diff --git a/arch/powerpc/configs/linkstation_defconfig b/arch/powerpc/configs/linkstation_defconfig
new file mode 100644
index 000000000000..23fd210eb56a
--- /dev/null
+++ b/arch/powerpc/configs/linkstation_defconfig
@@ -0,0 +1,1583 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.19-rc4
4# Wed Nov 15 20:36:30 2006
5#
6# CONFIG_PPC64 is not set
7CONFIG_PPC32=y
8CONFIG_PPC_MERGE=y
9CONFIG_MMU=y
10CONFIG_GENERIC_HARDIRQS=y
11CONFIG_IRQ_PER_CPU=y
12CONFIG_RWSEM_XCHGADD_ALGORITHM=y
13CONFIG_GENERIC_HWEIGHT=y
14CONFIG_GENERIC_CALIBRATE_DELAY=y
15CONFIG_GENERIC_FIND_NEXT_BIT=y
16CONFIG_PPC=y
17CONFIG_EARLY_PRINTK=y
18CONFIG_GENERIC_NVRAM=y
19CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
20CONFIG_ARCH_MAY_HAVE_PC_FDC=y
21CONFIG_PPC_OF=y
22CONFIG_PPC_UDBG_16550=y
23# CONFIG_GENERIC_TBSYNC is not set
24CONFIG_AUDIT_ARCH=y
25# CONFIG_DEFAULT_UIMAGE is not set
26
27#
28# Processor support
29#
30CONFIG_CLASSIC32=y
31# CONFIG_PPC_52xx is not set
32# CONFIG_PPC_82xx is not set
33# CONFIG_PPC_83xx is not set
34# CONFIG_PPC_85xx is not set
35# CONFIG_PPC_86xx is not set
36# CONFIG_40x is not set
37# CONFIG_44x is not set
38# CONFIG_8xx is not set
39# CONFIG_E200 is not set
40CONFIG_6xx=y
41CONFIG_PPC_FPU=y
42# CONFIG_PPC_DCR_NATIVE is not set
43# CONFIG_PPC_DCR_MMIO is not set
44# CONFIG_ALTIVEC is not set
45CONFIG_PPC_STD_MMU=y
46CONFIG_PPC_STD_MMU_32=y
47# CONFIG_SMP is not set
48CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
49
50#
51# Code maturity level options
52#
53CONFIG_EXPERIMENTAL=y
54CONFIG_BROKEN_ON_SMP=y
55CONFIG_INIT_ENV_ARG_LIMIT=32
56
57#
58# General setup
59#
60CONFIG_LOCALVERSION="-kuroboxHG"
61CONFIG_LOCALVERSION_AUTO=y
62CONFIG_SWAP=y
63CONFIG_SYSVIPC=y
64# CONFIG_IPC_NS is not set
65CONFIG_POSIX_MQUEUE=y
66# CONFIG_BSD_PROCESS_ACCT is not set
67# CONFIG_TASKSTATS is not set
68# CONFIG_UTS_NS is not set
69# CONFIG_AUDIT is not set
70CONFIG_IKCONFIG=y
71CONFIG_IKCONFIG_PROC=y
72# CONFIG_RELAY is not set
73CONFIG_INITRAMFS_SOURCE=""
74# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
75CONFIG_SYSCTL=y
76# CONFIG_EMBEDDED is not set
77# CONFIG_SYSCTL_SYSCALL is not set
78CONFIG_KALLSYMS=y
79# CONFIG_KALLSYMS_ALL is not set
80# CONFIG_KALLSYMS_EXTRA_PASS is not set
81CONFIG_HOTPLUG=y
82CONFIG_PRINTK=y
83CONFIG_BUG=y
84CONFIG_ELF_CORE=y
85CONFIG_BASE_FULL=y
86CONFIG_FUTEX=y
87CONFIG_EPOLL=y
88CONFIG_SHMEM=y
89CONFIG_SLAB=y
90CONFIG_VM_EVENT_COUNTERS=y
91CONFIG_RT_MUTEXES=y
92# CONFIG_TINY_SHMEM is not set
93CONFIG_BASE_SMALL=0
94# CONFIG_SLOB is not set
95
96#
97# Loadable module support
98#
99CONFIG_MODULES=y
100CONFIG_MODULE_UNLOAD=y
101# CONFIG_MODULE_FORCE_UNLOAD is not set
102# CONFIG_MODVERSIONS is not set
103# CONFIG_MODULE_SRCVERSION_ALL is not set
104CONFIG_KMOD=y
105
106#
107# Block layer
108#
109CONFIG_BLOCK=y
110# CONFIG_LBD is not set
111# CONFIG_BLK_DEV_IO_TRACE is not set
112# CONFIG_LSF is not set
113
114#
115# IO Schedulers
116#
117CONFIG_IOSCHED_NOOP=y
118CONFIG_IOSCHED_AS=y
119CONFIG_IOSCHED_DEADLINE=y
120CONFIG_IOSCHED_CFQ=y
121CONFIG_DEFAULT_AS=y
122# CONFIG_DEFAULT_DEADLINE is not set
123# CONFIG_DEFAULT_CFQ is not set
124# CONFIG_DEFAULT_NOOP is not set
125CONFIG_DEFAULT_IOSCHED="anticipatory"
126
127#
128# Platform support
129#
130# CONFIG_PPC_MULTIPLATFORM is not set
131CONFIG_EMBEDDED6xx=y
132# CONFIG_APUS is not set
133# CONFIG_PPC_CELL is not set
134# CONFIG_PPC_CELL_NATIVE is not set
135# CONFIG_PPC_RTAS is not set
136# CONFIG_MMIO_NVRAM is not set
137# CONFIG_PPC_MPC106 is not set
138# CONFIG_PPC_970_NAP is not set
139# CONFIG_PPC_INDIRECT_IO is not set
140# CONFIG_GENERIC_IOMAP is not set
141# CONFIG_CPU_FREQ is not set
142# CONFIG_TAU is not set
143# CONFIG_KATANA is not set
144# CONFIG_WILLOW is not set
145# CONFIG_CPCI690 is not set
146# CONFIG_POWERPMC250 is not set
147# CONFIG_CHESTNUT is not set
148# CONFIG_SPRUCE is not set
149# CONFIG_HDPU is not set
150# CONFIG_EV64260 is not set
151# CONFIG_LOPEC is not set
152# CONFIG_MVME5100 is not set
153# CONFIG_PPLUS is not set
154# CONFIG_PRPMC750 is not set
155# CONFIG_PRPMC800 is not set
156# CONFIG_SANDPOINT is not set
157CONFIG_LINKSTATION=y
158# CONFIG_MPC7448HPC2 is not set
159# CONFIG_RADSTONE_PPC7D is not set
160# CONFIG_PAL4 is not set
161# CONFIG_GEMINI is not set
162# CONFIG_EST8260 is not set
163# CONFIG_SBC82xx is not set
164# CONFIG_SBS8260 is not set
165# CONFIG_RPX8260 is not set
166# CONFIG_TQM8260 is not set
167# CONFIG_ADS8272 is not set
168# CONFIG_PQ2FADS is not set
169# CONFIG_LITE5200 is not set
170# CONFIG_EV64360 is not set
171CONFIG_PPC_GEN550=y
172CONFIG_MPC10X_BRIDGE=y
173CONFIG_MPC10X_OPENPIC=y
174# CONFIG_MPC10X_STORE_GATHERING is not set
175# CONFIG_WANT_EARLY_SERIAL is not set
176CONFIG_MPIC=y
177
178#
179# Kernel options
180#
181# CONFIG_HIGHMEM is not set
182CONFIG_HZ_100=y
183# CONFIG_HZ_250 is not set
184# CONFIG_HZ_1000 is not set
185CONFIG_HZ=100
186CONFIG_PREEMPT_NONE=y
187# CONFIG_PREEMPT_VOLUNTARY is not set
188# CONFIG_PREEMPT is not set
189CONFIG_BINFMT_ELF=y
190# CONFIG_BINFMT_MISC is not set
191CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
192CONFIG_ARCH_FLATMEM_ENABLE=y
193CONFIG_ARCH_POPULATES_NODE_MAP=y
194CONFIG_SELECT_MEMORY_MODEL=y
195CONFIG_FLATMEM_MANUAL=y
196# CONFIG_DISCONTIGMEM_MANUAL is not set
197# CONFIG_SPARSEMEM_MANUAL is not set
198CONFIG_FLATMEM=y
199CONFIG_FLAT_NODE_MEM_MAP=y
200# CONFIG_SPARSEMEM_STATIC is not set
201CONFIG_SPLIT_PTLOCK_CPUS=4
202# CONFIG_RESOURCES_64BIT is not set
203CONFIG_PROC_DEVICETREE=y
204# CONFIG_CMDLINE_BOOL is not set
205# CONFIG_PM is not set
206# CONFIG_SECCOMP is not set
207CONFIG_ISA_DMA_API=y
208
209#
210# Bus options
211#
212CONFIG_GENERIC_ISA_DMA=y
213# CONFIG_MPIC_WEIRD is not set
214# CONFIG_PPC_I8259 is not set
215CONFIG_PPC_INDIRECT_PCI=y
216CONFIG_FSL_SOC=y
217CONFIG_PCI=y
218CONFIG_PCI_DOMAINS=y
219# CONFIG_PCIEPORTBUS is not set
220# CONFIG_PCI_MULTITHREAD_PROBE is not set
221# CONFIG_PCI_DEBUG is not set
222
223#
224# PCCARD (PCMCIA/CardBus) support
225#
226# CONFIG_PCCARD is not set
227
228#
229# PCI Hotplug Support
230#
231# CONFIG_HOTPLUG_PCI is not set
232
233#
234# Advanced setup
235#
236# CONFIG_ADVANCED_OPTIONS is not set
237
238#
239# Default settings for advanced configuration options are used
240#
241CONFIG_HIGHMEM_START=0xfe000000
242CONFIG_LOWMEM_SIZE=0x30000000
243CONFIG_KERNEL_START=0xc0000000
244CONFIG_TASK_SIZE=0x80000000
245CONFIG_BOOT_LOAD=0x00800000
246
247#
248# Networking
249#
250CONFIG_NET=y
251
252#
253# Networking options
254#
255# CONFIG_NETDEBUG is not set
256CONFIG_PACKET=y
257CONFIG_PACKET_MMAP=y
258CONFIG_UNIX=y
259CONFIG_XFRM=y
260# CONFIG_XFRM_USER is not set
261# CONFIG_XFRM_SUB_POLICY is not set
262# CONFIG_NET_KEY is not set
263CONFIG_INET=y
264CONFIG_IP_MULTICAST=y
265# CONFIG_IP_ADVANCED_ROUTER is not set
266CONFIG_IP_FIB_HASH=y
267CONFIG_IP_PNP=y
268CONFIG_IP_PNP_DHCP=y
269CONFIG_IP_PNP_BOOTP=y
270# CONFIG_IP_PNP_RARP is not set
271# CONFIG_NET_IPIP is not set
272# CONFIG_NET_IPGRE is not set
273# CONFIG_IP_MROUTE is not set
274# CONFIG_ARPD is not set
275# CONFIG_SYN_COOKIES is not set
276# CONFIG_INET_AH is not set
277# CONFIG_INET_ESP is not set
278# CONFIG_INET_IPCOMP is not set
279# CONFIG_INET_XFRM_TUNNEL is not set
280# CONFIG_INET_TUNNEL is not set
281CONFIG_INET_XFRM_MODE_TRANSPORT=y
282CONFIG_INET_XFRM_MODE_TUNNEL=y
283CONFIG_INET_XFRM_MODE_BEET=y
284CONFIG_INET_DIAG=y
285CONFIG_INET_TCP_DIAG=y
286# CONFIG_TCP_CONG_ADVANCED is not set
287CONFIG_TCP_CONG_CUBIC=y
288CONFIG_DEFAULT_TCP_CONG="cubic"
289
290#
291# IP: Virtual Server Configuration
292#
293# CONFIG_IP_VS is not set
294# CONFIG_IPV6 is not set
295# CONFIG_INET6_XFRM_TUNNEL is not set
296# CONFIG_INET6_TUNNEL is not set
297# CONFIG_NETWORK_SECMARK is not set
298CONFIG_NETFILTER=y
299# CONFIG_NETFILTER_DEBUG is not set
300
301#
302# Core Netfilter Configuration
303#
304# CONFIG_NETFILTER_NETLINK is not set
305CONFIG_NETFILTER_XTABLES=m
306CONFIG_NETFILTER_XT_TARGET_CLASSIFY=m
307# CONFIG_NETFILTER_XT_TARGET_DSCP is not set
308CONFIG_NETFILTER_XT_TARGET_MARK=m
309# CONFIG_NETFILTER_XT_TARGET_NFQUEUE is not set
310# CONFIG_NETFILTER_XT_TARGET_NOTRACK is not set
311# CONFIG_NETFILTER_XT_MATCH_COMMENT is not set
312CONFIG_NETFILTER_XT_MATCH_CONNTRACK=m
313# CONFIG_NETFILTER_XT_MATCH_DCCP is not set
314# CONFIG_NETFILTER_XT_MATCH_DSCP is not set
315CONFIG_NETFILTER_XT_MATCH_ESP=m
316# CONFIG_NETFILTER_XT_MATCH_HELPER is not set
317CONFIG_NETFILTER_XT_MATCH_LENGTH=m
318CONFIG_NETFILTER_XT_MATCH_LIMIT=m
319CONFIG_NETFILTER_XT_MATCH_MAC=m
320CONFIG_NETFILTER_XT_MATCH_MARK=m
321# CONFIG_NETFILTER_XT_MATCH_POLICY is not set
322CONFIG_NETFILTER_XT_MATCH_MULTIPORT=m
323CONFIG_NETFILTER_XT_MATCH_PKTTYPE=m
324# CONFIG_NETFILTER_XT_MATCH_QUOTA is not set
325# CONFIG_NETFILTER_XT_MATCH_REALM is not set
326# CONFIG_NETFILTER_XT_MATCH_SCTP is not set
327CONFIG_NETFILTER_XT_MATCH_STATE=m
328# CONFIG_NETFILTER_XT_MATCH_STATISTIC is not set
329# CONFIG_NETFILTER_XT_MATCH_STRING is not set
330# CONFIG_NETFILTER_XT_MATCH_TCPMSS is not set
331
332#
333# IP: Netfilter Configuration
334#
335CONFIG_IP_NF_CONNTRACK=m
336# CONFIG_IP_NF_CT_ACCT is not set
337# CONFIG_IP_NF_CONNTRACK_MARK is not set
338# CONFIG_IP_NF_CONNTRACK_EVENTS is not set
339# CONFIG_IP_NF_CT_PROTO_SCTP is not set
340CONFIG_IP_NF_FTP=m
341CONFIG_IP_NF_IRC=m
342# CONFIG_IP_NF_NETBIOS_NS is not set
343CONFIG_IP_NF_TFTP=m
344# CONFIG_IP_NF_AMANDA is not set
345# CONFIG_IP_NF_PPTP is not set
346# CONFIG_IP_NF_H323 is not set
347# CONFIG_IP_NF_SIP is not set
348# CONFIG_IP_NF_QUEUE is not set
349CONFIG_IP_NF_IPTABLES=m
350CONFIG_IP_NF_MATCH_IPRANGE=m
351# CONFIG_IP_NF_MATCH_TOS is not set
352# CONFIG_IP_NF_MATCH_RECENT is not set
353# CONFIG_IP_NF_MATCH_ECN is not set
354# CONFIG_IP_NF_MATCH_AH is not set
355# CONFIG_IP_NF_MATCH_TTL is not set
356# CONFIG_IP_NF_MATCH_OWNER is not set
357# CONFIG_IP_NF_MATCH_ADDRTYPE is not set
358# CONFIG_IP_NF_MATCH_HASHLIMIT is not set
359CONFIG_IP_NF_FILTER=m
360CONFIG_IP_NF_TARGET_REJECT=m
361# CONFIG_IP_NF_TARGET_LOG is not set
362# CONFIG_IP_NF_TARGET_ULOG is not set
363# CONFIG_IP_NF_TARGET_TCPMSS is not set
364CONFIG_IP_NF_NAT=m
365CONFIG_IP_NF_NAT_NEEDED=y
366CONFIG_IP_NF_TARGET_MASQUERADE=m
367CONFIG_IP_NF_TARGET_REDIRECT=m
368CONFIG_IP_NF_TARGET_NETMAP=m
369CONFIG_IP_NF_TARGET_SAME=m
370# CONFIG_IP_NF_NAT_SNMP_BASIC is not set
371CONFIG_IP_NF_NAT_IRC=m
372CONFIG_IP_NF_NAT_FTP=m
373CONFIG_IP_NF_NAT_TFTP=m
374CONFIG_IP_NF_MANGLE=m
375CONFIG_IP_NF_TARGET_TOS=m
376CONFIG_IP_NF_TARGET_ECN=m
377CONFIG_IP_NF_TARGET_TTL=m
378CONFIG_IP_NF_RAW=m
379CONFIG_IP_NF_ARPTABLES=m
380CONFIG_IP_NF_ARPFILTER=m
381CONFIG_IP_NF_ARP_MANGLE=m
382
383#
384# DCCP Configuration (EXPERIMENTAL)
385#
386# CONFIG_IP_DCCP is not set
387
388#
389# SCTP Configuration (EXPERIMENTAL)
390#
391# CONFIG_IP_SCTP is not set
392
393#
394# TIPC Configuration (EXPERIMENTAL)
395#
396# CONFIG_TIPC is not set
397# CONFIG_ATM is not set
398# CONFIG_BRIDGE is not set
399# CONFIG_VLAN_8021Q is not set
400# CONFIG_DECNET is not set
401# CONFIG_LLC2 is not set
402# CONFIG_IPX is not set
403# CONFIG_ATALK is not set
404# CONFIG_X25 is not set
405# CONFIG_LAPB is not set
406# CONFIG_ECONET is not set
407# CONFIG_WAN_ROUTER is not set
408
409#
410# QoS and/or fair queueing
411#
412# CONFIG_NET_SCHED is not set
413
414#
415# Network testing
416#
417# CONFIG_NET_PKTGEN is not set
418# CONFIG_HAMRADIO is not set
419# CONFIG_IRDA is not set
420# CONFIG_BT is not set
421CONFIG_IEEE80211=m
422CONFIG_IEEE80211_DEBUG=y
423CONFIG_IEEE80211_CRYPT_WEP=m
424CONFIG_IEEE80211_CRYPT_CCMP=m
425CONFIG_IEEE80211_CRYPT_TKIP=m
426CONFIG_IEEE80211_SOFTMAC=m
427CONFIG_IEEE80211_SOFTMAC_DEBUG=y
428CONFIG_WIRELESS_EXT=y
429
430#
431# Device Drivers
432#
433
434#
435# Generic Driver Options
436#
437CONFIG_STANDALONE=y
438CONFIG_PREVENT_FIRMWARE_BUILD=y
439CONFIG_FW_LOADER=m
440# CONFIG_DEBUG_DRIVER is not set
441# CONFIG_SYS_HYPERVISOR is not set
442
443#
444# Connector - unified userspace <-> kernelspace linker
445#
446# CONFIG_CONNECTOR is not set
447
448#
449# Memory Technology Devices (MTD)
450#
451CONFIG_MTD=y
452# CONFIG_MTD_DEBUG is not set
453CONFIG_MTD_CONCAT=y
454CONFIG_MTD_PARTITIONS=y
455# CONFIG_MTD_REDBOOT_PARTS is not set
456# CONFIG_MTD_CMDLINE_PARTS is not set
457
458#
459# User Modules And Translation Layers
460#
461CONFIG_MTD_CHAR=y
462CONFIG_MTD_BLOCK=y
463# CONFIG_FTL is not set
464# CONFIG_NFTL is not set
465# CONFIG_INFTL is not set
466# CONFIG_RFD_FTL is not set
467# CONFIG_SSFDC is not set
468
469#
470# RAM/ROM/Flash chip drivers
471#
472CONFIG_MTD_CFI=y
473CONFIG_MTD_JEDECPROBE=y
474CONFIG_MTD_GEN_PROBE=y
475CONFIG_MTD_CFI_ADV_OPTIONS=y
476CONFIG_MTD_CFI_NOSWAP=y
477# CONFIG_MTD_CFI_BE_BYTE_SWAP is not set
478# CONFIG_MTD_CFI_LE_BYTE_SWAP is not set
479CONFIG_MTD_CFI_GEOMETRY=y
480CONFIG_MTD_MAP_BANK_WIDTH_1=y
481# CONFIG_MTD_MAP_BANK_WIDTH_2 is not set
482# CONFIG_MTD_MAP_BANK_WIDTH_4 is not set
483# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
484# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
485# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
486CONFIG_MTD_CFI_I1=y
487# CONFIG_MTD_CFI_I2 is not set
488# CONFIG_MTD_CFI_I4 is not set
489# CONFIG_MTD_CFI_I8 is not set
490# CONFIG_MTD_OTP is not set
491# CONFIG_MTD_CFI_INTELEXT is not set
492CONFIG_MTD_CFI_AMDSTD=y
493# CONFIG_MTD_CFI_STAA is not set
494CONFIG_MTD_CFI_UTIL=y
495# CONFIG_MTD_RAM is not set
496# CONFIG_MTD_ROM is not set
497# CONFIG_MTD_ABSENT is not set
498# CONFIG_MTD_OBSOLETE_CHIPS is not set
499
500#
501# Mapping drivers for chip access
502#
503# CONFIG_MTD_COMPLEX_MAPPINGS is not set
504CONFIG_MTD_PHYSMAP=y
505CONFIG_MTD_PHYSMAP_START=0xffc00000
506CONFIG_MTD_PHYSMAP_LEN=0x400000
507CONFIG_MTD_PHYSMAP_BANKWIDTH=1
508# CONFIG_MTD_PLATRAM is not set
509
510#
511# Self-contained MTD device drivers
512#
513# CONFIG_MTD_PMC551 is not set
514# CONFIG_MTD_SLRAM is not set
515# CONFIG_MTD_PHRAM is not set
516# CONFIG_MTD_MTDRAM is not set
517# CONFIG_MTD_BLOCK2MTD is not set
518
519#
520# Disk-On-Chip Device Drivers
521#
522# CONFIG_MTD_DOC2000 is not set
523# CONFIG_MTD_DOC2001 is not set
524# CONFIG_MTD_DOC2001PLUS is not set
525
526#
527# NAND Flash Device Drivers
528#
529# CONFIG_MTD_NAND is not set
530
531#
532# OneNAND Flash Device Drivers
533#
534# CONFIG_MTD_ONENAND is not set
535
536#
537# Parallel port support
538#
539# CONFIG_PARPORT is not set
540
541#
542# Plug and Play support
543#
544
545#
546# Block devices
547#
548# CONFIG_BLK_DEV_FD is not set
549# CONFIG_BLK_CPQ_DA is not set
550# CONFIG_BLK_CPQ_CISS_DA is not set
551# CONFIG_BLK_DEV_DAC960 is not set
552# CONFIG_BLK_DEV_UMEM is not set
553# CONFIG_BLK_DEV_COW_COMMON is not set
554CONFIG_BLK_DEV_LOOP=y
555# CONFIG_BLK_DEV_CRYPTOLOOP is not set
556# CONFIG_BLK_DEV_NBD is not set
557# CONFIG_BLK_DEV_SX8 is not set
558# CONFIG_BLK_DEV_UB is not set
559CONFIG_BLK_DEV_RAM=y
560CONFIG_BLK_DEV_RAM_COUNT=2
561CONFIG_BLK_DEV_RAM_SIZE=8192
562CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
563CONFIG_BLK_DEV_INITRD=y
564# CONFIG_CDROM_PKTCDVD is not set
565# CONFIG_ATA_OVER_ETH is not set
566
567#
568# Misc devices
569#
570# CONFIG_SGI_IOC4 is not set
571# CONFIG_TIFM_CORE is not set
572
573#
574# ATA/ATAPI/MFM/RLL support
575#
576# CONFIG_IDE is not set
577
578#
579# SCSI device support
580#
581# CONFIG_RAID_ATTRS is not set
582CONFIG_SCSI=y
583# CONFIG_SCSI_NETLINK is not set
584CONFIG_SCSI_PROC_FS=y
585
586#
587# SCSI support type (disk, tape, CD-ROM)
588#
589CONFIG_BLK_DEV_SD=y
590# CONFIG_CHR_DEV_ST is not set
591# CONFIG_CHR_DEV_OSST is not set
592# CONFIG_BLK_DEV_SR is not set
593CONFIG_CHR_DEV_SG=y
594# CONFIG_CHR_DEV_SCH is not set
595
596#
597# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
598#
599CONFIG_SCSI_MULTI_LUN=y
600# CONFIG_SCSI_CONSTANTS is not set
601# CONFIG_SCSI_LOGGING is not set
602
603#
604# SCSI Transports
605#
606# CONFIG_SCSI_SPI_ATTRS is not set
607# CONFIG_SCSI_FC_ATTRS is not set
608# CONFIG_SCSI_ISCSI_ATTRS is not set
609# CONFIG_SCSI_SAS_ATTRS is not set
610# CONFIG_SCSI_SAS_LIBSAS is not set
611
612#
613# SCSI low-level drivers
614#
615# CONFIG_ISCSI_TCP is not set
616# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
617# CONFIG_SCSI_3W_9XXX is not set
618# CONFIG_SCSI_ACARD is not set
619# CONFIG_SCSI_AACRAID is not set
620# CONFIG_SCSI_AIC7XXX is not set
621# CONFIG_SCSI_AIC7XXX_OLD is not set
622# CONFIG_SCSI_AIC79XX is not set
623# CONFIG_SCSI_AIC94XX is not set
624# CONFIG_SCSI_DPT_I2O is not set
625# CONFIG_SCSI_ARCMSR is not set
626# CONFIG_MEGARAID_NEWGEN is not set
627# CONFIG_MEGARAID_LEGACY is not set
628# CONFIG_MEGARAID_SAS is not set
629# CONFIG_SCSI_HPTIOP is not set
630# CONFIG_SCSI_BUSLOGIC is not set
631# CONFIG_SCSI_DMX3191D is not set
632# CONFIG_SCSI_EATA is not set
633# CONFIG_SCSI_FUTURE_DOMAIN is not set
634# CONFIG_SCSI_GDTH is not set
635# CONFIG_SCSI_IPS is not set
636# CONFIG_SCSI_INITIO is not set
637# CONFIG_SCSI_INIA100 is not set
638# CONFIG_SCSI_STEX is not set
639# CONFIG_SCSI_SYM53C8XX_2 is not set
640# CONFIG_SCSI_IPR is not set
641# CONFIG_SCSI_QLOGIC_1280 is not set
642# CONFIG_SCSI_QLA_FC is not set
643# CONFIG_SCSI_QLA_ISCSI is not set
644# CONFIG_SCSI_LPFC is not set
645# CONFIG_SCSI_DC395x is not set
646# CONFIG_SCSI_DC390T is not set
647# CONFIG_SCSI_NSP32 is not set
648# CONFIG_SCSI_DEBUG is not set
649
650#
651# Serial ATA (prod) and Parallel ATA (experimental) drivers
652#
653CONFIG_ATA=y
654# CONFIG_SATA_AHCI is not set
655# CONFIG_SATA_SVW is not set
656# CONFIG_ATA_PIIX is not set
657# CONFIG_SATA_MV is not set
658# CONFIG_SATA_NV is not set
659# CONFIG_PDC_ADMA is not set
660# CONFIG_SATA_QSTOR is not set
661# CONFIG_SATA_PROMISE is not set
662# CONFIG_SATA_SX4 is not set
663# CONFIG_SATA_SIL is not set
664# CONFIG_SATA_SIL24 is not set
665# CONFIG_SATA_SIS is not set
666# CONFIG_SATA_ULI is not set
667# CONFIG_SATA_VIA is not set
668# CONFIG_SATA_VITESSE is not set
669# CONFIG_PATA_ALI is not set
670# CONFIG_PATA_AMD is not set
671# CONFIG_PATA_ARTOP is not set
672# CONFIG_PATA_ATIIXP is not set
673# CONFIG_PATA_CMD64X is not set
674# CONFIG_PATA_CS5520 is not set
675# CONFIG_PATA_CS5530 is not set
676# CONFIG_PATA_CYPRESS is not set
677# CONFIG_PATA_EFAR is not set
678# CONFIG_ATA_GENERIC is not set
679# CONFIG_PATA_HPT366 is not set
680# CONFIG_PATA_HPT37X is not set
681# CONFIG_PATA_HPT3X2N is not set
682# CONFIG_PATA_HPT3X3 is not set
683# CONFIG_PATA_IT821X is not set
684# CONFIG_PATA_JMICRON is not set
685# CONFIG_PATA_TRIFLEX is not set
686# CONFIG_PATA_MPIIX is not set
687# CONFIG_PATA_OLDPIIX is not set
688# CONFIG_PATA_NETCELL is not set
689# CONFIG_PATA_NS87410 is not set
690# CONFIG_PATA_OPTI is not set
691# CONFIG_PATA_OPTIDMA is not set
692# CONFIG_PATA_PDC_OLD is not set
693# CONFIG_PATA_RADISYS is not set
694# CONFIG_PATA_RZ1000 is not set
695# CONFIG_PATA_SC1200 is not set
696# CONFIG_PATA_SERVERWORKS is not set
697# CONFIG_PATA_PDC2027X is not set
698CONFIG_PATA_SIL680=y
699# CONFIG_PATA_SIS is not set
700# CONFIG_PATA_VIA is not set
701# CONFIG_PATA_WINBOND is not set
702
703#
704# Multi-device support (RAID and LVM)
705#
706# CONFIG_MD is not set
707
708#
709# Fusion MPT device support
710#
711# CONFIG_FUSION is not set
712# CONFIG_FUSION_SPI is not set
713# CONFIG_FUSION_FC is not set
714# CONFIG_FUSION_SAS is not set
715
716#
717# IEEE 1394 (FireWire) support
718#
719# CONFIG_IEEE1394 is not set
720
721#
722# I2O device support
723#
724# CONFIG_I2O is not set
725
726#
727# Macintosh device drivers
728#
729# CONFIG_WINDFARM is not set
730
731#
732# Network device support
733#
734CONFIG_NETDEVICES=y
735# CONFIG_DUMMY is not set
736# CONFIG_BONDING is not set
737# CONFIG_EQUALIZER is not set
738CONFIG_TUN=m
739
740#
741# ARCnet devices
742#
743# CONFIG_ARCNET is not set
744
745#
746# PHY device support
747#
748
749#
750# Ethernet (10 or 100Mbit)
751#
752# CONFIG_NET_ETHERNET is not set
753
754#
755# Ethernet (1000 Mbit)
756#
757# CONFIG_ACENIC is not set
758# CONFIG_DL2K is not set
759# CONFIG_E1000 is not set
760# CONFIG_NS83820 is not set
761# CONFIG_HAMACHI is not set
762# CONFIG_YELLOWFIN is not set
763CONFIG_R8169=y
764# CONFIG_R8169_NAPI is not set
765# CONFIG_SIS190 is not set
766# CONFIG_SKGE is not set
767# CONFIG_SKY2 is not set
768# CONFIG_SK98LIN is not set
769# CONFIG_TIGON3 is not set
770# CONFIG_BNX2 is not set
771# CONFIG_QLA3XXX is not set
772
773#
774# Ethernet (10000 Mbit)
775#
776# CONFIG_CHELSIO_T1 is not set
777# CONFIG_IXGB is not set
778# CONFIG_S2IO is not set
779# CONFIG_MYRI10GE is not set
780
781#
782# Token Ring devices
783#
784# CONFIG_TR is not set
785
786#
787# Wireless LAN (non-hamradio)
788#
789CONFIG_NET_RADIO=y
790# CONFIG_NET_WIRELESS_RTNETLINK is not set
791
792#
793# Obsolete Wireless cards support (pre-802.11)
794#
795# CONFIG_STRIP is not set
796
797#
798# Wireless 802.11b ISA/PCI cards support
799#
800# CONFIG_IPW2100 is not set
801# CONFIG_IPW2200 is not set
802# CONFIG_AIRO is not set
803# CONFIG_HERMES is not set
804# CONFIG_ATMEL is not set
805
806#
807# Prism GT/Duette 802.11(a/b/g) PCI/Cardbus support
808#
809# CONFIG_PRISM54 is not set
810# CONFIG_USB_ZD1201 is not set
811# CONFIG_HOSTAP is not set
812# CONFIG_BCM43XX is not set
813# CONFIG_ZD1211RW is not set
814CONFIG_NET_WIRELESS=y
815
816#
817# Wan interfaces
818#
819# CONFIG_WAN is not set
820# CONFIG_FDDI is not set
821# CONFIG_HIPPI is not set
822# CONFIG_PPP is not set
823# CONFIG_SLIP is not set
824# CONFIG_NET_FC is not set
825# CONFIG_SHAPER is not set
826CONFIG_NETCONSOLE=y
827CONFIG_NETPOLL=y
828# CONFIG_NETPOLL_RX is not set
829# CONFIG_NETPOLL_TRAP is not set
830CONFIG_NET_POLL_CONTROLLER=y
831
832#
833# ISDN subsystem
834#
835# CONFIG_ISDN is not set
836
837#
838# Telephony Support
839#
840# CONFIG_PHONE is not set
841
842#
843# Input device support
844#
845CONFIG_INPUT=y
846# CONFIG_INPUT_FF_MEMLESS is not set
847
848#
849# Userland interfaces
850#
851CONFIG_INPUT_MOUSEDEV=y
852# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
853CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
854CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
855# CONFIG_INPUT_JOYDEV is not set
856# CONFIG_INPUT_TSDEV is not set
857CONFIG_INPUT_EVDEV=m
858# CONFIG_INPUT_EVBUG is not set
859
860#
861# Input Device Drivers
862#
863# CONFIG_INPUT_KEYBOARD is not set
864# CONFIG_INPUT_MOUSE is not set
865# CONFIG_INPUT_JOYSTICK is not set
866# CONFIG_INPUT_TOUCHSCREEN is not set
867CONFIG_INPUT_MISC=y
868CONFIG_INPUT_UINPUT=m
869
870#
871# Hardware I/O ports
872#
873CONFIG_SERIO=y
874# CONFIG_SERIO_I8042 is not set
875CONFIG_SERIO_SERPORT=y
876# CONFIG_SERIO_PCIPS2 is not set
877# CONFIG_SERIO_RAW is not set
878# CONFIG_GAMEPORT is not set
879
880#
881# Character devices
882#
883CONFIG_VT=y
884CONFIG_VT_CONSOLE=y
885CONFIG_HW_CONSOLE=y
886# CONFIG_VT_HW_CONSOLE_BINDING is not set
887# CONFIG_SERIAL_NONSTANDARD is not set
888
889#
890# Serial drivers
891#
892CONFIG_SERIAL_8250=y
893CONFIG_SERIAL_8250_CONSOLE=y
894CONFIG_SERIAL_8250_PCI=y
895CONFIG_SERIAL_8250_NR_UARTS=4
896CONFIG_SERIAL_8250_RUNTIME_UARTS=4
897# CONFIG_SERIAL_8250_EXTENDED is not set
898
899#
900# Non-8250 serial port support
901#
902CONFIG_SERIAL_CORE=y
903CONFIG_SERIAL_CORE_CONSOLE=y
904# CONFIG_SERIAL_JSM is not set
905CONFIG_UNIX98_PTYS=y
906CONFIG_LEGACY_PTYS=y
907CONFIG_LEGACY_PTY_COUNT=256
908
909#
910# IPMI
911#
912# CONFIG_IPMI_HANDLER is not set
913
914#
915# Watchdog Cards
916#
917# CONFIG_WATCHDOG is not set
918CONFIG_HW_RANDOM=y
919# CONFIG_NVRAM is not set
920# CONFIG_GEN_RTC is not set
921# CONFIG_DTLK is not set
922# CONFIG_R3964 is not set
923# CONFIG_APPLICOM is not set
924
925#
926# Ftape, the floppy tape device driver
927#
928# CONFIG_AGP is not set
929# CONFIG_DRM is not set
930# CONFIG_RAW_DRIVER is not set
931
932#
933# TPM devices
934#
935# CONFIG_TCG_TPM is not set
936
937#
938# I2C support
939#
940CONFIG_I2C=y
941CONFIG_I2C_CHARDEV=y
942
943#
944# I2C Algorithms
945#
946# CONFIG_I2C_ALGOBIT is not set
947# CONFIG_I2C_ALGOPCF is not set
948# CONFIG_I2C_ALGOPCA is not set
949
950#
951# I2C Hardware Bus support
952#
953# CONFIG_I2C_ALI1535 is not set
954# CONFIG_I2C_ALI1563 is not set
955# CONFIG_I2C_ALI15X3 is not set
956# CONFIG_I2C_AMD756 is not set
957# CONFIG_I2C_AMD8111 is not set
958# CONFIG_I2C_I801 is not set
959# CONFIG_I2C_I810 is not set
960# CONFIG_I2C_PIIX4 is not set
961CONFIG_I2C_MPC=y
962# CONFIG_I2C_NFORCE2 is not set
963# CONFIG_I2C_OCORES is not set
964# CONFIG_I2C_PARPORT_LIGHT is not set
965# CONFIG_I2C_PROSAVAGE is not set
966# CONFIG_I2C_SAVAGE4 is not set
967# CONFIG_I2C_SIS5595 is not set
968# CONFIG_I2C_SIS630 is not set
969# CONFIG_I2C_SIS96X is not set
970# CONFIG_I2C_STUB is not set
971# CONFIG_I2C_VIA is not set
972# CONFIG_I2C_VIAPRO is not set
973# CONFIG_I2C_VOODOO3 is not set
974# CONFIG_I2C_PCA_ISA is not set
975
976#
977# Miscellaneous I2C Chip support
978#
979# CONFIG_SENSORS_DS1337 is not set
980# CONFIG_SENSORS_DS1374 is not set
981CONFIG_SENSORS_EEPROM=m
982# CONFIG_SENSORS_PCF8574 is not set
983# CONFIG_SENSORS_PCA9539 is not set
984# CONFIG_SENSORS_PCF8591 is not set
985# CONFIG_SENSORS_M41T00 is not set
986# CONFIG_SENSORS_MAX6875 is not set
987# CONFIG_I2C_DEBUG_CORE is not set
988# CONFIG_I2C_DEBUG_ALGO is not set
989# CONFIG_I2C_DEBUG_BUS is not set
990# CONFIG_I2C_DEBUG_CHIP is not set
991
992#
993# SPI support
994#
995# CONFIG_SPI is not set
996# CONFIG_SPI_MASTER is not set
997
998#
999# Dallas's 1-wire bus
1000#
1001# CONFIG_W1 is not set
1002
1003#
1004# Hardware Monitoring support
1005#
1006CONFIG_HWMON=y
1007# CONFIG_HWMON_VID is not set
1008# CONFIG_SENSORS_ABITUGURU is not set
1009# CONFIG_SENSORS_ADM1021 is not set
1010# CONFIG_SENSORS_ADM1025 is not set
1011# CONFIG_SENSORS_ADM1026 is not set
1012# CONFIG_SENSORS_ADM1031 is not set
1013# CONFIG_SENSORS_ADM9240 is not set
1014# CONFIG_SENSORS_ASB100 is not set
1015# CONFIG_SENSORS_ATXP1 is not set
1016# CONFIG_SENSORS_DS1621 is not set
1017# CONFIG_SENSORS_F71805F is not set
1018# CONFIG_SENSORS_FSCHER is not set
1019# CONFIG_SENSORS_FSCPOS is not set
1020# CONFIG_SENSORS_GL518SM is not set
1021# CONFIG_SENSORS_GL520SM is not set
1022# CONFIG_SENSORS_IT87 is not set
1023# CONFIG_SENSORS_LM63 is not set
1024# CONFIG_SENSORS_LM75 is not set
1025# CONFIG_SENSORS_LM77 is not set
1026# CONFIG_SENSORS_LM78 is not set
1027# CONFIG_SENSORS_LM80 is not set
1028# CONFIG_SENSORS_LM83 is not set
1029# CONFIG_SENSORS_LM85 is not set
1030# CONFIG_SENSORS_LM87 is not set
1031# CONFIG_SENSORS_LM90 is not set
1032# CONFIG_SENSORS_LM92 is not set
1033# CONFIG_SENSORS_MAX1619 is not set
1034# CONFIG_SENSORS_PC87360 is not set
1035# CONFIG_SENSORS_SIS5595 is not set
1036# CONFIG_SENSORS_SMSC47M1 is not set
1037# CONFIG_SENSORS_SMSC47M192 is not set
1038# CONFIG_SENSORS_SMSC47B397 is not set
1039# CONFIG_SENSORS_VIA686A is not set
1040# CONFIG_SENSORS_VT1211 is not set
1041# CONFIG_SENSORS_VT8231 is not set
1042# CONFIG_SENSORS_W83781D is not set
1043# CONFIG_SENSORS_W83791D is not set
1044# CONFIG_SENSORS_W83792D is not set
1045# CONFIG_SENSORS_W83L785TS is not set
1046# CONFIG_SENSORS_W83627HF is not set
1047# CONFIG_SENSORS_W83627EHF is not set
1048# CONFIG_HWMON_DEBUG_CHIP is not set
1049
1050#
1051# Multimedia devices
1052#
1053# CONFIG_VIDEO_DEV is not set
1054
1055#
1056# Digital Video Broadcasting Devices
1057#
1058# CONFIG_DVB is not set
1059# CONFIG_USB_DABUSB is not set
1060
1061#
1062# Graphics support
1063#
1064CONFIG_FIRMWARE_EDID=y
1065# CONFIG_FB is not set
1066
1067#
1068# Console display driver support
1069#
1070# CONFIG_VGA_CONSOLE is not set
1071CONFIG_DUMMY_CONSOLE=y
1072# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
1073
1074#
1075# Sound
1076#
1077# CONFIG_SOUND is not set
1078
1079#
1080# USB support
1081#
1082CONFIG_USB_ARCH_HAS_HCD=y
1083CONFIG_USB_ARCH_HAS_OHCI=y
1084CONFIG_USB_ARCH_HAS_EHCI=y
1085CONFIG_USB=y
1086# CONFIG_USB_DEBUG is not set
1087
1088#
1089# Miscellaneous USB options
1090#
1091CONFIG_USB_DEVICEFS=y
1092# CONFIG_USB_BANDWIDTH is not set
1093# CONFIG_USB_DYNAMIC_MINORS is not set
1094# CONFIG_USB_OTG is not set
1095
1096#
1097# USB Host Controller Drivers
1098#
1099CONFIG_USB_EHCI_HCD=y
1100# CONFIG_USB_EHCI_SPLIT_ISO is not set
1101# CONFIG_USB_EHCI_ROOT_HUB_TT is not set
1102# CONFIG_USB_EHCI_TT_NEWSCHED is not set
1103# CONFIG_USB_ISP116X_HCD is not set
1104CONFIG_USB_OHCI_HCD=y
1105# CONFIG_USB_OHCI_BIG_ENDIAN is not set
1106CONFIG_USB_OHCI_LITTLE_ENDIAN=y
1107# CONFIG_USB_UHCI_HCD is not set
1108# CONFIG_USB_SL811_HCD is not set
1109
1110#
1111# USB Device Class drivers
1112#
1113# CONFIG_USB_ACM is not set
1114# CONFIG_USB_PRINTER is not set
1115
1116#
1117# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
1118#
1119
1120#
1121# may also be needed; see USB_STORAGE Help for more information
1122#
1123CONFIG_USB_STORAGE=m
1124# CONFIG_USB_STORAGE_DEBUG is not set
1125# CONFIG_USB_STORAGE_DATAFAB is not set
1126# CONFIG_USB_STORAGE_FREECOM is not set
1127# CONFIG_USB_STORAGE_DPCM is not set
1128# CONFIG_USB_STORAGE_USBAT is not set
1129# CONFIG_USB_STORAGE_SDDR09 is not set
1130# CONFIG_USB_STORAGE_SDDR55 is not set
1131# CONFIG_USB_STORAGE_JUMPSHOT is not set
1132# CONFIG_USB_STORAGE_ALAUDA is not set
1133# CONFIG_USB_STORAGE_ONETOUCH is not set
1134# CONFIG_USB_STORAGE_KARMA is not set
1135# CONFIG_USB_LIBUSUAL is not set
1136
1137#
1138# USB Input Devices
1139#
1140# CONFIG_USB_HID is not set
1141
1142#
1143# USB HID Boot Protocol drivers
1144#
1145# CONFIG_USB_KBD is not set
1146# CONFIG_USB_MOUSE is not set
1147# CONFIG_USB_AIPTEK is not set
1148# CONFIG_USB_WACOM is not set
1149# CONFIG_USB_ACECAD is not set
1150# CONFIG_USB_KBTAB is not set
1151# CONFIG_USB_POWERMATE is not set
1152# CONFIG_USB_TOUCHSCREEN is not set
1153# CONFIG_USB_YEALINK is not set
1154# CONFIG_USB_XPAD is not set
1155# CONFIG_USB_ATI_REMOTE is not set
1156# CONFIG_USB_ATI_REMOTE2 is not set
1157# CONFIG_USB_KEYSPAN_REMOTE is not set
1158# CONFIG_USB_APPLETOUCH is not set
1159
1160#
1161# USB Imaging devices
1162#
1163# CONFIG_USB_MDC800 is not set
1164# CONFIG_USB_MICROTEK is not set
1165
1166#
1167# USB Network Adapters
1168#
1169# CONFIG_USB_CATC is not set
1170# CONFIG_USB_KAWETH is not set
1171# CONFIG_USB_PEGASUS is not set
1172# CONFIG_USB_RTL8150 is not set
1173# CONFIG_USB_USBNET is not set
1174CONFIG_USB_MON=y
1175
1176#
1177# USB port drivers
1178#
1179
1180#
1181# USB Serial Converter support
1182#
1183CONFIG_USB_SERIAL=y
1184CONFIG_USB_SERIAL_CONSOLE=y
1185# CONFIG_USB_SERIAL_GENERIC is not set
1186# CONFIG_USB_SERIAL_AIRCABLE is not set
1187# CONFIG_USB_SERIAL_AIRPRIME is not set
1188# CONFIG_USB_SERIAL_ARK3116 is not set
1189# CONFIG_USB_SERIAL_BELKIN is not set
1190# CONFIG_USB_SERIAL_WHITEHEAT is not set
1191# CONFIG_USB_SERIAL_DIGI_ACCELEPORT is not set
1192# CONFIG_USB_SERIAL_CP2101 is not set
1193# CONFIG_USB_SERIAL_CYPRESS_M8 is not set
1194# CONFIG_USB_SERIAL_EMPEG is not set
1195CONFIG_USB_SERIAL_FTDI_SIO=y
1196# CONFIG_USB_SERIAL_FUNSOFT is not set
1197# CONFIG_USB_SERIAL_VISOR is not set
1198# CONFIG_USB_SERIAL_IPAQ is not set
1199# CONFIG_USB_SERIAL_IR is not set
1200# CONFIG_USB_SERIAL_EDGEPORT is not set
1201# CONFIG_USB_SERIAL_EDGEPORT_TI is not set
1202# CONFIG_USB_SERIAL_GARMIN is not set
1203# CONFIG_USB_SERIAL_IPW is not set
1204# CONFIG_USB_SERIAL_KEYSPAN_PDA is not set
1205# CONFIG_USB_SERIAL_KEYSPAN is not set
1206# CONFIG_USB_SERIAL_KLSI is not set
1207# CONFIG_USB_SERIAL_KOBIL_SCT is not set
1208# CONFIG_USB_SERIAL_MCT_U232 is not set
1209# CONFIG_USB_SERIAL_MOS7720 is not set
1210# CONFIG_USB_SERIAL_MOS7840 is not set
1211# CONFIG_USB_SERIAL_NAVMAN is not set
1212# CONFIG_USB_SERIAL_PL2303 is not set
1213# CONFIG_USB_SERIAL_HP4X is not set
1214# CONFIG_USB_SERIAL_SAFE is not set
1215# CONFIG_USB_SERIAL_SIERRAWIRELESS is not set
1216# CONFIG_USB_SERIAL_TI is not set
1217# CONFIG_USB_SERIAL_CYBERJACK is not set
1218# CONFIG_USB_SERIAL_XIRCOM is not set
1219# CONFIG_USB_SERIAL_OPTION is not set
1220# CONFIG_USB_SERIAL_OMNINET is not set
1221
1222#
1223# USB Miscellaneous drivers
1224#
1225# CONFIG_USB_EMI62 is not set
1226# CONFIG_USB_EMI26 is not set
1227# CONFIG_USB_ADUTUX is not set
1228# CONFIG_USB_AUERSWALD is not set
1229# CONFIG_USB_RIO500 is not set
1230# CONFIG_USB_LEGOTOWER is not set
1231# CONFIG_USB_LCD is not set
1232# CONFIG_USB_LED is not set
1233# CONFIG_USB_CYPRESS_CY7C63 is not set
1234# CONFIG_USB_CYTHERM is not set
1235# CONFIG_USB_PHIDGET is not set
1236# CONFIG_USB_IDMOUSE is not set
1237# CONFIG_USB_FTDI_ELAN is not set
1238# CONFIG_USB_APPLEDISPLAY is not set
1239# CONFIG_USB_SISUSBVGA is not set
1240# CONFIG_USB_LD is not set
1241# CONFIG_USB_TRANCEVIBRATOR is not set
1242# CONFIG_USB_TEST is not set
1243
1244#
1245# USB DSL modem support
1246#
1247
1248#
1249# USB Gadget Support
1250#
1251# CONFIG_USB_GADGET is not set
1252
1253#
1254# MMC/SD Card support
1255#
1256# CONFIG_MMC is not set
1257
1258#
1259# LED devices
1260#
1261# CONFIG_NEW_LEDS is not set
1262
1263#
1264# LED drivers
1265#
1266
1267#
1268# LED Triggers
1269#
1270
1271#
1272# InfiniBand support
1273#
1274# CONFIG_INFINIBAND is not set
1275
1276#
1277# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
1278#
1279
1280#
1281# Real Time Clock
1282#
1283CONFIG_RTC_LIB=y
1284CONFIG_RTC_CLASS=y
1285CONFIG_RTC_HCTOSYS=y
1286CONFIG_RTC_HCTOSYS_DEVICE="rtc0"
1287# CONFIG_RTC_DEBUG is not set
1288
1289#
1290# RTC interfaces
1291#
1292CONFIG_RTC_INTF_SYSFS=y
1293CONFIG_RTC_INTF_PROC=y
1294CONFIG_RTC_INTF_DEV=y
1295# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set
1296
1297#
1298# RTC drivers
1299#
1300# CONFIG_RTC_DRV_X1205 is not set
1301# CONFIG_RTC_DRV_DS1307 is not set
1302# CONFIG_RTC_DRV_DS1553 is not set
1303# CONFIG_RTC_DRV_ISL1208 is not set
1304# CONFIG_RTC_DRV_DS1672 is not set
1305# CONFIG_RTC_DRV_DS1742 is not set
1306# CONFIG_RTC_DRV_PCF8563 is not set
1307# CONFIG_RTC_DRV_PCF8583 is not set
1308CONFIG_RTC_DRV_RS5C372=y
1309# CONFIG_RTC_DRV_M48T86 is not set
1310# CONFIG_RTC_DRV_TEST is not set
1311# CONFIG_RTC_DRV_V3020 is not set
1312
1313#
1314# DMA Engine support
1315#
1316# CONFIG_DMA_ENGINE is not set
1317
1318#
1319# DMA Clients
1320#
1321
1322#
1323# DMA Devices
1324#
1325
1326#
1327# File systems
1328#
1329CONFIG_EXT2_FS=y
1330# CONFIG_EXT2_FS_XATTR is not set
1331# CONFIG_EXT2_FS_XIP is not set
1332CONFIG_EXT3_FS=y
1333CONFIG_EXT3_FS_XATTR=y
1334# CONFIG_EXT3_FS_POSIX_ACL is not set
1335# CONFIG_EXT3_FS_SECURITY is not set
1336# CONFIG_EXT4DEV_FS is not set
1337CONFIG_JBD=y
1338# CONFIG_JBD_DEBUG is not set
1339CONFIG_FS_MBCACHE=y
1340# CONFIG_REISERFS_FS is not set
1341# CONFIG_JFS_FS is not set
1342CONFIG_FS_POSIX_ACL=y
1343# CONFIG_XFS_FS is not set
1344# CONFIG_GFS2_FS is not set
1345# CONFIG_OCFS2_FS is not set
1346# CONFIG_MINIX_FS is not set
1347# CONFIG_ROMFS_FS is not set
1348CONFIG_INOTIFY=y
1349CONFIG_INOTIFY_USER=y
1350# CONFIG_QUOTA is not set
1351CONFIG_DNOTIFY=y
1352# CONFIG_AUTOFS_FS is not set
1353# CONFIG_AUTOFS4_FS is not set
1354# CONFIG_FUSE_FS is not set
1355
1356#
1357# CD-ROM/DVD Filesystems
1358#
1359CONFIG_ISO9660_FS=m
1360CONFIG_JOLIET=y
1361CONFIG_ZISOFS=y
1362CONFIG_ZISOFS_FS=m
1363CONFIG_UDF_FS=m
1364CONFIG_UDF_NLS=y
1365
1366#
1367# DOS/FAT/NT Filesystems
1368#
1369CONFIG_FAT_FS=m
1370CONFIG_MSDOS_FS=m
1371CONFIG_VFAT_FS=m
1372CONFIG_FAT_DEFAULT_CODEPAGE=437
1373CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1374CONFIG_NTFS_FS=m
1375# CONFIG_NTFS_DEBUG is not set
1376# CONFIG_NTFS_RW is not set
1377
1378#
1379# Pseudo filesystems
1380#
1381CONFIG_PROC_FS=y
1382CONFIG_PROC_KCORE=y
1383CONFIG_PROC_SYSCTL=y
1384CONFIG_SYSFS=y
1385CONFIG_TMPFS=y
1386# CONFIG_TMPFS_POSIX_ACL is not set
1387# CONFIG_HUGETLB_PAGE is not set
1388CONFIG_RAMFS=y
1389# CONFIG_CONFIGFS_FS is not set
1390
1391#
1392# Miscellaneous filesystems
1393#
1394# CONFIG_ADFS_FS is not set
1395# CONFIG_AFFS_FS is not set
1396# CONFIG_HFS_FS is not set
1397# CONFIG_HFSPLUS_FS is not set
1398# CONFIG_BEFS_FS is not set
1399# CONFIG_BFS_FS is not set
1400# CONFIG_EFS_FS is not set
1401# CONFIG_JFFS_FS is not set
1402# CONFIG_JFFS2_FS is not set
1403# CONFIG_CRAMFS is not set
1404# CONFIG_VXFS_FS is not set
1405# CONFIG_HPFS_FS is not set
1406# CONFIG_QNX4FS_FS is not set
1407# CONFIG_SYSV_FS is not set
1408# CONFIG_UFS_FS is not set
1409
1410#
1411# Network File Systems
1412#
1413CONFIG_NFS_FS=y
1414CONFIG_NFS_V3=y
1415CONFIG_NFS_V3_ACL=y
1416CONFIG_NFS_V4=y
1417# CONFIG_NFS_DIRECTIO is not set
1418CONFIG_NFSD=m
1419CONFIG_NFSD_V3=y
1420# CONFIG_NFSD_V3_ACL is not set
1421# CONFIG_NFSD_V4 is not set
1422CONFIG_NFSD_TCP=y
1423CONFIG_ROOT_NFS=y
1424CONFIG_LOCKD=y
1425CONFIG_LOCKD_V4=y
1426CONFIG_EXPORTFS=m
1427CONFIG_NFS_ACL_SUPPORT=y
1428CONFIG_NFS_COMMON=y
1429CONFIG_SUNRPC=y
1430CONFIG_SUNRPC_GSS=y
1431CONFIG_RPCSEC_GSS_KRB5=y
1432# CONFIG_RPCSEC_GSS_SPKM3 is not set
1433# CONFIG_SMB_FS is not set
1434# CONFIG_CIFS is not set
1435# CONFIG_NCP_FS is not set
1436# CONFIG_CODA_FS is not set
1437# CONFIG_AFS_FS is not set
1438# CONFIG_9P_FS is not set
1439
1440#
1441# Partition Types
1442#
1443# CONFIG_PARTITION_ADVANCED is not set
1444CONFIG_MSDOS_PARTITION=y
1445
1446#
1447# Native Language Support
1448#
1449CONFIG_NLS=m
1450CONFIG_NLS_DEFAULT="iso8859-1"
1451CONFIG_NLS_CODEPAGE_437=m
1452# CONFIG_NLS_CODEPAGE_737 is not set
1453# CONFIG_NLS_CODEPAGE_775 is not set
1454# CONFIG_NLS_CODEPAGE_850 is not set
1455# CONFIG_NLS_CODEPAGE_852 is not set
1456# CONFIG_NLS_CODEPAGE_855 is not set
1457# CONFIG_NLS_CODEPAGE_857 is not set
1458# CONFIG_NLS_CODEPAGE_860 is not set
1459# CONFIG_NLS_CODEPAGE_861 is not set
1460# CONFIG_NLS_CODEPAGE_862 is not set
1461# CONFIG_NLS_CODEPAGE_863 is not set
1462# CONFIG_NLS_CODEPAGE_864 is not set
1463# CONFIG_NLS_CODEPAGE_865 is not set
1464# CONFIG_NLS_CODEPAGE_866 is not set
1465# CONFIG_NLS_CODEPAGE_869 is not set
1466# CONFIG_NLS_CODEPAGE_936 is not set
1467# CONFIG_NLS_CODEPAGE_950 is not set
1468# CONFIG_NLS_CODEPAGE_932 is not set
1469# CONFIG_NLS_CODEPAGE_949 is not set
1470# CONFIG_NLS_CODEPAGE_874 is not set
1471# CONFIG_NLS_ISO8859_8 is not set
1472# CONFIG_NLS_CODEPAGE_1250 is not set
1473# CONFIG_NLS_CODEPAGE_1251 is not set
1474# CONFIG_NLS_ASCII is not set
1475CONFIG_NLS_ISO8859_1=m
1476# CONFIG_NLS_ISO8859_2 is not set
1477# CONFIG_NLS_ISO8859_3 is not set
1478# CONFIG_NLS_ISO8859_4 is not set
1479# CONFIG_NLS_ISO8859_5 is not set
1480# CONFIG_NLS_ISO8859_6 is not set
1481# CONFIG_NLS_ISO8859_7 is not set
1482# CONFIG_NLS_ISO8859_9 is not set
1483# CONFIG_NLS_ISO8859_13 is not set
1484# CONFIG_NLS_ISO8859_14 is not set
1485# CONFIG_NLS_ISO8859_15 is not set
1486# CONFIG_NLS_KOI8_R is not set
1487# CONFIG_NLS_KOI8_U is not set
1488CONFIG_NLS_UTF8=m
1489
1490#
1491# Library routines
1492#
1493# CONFIG_CRC_CCITT is not set
1494# CONFIG_CRC16 is not set
1495CONFIG_CRC32=y
1496CONFIG_LIBCRC32C=m
1497CONFIG_ZLIB_INFLATE=m
1498CONFIG_ZLIB_DEFLATE=m
1499CONFIG_PLIST=y
1500
1501#
1502# Instrumentation Support
1503#
1504CONFIG_PROFILING=y
1505CONFIG_OPROFILE=m
1506
1507#
1508# Kernel hacking
1509#
1510# CONFIG_PRINTK_TIME is not set
1511CONFIG_ENABLE_MUST_CHECK=y
1512CONFIG_MAGIC_SYSRQ=y
1513# CONFIG_UNUSED_SYMBOLS is not set
1514CONFIG_DEBUG_KERNEL=y
1515CONFIG_LOG_BUF_SHIFT=14
1516CONFIG_DETECT_SOFTLOCKUP=y
1517# CONFIG_SCHEDSTATS is not set
1518# CONFIG_DEBUG_SLAB is not set
1519# CONFIG_DEBUG_RT_MUTEXES is not set
1520# CONFIG_RT_MUTEX_TESTER is not set
1521# CONFIG_DEBUG_SPINLOCK is not set
1522# CONFIG_DEBUG_MUTEXES is not set
1523# CONFIG_DEBUG_RWSEMS is not set
1524# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1525# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
1526# CONFIG_DEBUG_KOBJECT is not set
1527# CONFIG_DEBUG_INFO is not set
1528# CONFIG_DEBUG_FS is not set
1529# CONFIG_DEBUG_VM is not set
1530# CONFIG_DEBUG_LIST is not set
1531CONFIG_FORCED_INLINING=y
1532# CONFIG_HEADERS_CHECK is not set
1533# CONFIG_RCU_TORTURE_TEST is not set
1534# CONFIG_DEBUGGER is not set
1535# CONFIG_BDI_SWITCH is not set
1536# CONFIG_BOOTX_TEXT is not set
1537# CONFIG_SERIAL_TEXT_DEBUG is not set
1538# CONFIG_PPC_EARLY_DEBUG is not set
1539
1540#
1541# Security options
1542#
1543# CONFIG_KEYS is not set
1544# CONFIG_SECURITY is not set
1545
1546#
1547# Cryptographic options
1548#
1549CONFIG_CRYPTO=y
1550CONFIG_CRYPTO_ALGAPI=y
1551CONFIG_CRYPTO_BLKCIPHER=y
1552CONFIG_CRYPTO_MANAGER=y
1553# CONFIG_CRYPTO_HMAC is not set
1554# CONFIG_CRYPTO_NULL is not set
1555CONFIG_CRYPTO_MD4=m
1556CONFIG_CRYPTO_MD5=y
1557CONFIG_CRYPTO_SHA1=m
1558# CONFIG_CRYPTO_SHA256 is not set
1559# CONFIG_CRYPTO_SHA512 is not set
1560# CONFIG_CRYPTO_WP512 is not set
1561# CONFIG_CRYPTO_TGR192 is not set
1562CONFIG_CRYPTO_ECB=m
1563CONFIG_CRYPTO_CBC=y
1564CONFIG_CRYPTO_DES=y
1565CONFIG_CRYPTO_BLOWFISH=m
1566CONFIG_CRYPTO_TWOFISH=m
1567CONFIG_CRYPTO_TWOFISH_COMMON=m
1568CONFIG_CRYPTO_SERPENT=m
1569CONFIG_CRYPTO_AES=m
1570# CONFIG_CRYPTO_CAST5 is not set
1571# CONFIG_CRYPTO_CAST6 is not set
1572# CONFIG_CRYPTO_TEA is not set
1573CONFIG_CRYPTO_ARC4=m
1574# CONFIG_CRYPTO_KHAZAD is not set
1575# CONFIG_CRYPTO_ANUBIS is not set
1576CONFIG_CRYPTO_DEFLATE=m
1577CONFIG_CRYPTO_MICHAEL_MIC=m
1578CONFIG_CRYPTO_CRC32C=m
1579# CONFIG_CRYPTO_TEST is not set
1580
1581#
1582# Hardware crypto devices
1583#
diff --git a/arch/powerpc/configs/lite5200_defconfig b/arch/powerpc/configs/lite5200_defconfig
new file mode 100644
index 000000000000..ee7655776d45
--- /dev/null
+++ b/arch/powerpc/configs/lite5200_defconfig
@@ -0,0 +1,931 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.19-rc6
4# Mon Nov 27 11:08:20 2006
5#
6# CONFIG_PPC64 is not set
7CONFIG_PPC32=y
8CONFIG_PPC_MERGE=y
9CONFIG_MMU=y
10CONFIG_GENERIC_HARDIRQS=y
11CONFIG_IRQ_PER_CPU=y
12CONFIG_RWSEM_XCHGADD_ALGORITHM=y
13CONFIG_GENERIC_HWEIGHT=y
14CONFIG_GENERIC_CALIBRATE_DELAY=y
15CONFIG_GENERIC_FIND_NEXT_BIT=y
16CONFIG_PPC=y
17CONFIG_EARLY_PRINTK=y
18CONFIG_GENERIC_NVRAM=y
19CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
20CONFIG_ARCH_MAY_HAVE_PC_FDC=y
21CONFIG_PPC_OF=y
22# CONFIG_PPC_UDBG_16550 is not set
23# CONFIG_GENERIC_TBSYNC is not set
24CONFIG_AUDIT_ARCH=y
25# CONFIG_DEFAULT_UIMAGE is not set
26
27#
28# Processor support
29#
30CONFIG_CLASSIC32=y
31# CONFIG_PPC_52xx is not set
32# CONFIG_PPC_82xx is not set
33# CONFIG_PPC_83xx is not set
34# CONFIG_PPC_85xx is not set
35# CONFIG_PPC_86xx is not set
36# CONFIG_40x is not set
37# CONFIG_44x is not set
38# CONFIG_8xx is not set
39# CONFIG_E200 is not set
40CONFIG_6xx=y
41CONFIG_PPC_FPU=y
42# CONFIG_PPC_DCR_NATIVE is not set
43# CONFIG_PPC_DCR_MMIO is not set
44# CONFIG_ALTIVEC is not set
45CONFIG_PPC_STD_MMU=y
46CONFIG_PPC_STD_MMU_32=y
47# CONFIG_SMP is not set
48CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
49
50#
51# Code maturity level options
52#
53CONFIG_EXPERIMENTAL=y
54CONFIG_BROKEN_ON_SMP=y
55CONFIG_INIT_ENV_ARG_LIMIT=32
56
57#
58# General setup
59#
60CONFIG_LOCALVERSION=""
61CONFIG_LOCALVERSION_AUTO=y
62CONFIG_SWAP=y
63CONFIG_SYSVIPC=y
64# CONFIG_IPC_NS is not set
65# CONFIG_POSIX_MQUEUE is not set
66# CONFIG_BSD_PROCESS_ACCT is not set
67# CONFIG_TASKSTATS is not set
68# CONFIG_UTS_NS is not set
69# CONFIG_AUDIT is not set
70# CONFIG_IKCONFIG is not set
71# CONFIG_RELAY is not set
72CONFIG_INITRAMFS_SOURCE=""
73# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
74CONFIG_SYSCTL=y
75CONFIG_EMBEDDED=y
76# CONFIG_SYSCTL_SYSCALL is not set
77# CONFIG_KALLSYMS is not set
78CONFIG_HOTPLUG=y
79CONFIG_PRINTK=y
80CONFIG_BUG=y
81CONFIG_ELF_CORE=y
82CONFIG_BASE_FULL=y
83CONFIG_FUTEX=y
84# CONFIG_EPOLL is not set
85CONFIG_SHMEM=y
86CONFIG_SLAB=y
87CONFIG_VM_EVENT_COUNTERS=y
88CONFIG_RT_MUTEXES=y
89# CONFIG_TINY_SHMEM is not set
90CONFIG_BASE_SMALL=0
91# CONFIG_SLOB is not set
92
93#
94# Loadable module support
95#
96CONFIG_MODULES=y
97CONFIG_MODULE_UNLOAD=y
98# CONFIG_MODULE_FORCE_UNLOAD is not set
99# CONFIG_MODVERSIONS is not set
100# CONFIG_MODULE_SRCVERSION_ALL is not set
101# CONFIG_KMOD is not set
102
103#
104# Block layer
105#
106CONFIG_BLOCK=y
107# CONFIG_LBD is not set
108# CONFIG_BLK_DEV_IO_TRACE is not set
109# CONFIG_LSF is not set
110
111#
112# IO Schedulers
113#
114CONFIG_IOSCHED_NOOP=y
115CONFIG_IOSCHED_AS=y
116CONFIG_IOSCHED_DEADLINE=y
117CONFIG_IOSCHED_CFQ=y
118CONFIG_DEFAULT_AS=y
119# CONFIG_DEFAULT_DEADLINE is not set
120# CONFIG_DEFAULT_CFQ is not set
121# CONFIG_DEFAULT_NOOP is not set
122CONFIG_DEFAULT_IOSCHED="anticipatory"
123
124#
125# Platform support
126#
127CONFIG_PPC_MULTIPLATFORM=y
128# CONFIG_EMBEDDED6xx is not set
129# CONFIG_APUS is not set
130# CONFIG_PPC_CHRP is not set
131CONFIG_PPC_MPC52xx=y
132# CONFIG_PPC_EFIKA is not set
133CONFIG_PPC_LITE5200=y
134# CONFIG_PPC_PMAC is not set
135# CONFIG_PPC_CELL is not set
136# CONFIG_PPC_CELL_NATIVE is not set
137# CONFIG_PPC_RTAS is not set
138# CONFIG_MMIO_NVRAM is not set
139# CONFIG_PPC_MPC106 is not set
140# CONFIG_PPC_970_NAP is not set
141# CONFIG_PPC_INDIRECT_IO is not set
142# CONFIG_GENERIC_IOMAP is not set
143# CONFIG_CPU_FREQ is not set
144# CONFIG_TAU is not set
145# CONFIG_WANT_EARLY_SERIAL is not set
146# CONFIG_MPIC is not set
147
148#
149# Kernel options
150#
151# CONFIG_HIGHMEM is not set
152# CONFIG_HZ_100 is not set
153CONFIG_HZ_250=y
154# CONFIG_HZ_1000 is not set
155CONFIG_HZ=250
156CONFIG_PREEMPT_NONE=y
157# CONFIG_PREEMPT_VOLUNTARY is not set
158# CONFIG_PREEMPT is not set
159CONFIG_BINFMT_ELF=y
160# CONFIG_BINFMT_MISC is not set
161CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
162# CONFIG_KEXEC is not set
163CONFIG_ARCH_FLATMEM_ENABLE=y
164CONFIG_ARCH_POPULATES_NODE_MAP=y
165CONFIG_SELECT_MEMORY_MODEL=y
166CONFIG_FLATMEM_MANUAL=y
167# CONFIG_DISCONTIGMEM_MANUAL is not set
168# CONFIG_SPARSEMEM_MANUAL is not set
169CONFIG_FLATMEM=y
170CONFIG_FLAT_NODE_MEM_MAP=y
171# CONFIG_SPARSEMEM_STATIC is not set
172CONFIG_SPLIT_PTLOCK_CPUS=4
173# CONFIG_RESOURCES_64BIT is not set
174CONFIG_PROC_DEVICETREE=y
175# CONFIG_CMDLINE_BOOL is not set
176CONFIG_PM=y
177# CONFIG_PM_LEGACY is not set
178# CONFIG_PM_DEBUG is not set
179# CONFIG_PM_SYSFS_DEPRECATED is not set
180# CONFIG_SOFTWARE_SUSPEND is not set
181CONFIG_SECCOMP=y
182CONFIG_ISA_DMA_API=y
183
184#
185# Bus options
186#
187CONFIG_GENERIC_ISA_DMA=y
188# CONFIG_MPIC_WEIRD is not set
189# CONFIG_PPC_I8259 is not set
190# CONFIG_PPC_INDIRECT_PCI is not set
191CONFIG_PCI=y
192CONFIG_PCI_DOMAINS=y
193# CONFIG_PCIEPORTBUS is not set
194# CONFIG_PCI_DEBUG is not set
195
196#
197# PCCARD (PCMCIA/CardBus) support
198#
199# CONFIG_PCCARD is not set
200
201#
202# PCI Hotplug Support
203#
204# CONFIG_HOTPLUG_PCI is not set
205
206#
207# Advanced setup
208#
209# CONFIG_ADVANCED_OPTIONS is not set
210
211#
212# Default settings for advanced configuration options are used
213#
214CONFIG_HIGHMEM_START=0xfe000000
215CONFIG_LOWMEM_SIZE=0x30000000
216CONFIG_KERNEL_START=0xc0000000
217CONFIG_TASK_SIZE=0x80000000
218CONFIG_BOOT_LOAD=0x00800000
219
220#
221# Networking
222#
223CONFIG_NET=y
224
225#
226# Networking options
227#
228# CONFIG_NETDEBUG is not set
229CONFIG_PACKET=y
230# CONFIG_PACKET_MMAP is not set
231CONFIG_UNIX=y
232CONFIG_XFRM=y
233CONFIG_XFRM_USER=m
234# CONFIG_XFRM_SUB_POLICY is not set
235# CONFIG_NET_KEY is not set
236CONFIG_INET=y
237CONFIG_IP_MULTICAST=y
238# CONFIG_IP_ADVANCED_ROUTER is not set
239CONFIG_IP_FIB_HASH=y
240CONFIG_IP_PNP=y
241CONFIG_IP_PNP_DHCP=y
242CONFIG_IP_PNP_BOOTP=y
243# CONFIG_IP_PNP_RARP is not set
244# CONFIG_NET_IPIP is not set
245# CONFIG_NET_IPGRE is not set
246# CONFIG_IP_MROUTE is not set
247# CONFIG_ARPD is not set
248CONFIG_SYN_COOKIES=y
249# CONFIG_INET_AH is not set
250# CONFIG_INET_ESP is not set
251# CONFIG_INET_IPCOMP is not set
252# CONFIG_INET_XFRM_TUNNEL is not set
253# CONFIG_INET_TUNNEL is not set
254CONFIG_INET_XFRM_MODE_TRANSPORT=y
255CONFIG_INET_XFRM_MODE_TUNNEL=y
256CONFIG_INET_XFRM_MODE_BEET=y
257CONFIG_INET_DIAG=y
258CONFIG_INET_TCP_DIAG=y
259# CONFIG_TCP_CONG_ADVANCED is not set
260CONFIG_TCP_CONG_CUBIC=y
261CONFIG_DEFAULT_TCP_CONG="cubic"
262# CONFIG_IPV6 is not set
263# CONFIG_INET6_XFRM_TUNNEL is not set
264# CONFIG_INET6_TUNNEL is not set
265# CONFIG_NETWORK_SECMARK is not set
266# CONFIG_NETFILTER is not set
267
268#
269# DCCP Configuration (EXPERIMENTAL)
270#
271# CONFIG_IP_DCCP is not set
272
273#
274# SCTP Configuration (EXPERIMENTAL)
275#
276# CONFIG_IP_SCTP is not set
277
278#
279# TIPC Configuration (EXPERIMENTAL)
280#
281# CONFIG_TIPC is not set
282# CONFIG_ATM is not set
283# CONFIG_BRIDGE is not set
284# CONFIG_VLAN_8021Q is not set
285# CONFIG_DECNET is not set
286# CONFIG_LLC2 is not set
287# CONFIG_IPX is not set
288# CONFIG_ATALK is not set
289# CONFIG_X25 is not set
290# CONFIG_LAPB is not set
291# CONFIG_ECONET is not set
292# CONFIG_WAN_ROUTER is not set
293
294#
295# QoS and/or fair queueing
296#
297# CONFIG_NET_SCHED is not set
298
299#
300# Network testing
301#
302# CONFIG_NET_PKTGEN is not set
303# CONFIG_HAMRADIO is not set
304# CONFIG_IRDA is not set
305# CONFIG_BT is not set
306# CONFIG_IEEE80211 is not set
307
308#
309# Device Drivers
310#
311
312#
313# Generic Driver Options
314#
315CONFIG_STANDALONE=y
316CONFIG_PREVENT_FIRMWARE_BUILD=y
317# CONFIG_FW_LOADER is not set
318# CONFIG_DEBUG_DRIVER is not set
319# CONFIG_SYS_HYPERVISOR is not set
320
321#
322# Connector - unified userspace <-> kernelspace linker
323#
324# CONFIG_CONNECTOR is not set
325
326#
327# Memory Technology Devices (MTD)
328#
329# CONFIG_MTD is not set
330
331#
332# Parallel port support
333#
334# CONFIG_PARPORT is not set
335
336#
337# Plug and Play support
338#
339
340#
341# Block devices
342#
343# CONFIG_BLK_DEV_FD is not set
344# CONFIG_BLK_CPQ_DA is not set
345# CONFIG_BLK_CPQ_CISS_DA is not set
346# CONFIG_BLK_DEV_DAC960 is not set
347# CONFIG_BLK_DEV_UMEM is not set
348# CONFIG_BLK_DEV_COW_COMMON is not set
349CONFIG_BLK_DEV_LOOP=y
350# CONFIG_BLK_DEV_CRYPTOLOOP is not set
351# CONFIG_BLK_DEV_NBD is not set
352# CONFIG_BLK_DEV_SX8 is not set
353CONFIG_BLK_DEV_RAM=y
354CONFIG_BLK_DEV_RAM_COUNT=16
355CONFIG_BLK_DEV_RAM_SIZE=32768
356CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
357CONFIG_BLK_DEV_INITRD=y
358# CONFIG_CDROM_PKTCDVD is not set
359# CONFIG_ATA_OVER_ETH is not set
360
361#
362# Misc devices
363#
364# CONFIG_SGI_IOC4 is not set
365# CONFIG_TIFM_CORE is not set
366
367#
368# ATA/ATAPI/MFM/RLL support
369#
370# CONFIG_IDE is not set
371
372#
373# SCSI device support
374#
375# CONFIG_RAID_ATTRS is not set
376CONFIG_SCSI=y
377# CONFIG_SCSI_NETLINK is not set
378# CONFIG_SCSI_PROC_FS is not set
379
380#
381# SCSI support type (disk, tape, CD-ROM)
382#
383# CONFIG_BLK_DEV_SD is not set
384# CONFIG_CHR_DEV_ST is not set
385# CONFIG_CHR_DEV_OSST is not set
386# CONFIG_BLK_DEV_SR is not set
387# CONFIG_CHR_DEV_SG is not set
388# CONFIG_CHR_DEV_SCH is not set
389
390#
391# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
392#
393# CONFIG_SCSI_MULTI_LUN is not set
394# CONFIG_SCSI_CONSTANTS is not set
395# CONFIG_SCSI_LOGGING is not set
396
397#
398# SCSI Transports
399#
400# CONFIG_SCSI_SPI_ATTRS is not set
401# CONFIG_SCSI_FC_ATTRS is not set
402# CONFIG_SCSI_ISCSI_ATTRS is not set
403# CONFIG_SCSI_SAS_ATTRS is not set
404# CONFIG_SCSI_SAS_LIBSAS is not set
405
406#
407# SCSI low-level drivers
408#
409# CONFIG_ISCSI_TCP is not set
410# CONFIG_BLK_DEV_3W_XXXX_RAID is not set
411# CONFIG_SCSI_3W_9XXX is not set
412# CONFIG_SCSI_ACARD is not set
413# CONFIG_SCSI_AACRAID is not set
414# CONFIG_SCSI_AIC7XXX is not set
415# CONFIG_SCSI_AIC7XXX_OLD is not set
416# CONFIG_SCSI_AIC79XX is not set
417# CONFIG_SCSI_AIC94XX is not set
418# CONFIG_SCSI_DPT_I2O is not set
419# CONFIG_SCSI_ARCMSR is not set
420# CONFIG_MEGARAID_NEWGEN is not set
421# CONFIG_MEGARAID_LEGACY is not set
422# CONFIG_MEGARAID_SAS is not set
423# CONFIG_SCSI_HPTIOP is not set
424# CONFIG_SCSI_BUSLOGIC is not set
425# CONFIG_SCSI_DMX3191D is not set
426# CONFIG_SCSI_EATA is not set
427# CONFIG_SCSI_FUTURE_DOMAIN is not set
428# CONFIG_SCSI_GDTH is not set
429# CONFIG_SCSI_IPS is not set
430# CONFIG_SCSI_INITIO is not set
431# CONFIG_SCSI_INIA100 is not set
432# CONFIG_SCSI_STEX is not set
433# CONFIG_SCSI_SYM53C8XX_2 is not set
434# CONFIG_SCSI_IPR is not set
435# CONFIG_SCSI_QLOGIC_1280 is not set
436# CONFIG_SCSI_QLA_FC is not set
437# CONFIG_SCSI_QLA_ISCSI is not set
438# CONFIG_SCSI_LPFC is not set
439# CONFIG_SCSI_DC395x is not set
440# CONFIG_SCSI_DC390T is not set
441# CONFIG_SCSI_NSP32 is not set
442# CONFIG_SCSI_DEBUG is not set
443
444#
445# Serial ATA (prod) and Parallel ATA (experimental) drivers
446#
447CONFIG_ATA=y
448# CONFIG_SATA_AHCI is not set
449# CONFIG_SATA_SVW is not set
450# CONFIG_ATA_PIIX is not set
451# CONFIG_SATA_MV is not set
452# CONFIG_SATA_NV is not set
453# CONFIG_PDC_ADMA is not set
454# CONFIG_SATA_QSTOR is not set
455# CONFIG_SATA_PROMISE is not set
456# CONFIG_SATA_SX4 is not set
457# CONFIG_SATA_SIL is not set
458# CONFIG_SATA_SIL24 is not set
459# CONFIG_SATA_SIS is not set
460# CONFIG_SATA_ULI is not set
461# CONFIG_SATA_VIA is not set
462# CONFIG_SATA_VITESSE is not set
463# CONFIG_PATA_ALI is not set
464# CONFIG_PATA_AMD is not set
465# CONFIG_PATA_ARTOP is not set
466# CONFIG_PATA_ATIIXP is not set
467# CONFIG_PATA_CMD64X is not set
468# CONFIG_PATA_CS5520 is not set
469# CONFIG_PATA_CS5530 is not set
470# CONFIG_PATA_CYPRESS is not set
471# CONFIG_PATA_EFAR is not set
472# CONFIG_ATA_GENERIC is not set
473# CONFIG_PATA_HPT366 is not set
474# CONFIG_PATA_HPT37X is not set
475# CONFIG_PATA_HPT3X2N is not set
476# CONFIG_PATA_HPT3X3 is not set
477# CONFIG_PATA_IT821X is not set
478# CONFIG_PATA_JMICRON is not set
479# CONFIG_PATA_TRIFLEX is not set
480CONFIG_PATA_MPC52xx=y
481# CONFIG_PATA_MPIIX is not set
482# CONFIG_PATA_OLDPIIX is not set
483# CONFIG_PATA_NETCELL is not set
484# CONFIG_PATA_NS87410 is not set
485# CONFIG_PATA_OPTI is not set
486# CONFIG_PATA_OPTIDMA is not set
487# CONFIG_PATA_PDC_OLD is not set
488# CONFIG_PATA_RADISYS is not set
489# CONFIG_PATA_RZ1000 is not set
490# CONFIG_PATA_SC1200 is not set
491# CONFIG_PATA_SERVERWORKS is not set
492# CONFIG_PATA_PDC2027X is not set
493# CONFIG_PATA_SIL680 is not set
494# CONFIG_PATA_SIS is not set
495# CONFIG_PATA_VIA is not set
496# CONFIG_PATA_WINBOND is not set
497
498#
499# Multi-device support (RAID and LVM)
500#
501# CONFIG_MD is not set
502
503#
504# Fusion MPT device support
505#
506# CONFIG_FUSION is not set
507# CONFIG_FUSION_SPI is not set
508# CONFIG_FUSION_FC is not set
509# CONFIG_FUSION_SAS is not set
510
511#
512# IEEE 1394 (FireWire) support
513#
514# CONFIG_IEEE1394 is not set
515
516#
517# I2O device support
518#
519# CONFIG_I2O is not set
520
521#
522# Macintosh device drivers
523#
524# CONFIG_WINDFARM is not set
525
526#
527# Network device support
528#
529CONFIG_NETDEVICES=y
530# CONFIG_DUMMY is not set
531# CONFIG_BONDING is not set
532# CONFIG_EQUALIZER is not set
533# CONFIG_TUN is not set
534
535#
536# ARCnet devices
537#
538# CONFIG_ARCNET is not set
539
540#
541# PHY device support
542#
543
544#
545# Ethernet (10 or 100Mbit)
546#
547# CONFIG_NET_ETHERNET is not set
548
549#
550# Ethernet (1000 Mbit)
551#
552# CONFIG_ACENIC is not set
553# CONFIG_DL2K is not set
554# CONFIG_E1000 is not set
555# CONFIG_NS83820 is not set
556# CONFIG_HAMACHI is not set
557# CONFIG_YELLOWFIN is not set
558# CONFIG_R8169 is not set
559# CONFIG_SIS190 is not set
560# CONFIG_SKGE is not set
561# CONFIG_SKY2 is not set
562# CONFIG_SK98LIN is not set
563# CONFIG_TIGON3 is not set
564# CONFIG_BNX2 is not set
565# CONFIG_MV643XX_ETH is not set
566# CONFIG_QLA3XXX is not set
567
568#
569# Ethernet (10000 Mbit)
570#
571# CONFIG_CHELSIO_T1 is not set
572# CONFIG_IXGB is not set
573# CONFIG_S2IO is not set
574# CONFIG_MYRI10GE is not set
575
576#
577# Token Ring devices
578#
579# CONFIG_TR is not set
580
581#
582# Wireless LAN (non-hamradio)
583#
584# CONFIG_NET_RADIO is not set
585
586#
587# Wan interfaces
588#
589# CONFIG_WAN is not set
590# CONFIG_FDDI is not set
591# CONFIG_HIPPI is not set
592# CONFIG_PPP is not set
593# CONFIG_SLIP is not set
594# CONFIG_NET_FC is not set
595# CONFIG_SHAPER is not set
596# CONFIG_NETCONSOLE is not set
597# CONFIG_NETPOLL is not set
598# CONFIG_NET_POLL_CONTROLLER is not set
599
600#
601# ISDN subsystem
602#
603# CONFIG_ISDN is not set
604
605#
606# Telephony Support
607#
608# CONFIG_PHONE is not set
609
610#
611# Input device support
612#
613# CONFIG_INPUT is not set
614
615#
616# Hardware I/O ports
617#
618# CONFIG_SERIO is not set
619# CONFIG_GAMEPORT is not set
620
621#
622# Character devices
623#
624# CONFIG_VT is not set
625# CONFIG_SERIAL_NONSTANDARD is not set
626
627#
628# Serial drivers
629#
630# CONFIG_SERIAL_8250 is not set
631
632#
633# Non-8250 serial port support
634#
635CONFIG_SERIAL_CORE=y
636CONFIG_SERIAL_CORE_CONSOLE=y
637CONFIG_SERIAL_MPC52xx=y
638CONFIG_SERIAL_MPC52xx_CONSOLE=y
639CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD=9600
640# CONFIG_SERIAL_JSM is not set
641CONFIG_UNIX98_PTYS=y
642CONFIG_LEGACY_PTYS=y
643CONFIG_LEGACY_PTY_COUNT=256
644
645#
646# IPMI
647#
648# CONFIG_IPMI_HANDLER is not set
649
650#
651# Watchdog Cards
652#
653# CONFIG_WATCHDOG is not set
654# CONFIG_HW_RANDOM is not set
655# CONFIG_NVRAM is not set
656# CONFIG_GEN_RTC is not set
657# CONFIG_DTLK is not set
658# CONFIG_R3964 is not set
659# CONFIG_APPLICOM is not set
660
661#
662# Ftape, the floppy tape device driver
663#
664# CONFIG_AGP is not set
665# CONFIG_DRM is not set
666# CONFIG_RAW_DRIVER is not set
667
668#
669# TPM devices
670#
671# CONFIG_TCG_TPM is not set
672
673#
674# I2C support
675#
676# CONFIG_I2C is not set
677
678#
679# SPI support
680#
681# CONFIG_SPI is not set
682# CONFIG_SPI_MASTER is not set
683
684#
685# Dallas's 1-wire bus
686#
687# CONFIG_W1 is not set
688
689#
690# Hardware Monitoring support
691#
692# CONFIG_HWMON is not set
693# CONFIG_HWMON_VID is not set
694
695#
696# Multimedia devices
697#
698# CONFIG_VIDEO_DEV is not set
699
700#
701# Digital Video Broadcasting Devices
702#
703# CONFIG_DVB is not set
704
705#
706# Graphics support
707#
708# CONFIG_FIRMWARE_EDID is not set
709# CONFIG_FB is not set
710# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
711
712#
713# Sound
714#
715# CONFIG_SOUND is not set
716
717#
718# USB support
719#
720CONFIG_USB_ARCH_HAS_HCD=y
721CONFIG_USB_ARCH_HAS_OHCI=y
722CONFIG_USB_ARCH_HAS_EHCI=y
723# CONFIG_USB is not set
724
725#
726# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
727#
728
729#
730# USB Gadget Support
731#
732# CONFIG_USB_GADGET is not set
733
734#
735# MMC/SD Card support
736#
737# CONFIG_MMC is not set
738
739#
740# LED devices
741#
742# CONFIG_NEW_LEDS is not set
743
744#
745# LED drivers
746#
747
748#
749# LED Triggers
750#
751
752#
753# InfiniBand support
754#
755# CONFIG_INFINIBAND is not set
756
757#
758# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
759#
760
761#
762# Real Time Clock
763#
764# CONFIG_RTC_CLASS is not set
765
766#
767# DMA Engine support
768#
769# CONFIG_DMA_ENGINE is not set
770
771#
772# DMA Clients
773#
774
775#
776# DMA Devices
777#
778
779#
780# File systems
781#
782CONFIG_EXT2_FS=y
783# CONFIG_EXT2_FS_XATTR is not set
784# CONFIG_EXT2_FS_XIP is not set
785CONFIG_EXT3_FS=y
786CONFIG_EXT3_FS_XATTR=y
787# CONFIG_EXT3_FS_POSIX_ACL is not set
788# CONFIG_EXT3_FS_SECURITY is not set
789# CONFIG_EXT4DEV_FS is not set
790CONFIG_JBD=y
791# CONFIG_JBD_DEBUG is not set
792CONFIG_FS_MBCACHE=y
793# CONFIG_REISERFS_FS is not set
794# CONFIG_JFS_FS is not set
795# CONFIG_FS_POSIX_ACL is not set
796# CONFIG_XFS_FS is not set
797# CONFIG_GFS2_FS is not set
798# CONFIG_OCFS2_FS is not set
799# CONFIG_MINIX_FS is not set
800# CONFIG_ROMFS_FS is not set
801CONFIG_INOTIFY=y
802CONFIG_INOTIFY_USER=y
803# CONFIG_QUOTA is not set
804CONFIG_DNOTIFY=y
805# CONFIG_AUTOFS_FS is not set
806# CONFIG_AUTOFS4_FS is not set
807# CONFIG_FUSE_FS is not set
808
809#
810# CD-ROM/DVD Filesystems
811#
812# CONFIG_ISO9660_FS is not set
813# CONFIG_UDF_FS is not set
814
815#
816# DOS/FAT/NT Filesystems
817#
818# CONFIG_MSDOS_FS is not set
819# CONFIG_VFAT_FS is not set
820# CONFIG_NTFS_FS is not set
821
822#
823# Pseudo filesystems
824#
825CONFIG_PROC_FS=y
826CONFIG_PROC_KCORE=y
827CONFIG_PROC_SYSCTL=y
828CONFIG_SYSFS=y
829CONFIG_TMPFS=y
830# CONFIG_TMPFS_POSIX_ACL is not set
831# CONFIG_HUGETLB_PAGE is not set
832CONFIG_RAMFS=y
833# CONFIG_CONFIGFS_FS is not set
834
835#
836# Miscellaneous filesystems
837#
838# CONFIG_ADFS_FS is not set
839# CONFIG_AFFS_FS is not set
840# CONFIG_HFS_FS is not set
841# CONFIG_HFSPLUS_FS is not set
842# CONFIG_BEFS_FS is not set
843# CONFIG_BFS_FS is not set
844# CONFIG_EFS_FS is not set
845# CONFIG_CRAMFS is not set
846# CONFIG_VXFS_FS is not set
847# CONFIG_HPFS_FS is not set
848# CONFIG_QNX4FS_FS is not set
849# CONFIG_SYSV_FS is not set
850# CONFIG_UFS_FS is not set
851
852#
853# Network File Systems
854#
855# CONFIG_NFS_FS is not set
856# CONFIG_NFSD is not set
857# CONFIG_SMB_FS is not set
858# CONFIG_CIFS is not set
859# CONFIG_NCP_FS is not set
860# CONFIG_CODA_FS is not set
861# CONFIG_AFS_FS is not set
862# CONFIG_9P_FS is not set
863
864#
865# Partition Types
866#
867# CONFIG_PARTITION_ADVANCED is not set
868CONFIG_MSDOS_PARTITION=y
869
870#
871# Native Language Support
872#
873# CONFIG_NLS is not set
874
875#
876# Library routines
877#
878# CONFIG_CRC_CCITT is not set
879# CONFIG_CRC16 is not set
880# CONFIG_CRC32 is not set
881# CONFIG_LIBCRC32C is not set
882CONFIG_PLIST=y
883
884#
885# Instrumentation Support
886#
887# CONFIG_PROFILING is not set
888
889#
890# Kernel hacking
891#
892CONFIG_PRINTK_TIME=y
893CONFIG_ENABLE_MUST_CHECK=y
894# CONFIG_MAGIC_SYSRQ is not set
895# CONFIG_UNUSED_SYMBOLS is not set
896CONFIG_DEBUG_KERNEL=y
897CONFIG_LOG_BUF_SHIFT=14
898CONFIG_DETECT_SOFTLOCKUP=y
899# CONFIG_SCHEDSTATS is not set
900# CONFIG_DEBUG_SLAB is not set
901# CONFIG_DEBUG_RT_MUTEXES is not set
902# CONFIG_RT_MUTEX_TESTER is not set
903# CONFIG_DEBUG_SPINLOCK is not set
904# CONFIG_DEBUG_MUTEXES is not set
905# CONFIG_DEBUG_RWSEMS is not set
906# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
907# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
908# CONFIG_DEBUG_KOBJECT is not set
909CONFIG_DEBUG_INFO=y
910# CONFIG_DEBUG_FS is not set
911# CONFIG_DEBUG_VM is not set
912# CONFIG_DEBUG_LIST is not set
913CONFIG_FORCED_INLINING=y
914# CONFIG_HEADERS_CHECK is not set
915# CONFIG_RCU_TORTURE_TEST is not set
916# CONFIG_DEBUGGER is not set
917# CONFIG_BDI_SWITCH is not set
918# CONFIG_BOOTX_TEXT is not set
919# CONFIG_SERIAL_TEXT_DEBUG is not set
920# CONFIG_PPC_EARLY_DEBUG is not set
921
922#
923# Security options
924#
925# CONFIG_KEYS is not set
926# CONFIG_SECURITY is not set
927
928#
929# Cryptographic options
930#
931# CONFIG_CRYPTO is not set
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index be11df7c11aa..1c009651f925 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -1386,8 +1386,8 @@ CONFIG_INOTIFY=y
1386CONFIG_INOTIFY_USER=y 1386CONFIG_INOTIFY_USER=y
1387# CONFIG_QUOTA is not set 1387# CONFIG_QUOTA is not set
1388CONFIG_DNOTIFY=y 1388CONFIG_DNOTIFY=y
1389CONFIG_AUTOFS_FS=y 1389# CONFIG_AUTOFS_FS is not set
1390# CONFIG_AUTOFS4_FS is not set 1390CONFIG_AUTOFS4_FS=m
1391# CONFIG_FUSE_FS is not set 1391# CONFIG_FUSE_FS is not set
1392 1392
1393# 1393#
diff --git a/arch/powerpc/configs/ps3_defconfig b/arch/powerpc/configs/ps3_defconfig
new file mode 100644
index 000000000000..f2d888e014a9
--- /dev/null
+++ b/arch/powerpc/configs/ps3_defconfig
@@ -0,0 +1,837 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.19-rc6
4# Tue Nov 21 19:38:53 2006
5#
6CONFIG_PPC64=y
7CONFIG_64BIT=y
8CONFIG_PPC_MERGE=y
9CONFIG_MMU=y
10CONFIG_GENERIC_HARDIRQS=y
11CONFIG_IRQ_PER_CPU=y
12CONFIG_RWSEM_XCHGADD_ALGORITHM=y
13CONFIG_GENERIC_HWEIGHT=y
14CONFIG_GENERIC_CALIBRATE_DELAY=y
15CONFIG_GENERIC_FIND_NEXT_BIT=y
16CONFIG_PPC=y
17CONFIG_EARLY_PRINTK=y
18CONFIG_COMPAT=y
19CONFIG_SYSVIPC_COMPAT=y
20CONFIG_SCHED_NO_NO_OMIT_FRAME_POINTER=y
21CONFIG_ARCH_MAY_HAVE_PC_FDC=y
22CONFIG_PPC_OF=y
23# CONFIG_PPC_UDBG_16550 is not set
24# CONFIG_GENERIC_TBSYNC is not set
25CONFIG_AUDIT_ARCH=y
26# CONFIG_DEFAULT_UIMAGE is not set
27
28#
29# Processor support
30#
31# CONFIG_POWER4_ONLY is not set
32CONFIG_POWER3=y
33CONFIG_POWER4=y
34CONFIG_PPC_FPU=y
35# CONFIG_PPC_DCR_NATIVE is not set
36# CONFIG_PPC_DCR_MMIO is not set
37# CONFIG_PPC_OF_PLATFORM_PCI is not set
38CONFIG_ALTIVEC=y
39CONFIG_PPC_STD_MMU=y
40CONFIG_VIRT_CPU_ACCOUNTING=y
41CONFIG_SMP=y
42CONFIG_NR_CPUS=2
43CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
44
45#
46# Code maturity level options
47#
48CONFIG_EXPERIMENTAL=y
49CONFIG_LOCK_KERNEL=y
50CONFIG_INIT_ENV_ARG_LIMIT=32
51
52#
53# General setup
54#
55CONFIG_LOCALVERSION=""
56CONFIG_LOCALVERSION_AUTO=y
57CONFIG_SWAP=y
58CONFIG_SYSVIPC=y
59# CONFIG_IPC_NS is not set
60# CONFIG_POSIX_MQUEUE is not set
61# CONFIG_BSD_PROCESS_ACCT is not set
62# CONFIG_TASKSTATS is not set
63# CONFIG_UTS_NS is not set
64# CONFIG_AUDIT is not set
65# CONFIG_IKCONFIG is not set
66# CONFIG_CPUSETS is not set
67# CONFIG_RELAY is not set
68CONFIG_INITRAMFS_SOURCE=""
69# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
70CONFIG_SYSCTL=y
71CONFIG_EMBEDDED=y
72# CONFIG_SYSCTL_SYSCALL is not set
73CONFIG_KALLSYMS=y
74CONFIG_KALLSYMS_ALL=y
75CONFIG_KALLSYMS_EXTRA_PASS=y
76CONFIG_HOTPLUG=y
77CONFIG_PRINTK=y
78CONFIG_BUG=y
79CONFIG_ELF_CORE=y
80CONFIG_BASE_FULL=y
81CONFIG_FUTEX=y
82CONFIG_EPOLL=y
83CONFIG_SHMEM=y
84CONFIG_SLAB=y
85CONFIG_VM_EVENT_COUNTERS=y
86CONFIG_RT_MUTEXES=y
87# CONFIG_TINY_SHMEM is not set
88CONFIG_BASE_SMALL=0
89# CONFIG_SLOB is not set
90
91#
92# Loadable module support
93#
94CONFIG_MODULES=y
95CONFIG_MODULE_UNLOAD=y
96# CONFIG_MODULE_FORCE_UNLOAD is not set
97# CONFIG_MODVERSIONS is not set
98# CONFIG_MODULE_SRCVERSION_ALL is not set
99CONFIG_KMOD=y
100CONFIG_STOP_MACHINE=y
101
102#
103# Block layer
104#
105CONFIG_BLOCK=y
106# CONFIG_BLK_DEV_IO_TRACE is not set
107
108#
109# IO Schedulers
110#
111CONFIG_IOSCHED_NOOP=y
112CONFIG_IOSCHED_AS=y
113CONFIG_IOSCHED_DEADLINE=y
114CONFIG_IOSCHED_CFQ=y
115CONFIG_DEFAULT_AS=y
116# CONFIG_DEFAULT_DEADLINE is not set
117# CONFIG_DEFAULT_CFQ is not set
118# CONFIG_DEFAULT_NOOP is not set
119CONFIG_DEFAULT_IOSCHED="anticipatory"
120
121#
122# Platform support
123#
124CONFIG_PPC_MULTIPLATFORM=y
125# CONFIG_EMBEDDED6xx is not set
126# CONFIG_APUS is not set
127# CONFIG_PPC_PSERIES is not set
128# CONFIG_PPC_ISERIES is not set
129# CONFIG_PPC_PMAC is not set
130# CONFIG_PPC_MAPLE is not set
131# CONFIG_PPC_PASEMI is not set
132CONFIG_PPC_CELL=y
133# CONFIG_PPC_CELL_NATIVE is not set
134# CONFIG_PPC_IBM_CELL_BLADE is not set
135CONFIG_PPC_PS3=y
136# CONFIG_U3_DART is not set
137# CONFIG_PPC_RTAS is not set
138# CONFIG_MMIO_NVRAM is not set
139# CONFIG_PPC_MPC106 is not set
140# CONFIG_PPC_970_NAP is not set
141# CONFIG_PPC_INDIRECT_IO is not set
142# CONFIG_GENERIC_IOMAP is not set
143# CONFIG_CPU_FREQ is not set
144# CONFIG_WANT_EARLY_SERIAL is not set
145# CONFIG_MPIC is not set
146
147#
148# Cell Broadband Engine options
149#
150CONFIG_SPU_FS=y
151CONFIG_SPU_BASE=y
152# CONFIG_CBE_RAS is not set
153
154#
155# PS3 Platform Options
156#
157CONFIG_PS3_HTAB_SIZE=20
158CONFIG_PS3_DYNAMIC_DMA=y
159CONFIG_PS3_USE_LPAR_ADDR=y
160
161#
162# Kernel options
163#
164# CONFIG_HZ_100 is not set
165CONFIG_HZ_250=y
166# CONFIG_HZ_1000 is not set
167CONFIG_HZ=250
168CONFIG_PREEMPT_NONE=y
169# CONFIG_PREEMPT_VOLUNTARY is not set
170# CONFIG_PREEMPT is not set
171# CONFIG_PREEMPT_BKL is not set
172CONFIG_BINFMT_ELF=y
173CONFIG_BINFMT_MISC=y
174CONFIG_FORCE_MAX_ZONEORDER=9
175# CONFIG_IOMMU_VMERGE is not set
176CONFIG_ARCH_ENABLE_MEMORY_HOTPLUG=y
177# CONFIG_KEXEC is not set
178# CONFIG_CRASH_DUMP is not set
179# CONFIG_IRQ_ALL_CPUS is not set
180# CONFIG_NUMA is not set
181CONFIG_ARCH_SELECT_MEMORY_MODEL=y
182CONFIG_ARCH_FLATMEM_ENABLE=y
183CONFIG_ARCH_SPARSEMEM_ENABLE=y
184CONFIG_ARCH_SPARSEMEM_DEFAULT=y
185CONFIG_ARCH_POPULATES_NODE_MAP=y
186CONFIG_SELECT_MEMORY_MODEL=y
187# CONFIG_FLATMEM_MANUAL is not set
188# CONFIG_DISCONTIGMEM_MANUAL is not set
189CONFIG_SPARSEMEM_MANUAL=y
190CONFIG_SPARSEMEM=y
191CONFIG_HAVE_MEMORY_PRESENT=y
192# CONFIG_SPARSEMEM_STATIC is not set
193CONFIG_SPARSEMEM_EXTREME=y
194CONFIG_MEMORY_HOTPLUG=y
195CONFIG_MEMORY_HOTPLUG_SPARSE=y
196CONFIG_SPLIT_PTLOCK_CPUS=4
197CONFIG_RESOURCES_64BIT=y
198CONFIG_ARCH_MEMORY_PROBE=y
199CONFIG_PPC_64K_PAGES=y
200# CONFIG_SCHED_SMT is not set
201CONFIG_PROC_DEVICETREE=y
202CONFIG_CMDLINE_BOOL=y
203CONFIG_CMDLINE="root=/dev/nfs rw ip=dhcp"
204# CONFIG_PM is not set
205# CONFIG_SECCOMP is not set
206CONFIG_ISA_DMA_API=y
207
208#
209# Bus options
210#
211CONFIG_GENERIC_ISA_DMA=y
212# CONFIG_MPIC_WEIRD is not set
213# CONFIG_PPC_I8259 is not set
214# CONFIG_PCI is not set
215# CONFIG_PCI_DOMAINS is not set
216
217#
218# PCCARD (PCMCIA/CardBus) support
219#
220# CONFIG_PCCARD is not set
221
222#
223# PCI Hotplug Support
224#
225CONFIG_KERNEL_START=0xc000000000000000
226
227#
228# Networking
229#
230CONFIG_NET=y
231
232#
233# Networking options
234#
235# CONFIG_NETDEBUG is not set
236# CONFIG_PACKET is not set
237CONFIG_UNIX=y
238# CONFIG_NET_KEY is not set
239CONFIG_INET=y
240# CONFIG_IP_MULTICAST is not set
241# CONFIG_IP_ADVANCED_ROUTER is not set
242CONFIG_IP_FIB_HASH=y
243CONFIG_IP_PNP=y
244CONFIG_IP_PNP_DHCP=y
245# CONFIG_IP_PNP_BOOTP is not set
246# CONFIG_IP_PNP_RARP is not set
247# CONFIG_NET_IPIP is not set
248# CONFIG_NET_IPGRE is not set
249# CONFIG_ARPD is not set
250# CONFIG_SYN_COOKIES is not set
251# CONFIG_INET_AH is not set
252# CONFIG_INET_ESP is not set
253# CONFIG_INET_IPCOMP is not set
254# CONFIG_INET_XFRM_TUNNEL is not set
255# CONFIG_INET_TUNNEL is not set
256# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
257# CONFIG_INET_XFRM_MODE_TUNNEL is not set
258# CONFIG_INET_XFRM_MODE_BEET is not set
259# CONFIG_INET_DIAG is not set
260# CONFIG_TCP_CONG_ADVANCED is not set
261CONFIG_TCP_CONG_CUBIC=y
262CONFIG_DEFAULT_TCP_CONG="cubic"
263# CONFIG_IPV6 is not set
264# CONFIG_INET6_XFRM_TUNNEL is not set
265# CONFIG_INET6_TUNNEL is not set
266# CONFIG_NETWORK_SECMARK is not set
267# CONFIG_NETFILTER is not set
268
269#
270# DCCP Configuration (EXPERIMENTAL)
271#
272# CONFIG_IP_DCCP is not set
273
274#
275# SCTP Configuration (EXPERIMENTAL)
276#
277# CONFIG_IP_SCTP is not set
278
279#
280# TIPC Configuration (EXPERIMENTAL)
281#
282# CONFIG_TIPC is not set
283# CONFIG_ATM is not set
284# CONFIG_BRIDGE is not set
285# CONFIG_VLAN_8021Q is not set
286# CONFIG_DECNET is not set
287# CONFIG_LLC2 is not set
288# CONFIG_IPX is not set
289# CONFIG_ATALK is not set
290# CONFIG_X25 is not set
291# CONFIG_LAPB is not set
292# CONFIG_ECONET is not set
293# CONFIG_WAN_ROUTER is not set
294
295#
296# QoS and/or fair queueing
297#
298# CONFIG_NET_SCHED is not set
299
300#
301# Network testing
302#
303# CONFIG_NET_PKTGEN is not set
304# CONFIG_HAMRADIO is not set
305# CONFIG_IRDA is not set
306# CONFIG_BT is not set
307# CONFIG_IEEE80211 is not set
308
309#
310# Device Drivers
311#
312
313#
314# Generic Driver Options
315#
316CONFIG_STANDALONE=y
317CONFIG_PREVENT_FIRMWARE_BUILD=y
318# CONFIG_FW_LOADER is not set
319# CONFIG_DEBUG_DRIVER is not set
320# CONFIG_SYS_HYPERVISOR is not set
321
322#
323# Connector - unified userspace <-> kernelspace linker
324#
325# CONFIG_CONNECTOR is not set
326
327#
328# Memory Technology Devices (MTD)
329#
330# CONFIG_MTD is not set
331
332#
333# Parallel port support
334#
335# CONFIG_PARPORT is not set
336
337#
338# Plug and Play support
339#
340
341#
342# Block devices
343#
344# CONFIG_BLK_DEV_FD is not set
345# CONFIG_BLK_DEV_COW_COMMON is not set
346# CONFIG_BLK_DEV_LOOP is not set
347# CONFIG_BLK_DEV_NBD is not set
348# CONFIG_BLK_DEV_RAM is not set
349# CONFIG_BLK_DEV_INITRD is not set
350# CONFIG_CDROM_PKTCDVD is not set
351# CONFIG_ATA_OVER_ETH is not set
352
353#
354# Misc devices
355#
356# CONFIG_TIFM_CORE is not set
357
358#
359# ATA/ATAPI/MFM/RLL support
360#
361# CONFIG_IDE is not set
362
363#
364# SCSI device support
365#
366# CONFIG_RAID_ATTRS is not set
367CONFIG_SCSI=y
368# CONFIG_SCSI_NETLINK is not set
369CONFIG_SCSI_PROC_FS=y
370
371#
372# SCSI support type (disk, tape, CD-ROM)
373#
374# CONFIG_BLK_DEV_SD is not set
375# CONFIG_CHR_DEV_ST is not set
376# CONFIG_CHR_DEV_OSST is not set
377# CONFIG_BLK_DEV_SR is not set
378# CONFIG_CHR_DEV_SG is not set
379# CONFIG_CHR_DEV_SCH is not set
380
381#
382# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
383#
384# CONFIG_SCSI_MULTI_LUN is not set
385# CONFIG_SCSI_CONSTANTS is not set
386# CONFIG_SCSI_LOGGING is not set
387
388#
389# SCSI Transports
390#
391# CONFIG_SCSI_SPI_ATTRS is not set
392# CONFIG_SCSI_FC_ATTRS is not set
393# CONFIG_SCSI_ISCSI_ATTRS is not set
394# CONFIG_SCSI_SAS_ATTRS is not set
395# CONFIG_SCSI_SAS_LIBSAS is not set
396
397#
398# SCSI low-level drivers
399#
400# CONFIG_ISCSI_TCP is not set
401# CONFIG_SCSI_DEBUG is not set
402
403#
404# Serial ATA (prod) and Parallel ATA (experimental) drivers
405#
406# CONFIG_ATA is not set
407
408#
409# Multi-device support (RAID and LVM)
410#
411# CONFIG_MD is not set
412
413#
414# Fusion MPT device support
415#
416# CONFIG_FUSION is not set
417
418#
419# IEEE 1394 (FireWire) support
420#
421
422#
423# I2O device support
424#
425
426#
427# Macintosh device drivers
428#
429# CONFIG_WINDFARM is not set
430
431#
432# Network device support
433#
434CONFIG_NETDEVICES=y
435# CONFIG_DUMMY is not set
436# CONFIG_BONDING is not set
437# CONFIG_EQUALIZER is not set
438# CONFIG_TUN is not set
439
440#
441# PHY device support
442#
443
444#
445# Ethernet (10 or 100Mbit)
446#
447# CONFIG_NET_ETHERNET is not set
448
449#
450# Ethernet (1000 Mbit)
451#
452
453#
454# Ethernet (10000 Mbit)
455#
456
457#
458# Token Ring devices
459#
460
461#
462# Wireless LAN (non-hamradio)
463#
464# CONFIG_NET_RADIO is not set
465
466#
467# Wan interfaces
468#
469# CONFIG_WAN is not set
470# CONFIG_PPP is not set
471# CONFIG_SLIP is not set
472# CONFIG_SHAPER is not set
473# CONFIG_NETCONSOLE is not set
474# CONFIG_NETPOLL is not set
475# CONFIG_NET_POLL_CONTROLLER is not set
476
477#
478# ISDN subsystem
479#
480# CONFIG_ISDN is not set
481
482#
483# Telephony Support
484#
485# CONFIG_PHONE is not set
486
487#
488# Input device support
489#
490CONFIG_INPUT=y
491# CONFIG_INPUT_FF_MEMLESS is not set
492
493#
494# Userland interfaces
495#
496# CONFIG_INPUT_MOUSEDEV is not set
497# CONFIG_INPUT_JOYDEV is not set
498# CONFIG_INPUT_TSDEV is not set
499CONFIG_INPUT_EVDEV=y
500# CONFIG_INPUT_EVBUG is not set
501
502#
503# Input Device Drivers
504#
505# CONFIG_INPUT_KEYBOARD is not set
506# CONFIG_INPUT_MOUSE is not set
507# CONFIG_INPUT_JOYSTICK is not set
508# CONFIG_INPUT_TOUCHSCREEN is not set
509# CONFIG_INPUT_MISC is not set
510
511#
512# Hardware I/O ports
513#
514# CONFIG_SERIO is not set
515# CONFIG_GAMEPORT is not set
516
517#
518# Character devices
519#
520CONFIG_VT=y
521CONFIG_VT_CONSOLE=y
522CONFIG_HW_CONSOLE=y
523# CONFIG_VT_HW_CONSOLE_BINDING is not set
524# CONFIG_SERIAL_NONSTANDARD is not set
525
526#
527# Serial drivers
528#
529# CONFIG_SERIAL_8250 is not set
530
531#
532# Non-8250 serial port support
533#
534CONFIG_UNIX98_PTYS=y
535# CONFIG_LEGACY_PTYS is not set
536
537#
538# IPMI
539#
540# CONFIG_IPMI_HANDLER is not set
541
542#
543# Watchdog Cards
544#
545# CONFIG_WATCHDOG is not set
546# CONFIG_HW_RANDOM is not set
547CONFIG_GEN_RTC=y
548# CONFIG_GEN_RTC_X is not set
549# CONFIG_DTLK is not set
550# CONFIG_R3964 is not set
551
552#
553# Ftape, the floppy tape device driver
554#
555# CONFIG_RAW_DRIVER is not set
556# CONFIG_HANGCHECK_TIMER is not set
557
558#
559# TPM devices
560#
561# CONFIG_TCG_TPM is not set
562
563#
564# I2C support
565#
566# CONFIG_I2C is not set
567
568#
569# SPI support
570#
571# CONFIG_SPI is not set
572# CONFIG_SPI_MASTER is not set
573
574#
575# Dallas's 1-wire bus
576#
577# CONFIG_W1 is not set
578
579#
580# Hardware Monitoring support
581#
582# CONFIG_HWMON is not set
583# CONFIG_HWMON_VID is not set
584
585#
586# Multimedia devices
587#
588# CONFIG_VIDEO_DEV is not set
589
590#
591# Digital Video Broadcasting Devices
592#
593# CONFIG_DVB is not set
594
595#
596# Graphics support
597#
598# CONFIG_FIRMWARE_EDID is not set
599# CONFIG_FB is not set
600
601#
602# Console display driver support
603#
604# CONFIG_VGA_CONSOLE is not set
605CONFIG_DUMMY_CONSOLE=y
606# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
607
608#
609# Sound
610#
611# CONFIG_SOUND is not set
612
613#
614# USB support
615#
616# CONFIG_USB_ARCH_HAS_HCD is not set
617# CONFIG_USB_ARCH_HAS_OHCI is not set
618# CONFIG_USB_ARCH_HAS_EHCI is not set
619
620#
621# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
622#
623
624#
625# USB Gadget Support
626#
627# CONFIG_USB_GADGET is not set
628
629#
630# MMC/SD Card support
631#
632# CONFIG_MMC is not set
633
634#
635# LED devices
636#
637# CONFIG_NEW_LEDS is not set
638
639#
640# LED drivers
641#
642
643#
644# LED Triggers
645#
646
647#
648# InfiniBand support
649#
650
651#
652# EDAC - error detection and reporting (RAS) (EXPERIMENTAL)
653#
654
655#
656# Real Time Clock
657#
658# CONFIG_RTC_CLASS is not set
659
660#
661# DMA Engine support
662#
663# CONFIG_DMA_ENGINE is not set
664
665#
666# DMA Clients
667#
668
669#
670# DMA Devices
671#
672
673#
674# File systems
675#
676# CONFIG_EXT2_FS is not set
677# CONFIG_EXT3_FS is not set
678# CONFIG_EXT4DEV_FS is not set
679# CONFIG_REISERFS_FS is not set
680# CONFIG_JFS_FS is not set
681# CONFIG_FS_POSIX_ACL is not set
682# CONFIG_XFS_FS is not set
683# CONFIG_GFS2_FS is not set
684# CONFIG_OCFS2_FS is not set
685# CONFIG_MINIX_FS is not set
686# CONFIG_ROMFS_FS is not set
687CONFIG_INOTIFY=y
688CONFIG_INOTIFY_USER=y
689# CONFIG_QUOTA is not set
690CONFIG_DNOTIFY=y
691# CONFIG_AUTOFS_FS is not set
692# CONFIG_AUTOFS4_FS is not set
693# CONFIG_FUSE_FS is not set
694
695#
696# CD-ROM/DVD Filesystems
697#
698# CONFIG_ISO9660_FS is not set
699# CONFIG_UDF_FS is not set
700
701#
702# DOS/FAT/NT Filesystems
703#
704# CONFIG_MSDOS_FS is not set
705# CONFIG_VFAT_FS is not set
706# CONFIG_NTFS_FS is not set
707
708#
709# Pseudo filesystems
710#
711CONFIG_PROC_FS=y
712CONFIG_PROC_KCORE=y
713CONFIG_PROC_SYSCTL=y
714CONFIG_SYSFS=y
715CONFIG_TMPFS=y
716# CONFIG_TMPFS_POSIX_ACL is not set
717# CONFIG_HUGETLBFS is not set
718# CONFIG_HUGETLB_PAGE is not set
719CONFIG_RAMFS=y
720# CONFIG_CONFIGFS_FS is not set
721
722#
723# Miscellaneous filesystems
724#
725# CONFIG_ADFS_FS is not set
726# CONFIG_AFFS_FS is not set
727# CONFIG_HFS_FS is not set
728# CONFIG_HFSPLUS_FS is not set
729# CONFIG_BEFS_FS is not set
730# CONFIG_BFS_FS is not set
731# CONFIG_EFS_FS is not set
732# CONFIG_CRAMFS is not set
733# CONFIG_VXFS_FS is not set
734# CONFIG_HPFS_FS is not set
735# CONFIG_QNX4FS_FS is not set
736# CONFIG_SYSV_FS is not set
737# CONFIG_UFS_FS is not set
738
739#
740# Network File Systems
741#
742CONFIG_NFS_FS=y
743CONFIG_NFS_V3=y
744# CONFIG_NFS_V3_ACL is not set
745# CONFIG_NFS_V4 is not set
746# CONFIG_NFS_DIRECTIO is not set
747# CONFIG_NFSD is not set
748CONFIG_ROOT_NFS=y
749CONFIG_LOCKD=y
750CONFIG_LOCKD_V4=y
751CONFIG_NFS_COMMON=y
752CONFIG_SUNRPC=y
753# CONFIG_RPCSEC_GSS_KRB5 is not set
754# CONFIG_RPCSEC_GSS_SPKM3 is not set
755# CONFIG_SMB_FS is not set
756# CONFIG_CIFS is not set
757# CONFIG_NCP_FS is not set
758# CONFIG_CODA_FS is not set
759# CONFIG_AFS_FS is not set
760# CONFIG_9P_FS is not set
761
762#
763# Partition Types
764#
765# CONFIG_PARTITION_ADVANCED is not set
766CONFIG_MSDOS_PARTITION=y
767
768#
769# Native Language Support
770#
771# CONFIG_NLS is not set
772
773#
774# Library routines
775#
776# CONFIG_CRC_CCITT is not set
777# CONFIG_CRC16 is not set
778# CONFIG_CRC32 is not set
779# CONFIG_LIBCRC32C is not set
780CONFIG_PLIST=y
781
782#
783# Instrumentation Support
784#
785# CONFIG_PROFILING is not set
786# CONFIG_KPROBES is not set
787
788#
789# Kernel hacking
790#
791# CONFIG_PRINTK_TIME is not set
792CONFIG_ENABLE_MUST_CHECK=y
793# CONFIG_MAGIC_SYSRQ is not set
794# CONFIG_UNUSED_SYMBOLS is not set
795CONFIG_DEBUG_KERNEL=y
796CONFIG_LOG_BUF_SHIFT=17
797CONFIG_DETECT_SOFTLOCKUP=y
798# CONFIG_SCHEDSTATS is not set
799# CONFIG_DEBUG_SLAB is not set
800# CONFIG_DEBUG_RT_MUTEXES is not set
801# CONFIG_RT_MUTEX_TESTER is not set
802CONFIG_DEBUG_SPINLOCK=y
803# CONFIG_DEBUG_MUTEXES is not set
804# CONFIG_DEBUG_RWSEMS is not set
805CONFIG_DEBUG_SPINLOCK_SLEEP=y
806# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
807# CONFIG_DEBUG_KOBJECT is not set
808CONFIG_DEBUG_INFO=y
809# CONFIG_DEBUG_FS is not set
810# CONFIG_DEBUG_VM is not set
811CONFIG_DEBUG_LIST=y
812CONFIG_FORCED_INLINING=y
813# CONFIG_HEADERS_CHECK is not set
814# CONFIG_RCU_TORTURE_TEST is not set
815# CONFIG_DEBUG_STACKOVERFLOW is not set
816# CONFIG_DEBUG_STACK_USAGE is not set
817# CONFIG_DEBUGGER is not set
818CONFIG_IRQSTACKS=y
819# CONFIG_BOOTX_TEXT is not set
820CONFIG_PPC_EARLY_DEBUG=y
821# CONFIG_PPC_EARLY_DEBUG_LPAR is not set
822# CONFIG_PPC_EARLY_DEBUG_G5 is not set
823# CONFIG_PPC_EARLY_DEBUG_RTAS_PANEL is not set
824# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set
825# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
826# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
827
828#
829# Security options
830#
831# CONFIG_KEYS is not set
832# CONFIG_SECURITY is not set
833
834#
835# Cryptographic options
836#
837# CONFIG_CRYPTO is not set
diff --git a/arch/powerpc/kernel/Makefile b/arch/powerpc/kernel/Makefile
index 7af23c43fd4b..4fe53d08ab81 100644
--- a/arch/powerpc/kernel/Makefile
+++ b/arch/powerpc/kernel/Makefile
@@ -17,11 +17,11 @@ obj-y += vdso32/
17obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \ 17obj-$(CONFIG_PPC64) += setup_64.o binfmt_elf32.o sys_ppc32.o \
18 signal_64.o ptrace32.o \ 18 signal_64.o ptrace32.o \
19 paca.o cpu_setup_ppc970.o \ 19 paca.o cpu_setup_ppc970.o \
20 firmware.o sysfs.o 20 firmware.o sysfs.o nvram_64.o
21obj-$(CONFIG_PPC64) += vdso64/ 21obj-$(CONFIG_PPC64) += vdso64/
22obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o 22obj-$(CONFIG_ALTIVEC) += vecemu.o vector.o
23obj-$(CONFIG_PPC_970_NAP) += idle_power4.o 23obj-$(CONFIG_PPC_970_NAP) += idle_power4.o
24obj-$(CONFIG_PPC_OF) += of_device.o prom_parse.o 24obj-$(CONFIG_PPC_OF) += of_device.o of_platform.o prom_parse.o
25procfs-$(CONFIG_PPC64) := proc_ppc64.o 25procfs-$(CONFIG_PPC64) := proc_ppc64.o
26obj-$(CONFIG_PROC_FS) += $(procfs-y) 26obj-$(CONFIG_PROC_FS) += $(procfs-y)
27rtaspci-$(CONFIG_PPC64) := rtas_pci.o 27rtaspci-$(CONFIG_PPC64) := rtas_pci.o
@@ -32,7 +32,6 @@ obj-$(CONFIG_LPARCFG) += lparcfg.o
32obj-$(CONFIG_IBMVIO) += vio.o 32obj-$(CONFIG_IBMVIO) += vio.o
33obj-$(CONFIG_IBMEBUS) += ibmebus.o 33obj-$(CONFIG_IBMEBUS) += ibmebus.o
34obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o 34obj-$(CONFIG_GENERIC_TBSYNC) += smp-tbsync.o
35obj64-$(CONFIG_PPC_MULTIPLATFORM) += nvram_64.o
36obj-$(CONFIG_CRASH_DUMP) += crash_dump.o 35obj-$(CONFIG_CRASH_DUMP) += crash_dump.o
37obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o 36obj-$(CONFIG_6xx) += idle_6xx.o l2cr_6xx.o cpu_setup_6xx.o
38obj-$(CONFIG_TAU) += tau_6xx.o 37obj-$(CONFIG_TAU) += tau_6xx.o
@@ -59,11 +58,11 @@ obj-$(CONFIG_BOOTX_TEXT) += btext.o
59obj-$(CONFIG_SMP) += smp.o 58obj-$(CONFIG_SMP) += smp.o
60obj-$(CONFIG_KPROBES) += kprobes.o 59obj-$(CONFIG_KPROBES) += kprobes.o
61obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o 60obj-$(CONFIG_PPC_UDBG_16550) += legacy_serial.o udbg_16550.o
61
62module-$(CONFIG_PPC64) += module_64.o 62module-$(CONFIG_PPC64) += module_64.o
63obj-$(CONFIG_MODULES) += $(module-y) 63obj-$(CONFIG_MODULES) += $(module-y)
64 64
65pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o pci_iommu.o \ 65pci64-$(CONFIG_PPC64) += pci_64.o pci_dn.o
66 pci_direct_iommu.o iomap.o
67pci32-$(CONFIG_PPC32) := pci_32.o 66pci32-$(CONFIG_PPC32) := pci_32.o
68obj-$(CONFIG_PCI) += $(pci64-y) $(pci32-y) 67obj-$(CONFIG_PCI) += $(pci64-y) $(pci32-y)
69kexec-$(CONFIG_PPC64) := machine_kexec_64.o 68kexec-$(CONFIG_PPC64) := machine_kexec_64.o
@@ -72,8 +71,12 @@ obj-$(CONFIG_KEXEC) += machine_kexec.o crash.o $(kexec-y)
72obj-$(CONFIG_AUDIT) += audit.o 71obj-$(CONFIG_AUDIT) += audit.o
73obj64-$(CONFIG_AUDIT) += compat_audit.o 72obj64-$(CONFIG_AUDIT) += compat_audit.o
74 73
74ifneq ($(CONFIG_PPC_INDIRECT_IO),y)
75obj-y += iomap.o
76endif
77
75ifeq ($(CONFIG_PPC_ISERIES),y) 78ifeq ($(CONFIG_PPC_ISERIES),y)
76$(obj)/head_64.o: $(obj)/lparmap.s 79extra-y += lparmap.s
77AFLAGS_head_64.o += -I$(obj) 80AFLAGS_head_64.o += -I$(obj)
78endif 81endif
79 82
diff --git a/arch/powerpc/kernel/asm-offsets.c b/arch/powerpc/kernel/asm-offsets.c
index d06f378597bb..e96521530d21 100644
--- a/arch/powerpc/kernel/asm-offsets.c
+++ b/arch/powerpc/kernel/asm-offsets.c
@@ -118,7 +118,8 @@ int main(void)
118 DEFINE(PACASTABRR, offsetof(struct paca_struct, stab_rr)); 118 DEFINE(PACASTABRR, offsetof(struct paca_struct, stab_rr));
119 DEFINE(PACAR1, offsetof(struct paca_struct, saved_r1)); 119 DEFINE(PACAR1, offsetof(struct paca_struct, saved_r1));
120 DEFINE(PACATOC, offsetof(struct paca_struct, kernel_toc)); 120 DEFINE(PACATOC, offsetof(struct paca_struct, kernel_toc));
121 DEFINE(PACAPROCENABLED, offsetof(struct paca_struct, proc_enabled)); 121 DEFINE(PACASOFTIRQEN, offsetof(struct paca_struct, soft_enabled));
122 DEFINE(PACAHARDIRQEN, offsetof(struct paca_struct, hard_enabled));
122 DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache)); 123 DEFINE(PACASLBCACHE, offsetof(struct paca_struct, slb_cache));
123 DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr)); 124 DEFINE(PACASLBCACHEPTR, offsetof(struct paca_struct, slb_cache_ptr));
124 DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id)); 125 DEFINE(PACACONTEXTID, offsetof(struct paca_struct, context.id));
diff --git a/arch/powerpc/kernel/cpu_setup_ppc970.S b/arch/powerpc/kernel/cpu_setup_ppc970.S
index 652594891d58..bf118c385752 100644
--- a/arch/powerpc/kernel/cpu_setup_ppc970.S
+++ b/arch/powerpc/kernel/cpu_setup_ppc970.S
@@ -83,6 +83,22 @@ _GLOBAL(__setup_cpu_ppc970)
83 rldimi r0,r11,52,8 /* set NAP and DPM */ 83 rldimi r0,r11,52,8 /* set NAP and DPM */
84 li r11,0 84 li r11,0
85 rldimi r0,r11,32,31 /* clear EN_ATTN */ 85 rldimi r0,r11,32,31 /* clear EN_ATTN */
86 b load_hids /* Jump to shared code */
87
88
89_GLOBAL(__setup_cpu_ppc970MP)
90 /* Do nothing if not running in HV mode */
91 mfmsr r0
92 rldicl. r0,r0,4,63
93 beqlr
94
95 mfspr r0,SPRN_HID0
96 li r11,0x15 /* clear DOZE and SLEEP */
97 rldimi r0,r11,52,6 /* set DEEPNAP, NAP and DPM */
98 li r11,0
99 rldimi r0,r11,32,31 /* clear EN_ATTN */
100
101load_hids:
86 mtspr SPRN_HID0,r0 102 mtspr SPRN_HID0,r0
87 mfspr r0,SPRN_HID0 103 mfspr r0,SPRN_HID0
88 mfspr r0,SPRN_HID0 104 mfspr r0,SPRN_HID0
diff --git a/arch/powerpc/kernel/cputable.c b/arch/powerpc/kernel/cputable.c
index bfd499ee3753..9d1614c3ce67 100644
--- a/arch/powerpc/kernel/cputable.c
+++ b/arch/powerpc/kernel/cputable.c
@@ -42,6 +42,7 @@ extern void __setup_cpu_745x(unsigned long offset, struct cpu_spec* spec);
42#endif /* CONFIG_PPC32 */ 42#endif /* CONFIG_PPC32 */
43#ifdef CONFIG_PPC64 43#ifdef CONFIG_PPC64
44extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec); 44extern void __setup_cpu_ppc970(unsigned long offset, struct cpu_spec* spec);
45extern void __setup_cpu_ppc970MP(unsigned long offset, struct cpu_spec* spec);
45extern void __restore_cpu_ppc970(void); 46extern void __restore_cpu_ppc970(void);
46#endif /* CONFIG_PPC64 */ 47#endif /* CONFIG_PPC64 */
47 48
@@ -222,9 +223,9 @@ static struct cpu_spec cpu_specs[] = {
222 .icache_bsize = 128, 223 .icache_bsize = 128,
223 .dcache_bsize = 128, 224 .dcache_bsize = 128,
224 .num_pmcs = 8, 225 .num_pmcs = 8,
225 .cpu_setup = __setup_cpu_ppc970, 226 .cpu_setup = __setup_cpu_ppc970MP,
226 .cpu_restore = __restore_cpu_ppc970, 227 .cpu_restore = __restore_cpu_ppc970,
227 .oprofile_cpu_type = "ppc64/970", 228 .oprofile_cpu_type = "ppc64/970MP",
228 .oprofile_type = PPC_OPROFILE_POWER4, 229 .oprofile_type = PPC_OPROFILE_POWER4,
229 .platform = "ppc970", 230 .platform = "ppc970",
230 }, 231 },
@@ -276,10 +277,45 @@ static struct cpu_spec cpu_specs[] = {
276 .oprofile_mmcra_sipr = MMCRA_SIPR, 277 .oprofile_mmcra_sipr = MMCRA_SIPR,
277 .platform = "power5+", 278 .platform = "power5+",
278 }, 279 },
280 { /* POWER6 in P5+ mode; 2.04-compliant processor */
281 .pvr_mask = 0xffffffff,
282 .pvr_value = 0x0f000001,
283 .cpu_name = "POWER5+",
284 .cpu_features = CPU_FTRS_POWER5,
285 .cpu_user_features = COMMON_USER_POWER5_PLUS,
286 .icache_bsize = 128,
287 .dcache_bsize = 128,
288 .num_pmcs = 6,
289 .oprofile_cpu_type = "ppc64/power6",
290 .oprofile_type = PPC_OPROFILE_POWER4,
291 .oprofile_mmcra_sihv = POWER6_MMCRA_SIHV,
292 .oprofile_mmcra_sipr = POWER6_MMCRA_SIPR,
293 .oprofile_mmcra_clear = POWER6_MMCRA_THRM |
294 POWER6_MMCRA_OTHER,
295 .platform = "power5+",
296 },
279 { /* Power6 */ 297 { /* Power6 */
280 .pvr_mask = 0xffff0000, 298 .pvr_mask = 0xffff0000,
281 .pvr_value = 0x003e0000, 299 .pvr_value = 0x003e0000,
282 .cpu_name = "POWER6", 300 .cpu_name = "POWER6 (raw)",
301 .cpu_features = CPU_FTRS_POWER6,
302 .cpu_user_features = COMMON_USER_POWER6 |
303 PPC_FEATURE_POWER6_EXT,
304 .icache_bsize = 128,
305 .dcache_bsize = 128,
306 .num_pmcs = 6,
307 .oprofile_cpu_type = "ppc64/power6",
308 .oprofile_type = PPC_OPROFILE_POWER4,
309 .oprofile_mmcra_sihv = POWER6_MMCRA_SIHV,
310 .oprofile_mmcra_sipr = POWER6_MMCRA_SIPR,
311 .oprofile_mmcra_clear = POWER6_MMCRA_THRM |
312 POWER6_MMCRA_OTHER,
313 .platform = "power6x",
314 },
315 { /* 2.05-compliant processor, i.e. Power6 "architected" mode */
316 .pvr_mask = 0xffffffff,
317 .pvr_value = 0x0f000002,
318 .cpu_name = "POWER6 (architected)",
283 .cpu_features = CPU_FTRS_POWER6, 319 .cpu_features = CPU_FTRS_POWER6,
284 .cpu_user_features = COMMON_USER_POWER6, 320 .cpu_user_features = COMMON_USER_POWER6,
285 .icache_bsize = 128, 321 .icache_bsize = 128,
@@ -303,6 +339,9 @@ static struct cpu_spec cpu_specs[] = {
303 PPC_FEATURE_SMT, 339 PPC_FEATURE_SMT,
304 .icache_bsize = 128, 340 .icache_bsize = 128,
305 .dcache_bsize = 128, 341 .dcache_bsize = 128,
342 .num_pmcs = 4,
343 .oprofile_cpu_type = "ppc64/cell-be",
344 .oprofile_type = PPC_OPROFILE_CELL,
306 .platform = "ppc-cell-be", 345 .platform = "ppc-cell-be",
307 }, 346 },
308 { /* PA Semi PA6T */ 347 { /* PA Semi PA6T */
@@ -801,6 +840,17 @@ static struct cpu_spec cpu_specs[] = {
801 .cpu_setup = __setup_cpu_603, 840 .cpu_setup = __setup_cpu_603,
802 .platform = "ppc603", 841 .platform = "ppc603",
803 }, 842 },
843 { /* e300c3 on 83xx */
844 .pvr_mask = 0x7fff0000,
845 .pvr_value = 0x00850000,
846 .cpu_name = "e300c3",
847 .cpu_features = CPU_FTRS_E300,
848 .cpu_user_features = COMMON_USER,
849 .icache_bsize = 32,
850 .dcache_bsize = 32,
851 .cpu_setup = __setup_cpu_603,
852 .platform = "ppc603",
853 },
804 { /* default match, we assume split I/D cache & TB (non-601)... */ 854 { /* default match, we assume split I/D cache & TB (non-601)... */
805 .pvr_mask = 0x00000000, 855 .pvr_mask = 0x00000000,
806 .pvr_value = 0x00000000, 856 .pvr_value = 0x00000000,
@@ -1169,19 +1219,15 @@ static struct cpu_spec cpu_specs[] = {
1169#endif /* CONFIG_PPC32 */ 1219#endif /* CONFIG_PPC32 */
1170}; 1220};
1171 1221
1172struct cpu_spec *identify_cpu(unsigned long offset) 1222struct cpu_spec *identify_cpu(unsigned long offset, unsigned int pvr)
1173{ 1223{
1174 struct cpu_spec *s = cpu_specs; 1224 struct cpu_spec *s = cpu_specs;
1175 struct cpu_spec **cur = &cur_cpu_spec; 1225 struct cpu_spec **cur = &cur_cpu_spec;
1176 unsigned int pvr = mfspr(SPRN_PVR);
1177 int i; 1226 int i;
1178 1227
1179 s = PTRRELOC(s); 1228 s = PTRRELOC(s);
1180 cur = PTRRELOC(cur); 1229 cur = PTRRELOC(cur);
1181 1230
1182 if (*cur != NULL)
1183 return PTRRELOC(*cur);
1184
1185 for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++) 1231 for (i = 0; i < ARRAY_SIZE(cpu_specs); i++,s++)
1186 if ((pvr & s->pvr_mask) == s->pvr_value) { 1232 if ((pvr & s->pvr_mask) == s->pvr_value) {
1187 *cur = cpu_specs + i; 1233 *cur = cpu_specs + i;
diff --git a/arch/powerpc/kernel/crash.c b/arch/powerpc/kernel/crash.c
index 1af41f7616dc..89b03c8da9d2 100644
--- a/arch/powerpc/kernel/crash.c
+++ b/arch/powerpc/kernel/crash.c
@@ -111,7 +111,7 @@ void crash_ipi_callback(struct pt_regs *regs)
111 if (!cpu_online(cpu)) 111 if (!cpu_online(cpu))
112 return; 112 return;
113 113
114 local_irq_disable(); 114 hard_irq_disable();
115 if (!cpu_isset(cpu, cpus_in_crash)) 115 if (!cpu_isset(cpu, cpus_in_crash))
116 crash_save_this_cpu(regs, cpu); 116 crash_save_this_cpu(regs, cpu);
117 cpu_set(cpu, cpus_in_crash); 117 cpu_set(cpu, cpus_in_crash);
@@ -289,7 +289,7 @@ void default_machine_crash_shutdown(struct pt_regs *regs)
289 * an SMP system. 289 * an SMP system.
290 * The kernel is broken so disable interrupts. 290 * The kernel is broken so disable interrupts.
291 */ 291 */
292 local_irq_disable(); 292 hard_irq_disable();
293 293
294 for_each_irq(irq) { 294 for_each_irq(irq) {
295 struct irq_desc *desc = irq_desc + irq; 295 struct irq_desc *desc = irq_desc + irq;
diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
index 6c168f6ea142..7b0e754383cf 100644
--- a/arch/powerpc/kernel/dma_64.c
+++ b/arch/powerpc/kernel/dma_64.c
@@ -1,151 +1,194 @@
1/* 1/*
2 * Copyright (C) 2004 IBM Corporation 2 * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corporation
3 * 3 *
4 * Implements the generic device dma API for ppc64. Handles 4 * Provide default implementations of the DMA mapping callbacks for
5 * the pci and vio busses 5 * directly mapped busses and busses using the iommu infrastructure
6 */ 6 */
7 7
8#include <linux/device.h> 8#include <linux/device.h>
9#include <linux/dma-mapping.h> 9#include <linux/dma-mapping.h>
10/* Include the busses we support */
11#include <linux/pci.h>
12#include <asm/vio.h>
13#include <asm/ibmebus.h>
14#include <asm/scatterlist.h>
15#include <asm/bug.h> 10#include <asm/bug.h>
11#include <asm/iommu.h>
12#include <asm/abs_addr.h>
16 13
17static struct dma_mapping_ops *get_dma_ops(struct device *dev) 14/*
18{ 15 * Generic iommu implementation
19#ifdef CONFIG_PCI 16 */
20 if (dev->bus == &pci_bus_type)
21 return &pci_dma_ops;
22#endif
23#ifdef CONFIG_IBMVIO
24 if (dev->bus == &vio_bus_type)
25 return &vio_dma_ops;
26#endif
27#ifdef CONFIG_IBMEBUS
28 if (dev->bus == &ibmebus_bus_type)
29 return &ibmebus_dma_ops;
30#endif
31 return NULL;
32}
33 17
34int dma_supported(struct device *dev, u64 mask) 18static inline unsigned long device_to_mask(struct device *dev)
35{ 19{
36 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 20 if (dev->dma_mask && *dev->dma_mask)
21 return *dev->dma_mask;
22 /* Assume devices without mask can take 32 bit addresses */
23 return 0xfffffffful;
24}
37 25
38 BUG_ON(!dma_ops);
39 26
40 return dma_ops->dma_supported(dev, mask); 27/* Allocates a contiguous real buffer and creates mappings over it.
28 * Returns the virtual address of the buffer and sets dma_handle
29 * to the dma address (mapping) of the first page.
30 */
31static void *dma_iommu_alloc_coherent(struct device *dev, size_t size,
32 dma_addr_t *dma_handle, gfp_t flag)
33{
34 return iommu_alloc_coherent(dev->archdata.dma_data, size, dma_handle,
35 device_to_mask(dev), flag,
36 dev->archdata.numa_node);
41} 37}
42EXPORT_SYMBOL(dma_supported);
43 38
44int dma_set_mask(struct device *dev, u64 dma_mask) 39static void dma_iommu_free_coherent(struct device *dev, size_t size,
40 void *vaddr, dma_addr_t dma_handle)
45{ 41{
46#ifdef CONFIG_PCI 42 iommu_free_coherent(dev->archdata.dma_data, size, vaddr, dma_handle);
47 if (dev->bus == &pci_bus_type)
48 return pci_set_dma_mask(to_pci_dev(dev), dma_mask);
49#endif
50#ifdef CONFIG_IBMVIO
51 if (dev->bus == &vio_bus_type)
52 return -EIO;
53#endif /* CONFIG_IBMVIO */
54#ifdef CONFIG_IBMEBUS
55 if (dev->bus == &ibmebus_bus_type)
56 return -EIO;
57#endif
58 BUG();
59 return 0;
60} 43}
61EXPORT_SYMBOL(dma_set_mask);
62 44
63void *dma_alloc_coherent(struct device *dev, size_t size, 45/* Creates TCEs for a user provided buffer. The user buffer must be
64 dma_addr_t *dma_handle, gfp_t flag) 46 * contiguous real kernel storage (not vmalloc). The address of the buffer
47 * passed here is the kernel (virtual) address of the buffer. The buffer
48 * need not be page aligned, the dma_addr_t returned will point to the same
49 * byte within the page as vaddr.
50 */
51static dma_addr_t dma_iommu_map_single(struct device *dev, void *vaddr,
52 size_t size,
53 enum dma_data_direction direction)
65{ 54{
66 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 55 return iommu_map_single(dev->archdata.dma_data, vaddr, size,
67 56 device_to_mask(dev), direction);
68 BUG_ON(!dma_ops);
69
70 return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
71} 57}
72EXPORT_SYMBOL(dma_alloc_coherent);
73 58
74void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, 59
75 dma_addr_t dma_handle) 60static void dma_iommu_unmap_single(struct device *dev, dma_addr_t dma_handle,
61 size_t size,
62 enum dma_data_direction direction)
76{ 63{
77 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 64 iommu_unmap_single(dev->archdata.dma_data, dma_handle, size, direction);
65}
78 66
79 BUG_ON(!dma_ops);
80 67
81 dma_ops->free_coherent(dev, size, cpu_addr, dma_handle); 68static int dma_iommu_map_sg(struct device *dev, struct scatterlist *sglist,
69 int nelems, enum dma_data_direction direction)
70{
71 return iommu_map_sg(dev->archdata.dma_data, sglist, nelems,
72 device_to_mask(dev), direction);
82} 73}
83EXPORT_SYMBOL(dma_free_coherent);
84 74
85dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, size_t size, 75static void dma_iommu_unmap_sg(struct device *dev, struct scatterlist *sglist,
86 enum dma_data_direction direction) 76 int nelems, enum dma_data_direction direction)
87{ 77{
88 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 78 iommu_unmap_sg(dev->archdata.dma_data, sglist, nelems, direction);
89
90 BUG_ON(!dma_ops);
91
92 return dma_ops->map_single(dev, cpu_addr, size, direction);
93} 79}
94EXPORT_SYMBOL(dma_map_single);
95 80
96void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, 81/* We support DMA to/from any memory page via the iommu */
97 enum dma_data_direction direction) 82static int dma_iommu_dma_supported(struct device *dev, u64 mask)
98{ 83{
99 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 84 struct iommu_table *tbl = dev->archdata.dma_data;
100 85
101 BUG_ON(!dma_ops); 86 if (!tbl || tbl->it_offset > mask) {
102 87 printk(KERN_INFO
103 dma_ops->unmap_single(dev, dma_addr, size, direction); 88 "Warning: IOMMU offset too big for device mask\n");
89 if (tbl)
90 printk(KERN_INFO
91 "mask: 0x%08lx, table offset: 0x%08lx\n",
92 mask, tbl->it_offset);
93 else
94 printk(KERN_INFO "mask: 0x%08lx, table unavailable\n",
95 mask);
96 return 0;
97 } else
98 return 1;
104} 99}
105EXPORT_SYMBOL(dma_unmap_single);
106 100
107dma_addr_t dma_map_page(struct device *dev, struct page *page, 101struct dma_mapping_ops dma_iommu_ops = {
108 unsigned long offset, size_t size, 102 .alloc_coherent = dma_iommu_alloc_coherent,
109 enum dma_data_direction direction) 103 .free_coherent = dma_iommu_free_coherent,
110{ 104 .map_single = dma_iommu_map_single,
111 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 105 .unmap_single = dma_iommu_unmap_single,
106 .map_sg = dma_iommu_map_sg,
107 .unmap_sg = dma_iommu_unmap_sg,
108 .dma_supported = dma_iommu_dma_supported,
109};
110EXPORT_SYMBOL(dma_iommu_ops);
112 111
113 BUG_ON(!dma_ops); 112/*
113 * Generic direct DMA implementation
114 *
115 * This implementation supports a global offset that can be applied if
116 * the address at which memory is visible to devices is not 0.
117 */
118unsigned long dma_direct_offset;
114 119
115 return dma_ops->map_single(dev, page_address(page) + offset, size, 120static void *dma_direct_alloc_coherent(struct device *dev, size_t size,
116 direction); 121 dma_addr_t *dma_handle, gfp_t flag)
122{
123 struct page *page;
124 void *ret;
125 int node = dev->archdata.numa_node;
126
127 /* TODO: Maybe use the numa node here too ? */
128 page = alloc_pages_node(node, flag, get_order(size));
129 if (page == NULL)
130 return NULL;
131 ret = page_address(page);
132 memset(ret, 0, size);
133 *dma_handle = virt_to_abs(ret) | dma_direct_offset;
134
135 return ret;
117} 136}
118EXPORT_SYMBOL(dma_map_page);
119 137
120void dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size, 138static void dma_direct_free_coherent(struct device *dev, size_t size,
121 enum dma_data_direction direction) 139 void *vaddr, dma_addr_t dma_handle)
122{ 140{
123 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 141 free_pages((unsigned long)vaddr, get_order(size));
142}
124 143
125 BUG_ON(!dma_ops); 144static dma_addr_t dma_direct_map_single(struct device *dev, void *ptr,
145 size_t size,
146 enum dma_data_direction direction)
147{
148 return virt_to_abs(ptr) | dma_direct_offset;
149}
126 150
127 dma_ops->unmap_single(dev, dma_address, size, direction); 151static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr,
152 size_t size,
153 enum dma_data_direction direction)
154{
128} 155}
129EXPORT_SYMBOL(dma_unmap_page);
130 156
131int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, 157static int dma_direct_map_sg(struct device *dev, struct scatterlist *sg,
132 enum dma_data_direction direction) 158 int nents, enum dma_data_direction direction)
133{ 159{
134 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 160 int i;
135 161
136 BUG_ON(!dma_ops); 162 for (i = 0; i < nents; i++, sg++) {
163 sg->dma_address = (page_to_phys(sg->page) + sg->offset) |
164 dma_direct_offset;
165 sg->dma_length = sg->length;
166 }
137 167
138 return dma_ops->map_sg(dev, sg, nents, direction); 168 return nents;
139} 169}
140EXPORT_SYMBOL(dma_map_sg);
141 170
142void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries, 171static void dma_direct_unmap_sg(struct device *dev, struct scatterlist *sg,
143 enum dma_data_direction direction) 172 int nents, enum dma_data_direction direction)
144{ 173{
145 struct dma_mapping_ops *dma_ops = get_dma_ops(dev); 174}
146
147 BUG_ON(!dma_ops);
148 175
149 dma_ops->unmap_sg(dev, sg, nhwentries, direction); 176static int dma_direct_dma_supported(struct device *dev, u64 mask)
177{
178 /* Could be improved to check for memory though it better be
179 * done via some global so platforms can set the limit in case
180 * they have limited DMA windows
181 */
182 return mask >= DMA_32BIT_MASK;
150} 183}
151EXPORT_SYMBOL(dma_unmap_sg); 184
185struct dma_mapping_ops dma_direct_ops = {
186 .alloc_coherent = dma_direct_alloc_coherent,
187 .free_coherent = dma_direct_free_coherent,
188 .map_single = dma_direct_map_single,
189 .unmap_single = dma_direct_unmap_single,
190 .map_sg = dma_direct_map_sg,
191 .unmap_sg = dma_direct_unmap_sg,
192 .dma_supported = dma_direct_dma_supported,
193};
194EXPORT_SYMBOL(dma_direct_ops);
diff --git a/arch/powerpc/kernel/entry_64.S b/arch/powerpc/kernel/entry_64.S
index 748e74fcf541..1a3d4de197d2 100644
--- a/arch/powerpc/kernel/entry_64.S
+++ b/arch/powerpc/kernel/entry_64.S
@@ -87,15 +87,19 @@ system_call_common:
87 addi r9,r1,STACK_FRAME_OVERHEAD 87 addi r9,r1,STACK_FRAME_OVERHEAD
88 ld r11,exception_marker@toc(r2) 88 ld r11,exception_marker@toc(r2)
89 std r11,-16(r9) /* "regshere" marker */ 89 std r11,-16(r9) /* "regshere" marker */
90 li r10,1
91 stb r10,PACASOFTIRQEN(r13)
92 stb r10,PACAHARDIRQEN(r13)
93 std r10,SOFTE(r1)
90#ifdef CONFIG_PPC_ISERIES 94#ifdef CONFIG_PPC_ISERIES
91BEGIN_FW_FTR_SECTION 95BEGIN_FW_FTR_SECTION
92 /* Hack for handling interrupts when soft-enabling on iSeries */ 96 /* Hack for handling interrupts when soft-enabling on iSeries */
93 cmpdi cr1,r0,0x5555 /* syscall 0x5555 */ 97 cmpdi cr1,r0,0x5555 /* syscall 0x5555 */
94 andi. r10,r12,MSR_PR /* from kernel */ 98 andi. r10,r12,MSR_PR /* from kernel */
95 crand 4*cr0+eq,4*cr1+eq,4*cr0+eq 99 crand 4*cr0+eq,4*cr1+eq,4*cr0+eq
96 beq hardware_interrupt_entry 100 bne 2f
97 lbz r10,PACAPROCENABLED(r13) 101 b hardware_interrupt_entry
98 std r10,SOFTE(r1) 1022:
99END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) 103END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
100#endif 104#endif
101 mfmsr r11 105 mfmsr r11
@@ -460,9 +464,9 @@ _GLOBAL(ret_from_except_lite)
460#endif 464#endif
461 465
462restore: 466restore:
467 ld r5,SOFTE(r1)
463#ifdef CONFIG_PPC_ISERIES 468#ifdef CONFIG_PPC_ISERIES
464BEGIN_FW_FTR_SECTION 469BEGIN_FW_FTR_SECTION
465 ld r5,SOFTE(r1)
466 cmpdi 0,r5,0 470 cmpdi 0,r5,0
467 beq 4f 471 beq 4f
468 /* Check for pending interrupts (iSeries) */ 472 /* Check for pending interrupts (iSeries) */
@@ -472,21 +476,25 @@ BEGIN_FW_FTR_SECTION
472 beq+ 4f /* skip do_IRQ if no interrupts */ 476 beq+ 4f /* skip do_IRQ if no interrupts */
473 477
474 li r3,0 478 li r3,0
475 stb r3,PACAPROCENABLED(r13) /* ensure we are soft-disabled */ 479 stb r3,PACASOFTIRQEN(r13) /* ensure we are soft-disabled */
476 ori r10,r10,MSR_EE 480 ori r10,r10,MSR_EE
477 mtmsrd r10 /* hard-enable again */ 481 mtmsrd r10 /* hard-enable again */
478 addi r3,r1,STACK_FRAME_OVERHEAD 482 addi r3,r1,STACK_FRAME_OVERHEAD
479 bl .do_IRQ 483 bl .do_IRQ
480 b .ret_from_except_lite /* loop back and handle more */ 484 b .ret_from_except_lite /* loop back and handle more */
481 4854:
4824: stb r5,PACAPROCENABLED(r13)
483END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) 486END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
484#endif 487#endif
488 stb r5,PACASOFTIRQEN(r13)
485 489
486 ld r3,_MSR(r1) 490 ld r3,_MSR(r1)
487 andi. r0,r3,MSR_RI 491 andi. r0,r3,MSR_RI
488 beq- unrecov_restore 492 beq- unrecov_restore
489 493
494 /* extract EE bit and use it to restore paca->hard_enabled */
495 rldicl r4,r3,49,63 /* r0 = (r3 >> 15) & 1 */
496 stb r4,PACAHARDIRQEN(r13)
497
490 andi. r0,r3,MSR_PR 498 andi. r0,r3,MSR_PR
491 499
492 /* 500 /*
@@ -538,25 +546,15 @@ do_work:
538 /* Check that preempt_count() == 0 and interrupts are enabled */ 546 /* Check that preempt_count() == 0 and interrupts are enabled */
539 lwz r8,TI_PREEMPT(r9) 547 lwz r8,TI_PREEMPT(r9)
540 cmpwi cr1,r8,0 548 cmpwi cr1,r8,0
541#ifdef CONFIG_PPC_ISERIES
542BEGIN_FW_FTR_SECTION
543 ld r0,SOFTE(r1) 549 ld r0,SOFTE(r1)
544 cmpdi r0,0 550 cmpdi r0,0
545END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
546#endif
547BEGIN_FW_FTR_SECTION
548 andi. r0,r3,MSR_EE
549END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
550 crandc eq,cr1*4+eq,eq 551 crandc eq,cr1*4+eq,eq
551 bne restore 552 bne restore
552 /* here we are preempting the current task */ 553 /* here we are preempting the current task */
5531: 5541:
554#ifdef CONFIG_PPC_ISERIES
555BEGIN_FW_FTR_SECTION
556 li r0,1 555 li r0,1
557 stb r0,PACAPROCENABLED(r13) 556 stb r0,PACASOFTIRQEN(r13)
558END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) 557 stb r0,PACAHARDIRQEN(r13)
559#endif
560 ori r10,r10,MSR_EE 558 ori r10,r10,MSR_EE
561 mtmsrd r10,1 /* reenable interrupts */ 559 mtmsrd r10,1 /* reenable interrupts */
562 bl .preempt_schedule 560 bl .preempt_schedule
@@ -639,8 +637,7 @@ _GLOBAL(enter_rtas)
639 /* There is no way it is acceptable to get here with interrupts enabled, 637 /* There is no way it is acceptable to get here with interrupts enabled,
640 * check it with the asm equivalent of WARN_ON 638 * check it with the asm equivalent of WARN_ON
641 */ 639 */
642 mfmsr r6 640 lbz r0,PACASOFTIRQEN(r13)
643 andi. r0,r6,MSR_EE
6441: tdnei r0,0 6411: tdnei r0,0
645.section __bug_table,"a" 642.section __bug_table,"a"
646 .llong 1b,__LINE__ + 0x1000000, 1f, 2f 643 .llong 1b,__LINE__ + 0x1000000, 1f, 2f
@@ -649,7 +646,13 @@ _GLOBAL(enter_rtas)
6491: .asciz __FILE__ 6461: .asciz __FILE__
6502: .asciz "enter_rtas" 6472: .asciz "enter_rtas"
651.previous 648.previous
652 649
650 /* Hard-disable interrupts */
651 mfmsr r6
652 rldicl r7,r6,48,1
653 rotldi r7,r7,16
654 mtmsrd r7,1
655
653 /* Unfortunately, the stack pointer and the MSR are also clobbered, 656 /* Unfortunately, the stack pointer and the MSR are also clobbered,
654 * so they are saved in the PACA which allows us to restore 657 * so they are saved in the PACA which allows us to restore
655 * our original state after RTAS returns. 658 * our original state after RTAS returns.
@@ -735,8 +738,6 @@ _STATIC(rtas_restore_regs)
735 738
736#endif /* CONFIG_PPC_RTAS */ 739#endif /* CONFIG_PPC_RTAS */
737 740
738#ifdef CONFIG_PPC_MULTIPLATFORM
739
740_GLOBAL(enter_prom) 741_GLOBAL(enter_prom)
741 mflr r0 742 mflr r0
742 std r0,16(r1) 743 std r0,16(r1)
@@ -821,5 +822,3 @@ _GLOBAL(enter_prom)
821 ld r0,16(r1) 822 ld r0,16(r1)
822 mtlr r0 823 mtlr r0
823 blr 824 blr
824
825#endif /* CONFIG_PPC_MULTIPLATFORM */
diff --git a/arch/powerpc/kernel/head_64.S b/arch/powerpc/kernel/head_64.S
index e720729f3e55..71b1fe58e9e4 100644
--- a/arch/powerpc/kernel/head_64.S
+++ b/arch/powerpc/kernel/head_64.S
@@ -35,9 +35,7 @@
35#include <asm/thread_info.h> 35#include <asm/thread_info.h>
36#include <asm/firmware.h> 36#include <asm/firmware.h>
37 37
38#ifdef CONFIG_PPC_ISERIES
39#define DO_SOFT_DISABLE 38#define DO_SOFT_DISABLE
40#endif
41 39
42/* 40/*
43 * We layout physical memory as follows: 41 * We layout physical memory as follows:
@@ -74,13 +72,11 @@
74 .text 72 .text
75 .globl _stext 73 .globl _stext
76_stext: 74_stext:
77#ifdef CONFIG_PPC_MULTIPLATFORM
78_GLOBAL(__start) 75_GLOBAL(__start)
79 /* NOP this out unconditionally */ 76 /* NOP this out unconditionally */
80BEGIN_FTR_SECTION 77BEGIN_FTR_SECTION
81 b .__start_initialization_multiplatform 78 b .__start_initialization_multiplatform
82END_FTR_SECTION(0, 1) 79END_FTR_SECTION(0, 1)
83#endif /* CONFIG_PPC_MULTIPLATFORM */
84 80
85 /* Catch branch to 0 in real mode */ 81 /* Catch branch to 0 in real mode */
86 trap 82 trap
@@ -308,7 +304,9 @@ exception_marker:
308 std r9,_LINK(r1); \ 304 std r9,_LINK(r1); \
309 mfctr r10; /* save CTR in stackframe */ \ 305 mfctr r10; /* save CTR in stackframe */ \
310 std r10,_CTR(r1); \ 306 std r10,_CTR(r1); \
307 lbz r10,PACASOFTIRQEN(r13); \
311 mfspr r11,SPRN_XER; /* save XER in stackframe */ \ 308 mfspr r11,SPRN_XER; /* save XER in stackframe */ \
309 std r10,SOFTE(r1); \
312 std r11,_XER(r1); \ 310 std r11,_XER(r1); \
313 li r9,(n)+1; \ 311 li r9,(n)+1; \
314 std r9,_TRAP(r1); /* set trap number */ \ 312 std r9,_TRAP(r1); /* set trap number */ \
@@ -343,6 +341,34 @@ label##_pSeries: \
343 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common) 341 EXCEPTION_PROLOG_PSERIES(PACA_EXGEN, label##_common)
344 342
345 343
344#define MASKABLE_EXCEPTION_PSERIES(n, label) \
345 . = n; \
346 .globl label##_pSeries; \
347label##_pSeries: \
348 HMT_MEDIUM; \
349 mtspr SPRN_SPRG1,r13; /* save r13 */ \
350 mfspr r13,SPRN_SPRG3; /* get paca address into r13 */ \
351 std r9,PACA_EXGEN+EX_R9(r13); /* save r9, r10 */ \
352 std r10,PACA_EXGEN+EX_R10(r13); \
353 lbz r10,PACASOFTIRQEN(r13); \
354 mfcr r9; \
355 cmpwi r10,0; \
356 beq masked_interrupt; \
357 mfspr r10,SPRN_SPRG1; \
358 std r10,PACA_EXGEN+EX_R13(r13); \
359 std r11,PACA_EXGEN+EX_R11(r13); \
360 std r12,PACA_EXGEN+EX_R12(r13); \
361 clrrdi r12,r13,32; /* get high part of &label */ \
362 mfmsr r10; \
363 mfspr r11,SPRN_SRR0; /* save SRR0 */ \
364 LOAD_HANDLER(r12,label##_common) \
365 ori r10,r10,MSR_IR|MSR_DR|MSR_RI; \
366 mtspr SPRN_SRR0,r12; \
367 mfspr r12,SPRN_SRR1; /* and SRR1 */ \
368 mtspr SPRN_SRR1,r10; \
369 rfid; \
370 b . /* prevent speculative execution */
371
346#define STD_EXCEPTION_ISERIES(n, label, area) \ 372#define STD_EXCEPTION_ISERIES(n, label, area) \
347 .globl label##_iSeries; \ 373 .globl label##_iSeries; \
348label##_iSeries: \ 374label##_iSeries: \
@@ -358,40 +384,32 @@ label##_iSeries: \
358 HMT_MEDIUM; \ 384 HMT_MEDIUM; \
359 mtspr SPRN_SPRG1,r13; /* save r13 */ \ 385 mtspr SPRN_SPRG1,r13; /* save r13 */ \
360 EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \ 386 EXCEPTION_PROLOG_ISERIES_1(PACA_EXGEN); \
361 lbz r10,PACAPROCENABLED(r13); \ 387 lbz r10,PACASOFTIRQEN(r13); \
362 cmpwi 0,r10,0; \ 388 cmpwi 0,r10,0; \
363 beq- label##_iSeries_masked; \ 389 beq- label##_iSeries_masked; \
364 EXCEPTION_PROLOG_ISERIES_2; \ 390 EXCEPTION_PROLOG_ISERIES_2; \
365 b label##_common; \ 391 b label##_common; \
366 392
367#ifdef DO_SOFT_DISABLE 393#ifdef CONFIG_PPC_ISERIES
368#define DISABLE_INTS \ 394#define DISABLE_INTS \
369BEGIN_FW_FTR_SECTION; \
370 lbz r10,PACAPROCENABLED(r13); \
371 li r11,0; \ 395 li r11,0; \
372 std r10,SOFTE(r1); \ 396 stb r11,PACASOFTIRQEN(r13); \
397BEGIN_FW_FTR_SECTION; \
398 stb r11,PACAHARDIRQEN(r13); \
399END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES); \
400BEGIN_FW_FTR_SECTION; \
373 mfmsr r10; \ 401 mfmsr r10; \
374 stb r11,PACAPROCENABLED(r13); \
375 ori r10,r10,MSR_EE; \ 402 ori r10,r10,MSR_EE; \
376 mtmsrd r10,1; \ 403 mtmsrd r10,1; \
377END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) 404END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
378 405
379#define ENABLE_INTS \ 406#else
380BEGIN_FW_FTR_SECTION; \ 407#define DISABLE_INTS \
381 lbz r10,PACAPROCENABLED(r13); \ 408 li r11,0; \
382 mfmsr r11; \ 409 stb r11,PACASOFTIRQEN(r13); \
383 std r10,SOFTE(r1); \ 410 stb r11,PACAHARDIRQEN(r13)
384 ori r11,r11,MSR_EE; \
385END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES); \
386BEGIN_FW_FTR_SECTION; \
387 ld r12,_MSR(r1); \
388 mfmsr r11; \
389 rlwimi r11,r12,0,MSR_EE; \
390END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES); \
391 mtmsrd r11,1
392 411
393#else /* hard enable/disable interrupts */ 412#endif /* CONFIG_PPC_ISERIES */
394#define DISABLE_INTS
395 413
396#define ENABLE_INTS \ 414#define ENABLE_INTS \
397 ld r12,_MSR(r1); \ 415 ld r12,_MSR(r1); \
@@ -399,8 +417,6 @@ END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES); \
399 rlwimi r11,r12,0,MSR_EE; \ 417 rlwimi r11,r12,0,MSR_EE; \
400 mtmsrd r11,1 418 mtmsrd r11,1
401 419
402#endif
403
404#define STD_EXCEPTION_COMMON(trap, label, hdlr) \ 420#define STD_EXCEPTION_COMMON(trap, label, hdlr) \
405 .align 7; \ 421 .align 7; \
406 .globl label##_common; \ 422 .globl label##_common; \
@@ -541,11 +557,11 @@ instruction_access_slb_pSeries:
541 mfspr r12,SPRN_SRR1 /* and SRR1 */ 557 mfspr r12,SPRN_SRR1 /* and SRR1 */
542 b .slb_miss_realmode /* Rel. branch works in real mode */ 558 b .slb_miss_realmode /* Rel. branch works in real mode */
543 559
544 STD_EXCEPTION_PSERIES(0x500, hardware_interrupt) 560 MASKABLE_EXCEPTION_PSERIES(0x500, hardware_interrupt)
545 STD_EXCEPTION_PSERIES(0x600, alignment) 561 STD_EXCEPTION_PSERIES(0x600, alignment)
546 STD_EXCEPTION_PSERIES(0x700, program_check) 562 STD_EXCEPTION_PSERIES(0x700, program_check)
547 STD_EXCEPTION_PSERIES(0x800, fp_unavailable) 563 STD_EXCEPTION_PSERIES(0x800, fp_unavailable)
548 STD_EXCEPTION_PSERIES(0x900, decrementer) 564 MASKABLE_EXCEPTION_PSERIES(0x900, decrementer)
549 STD_EXCEPTION_PSERIES(0xa00, trap_0a) 565 STD_EXCEPTION_PSERIES(0xa00, trap_0a)
550 STD_EXCEPTION_PSERIES(0xb00, trap_0b) 566 STD_EXCEPTION_PSERIES(0xb00, trap_0b)
551 567
@@ -597,7 +613,24 @@ system_call_pSeries:
597/*** pSeries interrupt support ***/ 613/*** pSeries interrupt support ***/
598 614
599 /* moved from 0xf00 */ 615 /* moved from 0xf00 */
600 STD_EXCEPTION_PSERIES(., performance_monitor) 616 MASKABLE_EXCEPTION_PSERIES(., performance_monitor)
617
618/*
619 * An interrupt came in while soft-disabled; clear EE in SRR1,
620 * clear paca->hard_enabled and return.
621 */
622masked_interrupt:
623 stb r10,PACAHARDIRQEN(r13)
624 mtcrf 0x80,r9
625 ld r9,PACA_EXGEN+EX_R9(r13)
626 mfspr r10,SPRN_SRR1
627 rldicl r10,r10,48,1 /* clear MSR_EE */
628 rotldi r10,r10,16
629 mtspr SPRN_SRR1,r10
630 ld r10,PACA_EXGEN+EX_R10(r13)
631 mfspr r13,SPRN_SPRG1
632 rfid
633 b .
601 634
602 .align 7 635 .align 7
603do_stab_bolted_pSeries: 636do_stab_bolted_pSeries:
@@ -792,7 +825,7 @@ system_reset_iSeries:
792 825
793 cmpwi 0,r23,0 826 cmpwi 0,r23,0
794 beq iSeries_secondary_smp_loop /* Loop until told to go */ 827 beq iSeries_secondary_smp_loop /* Loop until told to go */
795 bne .__secondary_start /* Loop until told to go */ 828 bne __secondary_start /* Loop until told to go */
796iSeries_secondary_smp_loop: 829iSeries_secondary_smp_loop:
797 /* Let the Hypervisor know we are alive */ 830 /* Let the Hypervisor know we are alive */
798 /* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */ 831 /* 8002 is a call to HvCallCfg::getLps, a harmless Hypervisor function */
@@ -813,7 +846,6 @@ iSeries_secondary_smp_loop:
813 b 1b /* If SMP not configured, secondaries 846 b 1b /* If SMP not configured, secondaries
814 * loop forever */ 847 * loop forever */
815 848
816 .globl decrementer_iSeries_masked
817decrementer_iSeries_masked: 849decrementer_iSeries_masked:
818 /* We may not have a valid TOC pointer in here. */ 850 /* We may not have a valid TOC pointer in here. */
819 li r11,1 851 li r11,1
@@ -824,7 +856,6 @@ decrementer_iSeries_masked:
824 mtspr SPRN_DEC,r12 856 mtspr SPRN_DEC,r12
825 /* fall through */ 857 /* fall through */
826 858
827 .globl hardware_interrupt_iSeries_masked
828hardware_interrupt_iSeries_masked: 859hardware_interrupt_iSeries_masked:
829 mtcrf 0x80,r9 /* Restore regs */ 860 mtcrf 0x80,r9 /* Restore regs */
830 ld r12,PACALPPACAPTR(r13) 861 ld r12,PACALPPACAPTR(r13)
@@ -926,10 +957,18 @@ bad_stack:
926 * any task or sent any task a signal, you should use 957 * any task or sent any task a signal, you should use
927 * ret_from_except or ret_from_except_lite instead of this. 958 * ret_from_except or ret_from_except_lite instead of this.
928 */ 959 */
960fast_exc_return_irq: /* restores irq state too */
961 ld r3,SOFTE(r1)
962 ld r12,_MSR(r1)
963 stb r3,PACASOFTIRQEN(r13) /* restore paca->soft_enabled */
964 rldicl r4,r12,49,63 /* get MSR_EE to LSB */
965 stb r4,PACAHARDIRQEN(r13) /* restore paca->hard_enabled */
966 b 1f
967
929 .globl fast_exception_return 968 .globl fast_exception_return
930fast_exception_return: 969fast_exception_return:
931 ld r12,_MSR(r1) 970 ld r12,_MSR(r1)
932 ld r11,_NIP(r1) 9711: ld r11,_NIP(r1)
933 andi. r3,r12,MSR_RI /* check if RI is set */ 972 andi. r3,r12,MSR_RI /* check if RI is set */
934 beq- unrecov_fer 973 beq- unrecov_fer
935 974
@@ -952,7 +991,8 @@ fast_exception_return:
952 REST_8GPRS(2, r1) 991 REST_8GPRS(2, r1)
953 992
954 mfmsr r10 993 mfmsr r10
955 clrrdi r10,r10,2 /* clear RI (LE is 0 already) */ 994 rldicl r10,r10,48,1 /* clear EE */
995 rldicr r10,r10,16,61 /* clear RI (LE is 0 already) */
956 mtmsrd r10,1 996 mtmsrd r10,1
957 997
958 mtspr SPRN_SRR1,r12 998 mtspr SPRN_SRR1,r12
@@ -1326,6 +1366,16 @@ BEGIN_FW_FTR_SECTION
1326 * interrupts if necessary. 1366 * interrupts if necessary.
1327 */ 1367 */
1328 beq 13f 1368 beq 13f
1369END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
1370#endif
1371BEGIN_FW_FTR_SECTION
1372 /*
1373 * Here we have interrupts hard-disabled, so it is sufficient
1374 * to restore paca->{soft,hard}_enable and get out.
1375 */
1376 beq fast_exc_return_irq /* Return from exception on success */
1377END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
1378
1329 /* For a hash failure, we don't bother re-enabling interrupts */ 1379 /* For a hash failure, we don't bother re-enabling interrupts */
1330 ble- 12f 1380 ble- 12f
1331 1381
@@ -1337,14 +1387,6 @@ BEGIN_FW_FTR_SECTION
1337 ld r3,SOFTE(r1) 1387 ld r3,SOFTE(r1)
1338 bl .local_irq_restore 1388 bl .local_irq_restore
1339 b 11f 1389 b 11f
1340END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
1341#endif
1342BEGIN_FW_FTR_SECTION
1343 beq fast_exception_return /* Return from exception on success */
1344 ble- 12f /* Failure return from hash_page */
1345
1346 /* fall through */
1347END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
1348 1390
1349/* Here we have a page fault that hash_page can't handle. */ 1391/* Here we have a page fault that hash_page can't handle. */
1350handle_page_fault: 1392handle_page_fault:
@@ -1362,6 +1404,8 @@ handle_page_fault:
1362 bl .bad_page_fault 1404 bl .bad_page_fault
1363 b .ret_from_except 1405 b .ret_from_except
1364 1406
140713: b .ret_from_except_lite
1408
1365/* We have a page fault that hash_page could handle but HV refused 1409/* We have a page fault that hash_page could handle but HV refused
1366 * the PTE insertion 1410 * the PTE insertion
1367 */ 1411 */
@@ -1371,8 +1415,6 @@ handle_page_fault:
1371 bl .low_hash_fault 1415 bl .low_hash_fault
1372 b .ret_from_except 1416 b .ret_from_except
1373 1417
137413: b .ret_from_except_lite
1375
1376 /* here we have a segment miss */ 1418 /* here we have a segment miss */
1377do_ste_alloc: 1419do_ste_alloc:
1378 bl .ste_allocate /* try to insert stab entry */ 1420 bl .ste_allocate /* try to insert stab entry */
@@ -1560,7 +1602,7 @@ _GLOBAL(generic_secondary_smp_init)
1560 ld r1,PACAEMERGSP(r13) 1602 ld r1,PACAEMERGSP(r13)
1561 subi r1,r1,STACK_FRAME_OVERHEAD 1603 subi r1,r1,STACK_FRAME_OVERHEAD
1562 1604
1563 b .__secondary_start 1605 b __secondary_start
1564#endif 1606#endif
1565 1607
1566#ifdef CONFIG_PPC_ISERIES 1608#ifdef CONFIG_PPC_ISERIES
@@ -1595,7 +1637,6 @@ _STATIC(__start_initialization_iSeries)
1595 b .start_here_common 1637 b .start_here_common
1596#endif /* CONFIG_PPC_ISERIES */ 1638#endif /* CONFIG_PPC_ISERIES */
1597 1639
1598#ifdef CONFIG_PPC_MULTIPLATFORM
1599 1640
1600_STATIC(__mmu_off) 1641_STATIC(__mmu_off)
1601 mfmsr r3 1642 mfmsr r3
@@ -1621,13 +1662,11 @@ _STATIC(__mmu_off)
1621 * 1662 *
1622 */ 1663 */
1623_GLOBAL(__start_initialization_multiplatform) 1664_GLOBAL(__start_initialization_multiplatform)
1624#ifdef CONFIG_PPC_MULTIPLATFORM
1625 /* 1665 /*
1626 * Are we booted from a PROM Of-type client-interface ? 1666 * Are we booted from a PROM Of-type client-interface ?
1627 */ 1667 */
1628 cmpldi cr0,r5,0 1668 cmpldi cr0,r5,0
1629 bne .__boot_from_prom /* yes -> prom */ 1669 bne .__boot_from_prom /* yes -> prom */
1630#endif
1631 1670
1632 /* Save parameters */ 1671 /* Save parameters */
1633 mr r31,r3 1672 mr r31,r3
@@ -1656,7 +1695,6 @@ _GLOBAL(__start_initialization_multiplatform)
1656 bl .__mmu_off 1695 bl .__mmu_off
1657 b .__after_prom_start 1696 b .__after_prom_start
1658 1697
1659#ifdef CONFIG_PPC_MULTIPLATFORM
1660_STATIC(__boot_from_prom) 1698_STATIC(__boot_from_prom)
1661 /* Save parameters */ 1699 /* Save parameters */
1662 mr r31,r3 1700 mr r31,r3
@@ -1696,7 +1734,6 @@ _STATIC(__boot_from_prom)
1696 bl .prom_init 1734 bl .prom_init
1697 /* We never return */ 1735 /* We never return */
1698 trap 1736 trap
1699#endif
1700 1737
1701/* 1738/*
1702 * At this point, r3 contains the physical address we are running at, 1739 * At this point, r3 contains the physical address we are running at,
@@ -1752,8 +1789,6 @@ _STATIC(__after_prom_start)
1752 bl .copy_and_flush /* copy the rest */ 1789 bl .copy_and_flush /* copy the rest */
1753 b .start_here_multiplatform 1790 b .start_here_multiplatform
1754 1791
1755#endif /* CONFIG_PPC_MULTIPLATFORM */
1756
1757/* 1792/*
1758 * Copy routine used to copy the kernel to start at physical address 0 1793 * Copy routine used to copy the kernel to start at physical address 0
1759 * and flush and invalidate the caches as needed. 1794 * and flush and invalidate the caches as needed.
@@ -1836,7 +1871,7 @@ _GLOBAL(pmac_secondary_start)
1836 ld r1,PACAEMERGSP(r13) 1871 ld r1,PACAEMERGSP(r13)
1837 subi r1,r1,STACK_FRAME_OVERHEAD 1872 subi r1,r1,STACK_FRAME_OVERHEAD
1838 1873
1839 b .__secondary_start 1874 b __secondary_start
1840 1875
1841#endif /* CONFIG_PPC_PMAC */ 1876#endif /* CONFIG_PPC_PMAC */
1842 1877
@@ -1853,7 +1888,7 @@ _GLOBAL(pmac_secondary_start)
1853 * r13 = paca virtual address 1888 * r13 = paca virtual address
1854 * SPRG3 = paca virtual address 1889 * SPRG3 = paca virtual address
1855 */ 1890 */
1856_GLOBAL(__secondary_start) 1891__secondary_start:
1857 /* Set thread priority to MEDIUM */ 1892 /* Set thread priority to MEDIUM */
1858 HMT_MEDIUM 1893 HMT_MEDIUM
1859 1894
@@ -1877,11 +1912,16 @@ _GLOBAL(__secondary_start)
1877 /* enable MMU and jump to start_secondary */ 1912 /* enable MMU and jump to start_secondary */
1878 LOAD_REG_ADDR(r3, .start_secondary_prolog) 1913 LOAD_REG_ADDR(r3, .start_secondary_prolog)
1879 LOAD_REG_IMMEDIATE(r4, MSR_KERNEL) 1914 LOAD_REG_IMMEDIATE(r4, MSR_KERNEL)
1880#ifdef DO_SOFT_DISABLE 1915#ifdef CONFIG_PPC_ISERIES
1881BEGIN_FW_FTR_SECTION 1916BEGIN_FW_FTR_SECTION
1882 ori r4,r4,MSR_EE 1917 ori r4,r4,MSR_EE
1883END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) 1918END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
1884#endif 1919#endif
1920BEGIN_FW_FTR_SECTION
1921 stb r7,PACASOFTIRQEN(r13)
1922 stb r7,PACAHARDIRQEN(r13)
1923END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
1924
1885 mtspr SPRN_SRR0,r3 1925 mtspr SPRN_SRR0,r3
1886 mtspr SPRN_SRR1,r4 1926 mtspr SPRN_SRR1,r4
1887 rfid 1927 rfid
@@ -1913,7 +1953,6 @@ _GLOBAL(enable_64b_mode)
1913 isync 1953 isync
1914 blr 1954 blr
1915 1955
1916#ifdef CONFIG_PPC_MULTIPLATFORM
1917/* 1956/*
1918 * This is where the main kernel code starts. 1957 * This is where the main kernel code starts.
1919 */ 1958 */
@@ -1977,7 +2016,6 @@ _STATIC(start_here_multiplatform)
1977 mtspr SPRN_SRR1,r4 2016 mtspr SPRN_SRR1,r4
1978 rfid 2017 rfid
1979 b . /* prevent speculative execution */ 2018 b . /* prevent speculative execution */
1980#endif /* CONFIG_PPC_MULTIPLATFORM */
1981 2019
1982 /* This is where all platforms converge execution */ 2020 /* This is where all platforms converge execution */
1983_STATIC(start_here_common) 2021_STATIC(start_here_common)
@@ -2005,15 +2043,18 @@ _STATIC(start_here_common)
2005 2043
2006 /* Load up the kernel context */ 2044 /* Load up the kernel context */
20075: 20455:
2008#ifdef DO_SOFT_DISABLE
2009BEGIN_FW_FTR_SECTION
2010 li r5,0 2046 li r5,0
2011 stb r5,PACAPROCENABLED(r13) /* Soft Disabled */ 2047 stb r5,PACASOFTIRQEN(r13) /* Soft Disabled */
2048#ifdef CONFIG_PPC_ISERIES
2049BEGIN_FW_FTR_SECTION
2012 mfmsr r5 2050 mfmsr r5
2013 ori r5,r5,MSR_EE /* Hard Enabled */ 2051 ori r5,r5,MSR_EE /* Hard Enabled */
2014 mtmsrd r5 2052 mtmsrd r5
2015END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES) 2053END_FW_FTR_SECTION_IFSET(FW_FEATURE_ISERIES)
2016#endif 2054#endif
2055BEGIN_FW_FTR_SECTION
2056 stb r5,PACAHARDIRQEN(r13)
2057END_FW_FTR_SECTION_IFCLR(FW_FEATURE_ISERIES)
2017 2058
2018 bl .start_kernel 2059 bl .start_kernel
2019 2060
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index 39db7a3affe1..82bd2f10770f 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -112,7 +112,7 @@ static int ibmebus_dma_supported(struct device *dev, u64 mask)
112 return 1; 112 return 1;
113} 113}
114 114
115struct dma_mapping_ops ibmebus_dma_ops = { 115static struct dma_mapping_ops ibmebus_dma_ops = {
116 .alloc_coherent = ibmebus_alloc_coherent, 116 .alloc_coherent = ibmebus_alloc_coherent,
117 .free_coherent = ibmebus_free_coherent, 117 .free_coherent = ibmebus_free_coherent,
118 .map_single = ibmebus_map_single, 118 .map_single = ibmebus_map_single,
@@ -176,6 +176,10 @@ static struct ibmebus_dev* __devinit ibmebus_register_device_common(
176 dev->ofdev.dev.bus = &ibmebus_bus_type; 176 dev->ofdev.dev.bus = &ibmebus_bus_type;
177 dev->ofdev.dev.release = ibmebus_dev_release; 177 dev->ofdev.dev.release = ibmebus_dev_release;
178 178
179 dev->ofdev.dev.archdata.of_node = dev->ofdev.node;
180 dev->ofdev.dev.archdata.dma_ops = &ibmebus_dma_ops;
181 dev->ofdev.dev.archdata.numa_node = of_node_to_nid(dev->ofdev.node);
182
179 /* An ibmebusdev is based on a of_device. We have to change the 183 /* An ibmebusdev is based on a of_device. We have to change the
180 * bus type to use our own DMA mapping operations. 184 * bus type to use our own DMA mapping operations.
181 */ 185 */
@@ -210,11 +214,10 @@ static struct ibmebus_dev* __devinit ibmebus_register_device_node(
210 return NULL; 214 return NULL;
211 } 215 }
212 216
213 dev = kmalloc(sizeof(struct ibmebus_dev), GFP_KERNEL); 217 dev = kzalloc(sizeof(struct ibmebus_dev), GFP_KERNEL);
214 if (!dev) { 218 if (!dev) {
215 return NULL; 219 return NULL;
216 } 220 }
217 memset(dev, 0, sizeof(struct ibmebus_dev));
218 221
219 dev->ofdev.node = of_node_get(dn); 222 dev->ofdev.node = of_node_get(dn);
220 223
diff --git a/arch/powerpc/kernel/idle.c b/arch/powerpc/kernel/idle.c
index 4180c3998b39..8994af327b47 100644
--- a/arch/powerpc/kernel/idle.c
+++ b/arch/powerpc/kernel/idle.c
@@ -39,6 +39,13 @@
39#define cpu_should_die() 0 39#define cpu_should_die() 0
40#endif 40#endif
41 41
42static int __init powersave_off(char *arg)
43{
44 ppc_md.power_save = NULL;
45 return 0;
46}
47__setup("powersave=off", powersave_off);
48
42/* 49/*
43 * The body of the idle task. 50 * The body of the idle task.
44 */ 51 */
diff --git a/arch/powerpc/kernel/idle_power4.S b/arch/powerpc/kernel/idle_power4.S
index 30de81da7b40..ba3195478600 100644
--- a/arch/powerpc/kernel/idle_power4.S
+++ b/arch/powerpc/kernel/idle_power4.S
@@ -30,6 +30,13 @@ END_FTR_SECTION_IFCLR(CPU_FTR_CAN_NAP)
30 beqlr 30 beqlr
31 31
32 /* Go to NAP now */ 32 /* Go to NAP now */
33 mfmsr r7
34 rldicl r0,r7,48,1
35 rotldi r0,r0,16
36 mtmsrd r0,1 /* hard-disable interrupts */
37 li r0,1
38 stb r0,PACASOFTIRQEN(r13) /* we'll hard-enable shortly */
39 stb r0,PACAHARDIRQEN(r13)
33BEGIN_FTR_SECTION 40BEGIN_FTR_SECTION
34 DSSALL 41 DSSALL
35 sync 42 sync
@@ -38,7 +45,6 @@ END_FTR_SECTION_IFSET(CPU_FTR_ALTIVEC)
38 ld r8,TI_LOCAL_FLAGS(r9) /* set napping bit */ 45 ld r8,TI_LOCAL_FLAGS(r9) /* set napping bit */
39 ori r8,r8,_TLF_NAPPING /* so when we take an exception */ 46 ori r8,r8,_TLF_NAPPING /* so when we take an exception */
40 std r8,TI_LOCAL_FLAGS(r9) /* it will return to our caller */ 47 std r8,TI_LOCAL_FLAGS(r9) /* it will return to our caller */
41 mfmsr r7
42 ori r7,r7,MSR_EE 48 ori r7,r7,MSR_EE
43 oris r7,r7,MSR_POW@h 49 oris r7,r7,MSR_POW@h
441: sync 501: sync
diff --git a/arch/powerpc/kernel/io.c b/arch/powerpc/kernel/io.c
index e98180686b35..34ae11494ddc 100644
--- a/arch/powerpc/kernel/io.c
+++ b/arch/powerpc/kernel/io.c
@@ -25,13 +25,11 @@
25#include <asm/firmware.h> 25#include <asm/firmware.h>
26#include <asm/bug.h> 26#include <asm/bug.h>
27 27
28void _insb(volatile u8 __iomem *port, void *buf, long count) 28void _insb(const volatile u8 __iomem *port, void *buf, long count)
29{ 29{
30 u8 *tbuf = buf; 30 u8 *tbuf = buf;
31 u8 tmp; 31 u8 tmp;
32 32
33 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
34
35 if (unlikely(count <= 0)) 33 if (unlikely(count <= 0))
36 return; 34 return;
37 asm volatile("sync"); 35 asm volatile("sync");
@@ -48,8 +46,6 @@ void _outsb(volatile u8 __iomem *port, const void *buf, long count)
48{ 46{
49 const u8 *tbuf = buf; 47 const u8 *tbuf = buf;
50 48
51 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
52
53 if (unlikely(count <= 0)) 49 if (unlikely(count <= 0))
54 return; 50 return;
55 asm volatile("sync"); 51 asm volatile("sync");
@@ -60,13 +56,11 @@ void _outsb(volatile u8 __iomem *port, const void *buf, long count)
60} 56}
61EXPORT_SYMBOL(_outsb); 57EXPORT_SYMBOL(_outsb);
62 58
63void _insw_ns(volatile u16 __iomem *port, void *buf, long count) 59void _insw_ns(const volatile u16 __iomem *port, void *buf, long count)
64{ 60{
65 u16 *tbuf = buf; 61 u16 *tbuf = buf;
66 u16 tmp; 62 u16 tmp;
67 63
68 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
69
70 if (unlikely(count <= 0)) 64 if (unlikely(count <= 0))
71 return; 65 return;
72 asm volatile("sync"); 66 asm volatile("sync");
@@ -83,8 +77,6 @@ void _outsw_ns(volatile u16 __iomem *port, const void *buf, long count)
83{ 77{
84 const u16 *tbuf = buf; 78 const u16 *tbuf = buf;
85 79
86 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
87
88 if (unlikely(count <= 0)) 80 if (unlikely(count <= 0))
89 return; 81 return;
90 asm volatile("sync"); 82 asm volatile("sync");
@@ -95,13 +87,11 @@ void _outsw_ns(volatile u16 __iomem *port, const void *buf, long count)
95} 87}
96EXPORT_SYMBOL(_outsw_ns); 88EXPORT_SYMBOL(_outsw_ns);
97 89
98void _insl_ns(volatile u32 __iomem *port, void *buf, long count) 90void _insl_ns(const volatile u32 __iomem *port, void *buf, long count)
99{ 91{
100 u32 *tbuf = buf; 92 u32 *tbuf = buf;
101 u32 tmp; 93 u32 tmp;
102 94
103 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
104
105 if (unlikely(count <= 0)) 95 if (unlikely(count <= 0))
106 return; 96 return;
107 asm volatile("sync"); 97 asm volatile("sync");
@@ -118,8 +108,6 @@ void _outsl_ns(volatile u32 __iomem *port, const void *buf, long count)
118{ 108{
119 const u32 *tbuf = buf; 109 const u32 *tbuf = buf;
120 110
121 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
122
123 if (unlikely(count <= 0)) 111 if (unlikely(count <= 0))
124 return; 112 return;
125 asm volatile("sync"); 113 asm volatile("sync");
@@ -129,3 +117,90 @@ void _outsl_ns(volatile u32 __iomem *port, const void *buf, long count)
129 asm volatile("sync"); 117 asm volatile("sync");
130} 118}
131EXPORT_SYMBOL(_outsl_ns); 119EXPORT_SYMBOL(_outsl_ns);
120
121#define IO_CHECK_ALIGN(v,a) ((((unsigned long)(v)) & ((a) - 1)) == 0)
122
123void _memset_io(volatile void __iomem *addr, int c, unsigned long n)
124{
125 void *p = (void __force *)addr;
126 u32 lc = c;
127 lc |= lc << 8;
128 lc |= lc << 16;
129
130 __asm__ __volatile__ ("sync" : : : "memory");
131 while(n && !IO_CHECK_ALIGN(p, 4)) {
132 *((volatile u8 *)p) = c;
133 p++;
134 n--;
135 }
136 while(n >= 4) {
137 *((volatile u32 *)p) = lc;
138 p += 4;
139 n -= 4;
140 }
141 while(n) {
142 *((volatile u8 *)p) = c;
143 p++;
144 n--;
145 }
146 __asm__ __volatile__ ("sync" : : : "memory");
147}
148EXPORT_SYMBOL(_memset_io);
149
150void _memcpy_fromio(void *dest, const volatile void __iomem *src,
151 unsigned long n)
152{
153 void *vsrc = (void __force *) src;
154
155 __asm__ __volatile__ ("sync" : : : "memory");
156 while(n && (!IO_CHECK_ALIGN(vsrc, 4) || !IO_CHECK_ALIGN(dest, 4))) {
157 *((u8 *)dest) = *((volatile u8 *)vsrc);
158 __asm__ __volatile__ ("eieio" : : : "memory");
159 vsrc++;
160 dest++;
161 n--;
162 }
163 while(n > 4) {
164 *((u32 *)dest) = *((volatile u32 *)vsrc);
165 __asm__ __volatile__ ("eieio" : : : "memory");
166 vsrc += 4;
167 dest += 4;
168 n -= 4;
169 }
170 while(n) {
171 *((u8 *)dest) = *((volatile u8 *)vsrc);
172 __asm__ __volatile__ ("eieio" : : : "memory");
173 vsrc++;
174 dest++;
175 n--;
176 }
177 __asm__ __volatile__ ("sync" : : : "memory");
178}
179EXPORT_SYMBOL(_memcpy_fromio);
180
181void _memcpy_toio(volatile void __iomem *dest, const void *src, unsigned long n)
182{
183 void *vdest = (void __force *) dest;
184
185 __asm__ __volatile__ ("sync" : : : "memory");
186 while(n && (!IO_CHECK_ALIGN(vdest, 4) || !IO_CHECK_ALIGN(src, 4))) {
187 *((volatile u8 *)vdest) = *((u8 *)src);
188 src++;
189 vdest++;
190 n--;
191 }
192 while(n > 4) {
193 *((volatile u32 *)vdest) = *((volatile u32 *)src);
194 src += 4;
195 vdest += 4;
196 n-=4;
197 }
198 while(n) {
199 *((volatile u8 *)vdest) = *((u8 *)src);
200 src++;
201 vdest++;
202 n--;
203 }
204 __asm__ __volatile__ ("sync" : : : "memory");
205}
206EXPORT_SYMBOL(_memcpy_toio);
diff --git a/arch/powerpc/kernel/iomap.c b/arch/powerpc/kernel/iomap.c
index a13a93dfc655..c68113371050 100644
--- a/arch/powerpc/kernel/iomap.c
+++ b/arch/powerpc/kernel/iomap.c
@@ -106,7 +106,7 @@ EXPORT_SYMBOL(iowrite32_rep);
106 106
107void __iomem *ioport_map(unsigned long port, unsigned int len) 107void __iomem *ioport_map(unsigned long port, unsigned int len)
108{ 108{
109 return (void __iomem *) (port+pci_io_base); 109 return (void __iomem *) (port + _IO_BASE);
110} 110}
111 111
112void ioport_unmap(void __iomem *addr) 112void ioport_unmap(void __iomem *addr)
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index ba6b7256084b..95edad4faf26 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -258,9 +258,9 @@ static void iommu_free(struct iommu_table *tbl, dma_addr_t dma_addr,
258 spin_unlock_irqrestore(&(tbl->it_lock), flags); 258 spin_unlock_irqrestore(&(tbl->it_lock), flags);
259} 259}
260 260
261int iommu_map_sg(struct device *dev, struct iommu_table *tbl, 261int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
262 struct scatterlist *sglist, int nelems, 262 int nelems, unsigned long mask,
263 unsigned long mask, enum dma_data_direction direction) 263 enum dma_data_direction direction)
264{ 264{
265 dma_addr_t dma_next = 0, dma_addr; 265 dma_addr_t dma_next = 0, dma_addr;
266 unsigned long flags; 266 unsigned long flags;
diff --git a/arch/powerpc/kernel/irq.c b/arch/powerpc/kernel/irq.c
index 5e37bf14ef2d..0bd8c7665834 100644
--- a/arch/powerpc/kernel/irq.c
+++ b/arch/powerpc/kernel/irq.c
@@ -64,8 +64,9 @@
64#include <asm/ptrace.h> 64#include <asm/ptrace.h>
65#include <asm/machdep.h> 65#include <asm/machdep.h>
66#include <asm/udbg.h> 66#include <asm/udbg.h>
67#ifdef CONFIG_PPC_ISERIES 67#ifdef CONFIG_PPC64
68#include <asm/paca.h> 68#include <asm/paca.h>
69#include <asm/firmware.h>
69#endif 70#endif
70 71
71int __irq_offset_value; 72int __irq_offset_value;
@@ -95,6 +96,74 @@ extern atomic_t ipi_sent;
95EXPORT_SYMBOL(irq_desc); 96EXPORT_SYMBOL(irq_desc);
96 97
97int distribute_irqs = 1; 98int distribute_irqs = 1;
99
100static inline unsigned long get_hard_enabled(void)
101{
102 unsigned long enabled;
103
104 __asm__ __volatile__("lbz %0,%1(13)"
105 : "=r" (enabled) : "i" (offsetof(struct paca_struct, hard_enabled)));
106
107 return enabled;
108}
109
110static inline void set_soft_enabled(unsigned long enable)
111{
112 __asm__ __volatile__("stb %0,%1(13)"
113 : : "r" (enable), "i" (offsetof(struct paca_struct, soft_enabled)));
114}
115
116void local_irq_restore(unsigned long en)
117{
118 /*
119 * get_paca()->soft_enabled = en;
120 * Is it ever valid to use local_irq_restore(0) when soft_enabled is 1?
121 * That was allowed before, and in such a case we do need to take care
122 * that gcc will set soft_enabled directly via r13, not choose to use
123 * an intermediate register, lest we're preempted to a different cpu.
124 */
125 set_soft_enabled(en);
126 if (!en)
127 return;
128
129 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
130 /*
131 * Do we need to disable preemption here? Not really: in the
132 * unlikely event that we're preempted to a different cpu in
133 * between getting r13, loading its lppaca_ptr, and loading
134 * its any_int, we might call iseries_handle_interrupts without
135 * an interrupt pending on the new cpu, but that's no disaster,
136 * is it? And the business of preempting us off the old cpu
137 * would itself involve a local_irq_restore which handles the
138 * interrupt to that cpu.
139 *
140 * But use "local_paca->lppaca_ptr" instead of "get_lppaca()"
141 * to avoid any preemption checking added into get_paca().
142 */
143 if (local_paca->lppaca_ptr->int_dword.any_int)
144 iseries_handle_interrupts();
145 return;
146 }
147
148 /*
149 * if (get_paca()->hard_enabled) return;
150 * But again we need to take care that gcc gets hard_enabled directly
151 * via r13, not choose to use an intermediate register, lest we're
152 * preempted to a different cpu in between the two instructions.
153 */
154 if (get_hard_enabled())
155 return;
156
157 /*
158 * Need to hard-enable interrupts here. Since currently disabled,
159 * no need to take further asm precautions against preemption; but
160 * use local_paca instead of get_paca() to avoid preemption checking.
161 */
162 local_paca->hard_enabled = en;
163 if ((int)mfspr(SPRN_DEC) < 0)
164 mtspr(SPRN_DEC, 1);
165 hard_irq_enable();
166}
98#endif /* CONFIG_PPC64 */ 167#endif /* CONFIG_PPC64 */
99 168
100int show_interrupts(struct seq_file *p, void *v) 169int show_interrupts(struct seq_file *p, void *v)
@@ -246,7 +315,8 @@ void do_IRQ(struct pt_regs *regs)
246 set_irq_regs(old_regs); 315 set_irq_regs(old_regs);
247 316
248#ifdef CONFIG_PPC_ISERIES 317#ifdef CONFIG_PPC_ISERIES
249 if (get_lppaca()->int_dword.fields.decr_int) { 318 if (firmware_has_feature(FW_FEATURE_ISERIES) &&
319 get_lppaca()->int_dword.fields.decr_int) {
250 get_lppaca()->int_dword.fields.decr_int = 0; 320 get_lppaca()->int_dword.fields.decr_int = 0;
251 /* Signal a fake decrementer interrupt */ 321 /* Signal a fake decrementer interrupt */
252 timer_interrupt(regs); 322 timer_interrupt(regs);
@@ -626,10 +696,14 @@ EXPORT_SYMBOL_GPL(irq_of_parse_and_map);
626 696
627void irq_dispose_mapping(unsigned int virq) 697void irq_dispose_mapping(unsigned int virq)
628{ 698{
629 struct irq_host *host = irq_map[virq].host; 699 struct irq_host *host;
630 irq_hw_number_t hwirq; 700 irq_hw_number_t hwirq;
631 unsigned long flags; 701 unsigned long flags;
632 702
703 if (virq == NO_IRQ)
704 return;
705
706 host = irq_map[virq].host;
633 WARN_ON (host == NULL); 707 WARN_ON (host == NULL);
634 if (host == NULL) 708 if (host == NULL)
635 return; 709 return;
diff --git a/arch/powerpc/kernel/of_device.c b/arch/powerpc/kernel/of_device.c
index 397c83eda20e..8a06724e029e 100644
--- a/arch/powerpc/kernel/of_device.c
+++ b/arch/powerpc/kernel/of_device.c
@@ -9,30 +9,26 @@
9#include <asm/of_device.h> 9#include <asm/of_device.h>
10 10
11/** 11/**
12 * of_match_device - Tell if an of_device structure has a matching 12 * of_match_node - Tell if an device_node has a matching of_match structure
13 * of_match structure
14 * @ids: array of of device match structures to search in 13 * @ids: array of of device match structures to search in
15 * @dev: the of device structure to match against 14 * @node: the of device structure to match against
16 * 15 *
17 * Used by a driver to check whether an of_device present in the 16 * Low level utility function used by device matching.
18 * system is in its list of supported devices.
19 */ 17 */
20const struct of_device_id *of_match_device(const struct of_device_id *matches, 18const struct of_device_id *of_match_node(const struct of_device_id *matches,
21 const struct of_device *dev) 19 const struct device_node *node)
22{ 20{
23 if (!dev->node)
24 return NULL;
25 while (matches->name[0] || matches->type[0] || matches->compatible[0]) { 21 while (matches->name[0] || matches->type[0] || matches->compatible[0]) {
26 int match = 1; 22 int match = 1;
27 if (matches->name[0]) 23 if (matches->name[0])
28 match &= dev->node->name 24 match &= node->name
29 && !strcmp(matches->name, dev->node->name); 25 && !strcmp(matches->name, node->name);
30 if (matches->type[0]) 26 if (matches->type[0])
31 match &= dev->node->type 27 match &= node->type
32 && !strcmp(matches->type, dev->node->type); 28 && !strcmp(matches->type, node->type);
33 if (matches->compatible[0]) 29 if (matches->compatible[0])
34 match &= device_is_compatible(dev->node, 30 match &= device_is_compatible(node,
35 matches->compatible); 31 matches->compatible);
36 if (match) 32 if (match)
37 return matches; 33 return matches;
38 matches++; 34 matches++;
@@ -40,16 +36,21 @@ const struct of_device_id *of_match_device(const struct of_device_id *matches,
40 return NULL; 36 return NULL;
41} 37}
42 38
43static int of_platform_bus_match(struct device *dev, struct device_driver *drv) 39/**
40 * of_match_device - Tell if an of_device structure has a matching
41 * of_match structure
42 * @ids: array of of device match structures to search in
43 * @dev: the of device structure to match against
44 *
45 * Used by a driver to check whether an of_device present in the
46 * system is in its list of supported devices.
47 */
48const struct of_device_id *of_match_device(const struct of_device_id *matches,
49 const struct of_device *dev)
44{ 50{
45 struct of_device * of_dev = to_of_device(dev); 51 if (!dev->node)
46 struct of_platform_driver * of_drv = to_of_platform_driver(drv); 52 return NULL;
47 const struct of_device_id * matches = of_drv->match_table; 53 return of_match_node(matches, dev->node);
48
49 if (!matches)
50 return 0;
51
52 return of_match_device(matches, of_dev) != NULL;
53} 54}
54 55
55struct of_device *of_dev_get(struct of_device *dev) 56struct of_device *of_dev_get(struct of_device *dev)
@@ -71,96 +72,8 @@ void of_dev_put(struct of_device *dev)
71 put_device(&dev->dev); 72 put_device(&dev->dev);
72} 73}
73 74
74 75static ssize_t dev_show_devspec(struct device *dev,
75static int of_device_probe(struct device *dev) 76 struct device_attribute *attr, char *buf)
76{
77 int error = -ENODEV;
78 struct of_platform_driver *drv;
79 struct of_device *of_dev;
80 const struct of_device_id *match;
81
82 drv = to_of_platform_driver(dev->driver);
83 of_dev = to_of_device(dev);
84
85 if (!drv->probe)
86 return error;
87
88 of_dev_get(of_dev);
89
90 match = of_match_device(drv->match_table, of_dev);
91 if (match)
92 error = drv->probe(of_dev, match);
93 if (error)
94 of_dev_put(of_dev);
95
96 return error;
97}
98
99static int of_device_remove(struct device *dev)
100{
101 struct of_device * of_dev = to_of_device(dev);
102 struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
103
104 if (dev->driver && drv->remove)
105 drv->remove(of_dev);
106 return 0;
107}
108
109static int of_device_suspend(struct device *dev, pm_message_t state)
110{
111 struct of_device * of_dev = to_of_device(dev);
112 struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
113 int error = 0;
114
115 if (dev->driver && drv->suspend)
116 error = drv->suspend(of_dev, state);
117 return error;
118}
119
120static int of_device_resume(struct device * dev)
121{
122 struct of_device * of_dev = to_of_device(dev);
123 struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
124 int error = 0;
125
126 if (dev->driver && drv->resume)
127 error = drv->resume(of_dev);
128 return error;
129}
130
131struct bus_type of_platform_bus_type = {
132 .name = "of_platform",
133 .match = of_platform_bus_match,
134 .probe = of_device_probe,
135 .remove = of_device_remove,
136 .suspend = of_device_suspend,
137 .resume = of_device_resume,
138};
139
140static int __init of_bus_driver_init(void)
141{
142 return bus_register(&of_platform_bus_type);
143}
144
145postcore_initcall(of_bus_driver_init);
146
147int of_register_driver(struct of_platform_driver *drv)
148{
149 /* initialize common driver fields */
150 drv->driver.name = drv->name;
151 drv->driver.bus = &of_platform_bus_type;
152
153 /* register with core */
154 return driver_register(&drv->driver);
155}
156
157void of_unregister_driver(struct of_platform_driver *drv)
158{
159 driver_unregister(&drv->driver);
160}
161
162
163static ssize_t dev_show_devspec(struct device *dev, struct device_attribute *attr, char *buf)
164{ 77{
165 struct of_device *ofdev; 78 struct of_device *ofdev;
166 79
@@ -208,41 +121,11 @@ void of_device_unregister(struct of_device *ofdev)
208 device_unregister(&ofdev->dev); 121 device_unregister(&ofdev->dev);
209} 122}
210 123
211struct of_device* of_platform_device_create(struct device_node *np,
212 const char *bus_id,
213 struct device *parent)
214{
215 struct of_device *dev;
216
217 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
218 if (!dev)
219 return NULL;
220 memset(dev, 0, sizeof(*dev));
221
222 dev->node = of_node_get(np);
223 dev->dma_mask = 0xffffffffUL;
224 dev->dev.dma_mask = &dev->dma_mask;
225 dev->dev.parent = parent;
226 dev->dev.bus = &of_platform_bus_type;
227 dev->dev.release = of_release_dev;
228
229 strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE);
230
231 if (of_device_register(dev) != 0) {
232 kfree(dev);
233 return NULL;
234 }
235
236 return dev;
237}
238 124
125EXPORT_SYMBOL(of_match_node);
239EXPORT_SYMBOL(of_match_device); 126EXPORT_SYMBOL(of_match_device);
240EXPORT_SYMBOL(of_platform_bus_type);
241EXPORT_SYMBOL(of_register_driver);
242EXPORT_SYMBOL(of_unregister_driver);
243EXPORT_SYMBOL(of_device_register); 127EXPORT_SYMBOL(of_device_register);
244EXPORT_SYMBOL(of_device_unregister); 128EXPORT_SYMBOL(of_device_unregister);
245EXPORT_SYMBOL(of_dev_get); 129EXPORT_SYMBOL(of_dev_get);
246EXPORT_SYMBOL(of_dev_put); 130EXPORT_SYMBOL(of_dev_put);
247EXPORT_SYMBOL(of_platform_device_create);
248EXPORT_SYMBOL(of_release_dev); 131EXPORT_SYMBOL(of_release_dev);
diff --git a/arch/powerpc/kernel/of_platform.c b/arch/powerpc/kernel/of_platform.c
new file mode 100644
index 000000000000..b3189d0161b8
--- /dev/null
+++ b/arch/powerpc/kernel/of_platform.c
@@ -0,0 +1,489 @@
1/*
2 * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
3 * <benh@kernel.crashing.org>
4 * and Arnd Bergmann, IBM Corp.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 *
11 */
12
13#undef DEBUG
14
15#include <linux/string.h>
16#include <linux/kernel.h>
17#include <linux/init.h>
18#include <linux/module.h>
19#include <linux/mod_devicetable.h>
20#include <linux/slab.h>
21#include <linux/pci.h>
22
23#include <asm/errno.h>
24#include <asm/dcr.h>
25#include <asm/of_device.h>
26#include <asm/of_platform.h>
27#include <asm/topology.h>
28#include <asm/pci-bridge.h>
29#include <asm/ppc-pci.h>
30#include <asm/atomic.h>
31
32
33/*
34 * The list of OF IDs below is used for matching bus types in the
35 * system whose devices are to be exposed as of_platform_devices.
36 *
37 * This is the default list valid for most platforms. This file provides
38 * functions who can take an explicit list if necessary though
39 *
40 * The search is always performed recursively looking for children of
41 * the provided device_node and recursively if such a children matches
42 * a bus type in the list
43 */
44
45static struct of_device_id of_default_bus_ids[] = {
46 { .type = "soc", },
47 { .compatible = "soc", },
48 { .type = "spider", },
49 { .type = "axon", },
50 { .type = "plb5", },
51 { .type = "plb4", },
52 { .type = "opb", },
53 {},
54};
55
56static atomic_t bus_no_reg_magic;
57
58/*
59 *
60 * OF platform device type definition & base infrastructure
61 *
62 */
63
64static int of_platform_bus_match(struct device *dev, struct device_driver *drv)
65{
66 struct of_device * of_dev = to_of_device(dev);
67 struct of_platform_driver * of_drv = to_of_platform_driver(drv);
68 const struct of_device_id * matches = of_drv->match_table;
69
70 if (!matches)
71 return 0;
72
73 return of_match_device(matches, of_dev) != NULL;
74}
75
76static int of_platform_device_probe(struct device *dev)
77{
78 int error = -ENODEV;
79 struct of_platform_driver *drv;
80 struct of_device *of_dev;
81 const struct of_device_id *match;
82
83 drv = to_of_platform_driver(dev->driver);
84 of_dev = to_of_device(dev);
85
86 if (!drv->probe)
87 return error;
88
89 of_dev_get(of_dev);
90
91 match = of_match_device(drv->match_table, of_dev);
92 if (match)
93 error = drv->probe(of_dev, match);
94 if (error)
95 of_dev_put(of_dev);
96
97 return error;
98}
99
100static int of_platform_device_remove(struct device *dev)
101{
102 struct of_device * of_dev = to_of_device(dev);
103 struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
104
105 if (dev->driver && drv->remove)
106 drv->remove(of_dev);
107 return 0;
108}
109
110static int of_platform_device_suspend(struct device *dev, pm_message_t state)
111{
112 struct of_device * of_dev = to_of_device(dev);
113 struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
114 int error = 0;
115
116 if (dev->driver && drv->suspend)
117 error = drv->suspend(of_dev, state);
118 return error;
119}
120
121static int of_platform_device_resume(struct device * dev)
122{
123 struct of_device * of_dev = to_of_device(dev);
124 struct of_platform_driver * drv = to_of_platform_driver(dev->driver);
125 int error = 0;
126
127 if (dev->driver && drv->resume)
128 error = drv->resume(of_dev);
129 return error;
130}
131
132struct bus_type of_platform_bus_type = {
133 .name = "of_platform",
134 .match = of_platform_bus_match,
135 .probe = of_platform_device_probe,
136 .remove = of_platform_device_remove,
137 .suspend = of_platform_device_suspend,
138 .resume = of_platform_device_resume,
139};
140EXPORT_SYMBOL(of_platform_bus_type);
141
142static int __init of_bus_driver_init(void)
143{
144 return bus_register(&of_platform_bus_type);
145}
146
147postcore_initcall(of_bus_driver_init);
148
149int of_register_platform_driver(struct of_platform_driver *drv)
150{
151 /* initialize common driver fields */
152 drv->driver.name = drv->name;
153 drv->driver.bus = &of_platform_bus_type;
154
155 /* register with core */
156 return driver_register(&drv->driver);
157}
158EXPORT_SYMBOL(of_register_platform_driver);
159
160void of_unregister_platform_driver(struct of_platform_driver *drv)
161{
162 driver_unregister(&drv->driver);
163}
164EXPORT_SYMBOL(of_unregister_platform_driver);
165
166static void of_platform_make_bus_id(struct of_device *dev)
167{
168 struct device_node *node = dev->node;
169 char *name = dev->dev.bus_id;
170 const u32 *reg;
171 u64 addr;
172 long magic;
173
174 /*
175 * If it's a DCR based device, use 'd' for native DCRs
176 * and 'D' for MMIO DCRs.
177 */
178#ifdef CONFIG_PPC_DCR
179 reg = get_property(node, "dcr-reg", NULL);
180 if (reg) {
181#ifdef CONFIG_PPC_DCR_NATIVE
182 snprintf(name, BUS_ID_SIZE, "d%x.%s",
183 *reg, node->name);
184#else /* CONFIG_PPC_DCR_NATIVE */
185 addr = of_translate_dcr_address(node, *reg, NULL);
186 if (addr != OF_BAD_ADDR) {
187 snprintf(name, BUS_ID_SIZE,
188 "D%llx.%s", (unsigned long long)addr,
189 node->name);
190 return;
191 }
192#endif /* !CONFIG_PPC_DCR_NATIVE */
193 }
194#endif /* CONFIG_PPC_DCR */
195
196 /*
197 * For MMIO, get the physical address
198 */
199 reg = get_property(node, "reg", NULL);
200 if (reg) {
201 addr = of_translate_address(node, reg);
202 if (addr != OF_BAD_ADDR) {
203 snprintf(name, BUS_ID_SIZE,
204 "%llx.%s", (unsigned long long)addr,
205 node->name);
206 return;
207 }
208 }
209
210 /*
211 * No BusID, use the node name and add a globally incremented
212 * counter (and pray...)
213 */
214 magic = atomic_add_return(1, &bus_no_reg_magic);
215 snprintf(name, BUS_ID_SIZE, "%s.%d", node->name, magic - 1);
216}
217
218struct of_device* of_platform_device_create(struct device_node *np,
219 const char *bus_id,
220 struct device *parent)
221{
222 struct of_device *dev;
223
224 dev = kmalloc(sizeof(*dev), GFP_KERNEL);
225 if (!dev)
226 return NULL;
227 memset(dev, 0, sizeof(*dev));
228
229 dev->node = of_node_get(np);
230 dev->dma_mask = 0xffffffffUL;
231 dev->dev.dma_mask = &dev->dma_mask;
232 dev->dev.parent = parent;
233 dev->dev.bus = &of_platform_bus_type;
234 dev->dev.release = of_release_dev;
235 dev->dev.archdata.of_node = np;
236 dev->dev.archdata.numa_node = of_node_to_nid(np);
237
238 /* We do not fill the DMA ops for platform devices by default.
239 * This is currently the responsibility of the platform code
240 * to do such, possibly using a device notifier
241 */
242
243 if (bus_id)
244 strlcpy(dev->dev.bus_id, bus_id, BUS_ID_SIZE);
245 else
246 of_platform_make_bus_id(dev);
247
248 if (of_device_register(dev) != 0) {
249 kfree(dev);
250 return NULL;
251 }
252
253 return dev;
254}
255EXPORT_SYMBOL(of_platform_device_create);
256
257
258
259/**
260 * of_platform_bus_create - Create an OF device for a bus node and all its
261 * children. Optionally recursively instanciate matching busses.
262 * @bus: device node of the bus to instanciate
263 * @matches: match table, NULL to use the default, OF_NO_DEEP_PROBE to
264 * disallow recursive creation of child busses
265 */
266static int of_platform_bus_create(struct device_node *bus,
267 struct of_device_id *matches,
268 struct device *parent)
269{
270 struct device_node *child;
271 struct of_device *dev;
272 int rc = 0;
273
274 for (child = NULL; (child = of_get_next_child(bus, child)); ) {
275 pr_debug(" create child: %s\n", child->full_name);
276 dev = of_platform_device_create(child, NULL, parent);
277 if (dev == NULL)
278 rc = -ENOMEM;
279 else if (!of_match_node(matches, child))
280 continue;
281 if (rc == 0) {
282 pr_debug(" and sub busses\n");
283 rc = of_platform_bus_create(child, matches, &dev->dev);
284 } if (rc) {
285 of_node_put(child);
286 break;
287 }
288 }
289 return rc;
290}
291
292/**
293 * of_platform_bus_probe - Probe the device-tree for platform busses
294 * @root: parent of the first level to probe or NULL for the root of the tree
295 * @matches: match table, NULL to use the default
296 * @parent: parent to hook devices from, NULL for toplevel
297 *
298 * Note that children of the provided root are not instanciated as devices
299 * unless the specified root itself matches the bus list and is not NULL.
300 */
301
302int of_platform_bus_probe(struct device_node *root,
303 struct of_device_id *matches,
304 struct device *parent)
305{
306 struct device_node *child;
307 struct of_device *dev;
308 int rc = 0;
309
310 if (matches == NULL)
311 matches = of_default_bus_ids;
312 if (matches == OF_NO_DEEP_PROBE)
313 return -EINVAL;
314 if (root == NULL)
315 root = of_find_node_by_path("/");
316 else
317 of_node_get(root);
318
319 pr_debug("of_platform_bus_probe()\n");
320 pr_debug(" starting at: %s\n", root->full_name);
321
322 /* Do a self check of bus type, if there's a match, create
323 * children
324 */
325 if (of_match_node(matches, root)) {
326 pr_debug(" root match, create all sub devices\n");
327 dev = of_platform_device_create(root, NULL, parent);
328 if (dev == NULL) {
329 rc = -ENOMEM;
330 goto bail;
331 }
332 pr_debug(" create all sub busses\n");
333 rc = of_platform_bus_create(root, matches, &dev->dev);
334 goto bail;
335 }
336 for (child = NULL; (child = of_get_next_child(root, child)); ) {
337 if (!of_match_node(matches, child))
338 continue;
339
340 pr_debug(" match: %s\n", child->full_name);
341 dev = of_platform_device_create(child, NULL, parent);
342 if (dev == NULL)
343 rc = -ENOMEM;
344 else
345 rc = of_platform_bus_create(child, matches, &dev->dev);
346 if (rc) {
347 of_node_put(child);
348 break;
349 }
350 }
351 bail:
352 of_node_put(root);
353 return rc;
354}
355EXPORT_SYMBOL(of_platform_bus_probe);
356
357static int of_dev_node_match(struct device *dev, void *data)
358{
359 return to_of_device(dev)->node == data;
360}
361
362struct of_device *of_find_device_by_node(struct device_node *np)
363{
364 struct device *dev;
365
366 dev = bus_find_device(&of_platform_bus_type,
367 NULL, np, of_dev_node_match);
368 if (dev)
369 return to_of_device(dev);
370 return NULL;
371}
372EXPORT_SYMBOL(of_find_device_by_node);
373
374static int of_dev_phandle_match(struct device *dev, void *data)
375{
376 phandle *ph = data;
377 return to_of_device(dev)->node->linux_phandle == *ph;
378}
379
380struct of_device *of_find_device_by_phandle(phandle ph)
381{
382 struct device *dev;
383
384 dev = bus_find_device(&of_platform_bus_type,
385 NULL, &ph, of_dev_phandle_match);
386 if (dev)
387 return to_of_device(dev);
388 return NULL;
389}
390EXPORT_SYMBOL(of_find_device_by_phandle);
391
392
393#ifdef CONFIG_PPC_OF_PLATFORM_PCI
394
395/* The probing of PCI controllers from of_platform is currently
396 * 64 bits only, mostly due to gratuitous differences between
397 * the 32 and 64 bits PCI code on PowerPC and the 32 bits one
398 * lacking some bits needed here.
399 */
400
401static int __devinit of_pci_phb_probe(struct of_device *dev,
402 const struct of_device_id *match)
403{
404 struct pci_controller *phb;
405
406 /* Check if we can do that ... */
407 if (ppc_md.pci_setup_phb == NULL)
408 return -ENODEV;
409
410 printk(KERN_INFO "Setting up PCI bus %s\n", dev->node->full_name);
411
412 /* Alloc and setup PHB data structure */
413 phb = pcibios_alloc_controller(dev->node);
414 if (!phb)
415 return -ENODEV;
416
417 /* Setup parent in sysfs */
418 phb->parent = &dev->dev;
419
420 /* Setup the PHB using arch provided callback */
421 if (ppc_md.pci_setup_phb(phb)) {
422 pcibios_free_controller(phb);
423 return -ENODEV;
424 }
425
426 /* Process "ranges" property */
427 pci_process_bridge_OF_ranges(phb, dev->node, 0);
428
429 /* Setup IO space.
430 * This will not work properly for ISA IOs, something needs to be done
431 * about it if we ever generalize that way of probing PCI brigdes
432 */
433 pci_setup_phb_io_dynamic(phb, 0);
434
435 /* Init pci_dn data structures */
436 pci_devs_phb_init_dynamic(phb);
437
438 /* Register devices with EEH */
439#ifdef CONFIG_EEH
440 if (dev->node->child)
441 eeh_add_device_tree_early(dev->node);
442#endif /* CONFIG_EEH */
443
444 /* Scan the bus */
445 scan_phb(phb);
446
447 /* Claim resources. This might need some rework as well depending
448 * wether we are doing probe-only or not, like assigning unassigned
449 * resources etc...
450 */
451 pcibios_claim_one_bus(phb->bus);
452
453 /* Finish EEH setup */
454#ifdef CONFIG_EEH
455 eeh_add_device_tree_late(phb->bus);
456#endif
457
458 /* Add probed PCI devices to the device model */
459 pci_bus_add_devices(phb->bus);
460
461 return 0;
462}
463
464static struct of_device_id of_pci_phb_ids[] = {
465 { .type = "pci", },
466 { .type = "pcix", },
467 { .type = "pcie", },
468 { .type = "pciex", },
469 { .type = "ht", },
470 {}
471};
472
473static struct of_platform_driver of_pci_phb_driver = {
474 .name = "of-pci",
475 .match_table = of_pci_phb_ids,
476 .probe = of_pci_phb_probe,
477 .driver = {
478 .multithread_probe = 1,
479 },
480};
481
482static __init int of_pci_phb_init(void)
483{
484 return of_register_platform_driver(&of_pci_phb_driver);
485}
486
487device_initcall(of_pci_phb_init);
488
489#endif /* CONFIG_PPC_OF_PLATFORM_PCI */
diff --git a/arch/powerpc/kernel/pci_32.c b/arch/powerpc/kernel/pci_32.c
index 0d9ff72e2852..2f54cd81dea5 100644
--- a/arch/powerpc/kernel/pci_32.c
+++ b/arch/powerpc/kernel/pci_32.c
@@ -12,6 +12,7 @@
12#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/bootmem.h> 13#include <linux/bootmem.h>
14#include <linux/irq.h> 14#include <linux/irq.h>
15#include <linux/list.h>
15 16
16#include <asm/processor.h> 17#include <asm/processor.h>
17#include <asm/io.h> 18#include <asm/io.h>
@@ -99,7 +100,7 @@ pcibios_fixup_resources(struct pci_dev *dev)
99 continue; 100 continue;
100 if (res->end == 0xffffffff) { 101 if (res->end == 0xffffffff) {
101 DBG("PCI:%s Resource %d [%016llx-%016llx] is unassigned\n", 102 DBG("PCI:%s Resource %d [%016llx-%016llx] is unassigned\n",
102 pci_name(dev), i, res->start, res->end); 103 pci_name(dev), i, (u64)res->start, (u64)res->end);
103 res->end -= res->start; 104 res->end -= res->start;
104 res->start = 0; 105 res->start = 0;
105 res->flags |= IORESOURCE_UNSET; 106 res->flags |= IORESOURCE_UNSET;
@@ -115,11 +116,9 @@ pcibios_fixup_resources(struct pci_dev *dev)
115 if (offset != 0) { 116 if (offset != 0) {
116 res->start += offset; 117 res->start += offset;
117 res->end += offset; 118 res->end += offset;
118#ifdef DEBUG 119 DBG("Fixup res %d (%lx) of dev %s: %llx -> %llx\n",
119 printk("Fixup res %d (%lx) of dev %s: %llx -> %llx\n", 120 i, res->flags, pci_name(dev),
120 i, res->flags, pci_name(dev), 121 (u64)res->start - offset, (u64)res->start);
121 res->start - offset, res->start);
122#endif
123 } 122 }
124 } 123 }
125 124
@@ -255,7 +254,7 @@ pcibios_allocate_bus_resources(struct list_head *bus_list)
255 } 254 }
256 255
257 DBG("PCI: bridge rsrc %llx..%llx (%lx), parent %p\n", 256 DBG("PCI: bridge rsrc %llx..%llx (%lx), parent %p\n",
258 res->start, res->end, res->flags, pr); 257 (u64)res->start, (u64)res->end, res->flags, pr);
259 if (pr) { 258 if (pr) {
260 if (request_resource(pr, res) == 0) 259 if (request_resource(pr, res) == 0)
261 continue; 260 continue;
@@ -306,7 +305,7 @@ reparent_resources(struct resource *parent, struct resource *res)
306 for (p = res->child; p != NULL; p = p->sibling) { 305 for (p = res->child; p != NULL; p = p->sibling) {
307 p->parent = res; 306 p->parent = res;
308 DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n", 307 DBG(KERN_INFO "PCI: reparented %s [%llx..%llx] under %s\n",
309 p->name, p->start, p->end, res->name); 308 p->name, (u64)p->start, (u64)p->end, res->name);
310 } 309 }
311 return 0; 310 return 0;
312} 311}
@@ -362,7 +361,7 @@ pci_relocate_bridge_resource(struct pci_bus *bus, int i)
362 } 361 }
363 if (request_resource(pr, res)) { 362 if (request_resource(pr, res)) {
364 DBG(KERN_ERR "PCI: huh? couldn't move to %llx..%llx\n", 363 DBG(KERN_ERR "PCI: huh? couldn't move to %llx..%llx\n",
365 res->start, res->end); 364 (u64)res->start, (u64)res->end);
366 return -1; /* "can't happen" */ 365 return -1; /* "can't happen" */
367 } 366 }
368 update_bridge_base(bus, i); 367 update_bridge_base(bus, i);
@@ -480,14 +479,14 @@ static inline void alloc_resource(struct pci_dev *dev, int idx)
480 struct resource *pr, *r = &dev->resource[idx]; 479 struct resource *pr, *r = &dev->resource[idx];
481 480
482 DBG("PCI:%s: Resource %d: %016llx-%016llx (f=%lx)\n", 481 DBG("PCI:%s: Resource %d: %016llx-%016llx (f=%lx)\n",
483 pci_name(dev), idx, r->start, r->end, r->flags); 482 pci_name(dev), idx, (u64)r->start, (u64)r->end, r->flags);
484 pr = pci_find_parent_resource(dev, r); 483 pr = pci_find_parent_resource(dev, r);
485 if (!pr || request_resource(pr, r) < 0) { 484 if (!pr || request_resource(pr, r) < 0) {
486 printk(KERN_ERR "PCI: Cannot allocate resource region %d" 485 printk(KERN_ERR "PCI: Cannot allocate resource region %d"
487 " of device %s\n", idx, pci_name(dev)); 486 " of device %s\n", idx, pci_name(dev));
488 if (pr) 487 if (pr)
489 DBG("PCI: parent is %p: %016llx-%016llx (f=%lx)\n", 488 DBG("PCI: parent is %p: %016llx-%016llx (f=%lx)\n",
490 pr, pr->start, pr->end, pr->flags); 489 pr, (u64)pr->start, (u64)pr->end, pr->flags);
491 /* We'll assign a new address later */ 490 /* We'll assign a new address later */
492 r->flags |= IORESOURCE_UNSET; 491 r->flags |= IORESOURCE_UNSET;
493 r->end -= r->start; 492 r->end -= r->start;
@@ -960,7 +959,7 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose,
960 res->flags = IORESOURCE_IO; 959 res->flags = IORESOURCE_IO;
961 res->start = ranges[2]; 960 res->start = ranges[2];
962 DBG("PCI: IO 0x%llx -> 0x%llx\n", 961 DBG("PCI: IO 0x%llx -> 0x%llx\n",
963 res->start, res->start + size - 1); 962 (u64)res->start, (u64)res->start + size - 1);
964 break; 963 break;
965 case 2: /* memory space */ 964 case 2: /* memory space */
966 memno = 0; 965 memno = 0;
@@ -982,7 +981,7 @@ pci_process_bridge_OF_ranges(struct pci_controller *hose,
982 res->flags |= IORESOURCE_PREFETCH; 981 res->flags |= IORESOURCE_PREFETCH;
983 res->start = ranges[na+2]; 982 res->start = ranges[na+2];
984 DBG("PCI: MEM[%d] 0x%llx -> 0x%llx\n", memno, 983 DBG("PCI: MEM[%d] 0x%llx -> 0x%llx\n", memno,
985 res->start, res->start + size - 1); 984 (u64)res->start, (u64)res->start + size - 1);
986 } 985 }
987 break; 986 break;
988 } 987 }
@@ -1268,7 +1267,10 @@ pcibios_init(void)
1268 if (pci_assign_all_buses) 1267 if (pci_assign_all_buses)
1269 hose->first_busno = next_busno; 1268 hose->first_busno = next_busno;
1270 hose->last_busno = 0xff; 1269 hose->last_busno = 0xff;
1271 bus = pci_scan_bus(hose->first_busno, hose->ops, hose); 1270 bus = pci_scan_bus_parented(hose->parent, hose->first_busno,
1271 hose->ops, hose);
1272 if (bus)
1273 pci_bus_add_devices(bus);
1272 hose->last_busno = bus->subordinate; 1274 hose->last_busno = bus->subordinate;
1273 if (pci_assign_all_buses || next_busno <= hose->last_busno) 1275 if (pci_assign_all_buses || next_busno <= hose->last_busno)
1274 next_busno = hose->last_busno + pcibios_assign_bus_offset; 1276 next_busno = hose->last_busno + pcibios_assign_bus_offset;
@@ -1282,10 +1284,6 @@ pcibios_init(void)
1282 if (pci_assign_all_buses && have_of) 1284 if (pci_assign_all_buses && have_of)
1283 pcibios_make_OF_bus_map(); 1285 pcibios_make_OF_bus_map();
1284 1286
1285 /* Do machine dependent PCI interrupt routing */
1286 if (ppc_md.pci_swizzle && ppc_md.pci_map_irq)
1287 pci_fixup_irqs(ppc_md.pci_swizzle, ppc_md.pci_map_irq);
1288
1289 /* Call machine dependent fixup */ 1287 /* Call machine dependent fixup */
1290 if (ppc_md.pcibios_fixup) 1288 if (ppc_md.pcibios_fixup)
1291 ppc_md.pcibios_fixup(); 1289 ppc_md.pcibios_fixup();
@@ -1308,25 +1306,6 @@ pcibios_init(void)
1308 1306
1309subsys_initcall(pcibios_init); 1307subsys_initcall(pcibios_init);
1310 1308
1311unsigned char __init
1312common_swizzle(struct pci_dev *dev, unsigned char *pinp)
1313{
1314 struct pci_controller *hose = dev->sysdata;
1315
1316 if (dev->bus->number != hose->first_busno) {
1317 u8 pin = *pinp;
1318 do {
1319 pin = bridge_swizzle(pin, PCI_SLOT(dev->devfn));
1320 /* Move up the chain of bridges. */
1321 dev = dev->bus->self;
1322 } while (dev->bus->self);
1323 *pinp = pin;
1324
1325 /* The slot is the idsel of the last bridge. */
1326 }
1327 return PCI_SLOT(dev->devfn);
1328}
1329
1330unsigned long resource_fixup(struct pci_dev * dev, struct resource * res, 1309unsigned long resource_fixup(struct pci_dev * dev, struct resource * res,
1331 unsigned long start, unsigned long size) 1310 unsigned long start, unsigned long size)
1332{ 1311{
@@ -1338,6 +1317,7 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
1338 struct pci_controller *hose = (struct pci_controller *) bus->sysdata; 1317 struct pci_controller *hose = (struct pci_controller *) bus->sysdata;
1339 unsigned long io_offset; 1318 unsigned long io_offset;
1340 struct resource *res; 1319 struct resource *res;
1320 struct pci_dev *dev;
1341 int i; 1321 int i;
1342 1322
1343 io_offset = (unsigned long)hose->io_base_virt - isa_io_base; 1323 io_offset = (unsigned long)hose->io_base_virt - isa_io_base;
@@ -1390,8 +1370,16 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
1390 } 1370 }
1391 } 1371 }
1392 1372
1373 /* Platform specific bus fixups */
1393 if (ppc_md.pcibios_fixup_bus) 1374 if (ppc_md.pcibios_fixup_bus)
1394 ppc_md.pcibios_fixup_bus(bus); 1375 ppc_md.pcibios_fixup_bus(bus);
1376
1377 /* Read default IRQs and fixup if necessary */
1378 list_for_each_entry(dev, &bus->devices, bus_list) {
1379 pci_read_irq_line(dev);
1380 if (ppc_md.pci_irq_fixup)
1381 ppc_md.pci_irq_fixup(dev);
1382 }
1395} 1383}
1396 1384
1397char __init *pcibios_setup(char *str) 1385char __init *pcibios_setup(char *str)
@@ -1571,7 +1559,7 @@ static struct resource *__pci_mmap_make_offset(struct pci_dev *dev,
1571 *offset += hose->pci_mem_offset; 1559 *offset += hose->pci_mem_offset;
1572 res_bit = IORESOURCE_MEM; 1560 res_bit = IORESOURCE_MEM;
1573 } else { 1561 } else {
1574 io_offset = hose->io_base_virt - ___IO_BASE; 1562 io_offset = hose->io_base_virt - (void __iomem *)_IO_BASE;
1575 *offset += io_offset; 1563 *offset += io_offset;
1576 res_bit = IORESOURCE_IO; 1564 res_bit = IORESOURCE_IO;
1577 } 1565 }
@@ -1826,7 +1814,8 @@ void pci_resource_to_user(const struct pci_dev *dev, int bar,
1826 return; 1814 return;
1827 1815
1828 if (rsrc->flags & IORESOURCE_IO) 1816 if (rsrc->flags & IORESOURCE_IO)
1829 offset = ___IO_BASE - hose->io_base_virt + hose->io_base_phys; 1817 offset = (void __iomem *)_IO_BASE - hose->io_base_virt
1818 + hose->io_base_phys;
1830 1819
1831 *start = rsrc->start + offset; 1820 *start = rsrc->start + offset;
1832 *end = rsrc->end + offset; 1821 *end = rsrc->end + offset;
@@ -1845,35 +1834,6 @@ pci_init_resource(struct resource *res, unsigned long start, unsigned long end,
1845 res->child = NULL; 1834 res->child = NULL;
1846} 1835}
1847 1836
1848void __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long max)
1849{
1850 unsigned long start = pci_resource_start(dev, bar);
1851 unsigned long len = pci_resource_len(dev, bar);
1852 unsigned long flags = pci_resource_flags(dev, bar);
1853
1854 if (!len)
1855 return NULL;
1856 if (max && len > max)
1857 len = max;
1858 if (flags & IORESOURCE_IO)
1859 return ioport_map(start, len);
1860 if (flags & IORESOURCE_MEM)
1861 /* Not checking IORESOURCE_CACHEABLE because PPC does
1862 * not currently distinguish between ioremap and
1863 * ioremap_nocache.
1864 */
1865 return ioremap(start, len);
1866 /* What? */
1867 return NULL;
1868}
1869
1870void pci_iounmap(struct pci_dev *dev, void __iomem *addr)
1871{
1872 /* Nothing to do */
1873}
1874EXPORT_SYMBOL(pci_iomap);
1875EXPORT_SYMBOL(pci_iounmap);
1876
1877unsigned long pci_address_to_pio(phys_addr_t address) 1837unsigned long pci_address_to_pio(phys_addr_t address)
1878{ 1838{
1879 struct pci_controller* hose = hose_head; 1839 struct pci_controller* hose = hose_head;
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 9bae8a5bf671..6fa9a0a5c8db 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -42,11 +42,9 @@
42unsigned long pci_probe_only = 1; 42unsigned long pci_probe_only = 1;
43int pci_assign_all_buses = 0; 43int pci_assign_all_buses = 0;
44 44
45#ifdef CONFIG_PPC_MULTIPLATFORM
46static void fixup_resource(struct resource *res, struct pci_dev *dev); 45static void fixup_resource(struct resource *res, struct pci_dev *dev);
47static void do_bus_setup(struct pci_bus *bus); 46static void do_bus_setup(struct pci_bus *bus);
48static void phbs_remap_io(void); 47static void phbs_remap_io(void);
49#endif
50 48
51/* pci_io_base -- the base address from which io bars are offsets. 49/* pci_io_base -- the base address from which io bars are offsets.
52 * This is the lowest I/O base address (so bar values are always positive), 50 * This is the lowest I/O base address (so bar values are always positive),
@@ -63,7 +61,7 @@ void iSeries_pcibios_init(void);
63 61
64LIST_HEAD(hose_list); 62LIST_HEAD(hose_list);
65 63
66struct dma_mapping_ops pci_dma_ops; 64struct dma_mapping_ops *pci_dma_ops;
67EXPORT_SYMBOL(pci_dma_ops); 65EXPORT_SYMBOL(pci_dma_ops);
68 66
69int global_phb_number; /* Global phb counter */ 67int global_phb_number; /* Global phb counter */
@@ -212,6 +210,10 @@ struct pci_controller * pcibios_alloc_controller(struct device_node *dev)
212 210
213void pcibios_free_controller(struct pci_controller *phb) 211void pcibios_free_controller(struct pci_controller *phb)
214{ 212{
213 spin_lock(&hose_spinlock);
214 list_del(&phb->list_node);
215 spin_unlock(&hose_spinlock);
216
215 if (phb->is_dynamic) 217 if (phb->is_dynamic)
216 kfree(phb); 218 kfree(phb);
217} 219}
@@ -251,7 +253,6 @@ static void __init pcibios_claim_of_setup(void)
251 pcibios_claim_one_bus(b); 253 pcibios_claim_one_bus(b);
252} 254}
253 255
254#ifdef CONFIG_PPC_MULTIPLATFORM
255static u32 get_int_prop(struct device_node *np, const char *name, u32 def) 256static u32 get_int_prop(struct device_node *np, const char *name, u32 def)
256{ 257{
257 const u32 *prop; 258 const u32 *prop;
@@ -329,7 +330,7 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
329 struct pci_dev *dev; 330 struct pci_dev *dev;
330 const char *type; 331 const char *type;
331 332
332 dev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL); 333 dev = kzalloc(sizeof(struct pci_dev), GFP_KERNEL);
333 if (!dev) 334 if (!dev)
334 return NULL; 335 return NULL;
335 type = get_property(node, "device_type", NULL); 336 type = get_property(node, "device_type", NULL);
@@ -338,7 +339,6 @@ struct pci_dev *of_create_pci_dev(struct device_node *node,
338 339
339 DBG(" create device, devfn: %x, type: %s\n", devfn, type); 340 DBG(" create device, devfn: %x, type: %s\n", devfn, type);
340 341
341 memset(dev, 0, sizeof(struct pci_dev));
342 dev->bus = bus; 342 dev->bus = bus;
343 dev->sysdata = node; 343 dev->sysdata = node;
344 dev->dev.parent = bus->bridge; 344 dev->dev.parent = bus->bridge;
@@ -506,7 +506,6 @@ void __devinit of_scan_pci_bridge(struct device_node *node,
506 pci_scan_child_bus(bus); 506 pci_scan_child_bus(bus);
507} 507}
508EXPORT_SYMBOL(of_scan_pci_bridge); 508EXPORT_SYMBOL(of_scan_pci_bridge);
509#endif /* CONFIG_PPC_MULTIPLATFORM */
510 509
511void __devinit scan_phb(struct pci_controller *hose) 510void __devinit scan_phb(struct pci_controller *hose)
512{ 511{
@@ -517,7 +516,7 @@ void __devinit scan_phb(struct pci_controller *hose)
517 516
518 DBG("Scanning PHB %s\n", node ? node->full_name : "<NO NAME>"); 517 DBG("Scanning PHB %s\n", node ? node->full_name : "<NO NAME>");
519 518
520 bus = pci_create_bus(NULL, hose->first_busno, hose->ops, node); 519 bus = pci_create_bus(hose->parent, hose->first_busno, hose->ops, node);
521 if (bus == NULL) { 520 if (bus == NULL) {
522 printk(KERN_ERR "Failed to create bus for PCI domain %04x\n", 521 printk(KERN_ERR "Failed to create bus for PCI domain %04x\n",
523 hose->global_number); 522 hose->global_number);
@@ -540,7 +539,7 @@ void __devinit scan_phb(struct pci_controller *hose)
540 } 539 }
541 540
542 mode = PCI_PROBE_NORMAL; 541 mode = PCI_PROBE_NORMAL;
543#ifdef CONFIG_PPC_MULTIPLATFORM 542
544 if (node && ppc_md.pci_probe_mode) 543 if (node && ppc_md.pci_probe_mode)
545 mode = ppc_md.pci_probe_mode(bus); 544 mode = ppc_md.pci_probe_mode(bus);
546 DBG(" probe mode: %d\n", mode); 545 DBG(" probe mode: %d\n", mode);
@@ -548,7 +547,7 @@ void __devinit scan_phb(struct pci_controller *hose)
548 bus->subordinate = hose->last_busno; 547 bus->subordinate = hose->last_busno;
549 of_scan_bus(node, bus); 548 of_scan_bus(node, bus);
550 } 549 }
551#endif /* CONFIG_PPC_MULTIPLATFORM */ 550
552 if (mode == PCI_PROBE_NORMAL) 551 if (mode == PCI_PROBE_NORMAL)
553 hose->last_busno = bus->subordinate = pci_scan_child_bus(bus); 552 hose->last_busno = bus->subordinate = pci_scan_child_bus(bus);
554} 553}
@@ -592,11 +591,9 @@ static int __init pcibios_init(void)
592 if (ppc64_isabridge_dev != NULL) 591 if (ppc64_isabridge_dev != NULL)
593 printk(KERN_DEBUG "ISA bridge at %s\n", pci_name(ppc64_isabridge_dev)); 592 printk(KERN_DEBUG "ISA bridge at %s\n", pci_name(ppc64_isabridge_dev));
594 593
595#ifdef CONFIG_PPC_MULTIPLATFORM
596 if (!firmware_has_feature(FW_FEATURE_ISERIES)) 594 if (!firmware_has_feature(FW_FEATURE_ISERIES))
597 /* map in PCI I/O space */ 595 /* map in PCI I/O space */
598 phbs_remap_io(); 596 phbs_remap_io();
599#endif
600 597
601 printk(KERN_DEBUG "PCI: Probing PCI hardware done\n"); 598 printk(KERN_DEBUG "PCI: Probing PCI hardware done\n");
602 599
@@ -873,8 +870,6 @@ void pcibios_add_platform_entries(struct pci_dev *pdev)
873 device_create_file(&pdev->dev, &dev_attr_devspec); 870 device_create_file(&pdev->dev, &dev_attr_devspec);
874} 871}
875 872
876#ifdef CONFIG_PPC_MULTIPLATFORM
877
878#define ISA_SPACE_MASK 0x1 873#define ISA_SPACE_MASK 0x1
879#define ISA_SPACE_IO 0x1 874#define ISA_SPACE_IO 0x1
880 875
@@ -975,11 +970,7 @@ void __devinit pci_process_bridge_OF_ranges(struct pci_controller *hose,
975 res = NULL; 970 res = NULL;
976 pci_space = ranges[0]; 971 pci_space = ranges[0];
977 pci_addr = ((unsigned long)ranges[1] << 32) | ranges[2]; 972 pci_addr = ((unsigned long)ranges[1] << 32) | ranges[2];
978 973 cpu_phys_addr = of_translate_address(dev, &ranges[3]);
979 cpu_phys_addr = ranges[3];
980 if (na >= 2)
981 cpu_phys_addr = (cpu_phys_addr << 32) | ranges[4];
982
983 size = ((unsigned long)ranges[na+3] << 32) | ranges[na+4]; 974 size = ((unsigned long)ranges[na+3] << 32) | ranges[na+4];
984 ranges += np; 975 ranges += np;
985 if (size == 0) 976 if (size == 0)
@@ -1145,7 +1136,7 @@ int unmap_bus_range(struct pci_bus *bus)
1145 1136
1146 if (get_bus_io_range(bus, &start_phys, &start_virt, &size)) 1137 if (get_bus_io_range(bus, &start_phys, &start_virt, &size))
1147 return 1; 1138 return 1;
1148 if (iounmap_explicit((void __iomem *) start_virt, size)) 1139 if (__iounmap_explicit((void __iomem *) start_virt, size))
1149 return 1; 1140 return 1;
1150 1141
1151 return 0; 1142 return 0;
@@ -1213,23 +1204,52 @@ void __devinit pcibios_fixup_device_resources(struct pci_dev *dev,
1213} 1204}
1214EXPORT_SYMBOL(pcibios_fixup_device_resources); 1205EXPORT_SYMBOL(pcibios_fixup_device_resources);
1215 1206
1207void __devinit pcibios_setup_new_device(struct pci_dev *dev)
1208{
1209 struct dev_archdata *sd = &dev->dev.archdata;
1210
1211 sd->of_node = pci_device_to_OF_node(dev);
1212
1213 DBG("PCI device %s OF node: %s\n", pci_name(dev),
1214 sd->of_node ? sd->of_node->full_name : "<none>");
1215
1216 sd->dma_ops = pci_dma_ops;
1217#ifdef CONFIG_NUMA
1218 sd->numa_node = pcibus_to_node(dev->bus);
1219#else
1220 sd->numa_node = -1;
1221#endif
1222 if (ppc_md.pci_dma_dev_setup)
1223 ppc_md.pci_dma_dev_setup(dev);
1224}
1225EXPORT_SYMBOL(pcibios_setup_new_device);
1216 1226
1217static void __devinit do_bus_setup(struct pci_bus *bus) 1227static void __devinit do_bus_setup(struct pci_bus *bus)
1218{ 1228{
1219 struct pci_dev *dev; 1229 struct pci_dev *dev;
1220 1230
1221 ppc_md.iommu_bus_setup(bus); 1231 if (ppc_md.pci_dma_bus_setup)
1232 ppc_md.pci_dma_bus_setup(bus);
1222 1233
1223 list_for_each_entry(dev, &bus->devices, bus_list) 1234 list_for_each_entry(dev, &bus->devices, bus_list)
1224 ppc_md.iommu_dev_setup(dev); 1235 pcibios_setup_new_device(dev);
1225 1236
1226 if (ppc_md.irq_bus_setup) 1237 /* Read default IRQs and fixup if necessary */
1227 ppc_md.irq_bus_setup(bus); 1238 list_for_each_entry(dev, &bus->devices, bus_list) {
1239 pci_read_irq_line(dev);
1240 if (ppc_md.pci_irq_fixup)
1241 ppc_md.pci_irq_fixup(dev);
1242 }
1228} 1243}
1229 1244
1230void __devinit pcibios_fixup_bus(struct pci_bus *bus) 1245void __devinit pcibios_fixup_bus(struct pci_bus *bus)
1231{ 1246{
1232 struct pci_dev *dev = bus->self; 1247 struct pci_dev *dev = bus->self;
1248 struct device_node *np;
1249
1250 np = pci_bus_to_OF_node(bus);
1251
1252 DBG("pcibios_fixup_bus(%s)\n", np ? np->full_name : "<???>");
1233 1253
1234 if (dev && pci_probe_only && 1254 if (dev && pci_probe_only &&
1235 (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) { 1255 (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI) {
@@ -1343,8 +1363,6 @@ struct pci_controller* pci_find_hose_for_OF_device(struct device_node* node)
1343 return NULL; 1363 return NULL;
1344} 1364}
1345 1365
1346#endif /* CONFIG_PPC_MULTIPLATFORM */
1347
1348unsigned long pci_address_to_pio(phys_addr_t address) 1366unsigned long pci_address_to_pio(phys_addr_t address)
1349{ 1367{
1350 struct pci_controller *hose, *tmp; 1368 struct pci_controller *hose, *tmp;
diff --git a/arch/powerpc/kernel/pci_direct_iommu.c b/arch/powerpc/kernel/pci_direct_iommu.c
deleted file mode 100644
index 72ce082ce738..000000000000
--- a/arch/powerpc/kernel/pci_direct_iommu.c
+++ /dev/null
@@ -1,98 +0,0 @@
1/*
2 * Support for DMA from PCI devices to main memory on
3 * machines without an iommu or with directly addressable
4 * RAM (typically a pmac with 2Gb of RAM or less)
5 *
6 * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.org)
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version
11 * 2 of the License, or (at your option) any later version.
12 */
13
14#include <linux/kernel.h>
15#include <linux/pci.h>
16#include <linux/delay.h>
17#include <linux/string.h>
18#include <linux/init.h>
19#include <linux/bootmem.h>
20#include <linux/mm.h>
21#include <linux/dma-mapping.h>
22
23#include <asm/sections.h>
24#include <asm/io.h>
25#include <asm/prom.h>
26#include <asm/pci-bridge.h>
27#include <asm/machdep.h>
28#include <asm/pmac_feature.h>
29#include <asm/abs_addr.h>
30#include <asm/ppc-pci.h>
31
32static void *pci_direct_alloc_coherent(struct device *hwdev, size_t size,
33 dma_addr_t *dma_handle, gfp_t flag)
34{
35 void *ret;
36
37 ret = (void *)__get_free_pages(flag, get_order(size));
38 if (ret != NULL) {
39 memset(ret, 0, size);
40 *dma_handle = virt_to_abs(ret);
41 }
42 return ret;
43}
44
45static void pci_direct_free_coherent(struct device *hwdev, size_t size,
46 void *vaddr, dma_addr_t dma_handle)
47{
48 free_pages((unsigned long)vaddr, get_order(size));
49}
50
51static dma_addr_t pci_direct_map_single(struct device *hwdev, void *ptr,
52 size_t size, enum dma_data_direction direction)
53{
54 return virt_to_abs(ptr);
55}
56
57static void pci_direct_unmap_single(struct device *hwdev, dma_addr_t dma_addr,
58 size_t size, enum dma_data_direction direction)
59{
60}
61
62static int pci_direct_map_sg(struct device *hwdev, struct scatterlist *sg,
63 int nents, enum dma_data_direction direction)
64{
65 int i;
66
67 for (i = 0; i < nents; i++, sg++) {
68 sg->dma_address = page_to_phys(sg->page) + sg->offset;
69 sg->dma_length = sg->length;
70 }
71
72 return nents;
73}
74
75static void pci_direct_unmap_sg(struct device *hwdev, struct scatterlist *sg,
76 int nents, enum dma_data_direction direction)
77{
78}
79
80static int pci_direct_dma_supported(struct device *dev, u64 mask)
81{
82 return mask < 0x100000000ull;
83}
84
85static struct dma_mapping_ops pci_direct_ops = {
86 .alloc_coherent = pci_direct_alloc_coherent,
87 .free_coherent = pci_direct_free_coherent,
88 .map_single = pci_direct_map_single,
89 .unmap_single = pci_direct_unmap_single,
90 .map_sg = pci_direct_map_sg,
91 .unmap_sg = pci_direct_unmap_sg,
92 .dma_supported = pci_direct_dma_supported,
93};
94
95void __init pci_direct_iommu_init(void)
96{
97 pci_dma_ops = pci_direct_ops;
98}
diff --git a/arch/powerpc/kernel/pci_iommu.c b/arch/powerpc/kernel/pci_iommu.c
deleted file mode 100644
index 0688b2534acb..000000000000
--- a/arch/powerpc/kernel/pci_iommu.c
+++ /dev/null
@@ -1,164 +0,0 @@
1/*
2 * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation
3 *
4 * Rewrite, cleanup, new allocation schemes:
5 * Copyright (C) 2004 Olof Johansson, IBM Corporation
6 *
7 * Dynamic DMA mapping support, platform-independent parts.
8 *
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 */
23
24
25#include <linux/init.h>
26#include <linux/types.h>
27#include <linux/slab.h>
28#include <linux/mm.h>
29#include <linux/spinlock.h>
30#include <linux/string.h>
31#include <linux/pci.h>
32#include <linux/dma-mapping.h>
33#include <asm/io.h>
34#include <asm/prom.h>
35#include <asm/iommu.h>
36#include <asm/pci-bridge.h>
37#include <asm/machdep.h>
38#include <asm/ppc-pci.h>
39
40/*
41 * We can use ->sysdata directly and avoid the extra work in
42 * pci_device_to_OF_node since ->sysdata will have been initialised
43 * in the iommu init code for all devices.
44 */
45#define PCI_GET_DN(dev) ((struct device_node *)((dev)->sysdata))
46
47static inline struct iommu_table *device_to_table(struct device *hwdev)
48{
49 struct pci_dev *pdev;
50
51 if (!hwdev) {
52 pdev = ppc64_isabridge_dev;
53 if (!pdev)
54 return NULL;
55 } else
56 pdev = to_pci_dev(hwdev);
57
58 return PCI_DN(PCI_GET_DN(pdev))->iommu_table;
59}
60
61
62static inline unsigned long device_to_mask(struct device *hwdev)
63{
64 struct pci_dev *pdev;
65
66 if (!hwdev) {
67 pdev = ppc64_isabridge_dev;
68 if (!pdev) /* This is the best guess we can do */
69 return 0xfffffffful;
70 } else
71 pdev = to_pci_dev(hwdev);
72
73 if (pdev->dma_mask)
74 return pdev->dma_mask;
75
76 /* Assume devices without mask can take 32 bit addresses */
77 return 0xfffffffful;
78}
79
80
81/* Allocates a contiguous real buffer and creates mappings over it.
82 * Returns the virtual address of the buffer and sets dma_handle
83 * to the dma address (mapping) of the first page.
84 */
85static void *pci_iommu_alloc_coherent(struct device *hwdev, size_t size,
86 dma_addr_t *dma_handle, gfp_t flag)
87{
88 return iommu_alloc_coherent(device_to_table(hwdev), size, dma_handle,
89 device_to_mask(hwdev), flag,
90 pcibus_to_node(to_pci_dev(hwdev)->bus));
91}
92
93static void pci_iommu_free_coherent(struct device *hwdev, size_t size,
94 void *vaddr, dma_addr_t dma_handle)
95{
96 iommu_free_coherent(device_to_table(hwdev), size, vaddr, dma_handle);
97}
98
99/* Creates TCEs for a user provided buffer. The user buffer must be
100 * contiguous real kernel storage (not vmalloc). The address of the buffer
101 * passed here is the kernel (virtual) address of the buffer. The buffer
102 * need not be page aligned, the dma_addr_t returned will point to the same
103 * byte within the page as vaddr.
104 */
105static dma_addr_t pci_iommu_map_single(struct device *hwdev, void *vaddr,
106 size_t size, enum dma_data_direction direction)
107{
108 return iommu_map_single(device_to_table(hwdev), vaddr, size,
109 device_to_mask(hwdev), direction);
110}
111
112
113static void pci_iommu_unmap_single(struct device *hwdev, dma_addr_t dma_handle,
114 size_t size, enum dma_data_direction direction)
115{
116 iommu_unmap_single(device_to_table(hwdev), dma_handle, size, direction);
117}
118
119
120static int pci_iommu_map_sg(struct device *pdev, struct scatterlist *sglist,
121 int nelems, enum dma_data_direction direction)
122{
123 return iommu_map_sg(pdev, device_to_table(pdev), sglist,
124 nelems, device_to_mask(pdev), direction);
125}
126
127static void pci_iommu_unmap_sg(struct device *pdev, struct scatterlist *sglist,
128 int nelems, enum dma_data_direction direction)
129{
130 iommu_unmap_sg(device_to_table(pdev), sglist, nelems, direction);
131}
132
133/* We support DMA to/from any memory page via the iommu */
134static int pci_iommu_dma_supported(struct device *dev, u64 mask)
135{
136 struct iommu_table *tbl = device_to_table(dev);
137
138 if (!tbl || tbl->it_offset > mask) {
139 printk(KERN_INFO "Warning: IOMMU table offset too big for device mask\n");
140 if (tbl)
141 printk(KERN_INFO "mask: 0x%08lx, table offset: 0x%08lx\n",
142 mask, tbl->it_offset);
143 else
144 printk(KERN_INFO "mask: 0x%08lx, table unavailable\n",
145 mask);
146 return 0;
147 } else
148 return 1;
149}
150
151struct dma_mapping_ops pci_iommu_ops = {
152 .alloc_coherent = pci_iommu_alloc_coherent,
153 .free_coherent = pci_iommu_free_coherent,
154 .map_single = pci_iommu_map_single,
155 .unmap_single = pci_iommu_unmap_single,
156 .map_sg = pci_iommu_map_sg,
157 .unmap_sg = pci_iommu_unmap_sg,
158 .dma_supported = pci_iommu_dma_supported,
159};
160
161void pci_iommu_init(void)
162{
163 pci_dma_ops = pci_iommu_ops;
164}
diff --git a/arch/powerpc/kernel/ppc_ksyms.c b/arch/powerpc/kernel/ppc_ksyms.c
index 807193a3c784..9179f0739ea2 100644
--- a/arch/powerpc/kernel/ppc_ksyms.c
+++ b/arch/powerpc/kernel/ppc_ksyms.c
@@ -49,6 +49,10 @@
49#include <asm/commproc.h> 49#include <asm/commproc.h>
50#endif 50#endif
51 51
52#ifdef CONFIG_PPC64
53EXPORT_SYMBOL(local_irq_restore);
54#endif
55
52#ifdef CONFIG_PPC32 56#ifdef CONFIG_PPC32
53extern void transfer_to_handler(void); 57extern void transfer_to_handler(void);
54extern void do_IRQ(struct pt_regs *regs); 58extern void do_IRQ(struct pt_regs *regs);
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index bdb412d4b748..c18dbe77fdc2 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -538,35 +538,31 @@ static struct ibm_pa_feature {
538 {CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0}, 538 {CPU_FTR_REAL_LE, PPC_FEATURE_TRUE_LE, 5, 0, 0},
539}; 539};
540 540
541static void __init check_cpu_pa_features(unsigned long node) 541static void __init scan_features(unsigned long node, unsigned char *ftrs,
542 unsigned long tablelen,
543 struct ibm_pa_feature *fp,
544 unsigned long ft_size)
542{ 545{
543 unsigned char *pa_ftrs; 546 unsigned long i, len, bit;
544 unsigned long len, tablelen, i, bit;
545
546 pa_ftrs = of_get_flat_dt_prop(node, "ibm,pa-features", &tablelen);
547 if (pa_ftrs == NULL)
548 return;
549 547
550 /* find descriptor with type == 0 */ 548 /* find descriptor with type == 0 */
551 for (;;) { 549 for (;;) {
552 if (tablelen < 3) 550 if (tablelen < 3)
553 return; 551 return;
554 len = 2 + pa_ftrs[0]; 552 len = 2 + ftrs[0];
555 if (tablelen < len) 553 if (tablelen < len)
556 return; /* descriptor 0 not found */ 554 return; /* descriptor 0 not found */
557 if (pa_ftrs[1] == 0) 555 if (ftrs[1] == 0)
558 break; 556 break;
559 tablelen -= len; 557 tablelen -= len;
560 pa_ftrs += len; 558 ftrs += len;
561 } 559 }
562 560
563 /* loop over bits we know about */ 561 /* loop over bits we know about */
564 for (i = 0; i < ARRAY_SIZE(ibm_pa_features); ++i) { 562 for (i = 0; i < ft_size; ++i, ++fp) {
565 struct ibm_pa_feature *fp = &ibm_pa_features[i]; 563 if (fp->pabyte >= ftrs[0])
566
567 if (fp->pabyte >= pa_ftrs[0])
568 continue; 564 continue;
569 bit = (pa_ftrs[2 + fp->pabyte] >> (7 - fp->pabit)) & 1; 565 bit = (ftrs[2 + fp->pabyte] >> (7 - fp->pabit)) & 1;
570 if (bit ^ fp->invert) { 566 if (bit ^ fp->invert) {
571 cur_cpu_spec->cpu_features |= fp->cpu_features; 567 cur_cpu_spec->cpu_features |= fp->cpu_features;
572 cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftrs; 568 cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftrs;
@@ -577,16 +573,59 @@ static void __init check_cpu_pa_features(unsigned long node)
577 } 573 }
578} 574}
579 575
576static void __init check_cpu_pa_features(unsigned long node)
577{
578 unsigned char *pa_ftrs;
579 unsigned long tablelen;
580
581 pa_ftrs = of_get_flat_dt_prop(node, "ibm,pa-features", &tablelen);
582 if (pa_ftrs == NULL)
583 return;
584
585 scan_features(node, pa_ftrs, tablelen,
586 ibm_pa_features, ARRAY_SIZE(ibm_pa_features));
587}
588
589static struct feature_property {
590 const char *name;
591 u32 min_value;
592 unsigned long cpu_feature;
593 unsigned long cpu_user_ftr;
594} feature_properties[] __initdata = {
595#ifdef CONFIG_ALTIVEC
596 {"altivec", 0, CPU_FTR_ALTIVEC, PPC_FEATURE_HAS_ALTIVEC},
597 {"ibm,vmx", 1, CPU_FTR_ALTIVEC, PPC_FEATURE_HAS_ALTIVEC},
598#endif /* CONFIG_ALTIVEC */
599#ifdef CONFIG_PPC64
600 {"ibm,dfp", 1, 0, PPC_FEATURE_HAS_DFP},
601 {"ibm,purr", 1, CPU_FTR_PURR, 0},
602 {"ibm,spurr", 1, CPU_FTR_SPURR, 0},
603#endif /* CONFIG_PPC64 */
604};
605
606static void __init check_cpu_feature_properties(unsigned long node)
607{
608 unsigned long i;
609 struct feature_property *fp = feature_properties;
610 const u32 *prop;
611
612 for (i = 0; i < ARRAY_SIZE(feature_properties); ++i, ++fp) {
613 prop = of_get_flat_dt_prop(node, fp->name, NULL);
614 if (prop && *prop >= fp->min_value) {
615 cur_cpu_spec->cpu_features |= fp->cpu_feature;
616 cur_cpu_spec->cpu_user_features |= fp->cpu_user_ftr;
617 }
618 }
619}
620
580static int __init early_init_dt_scan_cpus(unsigned long node, 621static int __init early_init_dt_scan_cpus(unsigned long node,
581 const char *uname, int depth, 622 const char *uname, int depth,
582 void *data) 623 void *data)
583{ 624{
584 static int logical_cpuid = 0; 625 static int logical_cpuid = 0;
585 char *type = of_get_flat_dt_prop(node, "device_type", NULL); 626 char *type = of_get_flat_dt_prop(node, "device_type", NULL);
586#ifdef CONFIG_ALTIVEC 627 const u32 *prop;
587 u32 *prop; 628 const u32 *intserv;
588#endif
589 u32 *intserv;
590 int i, nthreads; 629 int i, nthreads;
591 unsigned long len; 630 unsigned long len;
592 int found = 0; 631 int found = 0;
@@ -643,24 +682,27 @@ static int __init early_init_dt_scan_cpus(unsigned long node,
643 intserv[i]); 682 intserv[i]);
644 boot_cpuid = logical_cpuid; 683 boot_cpuid = logical_cpuid;
645 set_hard_smp_processor_id(boot_cpuid, intserv[i]); 684 set_hard_smp_processor_id(boot_cpuid, intserv[i]);
646 }
647 685
648#ifdef CONFIG_ALTIVEC 686 /*
649 /* Check if we have a VMX and eventually update CPU features */ 687 * PAPR defines "logical" PVR values for cpus that
650 prop = (u32 *)of_get_flat_dt_prop(node, "ibm,vmx", NULL); 688 * meet various levels of the architecture:
651 if (prop && (*prop) > 0) { 689 * 0x0f000001 Architecture version 2.04
652 cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC; 690 * 0x0f000002 Architecture version 2.05
653 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC; 691 * If the cpu-version property in the cpu node contains
654 } 692 * such a value, we call identify_cpu again with the
655 693 * logical PVR value in order to use the cpu feature
656 /* Same goes for Apple's "altivec" property */ 694 * bits appropriate for the architecture level.
657 prop = (u32 *)of_get_flat_dt_prop(node, "altivec", NULL); 695 *
658 if (prop) { 696 * A POWER6 partition in "POWER6 architected" mode
659 cur_cpu_spec->cpu_features |= CPU_FTR_ALTIVEC; 697 * uses the 0x0f000002 PVR value; in POWER5+ mode
660 cur_cpu_spec->cpu_user_features |= PPC_FEATURE_HAS_ALTIVEC; 698 * it uses 0x0f000001.
699 */
700 prop = of_get_flat_dt_prop(node, "cpu-version", NULL);
701 if (prop && (*prop & 0xff000000) == 0x0f000000)
702 identify_cpu(0, *prop);
661 } 703 }
662#endif /* CONFIG_ALTIVEC */
663 704
705 check_cpu_feature_properties(node);
664 check_cpu_pa_features(node); 706 check_cpu_pa_features(node);
665 707
666#ifdef CONFIG_PPC_PSERIES 708#ifdef CONFIG_PPC_PSERIES
@@ -1674,6 +1716,7 @@ struct device_node *of_get_cpu_node(int cpu, unsigned int *thread)
1674 } 1716 }
1675 return NULL; 1717 return NULL;
1676} 1718}
1719EXPORT_SYMBOL(of_get_cpu_node);
1677 1720
1678#ifdef DEBUG 1721#ifdef DEBUG
1679static struct debugfs_blob_wrapper flat_dt_blob; 1722static struct debugfs_blob_wrapper flat_dt_blob;
diff --git a/arch/powerpc/kernel/prom_init.c b/arch/powerpc/kernel/prom_init.c
index b91761639d96..46cf32670ddb 100644
--- a/arch/powerpc/kernel/prom_init.c
+++ b/arch/powerpc/kernel/prom_init.c
@@ -173,8 +173,8 @@ static unsigned long __initdata dt_string_start, dt_string_end;
173static unsigned long __initdata prom_initrd_start, prom_initrd_end; 173static unsigned long __initdata prom_initrd_start, prom_initrd_end;
174 174
175#ifdef CONFIG_PPC64 175#ifdef CONFIG_PPC64
176static int __initdata iommu_force_on; 176static int __initdata prom_iommu_force_on;
177static int __initdata ppc64_iommu_off; 177static int __initdata prom_iommu_off;
178static unsigned long __initdata prom_tce_alloc_start; 178static unsigned long __initdata prom_tce_alloc_start;
179static unsigned long __initdata prom_tce_alloc_end; 179static unsigned long __initdata prom_tce_alloc_end;
180#endif 180#endif
@@ -582,9 +582,9 @@ static void __init early_cmdline_parse(void)
582 while (*opt && *opt == ' ') 582 while (*opt && *opt == ' ')
583 opt++; 583 opt++;
584 if (!strncmp(opt, RELOC("off"), 3)) 584 if (!strncmp(opt, RELOC("off"), 3))
585 RELOC(ppc64_iommu_off) = 1; 585 RELOC(prom_iommu_off) = 1;
586 else if (!strncmp(opt, RELOC("force"), 5)) 586 else if (!strncmp(opt, RELOC("force"), 5))
587 RELOC(iommu_force_on) = 1; 587 RELOC(prom_iommu_force_on) = 1;
588 } 588 }
589#endif 589#endif
590} 590}
@@ -627,6 +627,7 @@ static void __init early_cmdline_parse(void)
627/* Option vector 3: processor options supported */ 627/* Option vector 3: processor options supported */
628#define OV3_FP 0x80 /* floating point */ 628#define OV3_FP 0x80 /* floating point */
629#define OV3_VMX 0x40 /* VMX/Altivec */ 629#define OV3_VMX 0x40 /* VMX/Altivec */
630#define OV3_DFP 0x20 /* decimal FP */
630 631
631/* Option vector 5: PAPR/OF options supported */ 632/* Option vector 5: PAPR/OF options supported */
632#define OV5_LPAR 0x80 /* logical partitioning supported */ 633#define OV5_LPAR 0x80 /* logical partitioning supported */
@@ -642,6 +643,7 @@ static void __init early_cmdline_parse(void)
642static unsigned char ibm_architecture_vec[] = { 643static unsigned char ibm_architecture_vec[] = {
643 W(0xfffe0000), W(0x003a0000), /* POWER5/POWER5+ */ 644 W(0xfffe0000), W(0x003a0000), /* POWER5/POWER5+ */
644 W(0xffff0000), W(0x003e0000), /* POWER6 */ 645 W(0xffff0000), W(0x003e0000), /* POWER6 */
646 W(0xffffffff), W(0x0f000002), /* all 2.05-compliant */
645 W(0xfffffffe), W(0x0f000001), /* all 2.04-compliant and earlier */ 647 W(0xfffffffe), W(0x0f000001), /* all 2.04-compliant and earlier */
646 5 - 1, /* 5 option vectors */ 648 5 - 1, /* 5 option vectors */
647 649
@@ -668,7 +670,7 @@ static unsigned char ibm_architecture_vec[] = {
668 /* option vector 3: processor options supported */ 670 /* option vector 3: processor options supported */
669 3 - 2, /* length */ 671 3 - 2, /* length */
670 0, /* don't ignore, don't halt */ 672 0, /* don't ignore, don't halt */
671 OV3_FP | OV3_VMX, 673 OV3_FP | OV3_VMX | OV3_DFP,
672 674
673 /* option vector 4: IBM PAPR implementation */ 675 /* option vector 4: IBM PAPR implementation */
674 2 - 2, /* length */ 676 2 - 2, /* length */
@@ -1167,7 +1169,7 @@ static void __init prom_initialize_tce_table(void)
1167 u64 local_alloc_top, local_alloc_bottom; 1169 u64 local_alloc_top, local_alloc_bottom;
1168 u64 i; 1170 u64 i;
1169 1171
1170 if (RELOC(ppc64_iommu_off)) 1172 if (RELOC(prom_iommu_off))
1171 return; 1173 return;
1172 1174
1173 prom_debug("starting prom_initialize_tce_table\n"); 1175 prom_debug("starting prom_initialize_tce_table\n");
@@ -2283,11 +2285,11 @@ unsigned long __init prom_init(unsigned long r3, unsigned long r4,
2283 * Fill in some infos for use by the kernel later on 2285 * Fill in some infos for use by the kernel later on
2284 */ 2286 */
2285#ifdef CONFIG_PPC64 2287#ifdef CONFIG_PPC64
2286 if (RELOC(ppc64_iommu_off)) 2288 if (RELOC(prom_iommu_off))
2287 prom_setprop(_prom->chosen, "/chosen", "linux,iommu-off", 2289 prom_setprop(_prom->chosen, "/chosen", "linux,iommu-off",
2288 NULL, 0); 2290 NULL, 0);
2289 2291
2290 if (RELOC(iommu_force_on)) 2292 if (RELOC(prom_iommu_force_on))
2291 prom_setprop(_prom->chosen, "/chosen", "linux,iommu-force-on", 2293 prom_setprop(_prom->chosen, "/chosen", "linux,iommu-force-on",
2292 NULL, 0); 2294 NULL, 0);
2293 2295
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index 603dff3ad62a..0dfbe1cd28eb 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -25,6 +25,12 @@
25#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \ 25#define OF_CHECK_COUNTS(na, ns) ((na) > 0 && (na) <= OF_MAX_ADDR_CELLS && \
26 (ns) > 0) 26 (ns) > 0)
27 27
28static struct of_bus *of_match_bus(struct device_node *np);
29static int __of_address_to_resource(struct device_node *dev,
30 const u32 *addrp, u64 size, unsigned int flags,
31 struct resource *r);
32
33
28/* Debug utility */ 34/* Debug utility */
29#ifdef DEBUG 35#ifdef DEBUG
30static void of_dump_addr(const char *s, const u32 *addr, int na) 36static void of_dump_addr(const char *s, const u32 *addr, int na)
@@ -101,6 +107,7 @@ static unsigned int of_bus_default_get_flags(const u32 *addr)
101} 107}
102 108
103 109
110#ifdef CONFIG_PCI
104/* 111/*
105 * PCI bus specific translator 112 * PCI bus specific translator
106 */ 113 */
@@ -153,15 +160,156 @@ static unsigned int of_bus_pci_get_flags(const u32 *addr)
153 switch((w >> 24) & 0x03) { 160 switch((w >> 24) & 0x03) {
154 case 0x01: 161 case 0x01:
155 flags |= IORESOURCE_IO; 162 flags |= IORESOURCE_IO;
163 break;
156 case 0x02: /* 32 bits */ 164 case 0x02: /* 32 bits */
157 case 0x03: /* 64 bits */ 165 case 0x03: /* 64 bits */
158 flags |= IORESOURCE_MEM; 166 flags |= IORESOURCE_MEM;
167 break;
159 } 168 }
160 if (w & 0x40000000) 169 if (w & 0x40000000)
161 flags |= IORESOURCE_PREFETCH; 170 flags |= IORESOURCE_PREFETCH;
162 return flags; 171 return flags;
163} 172}
164 173
174const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
175 unsigned int *flags)
176{
177 const u32 *prop;
178 unsigned int psize;
179 struct device_node *parent;
180 struct of_bus *bus;
181 int onesize, i, na, ns;
182
183 /* Get parent & match bus type */
184 parent = of_get_parent(dev);
185 if (parent == NULL)
186 return NULL;
187 bus = of_match_bus(parent);
188 if (strcmp(bus->name, "pci")) {
189 of_node_put(parent);
190 return NULL;
191 }
192 bus->count_cells(dev, &na, &ns);
193 of_node_put(parent);
194 if (!OF_CHECK_COUNTS(na, ns))
195 return NULL;
196
197 /* Get "reg" or "assigned-addresses" property */
198 prop = get_property(dev, bus->addresses, &psize);
199 if (prop == NULL)
200 return NULL;
201 psize /= 4;
202
203 onesize = na + ns;
204 for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
205 if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) {
206 if (size)
207 *size = of_read_number(prop + na, ns);
208 if (flags)
209 *flags = bus->get_flags(prop);
210 return prop;
211 }
212 return NULL;
213}
214EXPORT_SYMBOL(of_get_pci_address);
215
216int of_pci_address_to_resource(struct device_node *dev, int bar,
217 struct resource *r)
218{
219 const u32 *addrp;
220 u64 size;
221 unsigned int flags;
222
223 addrp = of_get_pci_address(dev, bar, &size, &flags);
224 if (addrp == NULL)
225 return -EINVAL;
226 return __of_address_to_resource(dev, addrp, size, flags, r);
227}
228EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
229
230static u8 of_irq_pci_swizzle(u8 slot, u8 pin)
231{
232 return (((pin - 1) + slot) % 4) + 1;
233}
234
235int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
236{
237 struct device_node *dn, *ppnode;
238 struct pci_dev *ppdev;
239 u32 lspec;
240 u32 laddr[3];
241 u8 pin;
242 int rc;
243
244 /* Check if we have a device node, if yes, fallback to standard OF
245 * parsing
246 */
247 dn = pci_device_to_OF_node(pdev);
248 if (dn)
249 return of_irq_map_one(dn, 0, out_irq);
250
251 /* Ok, we don't, time to have fun. Let's start by building up an
252 * interrupt spec. we assume #interrupt-cells is 1, which is standard
253 * for PCI. If you do different, then don't use that routine.
254 */
255 rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
256 if (rc != 0)
257 return rc;
258 /* No pin, exit */
259 if (pin == 0)
260 return -ENODEV;
261
262 /* Now we walk up the PCI tree */
263 lspec = pin;
264 for (;;) {
265 /* Get the pci_dev of our parent */
266 ppdev = pdev->bus->self;
267
268 /* Ouch, it's a host bridge... */
269 if (ppdev == NULL) {
270#ifdef CONFIG_PPC64
271 ppnode = pci_bus_to_OF_node(pdev->bus);
272#else
273 struct pci_controller *host;
274 host = pci_bus_to_host(pdev->bus);
275 ppnode = host ? host->arch_data : NULL;
276#endif
277 /* No node for host bridge ? give up */
278 if (ppnode == NULL)
279 return -EINVAL;
280 } else
281 /* We found a P2P bridge, check if it has a node */
282 ppnode = pci_device_to_OF_node(ppdev);
283
284 /* Ok, we have found a parent with a device-node, hand over to
285 * the OF parsing code.
286 * We build a unit address from the linux device to be used for
287 * resolution. Note that we use the linux bus number which may
288 * not match your firmware bus numbering.
289 * Fortunately, in most cases, interrupt-map-mask doesn't include
290 * the bus number as part of the matching.
291 * You should still be careful about that though if you intend
292 * to rely on this function (you ship a firmware that doesn't
293 * create device nodes for all PCI devices).
294 */
295 if (ppnode)
296 break;
297
298 /* We can only get here if we hit a P2P bridge with no node,
299 * let's do standard swizzling and try again
300 */
301 lspec = of_irq_pci_swizzle(PCI_SLOT(pdev->devfn), lspec);
302 pdev = ppdev;
303 }
304
305 laddr[0] = (pdev->bus->number << 16)
306 | (pdev->devfn << 8);
307 laddr[1] = laddr[2] = 0;
308 return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
309}
310EXPORT_SYMBOL_GPL(of_irq_map_pci);
311#endif /* CONFIG_PCI */
312
165/* 313/*
166 * ISA bus specific translator 314 * ISA bus specific translator
167 */ 315 */
@@ -223,6 +371,7 @@ static unsigned int of_bus_isa_get_flags(const u32 *addr)
223 */ 371 */
224 372
225static struct of_bus of_busses[] = { 373static struct of_bus of_busses[] = {
374#ifdef CONFIG_PCI
226 /* PCI */ 375 /* PCI */
227 { 376 {
228 .name = "pci", 377 .name = "pci",
@@ -233,6 +382,7 @@ static struct of_bus of_busses[] = {
233 .translate = of_bus_pci_translate, 382 .translate = of_bus_pci_translate,
234 .get_flags = of_bus_pci_get_flags, 383 .get_flags = of_bus_pci_get_flags,
235 }, 384 },
385#endif /* CONFIG_PCI */
236 /* ISA */ 386 /* ISA */
237 { 387 {
238 .name = "isa", 388 .name = "isa",
@@ -445,48 +595,6 @@ const u32 *of_get_address(struct device_node *dev, int index, u64 *size,
445} 595}
446EXPORT_SYMBOL(of_get_address); 596EXPORT_SYMBOL(of_get_address);
447 597
448const u32 *of_get_pci_address(struct device_node *dev, int bar_no, u64 *size,
449 unsigned int *flags)
450{
451 const u32 *prop;
452 unsigned int psize;
453 struct device_node *parent;
454 struct of_bus *bus;
455 int onesize, i, na, ns;
456
457 /* Get parent & match bus type */
458 parent = of_get_parent(dev);
459 if (parent == NULL)
460 return NULL;
461 bus = of_match_bus(parent);
462 if (strcmp(bus->name, "pci")) {
463 of_node_put(parent);
464 return NULL;
465 }
466 bus->count_cells(dev, &na, &ns);
467 of_node_put(parent);
468 if (!OF_CHECK_COUNTS(na, ns))
469 return NULL;
470
471 /* Get "reg" or "assigned-addresses" property */
472 prop = get_property(dev, bus->addresses, &psize);
473 if (prop == NULL)
474 return NULL;
475 psize /= 4;
476
477 onesize = na + ns;
478 for (i = 0; psize >= onesize; psize -= onesize, prop += onesize, i++)
479 if ((prop[0] & 0xff) == ((bar_no * 4) + PCI_BASE_ADDRESS_0)) {
480 if (size)
481 *size = of_read_number(prop + na, ns);
482 if (flags)
483 *flags = bus->get_flags(prop);
484 return prop;
485 }
486 return NULL;
487}
488EXPORT_SYMBOL(of_get_pci_address);
489
490static int __of_address_to_resource(struct device_node *dev, const u32 *addrp, 598static int __of_address_to_resource(struct device_node *dev, const u32 *addrp,
491 u64 size, unsigned int flags, 599 u64 size, unsigned int flags,
492 struct resource *r) 600 struct resource *r)
@@ -529,20 +637,6 @@ int of_address_to_resource(struct device_node *dev, int index,
529} 637}
530EXPORT_SYMBOL_GPL(of_address_to_resource); 638EXPORT_SYMBOL_GPL(of_address_to_resource);
531 639
532int of_pci_address_to_resource(struct device_node *dev, int bar,
533 struct resource *r)
534{
535 const u32 *addrp;
536 u64 size;
537 unsigned int flags;
538
539 addrp = of_get_pci_address(dev, bar, &size, &flags);
540 if (addrp == NULL)
541 return -EINVAL;
542 return __of_address_to_resource(dev, addrp, size, flags, r);
543}
544EXPORT_SYMBOL_GPL(of_pci_address_to_resource);
545
546void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop, 640void of_parse_dma_window(struct device_node *dn, const void *dma_window_prop,
547 unsigned long *busno, unsigned long *phys, unsigned long *size) 641 unsigned long *busno, unsigned long *phys, unsigned long *size)
548{ 642{
@@ -898,87 +992,3 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq
898 return res; 992 return res;
899} 993}
900EXPORT_SYMBOL_GPL(of_irq_map_one); 994EXPORT_SYMBOL_GPL(of_irq_map_one);
901
902#ifdef CONFIG_PCI
903static u8 of_irq_pci_swizzle(u8 slot, u8 pin)
904{
905 return (((pin - 1) + slot) % 4) + 1;
906}
907
908int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq)
909{
910 struct device_node *dn, *ppnode;
911 struct pci_dev *ppdev;
912 u32 lspec;
913 u32 laddr[3];
914 u8 pin;
915 int rc;
916
917 /* Check if we have a device node, if yes, fallback to standard OF
918 * parsing
919 */
920 dn = pci_device_to_OF_node(pdev);
921 if (dn)
922 return of_irq_map_one(dn, 0, out_irq);
923
924 /* Ok, we don't, time to have fun. Let's start by building up an
925 * interrupt spec. we assume #interrupt-cells is 1, which is standard
926 * for PCI. If you do different, then don't use that routine.
927 */
928 rc = pci_read_config_byte(pdev, PCI_INTERRUPT_PIN, &pin);
929 if (rc != 0)
930 return rc;
931 /* No pin, exit */
932 if (pin == 0)
933 return -ENODEV;
934
935 /* Now we walk up the PCI tree */
936 lspec = pin;
937 for (;;) {
938 /* Get the pci_dev of our parent */
939 ppdev = pdev->bus->self;
940
941 /* Ouch, it's a host bridge... */
942 if (ppdev == NULL) {
943#ifdef CONFIG_PPC64
944 ppnode = pci_bus_to_OF_node(pdev->bus);
945#else
946 struct pci_controller *host;
947 host = pci_bus_to_host(pdev->bus);
948 ppnode = host ? host->arch_data : NULL;
949#endif
950 /* No node for host bridge ? give up */
951 if (ppnode == NULL)
952 return -EINVAL;
953 } else
954 /* We found a P2P bridge, check if it has a node */
955 ppnode = pci_device_to_OF_node(ppdev);
956
957 /* Ok, we have found a parent with a device-node, hand over to
958 * the OF parsing code.
959 * We build a unit address from the linux device to be used for
960 * resolution. Note that we use the linux bus number which may
961 * not match your firmware bus numbering.
962 * Fortunately, in most cases, interrupt-map-mask doesn't include
963 * the bus number as part of the matching.
964 * You should still be careful about that though if you intend
965 * to rely on this function (you ship a firmware that doesn't
966 * create device nodes for all PCI devices).
967 */
968 if (ppnode)
969 break;
970
971 /* We can only get here if we hit a P2P bridge with no node,
972 * let's do standard swizzling and try again
973 */
974 lspec = of_irq_pci_swizzle(PCI_SLOT(pdev->devfn), lspec);
975 pdev = ppdev;
976 }
977
978 laddr[0] = (pdev->bus->number << 16)
979 | (pdev->devfn << 8);
980 laddr[1] = laddr[2] = 0;
981 return of_irq_map_raw(ppnode, &lspec, 1, laddr, out_irq);
982}
983EXPORT_SYMBOL_GPL(of_irq_map_pci);
984#endif /* CONFIG_PCI */
diff --git a/arch/powerpc/kernel/rtas.c b/arch/powerpc/kernel/rtas.c
index 6ef80d4e38d3..387ed0d9ad61 100644
--- a/arch/powerpc/kernel/rtas.c
+++ b/arch/powerpc/kernel/rtas.c
@@ -810,9 +810,9 @@ asmlinkage int ppc_rtas(struct rtas_args __user *uargs)
810 return 0; 810 return 0;
811} 811}
812 812
813#ifdef CONFIG_HOTPLUG_CPU
813/* This version can't take the spinlock, because it never returns */ 814/* This version can't take the spinlock, because it never returns */
814 815static struct rtas_args rtas_stop_self_args = {
815struct rtas_args rtas_stop_self_args = {
816 /* The token is initialized for real in setup_system() */ 816 /* The token is initialized for real in setup_system() */
817 .token = RTAS_UNKNOWN_SERVICE, 817 .token = RTAS_UNKNOWN_SERVICE,
818 .nargs = 0, 818 .nargs = 0,
@@ -834,6 +834,7 @@ void rtas_stop_self(void)
834 834
835 panic("Alas, I survived.\n"); 835 panic("Alas, I survived.\n");
836} 836}
837#endif
837 838
838/* 839/*
839 * Call early during boot, before mem init or bootmem, to retrieve the RTAS 840 * Call early during boot, before mem init or bootmem, to retrieve the RTAS
diff --git a/arch/powerpc/kernel/rtas_flash.c b/arch/powerpc/kernel/rtas_flash.c
index 6f6fc977cb39..b9561d300516 100644
--- a/arch/powerpc/kernel/rtas_flash.c
+++ b/arch/powerpc/kernel/rtas_flash.c
@@ -681,14 +681,12 @@ static int initialize_flash_pde_data(const char *rtas_call_name,
681 int *status; 681 int *status;
682 int token; 682 int token;
683 683
684 dp->data = kmalloc(buf_size, GFP_KERNEL); 684 dp->data = kzalloc(buf_size, GFP_KERNEL);
685 if (dp->data == NULL) { 685 if (dp->data == NULL) {
686 remove_flash_pde(dp); 686 remove_flash_pde(dp);
687 return -ENOMEM; 687 return -ENOMEM;
688 } 688 }
689 689
690 memset(dp->data, 0, buf_size);
691
692 /* 690 /*
693 * This code assumes that the status int is the first member of the 691 * This code assumes that the status int is the first member of the
694 * struct 692 * struct
diff --git a/arch/powerpc/kernel/rtas_pci.c b/arch/powerpc/kernel/rtas_pci.c
index b4a0de79c060..ace9f4c86e67 100644
--- a/arch/powerpc/kernel/rtas_pci.c
+++ b/arch/powerpc/kernel/rtas_pci.c
@@ -38,6 +38,7 @@
38#include <asm/rtas.h> 38#include <asm/rtas.h>
39#include <asm/mpic.h> 39#include <asm/mpic.h>
40#include <asm/ppc-pci.h> 40#include <asm/ppc-pci.h>
41#include <asm/eeh.h>
41 42
42/* RTAS tokens */ 43/* RTAS tokens */
43static int read_pci_config; 44static int read_pci_config;
@@ -231,32 +232,13 @@ void __init init_pci_config_tokens (void)
231 232
232unsigned long __devinit get_phb_buid (struct device_node *phb) 233unsigned long __devinit get_phb_buid (struct device_node *phb)
233{ 234{
234 int addr_cells; 235 struct resource r;
235 const unsigned int *buid_vals;
236 unsigned int len;
237 unsigned long buid;
238
239 if (ibm_read_pci_config == -1) return 0;
240 236
241 /* PHB's will always be children of the root node, 237 if (ibm_read_pci_config == -1)
242 * or so it is promised by the current firmware. */
243 if (phb->parent == NULL)
244 return 0; 238 return 0;
245 if (phb->parent->parent) 239 if (of_address_to_resource(phb, 0, &r))
246 return 0;
247
248 buid_vals = get_property(phb, "reg", &len);
249 if (buid_vals == NULL)
250 return 0; 240 return 0;
251 241 return r.start;
252 addr_cells = prom_n_addr_cells(phb);
253 if (addr_cells == 1) {
254 buid = (unsigned long) buid_vals[0];
255 } else {
256 buid = (((unsigned long)buid_vals[0]) << 32UL) |
257 (((unsigned long)buid_vals[1]) & 0xffffffff);
258 }
259 return buid;
260} 242}
261 243
262static int phb_set_bus_ranges(struct device_node *dev, 244static int phb_set_bus_ranges(struct device_node *dev,
@@ -276,8 +258,10 @@ static int phb_set_bus_ranges(struct device_node *dev,
276 return 0; 258 return 0;
277} 259}
278 260
279int __devinit setup_phb(struct device_node *dev, struct pci_controller *phb) 261int __devinit rtas_setup_phb(struct pci_controller *phb)
280{ 262{
263 struct device_node *dev = phb->arch_data;
264
281 if (is_python(dev)) 265 if (is_python(dev))
282 python_countermeasures(dev); 266 python_countermeasures(dev);
283 267
@@ -309,7 +293,7 @@ unsigned long __init find_and_init_phbs(void)
309 phb = pcibios_alloc_controller(node); 293 phb = pcibios_alloc_controller(node);
310 if (!phb) 294 if (!phb)
311 continue; 295 continue;
312 setup_phb(node, phb); 296 rtas_setup_phb(phb);
313 pci_process_bridge_OF_ranges(phb, node, 0); 297 pci_process_bridge_OF_ranges(phb, node, 0);
314 pci_setup_phb_io(phb, index == 0); 298 pci_setup_phb_io(phb, index == 0);
315 index++; 299 index++;
@@ -381,7 +365,6 @@ int pcibios_remove_root_bus(struct pci_controller *phb)
381 } 365 }
382 } 366 }
383 367
384 list_del(&phb->list_node);
385 pcibios_free_controller(phb); 368 pcibios_free_controller(phb);
386 369
387 return 0; 370 return 0;
diff --git a/arch/powerpc/kernel/setup_32.c b/arch/powerpc/kernel/setup_32.c
index a4c2964a3ca6..61c65d19ef06 100644
--- a/arch/powerpc/kernel/setup_32.c
+++ b/arch/powerpc/kernel/setup_32.c
@@ -63,10 +63,6 @@ unsigned int DMA_MODE_WRITE;
63 63
64int have_of = 1; 64int have_of = 1;
65 65
66#ifdef CONFIG_PPC_MULTIPLATFORM
67dev_t boot_dev;
68#endif /* CONFIG_PPC_MULTIPLATFORM */
69
70#ifdef CONFIG_VGA_CONSOLE 66#ifdef CONFIG_VGA_CONSOLE
71unsigned long vgacon_remap_base; 67unsigned long vgacon_remap_base;
72#endif 68#endif
@@ -101,7 +97,7 @@ unsigned long __init early_init(unsigned long dt_ptr)
101 * Identify the CPU type and fix up code sections 97 * Identify the CPU type and fix up code sections
102 * that depend on which cpu we have. 98 * that depend on which cpu we have.
103 */ 99 */
104 spec = identify_cpu(offset); 100 spec = identify_cpu(offset, mfspr(SPRN_PVR));
105 101
106 do_feature_fixups(spec->cpu_features, 102 do_feature_fixups(spec->cpu_features,
107 PTRRELOC(&__start___ftr_fixup), 103 PTRRELOC(&__start___ftr_fixup),
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 16278968dab6..3733de30e84d 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -33,6 +33,7 @@
33#include <linux/serial.h> 33#include <linux/serial.h>
34#include <linux/serial_8250.h> 34#include <linux/serial_8250.h>
35#include <linux/bootmem.h> 35#include <linux/bootmem.h>
36#include <linux/pci.h>
36#include <asm/io.h> 37#include <asm/io.h>
37#include <asm/kdump.h> 38#include <asm/kdump.h>
38#include <asm/prom.h> 39#include <asm/prom.h>
@@ -71,7 +72,6 @@
71 72
72int have_of = 1; 73int have_of = 1;
73int boot_cpuid = 0; 74int boot_cpuid = 0;
74dev_t boot_dev;
75u64 ppc64_pft_size; 75u64 ppc64_pft_size;
76 76
77/* Pick defaults since we might want to patch instructions 77/* Pick defaults since we might want to patch instructions
@@ -171,7 +171,7 @@ void __init setup_paca(int cpu)
171void __init early_setup(unsigned long dt_ptr) 171void __init early_setup(unsigned long dt_ptr)
172{ 172{
173 /* Identify CPU type */ 173 /* Identify CPU type */
174 identify_cpu(0); 174 identify_cpu(0, mfspr(SPRN_PVR));
175 175
176 /* Assume we're on cpu 0 for now. Don't write to the paca yet! */ 176 /* Assume we're on cpu 0 for now. Don't write to the paca yet! */
177 setup_paca(0); 177 setup_paca(0);
@@ -226,8 +226,8 @@ void early_setup_secondary(void)
226{ 226{
227 struct paca_struct *lpaca = get_paca(); 227 struct paca_struct *lpaca = get_paca();
228 228
229 /* Mark enabled in PACA */ 229 /* Mark interrupts enabled in PACA */
230 lpaca->proc_enabled = 0; 230 lpaca->soft_enabled = 0;
231 231
232 /* Initialize hash table for that CPU */ 232 /* Initialize hash table for that CPU */
233 htab_initialize_secondary(); 233 htab_initialize_secondary();
@@ -392,7 +392,8 @@ void __init setup_system(void)
392 * setting up the hash table pointers. It also sets up some interrupt-mapping 392 * setting up the hash table pointers. It also sets up some interrupt-mapping
393 * related options that will be used by finish_device_tree() 393 * related options that will be used by finish_device_tree()
394 */ 394 */
395 ppc_md.init_early(); 395 if (ppc_md.init_early)
396 ppc_md.init_early();
396 397
397 /* 398 /*
398 * We can discover serial ports now since the above did setup the 399 * We can discover serial ports now since the above did setup the
@@ -598,3 +599,10 @@ void __init setup_per_cpu_areas(void)
598 } 599 }
599} 600}
600#endif 601#endif
602
603
604#ifdef CONFIG_PPC_INDIRECT_IO
605struct ppc_pci_io ppc_pci_io;
606EXPORT_SYMBOL(ppc_pci_io);
607#endif /* CONFIG_PPC_INDIRECT_IO */
608
diff --git a/arch/powerpc/kernel/smp-tbsync.c b/arch/powerpc/kernel/smp-tbsync.c
index de59c6c31a5b..bc892e69b4f7 100644
--- a/arch/powerpc/kernel/smp-tbsync.c
+++ b/arch/powerpc/kernel/smp-tbsync.c
@@ -78,7 +78,7 @@ static int __devinit start_contest(int cmd, long offset, int num)
78{ 78{
79 int i, score=0; 79 int i, score=0;
80 u64 tb; 80 u64 tb;
81 long mark; 81 u64 mark;
82 82
83 tbsync->cmd = cmd; 83 tbsync->cmd = cmd;
84 84
@@ -116,8 +116,7 @@ void __devinit smp_generic_give_timebase(void)
116 printk("Synchronizing timebase\n"); 116 printk("Synchronizing timebase\n");
117 117
118 /* if this fails then this kernel won't work anyway... */ 118 /* if this fails then this kernel won't work anyway... */
119 tbsync = kmalloc( sizeof(*tbsync), GFP_KERNEL ); 119 tbsync = kzalloc( sizeof(*tbsync), GFP_KERNEL );
120 memset( tbsync, 0, sizeof(*tbsync) );
121 mb(); 120 mb();
122 running = 1; 121 running = 1;
123 122
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index 35c6309bdb76..9b28c238b6c0 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -65,6 +65,7 @@ cpumask_t cpu_sibling_map[NR_CPUS] = { [0 ... NR_CPUS-1] = CPU_MASK_NONE };
65 65
66EXPORT_SYMBOL(cpu_online_map); 66EXPORT_SYMBOL(cpu_online_map);
67EXPORT_SYMBOL(cpu_possible_map); 67EXPORT_SYMBOL(cpu_possible_map);
68EXPORT_SYMBOL(cpu_sibling_map);
68 69
69/* SMP operations for this machine */ 70/* SMP operations for this machine */
70struct smp_ops_t *smp_ops; 71struct smp_ops_t *smp_ops;
diff --git a/arch/powerpc/kernel/sys_ppc32.c b/arch/powerpc/kernel/sys_ppc32.c
index d15c33e95959..03a2a2f30d66 100644
--- a/arch/powerpc/kernel/sys_ppc32.c
+++ b/arch/powerpc/kernel/sys_ppc32.c
@@ -51,6 +51,7 @@
51#include <asm/time.h> 51#include <asm/time.h>
52#include <asm/mmu_context.h> 52#include <asm/mmu_context.h>
53#include <asm/ppc-pci.h> 53#include <asm/ppc-pci.h>
54#include <asm/syscalls.h>
54 55
55/* readdir & getdents */ 56/* readdir & getdents */
56#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de))) 57#define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de)))
diff --git a/arch/powerpc/kernel/sysfs.c b/arch/powerpc/kernel/sysfs.c
index d45a168bdaca..22123a0d5416 100644
--- a/arch/powerpc/kernel/sysfs.c
+++ b/arch/powerpc/kernel/sysfs.c
@@ -200,10 +200,9 @@ static void register_cpu_online(unsigned int cpu)
200 struct cpu *c = &per_cpu(cpu_devices, cpu); 200 struct cpu *c = &per_cpu(cpu_devices, cpu);
201 struct sys_device *s = &c->sysdev; 201 struct sys_device *s = &c->sysdev;
202 202
203#ifndef CONFIG_PPC_ISERIES 203 if (!firmware_has_feature(FW_FEATURE_ISERIES) &&
204 if (cpu_has_feature(CPU_FTR_SMT)) 204 cpu_has_feature(CPU_FTR_SMT))
205 sysdev_create_file(s, &attr_smt_snooze_delay); 205 sysdev_create_file(s, &attr_smt_snooze_delay);
206#endif
207 206
208 /* PMC stuff */ 207 /* PMC stuff */
209 208
@@ -242,10 +241,9 @@ static void unregister_cpu_online(unsigned int cpu)
242 241
243 BUG_ON(c->no_control); 242 BUG_ON(c->no_control);
244 243
245#ifndef CONFIG_PPC_ISERIES 244 if (!firmware_has_feature(FW_FEATURE_ISERIES) &&
246 if (cpu_has_feature(CPU_FTR_SMT)) 245 cpu_has_feature(CPU_FTR_SMT))
247 sysdev_remove_file(s, &attr_smt_snooze_delay); 246 sysdev_remove_file(s, &attr_smt_snooze_delay);
248#endif
249 247
250 /* PMC stuff */ 248 /* PMC stuff */
251 249
@@ -299,6 +297,72 @@ static struct notifier_block __cpuinitdata sysfs_cpu_nb = {
299 .notifier_call = sysfs_cpu_notify, 297 .notifier_call = sysfs_cpu_notify,
300}; 298};
301 299
300static DEFINE_MUTEX(cpu_mutex);
301
302int cpu_add_sysdev_attr(struct sysdev_attribute *attr)
303{
304 int cpu;
305
306 mutex_lock(&cpu_mutex);
307
308 for_each_possible_cpu(cpu) {
309 sysdev_create_file(get_cpu_sysdev(cpu), attr);
310 }
311
312 mutex_unlock(&cpu_mutex);
313 return 0;
314}
315EXPORT_SYMBOL_GPL(cpu_add_sysdev_attr);
316
317int cpu_add_sysdev_attr_group(struct attribute_group *attrs)
318{
319 int cpu;
320 struct sys_device *sysdev;
321
322 mutex_lock(&cpu_mutex);
323
324 for_each_possible_cpu(cpu) {
325 sysdev = get_cpu_sysdev(cpu);
326 sysfs_create_group(&sysdev->kobj, attrs);
327 }
328
329 mutex_unlock(&cpu_mutex);
330 return 0;
331}
332EXPORT_SYMBOL_GPL(cpu_add_sysdev_attr_group);
333
334
335void cpu_remove_sysdev_attr(struct sysdev_attribute *attr)
336{
337 int cpu;
338
339 mutex_lock(&cpu_mutex);
340
341 for_each_possible_cpu(cpu) {
342 sysdev_remove_file(get_cpu_sysdev(cpu), attr);
343 }
344
345 mutex_unlock(&cpu_mutex);
346}
347EXPORT_SYMBOL_GPL(cpu_remove_sysdev_attr);
348
349void cpu_remove_sysdev_attr_group(struct attribute_group *attrs)
350{
351 int cpu;
352 struct sys_device *sysdev;
353
354 mutex_lock(&cpu_mutex);
355
356 for_each_possible_cpu(cpu) {
357 sysdev = get_cpu_sysdev(cpu);
358 sysfs_remove_group(&sysdev->kobj, attrs);
359 }
360
361 mutex_unlock(&cpu_mutex);
362}
363EXPORT_SYMBOL_GPL(cpu_remove_sysdev_attr_group);
364
365
302/* NUMA stuff */ 366/* NUMA stuff */
303 367
304#ifdef CONFIG_NUMA 368#ifdef CONFIG_NUMA
diff --git a/arch/powerpc/kernel/time.c b/arch/powerpc/kernel/time.c
index 46a24de36fec..f6f0c6b07c4c 100644
--- a/arch/powerpc/kernel/time.c
+++ b/arch/powerpc/kernel/time.c
@@ -631,7 +631,8 @@ void timer_interrupt(struct pt_regs * regs)
631 calculate_steal_time(); 631 calculate_steal_time();
632 632
633#ifdef CONFIG_PPC_ISERIES 633#ifdef CONFIG_PPC_ISERIES
634 get_lppaca()->int_dword.fields.decr_int = 0; 634 if (firmware_has_feature(FW_FEATURE_ISERIES))
635 get_lppaca()->int_dword.fields.decr_int = 0;
635#endif 636#endif
636 637
637 while ((ticks = tb_ticks_since(per_cpu(last_jiffy, cpu))) 638 while ((ticks = tb_ticks_since(per_cpu(last_jiffy, cpu)))
@@ -674,7 +675,7 @@ void timer_interrupt(struct pt_regs * regs)
674 set_dec(next_dec); 675 set_dec(next_dec);
675 676
676#ifdef CONFIG_PPC_ISERIES 677#ifdef CONFIG_PPC_ISERIES
677 if (hvlpevent_is_pending()) 678 if (firmware_has_feature(FW_FEATURE_ISERIES) && hvlpevent_is_pending())
678 process_hvlpevents(); 679 process_hvlpevents();
679#endif 680#endif
680 681
@@ -774,7 +775,7 @@ int do_settimeofday(struct timespec *tv)
774 * settimeofday to perform this operation. 775 * settimeofday to perform this operation.
775 */ 776 */
776#ifdef CONFIG_PPC_ISERIES 777#ifdef CONFIG_PPC_ISERIES
777 if (first_settimeofday) { 778 if (firmware_has_feature(FW_FEATURE_ISERIES) && first_settimeofday) {
778 iSeries_tb_recal(); 779 iSeries_tb_recal();
779 first_settimeofday = 0; 780 first_settimeofday = 0;
780 } 781 }
diff --git a/arch/powerpc/kernel/traps.c b/arch/powerpc/kernel/traps.c
index c66b4771ef44..0d4e203fa7a0 100644
--- a/arch/powerpc/kernel/traps.c
+++ b/arch/powerpc/kernel/traps.c
@@ -53,10 +53,6 @@
53#endif 53#endif
54#include <asm/kexec.h> 54#include <asm/kexec.h>
55 55
56#ifdef CONFIG_PPC64 /* XXX */
57#define _IO_BASE pci_io_base
58#endif
59
60#ifdef CONFIG_DEBUGGER 56#ifdef CONFIG_DEBUGGER
61int (*__debugger)(struct pt_regs *regs); 57int (*__debugger)(struct pt_regs *regs);
62int (*__debugger_ipi)(struct pt_regs *regs); 58int (*__debugger_ipi)(struct pt_regs *regs);
@@ -241,7 +237,7 @@ void system_reset_exception(struct pt_regs *regs)
241 */ 237 */
242static inline int check_io_access(struct pt_regs *regs) 238static inline int check_io_access(struct pt_regs *regs)
243{ 239{
244#if defined(CONFIG_PPC_PMAC) && defined(CONFIG_PPC32) 240#ifdef CONFIG_PPC32
245 unsigned long msr = regs->msr; 241 unsigned long msr = regs->msr;
246 const struct exception_table_entry *entry; 242 const struct exception_table_entry *entry;
247 unsigned int *nip = (unsigned int *)regs->nip; 243 unsigned int *nip = (unsigned int *)regs->nip;
@@ -274,7 +270,7 @@ static inline int check_io_access(struct pt_regs *regs)
274 return 1; 270 return 1;
275 } 271 }
276 } 272 }
277#endif /* CONFIG_PPC_PMAC && CONFIG_PPC32 */ 273#endif /* CONFIG_PPC32 */
278 return 0; 274 return 0;
279} 275}
280 276
diff --git a/arch/powerpc/kernel/vio.c b/arch/powerpc/kernel/vio.c
index ed007878d1bf..a80f8f1d2e5d 100644
--- a/arch/powerpc/kernel/vio.c
+++ b/arch/powerpc/kernel/vio.c
@@ -81,15 +81,15 @@ static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev)
81 struct iommu_table *tbl; 81 struct iommu_table *tbl;
82 unsigned long offset, size; 82 unsigned long offset, size;
83 83
84 dma_window = get_property(dev->dev.platform_data, 84 dma_window = get_property(dev->dev.archdata.of_node,
85 "ibm,my-dma-window", NULL); 85 "ibm,my-dma-window", NULL);
86 if (!dma_window) 86 if (!dma_window)
87 return NULL; 87 return NULL;
88 88
89 tbl = kmalloc(sizeof(*tbl), GFP_KERNEL); 89 tbl = kmalloc(sizeof(*tbl), GFP_KERNEL);
90 90
91 of_parse_dma_window(dev->dev.platform_data, dma_window, 91 of_parse_dma_window(dev->dev.archdata.of_node, dma_window,
92 &tbl->it_index, &offset, &size); 92 &tbl->it_index, &offset, &size);
93 93
94 /* TCE table size - measured in tce entries */ 94 /* TCE table size - measured in tce entries */
95 tbl->it_size = size >> IOMMU_PAGE_SHIFT; 95 tbl->it_size = size >> IOMMU_PAGE_SHIFT;
@@ -117,7 +117,8 @@ static const struct vio_device_id *vio_match_device(
117{ 117{
118 while (ids->type[0] != '\0') { 118 while (ids->type[0] != '\0') {
119 if ((strncmp(dev->type, ids->type, strlen(ids->type)) == 0) && 119 if ((strncmp(dev->type, ids->type, strlen(ids->type)) == 0) &&
120 device_is_compatible(dev->dev.platform_data, ids->compat)) 120 device_is_compatible(dev->dev.archdata.of_node,
121 ids->compat))
121 return ids; 122 return ids;
122 ids++; 123 ids++;
123 } 124 }
@@ -198,9 +199,9 @@ EXPORT_SYMBOL(vio_unregister_driver);
198/* vio_dev refcount hit 0 */ 199/* vio_dev refcount hit 0 */
199static void __devinit vio_dev_release(struct device *dev) 200static void __devinit vio_dev_release(struct device *dev)
200{ 201{
201 if (dev->platform_data) { 202 if (dev->archdata.of_node) {
202 /* XXX free TCE table */ 203 /* XXX should free TCE table */
203 of_node_put(dev->platform_data); 204 of_node_put(dev->archdata.of_node);
204 } 205 }
205 kfree(to_vio_dev(dev)); 206 kfree(to_vio_dev(dev));
206} 207}
@@ -210,7 +211,7 @@ static void __devinit vio_dev_release(struct device *dev)
210 * @of_node: The OF node for this device. 211 * @of_node: The OF node for this device.
211 * 212 *
212 * Creates and initializes a vio_dev structure from the data in 213 * Creates and initializes a vio_dev structure from the data in
213 * of_node (dev.platform_data) and adds it to the list of virtual devices. 214 * of_node and adds it to the list of virtual devices.
214 * Returns a pointer to the created vio_dev or NULL if node has 215 * Returns a pointer to the created vio_dev or NULL if node has
215 * NULL device_type or compatible fields. 216 * NULL device_type or compatible fields.
216 */ 217 */
@@ -240,8 +241,6 @@ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
240 if (viodev == NULL) 241 if (viodev == NULL)
241 return NULL; 242 return NULL;
242 243
243 viodev->dev.platform_data = of_node_get(of_node);
244
245 viodev->irq = irq_of_parse_and_map(of_node, 0); 244 viodev->irq = irq_of_parse_and_map(of_node, 0);
246 245
247 snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address); 246 snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address);
@@ -254,7 +253,10 @@ struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node)
254 if (unit_address != NULL) 253 if (unit_address != NULL)
255 viodev->unit_address = *unit_address; 254 viodev->unit_address = *unit_address;
256 } 255 }
257 viodev->iommu_table = vio_build_iommu_table(viodev); 256 viodev->dev.archdata.of_node = of_node_get(of_node);
257 viodev->dev.archdata.dma_ops = &dma_iommu_ops;
258 viodev->dev.archdata.dma_data = vio_build_iommu_table(viodev);
259 viodev->dev.archdata.numa_node = of_node_to_nid(of_node);
258 260
259 /* init generic 'struct device' fields: */ 261 /* init generic 'struct device' fields: */
260 viodev->dev.parent = &vio_bus_device.dev; 262 viodev->dev.parent = &vio_bus_device.dev;
@@ -285,10 +287,11 @@ static int __init vio_bus_init(void)
285#ifdef CONFIG_PPC_ISERIES 287#ifdef CONFIG_PPC_ISERIES
286 if (firmware_has_feature(FW_FEATURE_ISERIES)) { 288 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
287 iommu_vio_init(); 289 iommu_vio_init();
288 vio_bus_device.iommu_table = &vio_iommu_table; 290 vio_bus_device.dev.archdata.dma_ops = &dma_iommu_ops;
291 vio_bus_device.dev.archdata.dma_data = &vio_iommu_table;
289 iSeries_vio_dev = &vio_bus_device.dev; 292 iSeries_vio_dev = &vio_bus_device.dev;
290 } 293 }
291#endif 294#endif /* CONFIG_PPC_ISERIES */
292 295
293 err = bus_register(&vio_bus_type); 296 err = bus_register(&vio_bus_type);
294 if (err) { 297 if (err) {
@@ -336,7 +339,7 @@ static ssize_t name_show(struct device *dev,
336static ssize_t devspec_show(struct device *dev, 339static ssize_t devspec_show(struct device *dev,
337 struct device_attribute *attr, char *buf) 340 struct device_attribute *attr, char *buf)
338{ 341{
339 struct device_node *of_node = dev->platform_data; 342 struct device_node *of_node = dev->archdata.of_node;
340 343
341 return sprintf(buf, "%s\n", of_node ? of_node->full_name : "none"); 344 return sprintf(buf, "%s\n", of_node ? of_node->full_name : "none");
342} 345}
@@ -353,62 +356,6 @@ void __devinit vio_unregister_device(struct vio_dev *viodev)
353} 356}
354EXPORT_SYMBOL(vio_unregister_device); 357EXPORT_SYMBOL(vio_unregister_device);
355 358
356static dma_addr_t vio_map_single(struct device *dev, void *vaddr,
357 size_t size, enum dma_data_direction direction)
358{
359 return iommu_map_single(to_vio_dev(dev)->iommu_table, vaddr, size,
360 ~0ul, direction);
361}
362
363static void vio_unmap_single(struct device *dev, dma_addr_t dma_handle,
364 size_t size, enum dma_data_direction direction)
365{
366 iommu_unmap_single(to_vio_dev(dev)->iommu_table, dma_handle, size,
367 direction);
368}
369
370static int vio_map_sg(struct device *dev, struct scatterlist *sglist,
371 int nelems, enum dma_data_direction direction)
372{
373 return iommu_map_sg(dev, to_vio_dev(dev)->iommu_table, sglist,
374 nelems, ~0ul, direction);
375}
376
377static void vio_unmap_sg(struct device *dev, struct scatterlist *sglist,
378 int nelems, enum dma_data_direction direction)
379{
380 iommu_unmap_sg(to_vio_dev(dev)->iommu_table, sglist, nelems, direction);
381}
382
383static void *vio_alloc_coherent(struct device *dev, size_t size,
384 dma_addr_t *dma_handle, gfp_t flag)
385{
386 return iommu_alloc_coherent(to_vio_dev(dev)->iommu_table, size,
387 dma_handle, ~0ul, flag, -1);
388}
389
390static void vio_free_coherent(struct device *dev, size_t size,
391 void *vaddr, dma_addr_t dma_handle)
392{
393 iommu_free_coherent(to_vio_dev(dev)->iommu_table, size, vaddr,
394 dma_handle);
395}
396
397static int vio_dma_supported(struct device *dev, u64 mask)
398{
399 return 1;
400}
401
402struct dma_mapping_ops vio_dma_ops = {
403 .alloc_coherent = vio_alloc_coherent,
404 .free_coherent = vio_free_coherent,
405 .map_single = vio_map_single,
406 .unmap_single = vio_unmap_single,
407 .map_sg = vio_map_sg,
408 .unmap_sg = vio_unmap_sg,
409 .dma_supported = vio_dma_supported,
410};
411
412static int vio_bus_match(struct device *dev, struct device_driver *drv) 359static int vio_bus_match(struct device *dev, struct device_driver *drv)
413{ 360{
414 const struct vio_dev *vio_dev = to_vio_dev(dev); 361 const struct vio_dev *vio_dev = to_vio_dev(dev);
@@ -422,13 +369,14 @@ static int vio_hotplug(struct device *dev, char **envp, int num_envp,
422 char *buffer, int buffer_size) 369 char *buffer, int buffer_size)
423{ 370{
424 const struct vio_dev *vio_dev = to_vio_dev(dev); 371 const struct vio_dev *vio_dev = to_vio_dev(dev);
425 struct device_node *dn = dev->platform_data; 372 struct device_node *dn;
426 const char *cp; 373 const char *cp;
427 int length; 374 int length;
428 375
429 if (!num_envp) 376 if (!num_envp)
430 return -ENOMEM; 377 return -ENOMEM;
431 378
379 dn = dev->archdata.of_node;
432 if (!dn) 380 if (!dn)
433 return -ENODEV; 381 return -ENODEV;
434 cp = get_property(dn, "compatible", &length); 382 cp = get_property(dn, "compatible", &length);
@@ -465,7 +413,7 @@ struct bus_type vio_bus_type = {
465*/ 413*/
466const void *vio_get_attribute(struct vio_dev *vdev, char *which, int *length) 414const void *vio_get_attribute(struct vio_dev *vdev, char *which, int *length)
467{ 415{
468 return get_property(vdev->dev.platform_data, which, length); 416 return get_property(vdev->dev.archdata.of_node, which, length);
469} 417}
470EXPORT_SYMBOL(vio_get_attribute); 418EXPORT_SYMBOL(vio_get_attribute);
471 419
diff --git a/arch/powerpc/mm/Makefile b/arch/powerpc/mm/Makefile
index 93441e7a2921..38a81967ca07 100644
--- a/arch/powerpc/mm/Makefile
+++ b/arch/powerpc/mm/Makefile
@@ -8,7 +8,7 @@ endif
8 8
9obj-y := fault.o mem.o lmb.o 9obj-y := fault.o mem.o lmb.o
10obj-$(CONFIG_PPC32) += init_32.o pgtable_32.o mmu_context_32.o 10obj-$(CONFIG_PPC32) += init_32.o pgtable_32.o mmu_context_32.o
11hash-$(CONFIG_PPC_MULTIPLATFORM) := hash_native_64.o 11hash-$(CONFIG_PPC_NATIVE) := hash_native_64.o
12obj-$(CONFIG_PPC64) += init_64.o pgtable_64.o mmu_context_64.o \ 12obj-$(CONFIG_PPC64) += init_64.o pgtable_64.o mmu_context_64.o \
13 hash_utils_64.o hash_low_64.o tlb_64.o \ 13 hash_utils_64.o hash_low_64.o tlb_64.o \
14 slb_low.o slb.o stab.o mmap.o imalloc.o \ 14 slb_low.o slb.o stab.o mmap.o imalloc.o \
diff --git a/arch/powerpc/mm/fault.c b/arch/powerpc/mm/fault.c
index e8fa50624b70..03aeb3a46077 100644
--- a/arch/powerpc/mm/fault.c
+++ b/arch/powerpc/mm/fault.c
@@ -426,18 +426,21 @@ void bad_page_fault(struct pt_regs *regs, unsigned long address, int sig)
426 426
427 /* kernel has accessed a bad area */ 427 /* kernel has accessed a bad area */
428 428
429 printk(KERN_ALERT "Unable to handle kernel paging request for ");
430 switch (regs->trap) { 429 switch (regs->trap) {
431 case 0x300: 430 case 0x300:
432 case 0x380: 431 case 0x380:
433 printk("data at address 0x%08lx\n", regs->dar); 432 printk(KERN_ALERT "Unable to handle kernel paging request for "
434 break; 433 "data at address 0x%08lx\n", regs->dar);
435 case 0x400: 434 break;
436 case 0x480: 435 case 0x400:
437 printk("instruction fetch\n"); 436 case 0x480:
438 break; 437 printk(KERN_ALERT "Unable to handle kernel paging request for "
439 default: 438 "instruction fetch\n");
440 printk("unknown fault\n"); 439 break;
440 default:
441 printk(KERN_ALERT "Unable to handle kernel paging request for "
442 "unknown fault\n");
443 break;
441 } 444 }
442 printk(KERN_ALERT "Faulting instruction address: 0x%08lx\n", 445 printk(KERN_ALERT "Faulting instruction address: 0x%08lx\n",
443 regs->nip); 446 regs->nip);
diff --git a/arch/powerpc/mm/hash_native_64.c b/arch/powerpc/mm/hash_native_64.c
index c90f124f3c71..6f1016acdbf6 100644
--- a/arch/powerpc/mm/hash_native_64.c
+++ b/arch/powerpc/mm/hash_native_64.c
@@ -123,7 +123,7 @@ static inline void native_unlock_hpte(hpte_t *hptep)
123 clear_bit(HPTE_LOCK_BIT, word); 123 clear_bit(HPTE_LOCK_BIT, word);
124} 124}
125 125
126long native_hpte_insert(unsigned long hpte_group, unsigned long va, 126static long native_hpte_insert(unsigned long hpte_group, unsigned long va,
127 unsigned long pa, unsigned long rflags, 127 unsigned long pa, unsigned long rflags,
128 unsigned long vflags, int psize) 128 unsigned long vflags, int psize)
129{ 129{
diff --git a/arch/powerpc/mm/hash_utils_64.c b/arch/powerpc/mm/hash_utils_64.c
index 1915661c2c81..c0d2a694fa30 100644
--- a/arch/powerpc/mm/hash_utils_64.c
+++ b/arch/powerpc/mm/hash_utils_64.c
@@ -277,7 +277,7 @@ static void __init htab_init_page_sizes(void)
277 * Not in the device-tree, let's fallback on known size 277 * Not in the device-tree, let's fallback on known size
278 * list for 16M capable GP & GR 278 * list for 16M capable GP & GR
279 */ 279 */
280 if (cpu_has_feature(CPU_FTR_16M_PAGE) && !machine_is(iseries)) 280 if (cpu_has_feature(CPU_FTR_16M_PAGE))
281 memcpy(mmu_psize_defs, mmu_psize_defaults_gp, 281 memcpy(mmu_psize_defs, mmu_psize_defaults_gp,
282 sizeof(mmu_psize_defaults_gp)); 282 sizeof(mmu_psize_defaults_gp));
283 found: 283 found:
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index 3ff374697e34..9a178549cbcf 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -130,7 +130,7 @@ static int __init setup_kcore(void)
130 /* GFP_ATOMIC to avoid might_sleep warnings during boot */ 130 /* GFP_ATOMIC to avoid might_sleep warnings during boot */
131 kcore_mem = kmalloc(sizeof(struct kcore_list), GFP_ATOMIC); 131 kcore_mem = kmalloc(sizeof(struct kcore_list), GFP_ATOMIC);
132 if (!kcore_mem) 132 if (!kcore_mem)
133 panic("mem_init: kmalloc failed\n"); 133 panic("%s: kmalloc failed\n", __FUNCTION__);
134 134
135 kclist_add(kcore_mem, __va(base), size); 135 kclist_add(kcore_mem, __va(base), size);
136 } 136 }
diff --git a/arch/powerpc/mm/pgtable_32.c b/arch/powerpc/mm/pgtable_32.c
index 8fcacb0239da..1891dbeeb8e9 100644
--- a/arch/powerpc/mm/pgtable_32.c
+++ b/arch/powerpc/mm/pgtable_32.c
@@ -141,29 +141,19 @@ void pte_free(struct page *ptepage)
141 __free_page(ptepage); 141 __free_page(ptepage);
142} 142}
143 143
144#ifndef CONFIG_PHYS_64BIT
145void __iomem * 144void __iomem *
146ioremap(phys_addr_t addr, unsigned long size) 145ioremap(phys_addr_t addr, unsigned long size)
147{ 146{
148 return __ioremap(addr, size, _PAGE_NO_CACHE); 147 return __ioremap(addr, size, _PAGE_NO_CACHE);
149} 148}
150#else /* CONFIG_PHYS_64BIT */ 149EXPORT_SYMBOL(ioremap);
151void __iomem *
152ioremap64(unsigned long long addr, unsigned long size)
153{
154 return __ioremap(addr, size, _PAGE_NO_CACHE);
155}
156EXPORT_SYMBOL(ioremap64);
157 150
158void __iomem * 151void __iomem *
159ioremap(phys_addr_t addr, unsigned long size) 152ioremap_flags(phys_addr_t addr, unsigned long size, unsigned long flags)
160{ 153{
161 phys_addr_t addr64 = fixup_bigphys_addr(addr, size); 154 return __ioremap(addr, size, flags);
162
163 return ioremap64(addr64, size);
164} 155}
165#endif /* CONFIG_PHYS_64BIT */ 156EXPORT_SYMBOL(ioremap_flags);
166EXPORT_SYMBOL(ioremap);
167 157
168void __iomem * 158void __iomem *
169__ioremap(phys_addr_t addr, unsigned long size, unsigned long flags) 159__ioremap(phys_addr_t addr, unsigned long size, unsigned long flags)
@@ -264,20 +254,7 @@ void iounmap(volatile void __iomem *addr)
264} 254}
265EXPORT_SYMBOL(iounmap); 255EXPORT_SYMBOL(iounmap);
266 256
267void __iomem *ioport_map(unsigned long port, unsigned int len) 257int map_page(unsigned long va, phys_addr_t pa, int flags)
268{
269 return (void __iomem *) (port + _IO_BASE);
270}
271
272void ioport_unmap(void __iomem *addr)
273{
274 /* Nothing to do */
275}
276EXPORT_SYMBOL(ioport_map);
277EXPORT_SYMBOL(ioport_unmap);
278
279int
280map_page(unsigned long va, phys_addr_t pa, int flags)
281{ 258{
282 pmd_t *pd; 259 pmd_t *pd;
283 pte_t *pg; 260 pte_t *pg;
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index ac64f4aaa509..16e4ee1c2318 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -113,7 +113,7 @@ static int map_io_page(unsigned long ea, unsigned long pa, int flags)
113} 113}
114 114
115 115
116static void __iomem * __ioremap_com(unsigned long addr, unsigned long pa, 116static void __iomem * __ioremap_com(phys_addr_t addr, unsigned long pa,
117 unsigned long ea, unsigned long size, 117 unsigned long ea, unsigned long size,
118 unsigned long flags) 118 unsigned long flags)
119{ 119{
@@ -129,22 +129,12 @@ static void __iomem * __ioremap_com(unsigned long addr, unsigned long pa,
129 return (void __iomem *) (ea + (addr & ~PAGE_MASK)); 129 return (void __iomem *) (ea + (addr & ~PAGE_MASK));
130} 130}
131 131
132 132void __iomem * __ioremap(phys_addr_t addr, unsigned long size,
133void __iomem *
134ioremap(unsigned long addr, unsigned long size)
135{
136 return __ioremap(addr, size, _PAGE_NO_CACHE | _PAGE_GUARDED);
137}
138
139void __iomem * __ioremap(unsigned long addr, unsigned long size,
140 unsigned long flags) 133 unsigned long flags)
141{ 134{
142 unsigned long pa, ea; 135 unsigned long pa, ea;
143 void __iomem *ret; 136 void __iomem *ret;
144 137
145 if (firmware_has_feature(FW_FEATURE_ISERIES))
146 return (void __iomem *)addr;
147
148 /* 138 /*
149 * Choose an address to map it to. 139 * Choose an address to map it to.
150 * Once the imalloc system is running, we use it. 140 * Once the imalloc system is running, we use it.
@@ -178,9 +168,28 @@ void __iomem * __ioremap(unsigned long addr, unsigned long size,
178 return ret; 168 return ret;
179} 169}
180 170
171
172void __iomem * ioremap(phys_addr_t addr, unsigned long size)
173{
174 unsigned long flags = _PAGE_NO_CACHE | _PAGE_GUARDED;
175
176 if (ppc_md.ioremap)
177 return ppc_md.ioremap(addr, size, flags);
178 return __ioremap(addr, size, flags);
179}
180
181void __iomem * ioremap_flags(phys_addr_t addr, unsigned long size,
182 unsigned long flags)
183{
184 if (ppc_md.ioremap)
185 return ppc_md.ioremap(addr, size, flags);
186 return __ioremap(addr, size, flags);
187}
188
189
181#define IS_PAGE_ALIGNED(_val) ((_val) == ((_val) & PAGE_MASK)) 190#define IS_PAGE_ALIGNED(_val) ((_val) == ((_val) & PAGE_MASK))
182 191
183int __ioremap_explicit(unsigned long pa, unsigned long ea, 192int __ioremap_explicit(phys_addr_t pa, unsigned long ea,
184 unsigned long size, unsigned long flags) 193 unsigned long size, unsigned long flags)
185{ 194{
186 struct vm_struct *area; 195 struct vm_struct *area;
@@ -235,13 +244,10 @@ int __ioremap_explicit(unsigned long pa, unsigned long ea,
235 * 244 *
236 * XXX what about calls before mem_init_done (ie python_countermeasures()) 245 * XXX what about calls before mem_init_done (ie python_countermeasures())
237 */ 246 */
238void iounmap(volatile void __iomem *token) 247void __iounmap(volatile void __iomem *token)
239{ 248{
240 void *addr; 249 void *addr;
241 250
242 if (firmware_has_feature(FW_FEATURE_ISERIES))
243 return;
244
245 if (!mem_init_done) 251 if (!mem_init_done)
246 return; 252 return;
247 253
@@ -250,6 +256,14 @@ void iounmap(volatile void __iomem *token)
250 im_free(addr); 256 im_free(addr);
251} 257}
252 258
259void iounmap(volatile void __iomem *token)
260{
261 if (ppc_md.iounmap)
262 ppc_md.iounmap(token);
263 else
264 __iounmap(token);
265}
266
253static int iounmap_subset_regions(unsigned long addr, unsigned long size) 267static int iounmap_subset_regions(unsigned long addr, unsigned long size)
254{ 268{
255 struct vm_struct *area; 269 struct vm_struct *area;
@@ -268,7 +282,7 @@ static int iounmap_subset_regions(unsigned long addr, unsigned long size)
268 return 0; 282 return 0;
269} 283}
270 284
271int iounmap_explicit(volatile void __iomem *start, unsigned long size) 285int __iounmap_explicit(volatile void __iomem *start, unsigned long size)
272{ 286{
273 struct vm_struct *area; 287 struct vm_struct *area;
274 unsigned long addr; 288 unsigned long addr;
@@ -303,8 +317,10 @@ int iounmap_explicit(volatile void __iomem *start, unsigned long size)
303} 317}
304 318
305EXPORT_SYMBOL(ioremap); 319EXPORT_SYMBOL(ioremap);
320EXPORT_SYMBOL(ioremap_flags);
306EXPORT_SYMBOL(__ioremap); 321EXPORT_SYMBOL(__ioremap);
307EXPORT_SYMBOL(iounmap); 322EXPORT_SYMBOL(iounmap);
323EXPORT_SYMBOL(__iounmap);
308 324
309void __iomem * reserve_phb_iospace(unsigned long size) 325void __iomem * reserve_phb_iospace(unsigned long size)
310{ 326{
diff --git a/arch/powerpc/mm/slb.c b/arch/powerpc/mm/slb.c
index d3733912adb4..224e960650a0 100644
--- a/arch/powerpc/mm/slb.c
+++ b/arch/powerpc/mm/slb.c
@@ -23,6 +23,7 @@
23#include <asm/cputable.h> 23#include <asm/cputable.h>
24#include <asm/cacheflush.h> 24#include <asm/cacheflush.h>
25#include <asm/smp.h> 25#include <asm/smp.h>
26#include <asm/firmware.h>
26#include <linux/compiler.h> 27#include <linux/compiler.h>
27 28
28#ifdef DEBUG 29#ifdef DEBUG
@@ -193,6 +194,7 @@ static inline void patch_slb_encoding(unsigned int *insn_addr,
193void slb_initialize(void) 194void slb_initialize(void)
194{ 195{
195 unsigned long linear_llp, vmalloc_llp, io_llp; 196 unsigned long linear_llp, vmalloc_llp, io_llp;
197 unsigned long lflags, vflags;
196 static int slb_encoding_inited; 198 static int slb_encoding_inited;
197 extern unsigned int *slb_miss_kernel_load_linear; 199 extern unsigned int *slb_miss_kernel_load_linear;
198 extern unsigned int *slb_miss_kernel_load_io; 200 extern unsigned int *slb_miss_kernel_load_io;
@@ -225,11 +227,12 @@ void slb_initialize(void)
225#endif 227#endif
226 } 228 }
227 229
230 get_paca()->stab_rr = SLB_NUM_BOLTED;
231
228 /* On iSeries the bolted entries have already been set up by 232 /* On iSeries the bolted entries have already been set up by
229 * the hypervisor from the lparMap data in head.S */ 233 * the hypervisor from the lparMap data in head.S */
230#ifndef CONFIG_PPC_ISERIES 234 if (firmware_has_feature(FW_FEATURE_ISERIES))
231 { 235 return;
232 unsigned long lflags, vflags;
233 236
234 lflags = SLB_VSID_KERNEL | linear_llp; 237 lflags = SLB_VSID_KERNEL | linear_llp;
235 vflags = SLB_VSID_KERNEL | vmalloc_llp; 238 vflags = SLB_VSID_KERNEL | vmalloc_llp;
@@ -247,8 +250,4 @@ void slb_initialize(void)
247 * elsewhere, we'll call _switch() which will bolt in the new 250 * elsewhere, we'll call _switch() which will bolt in the new
248 * one. */ 251 * one. */
249 asm volatile("isync":::"memory"); 252 asm volatile("isync":::"memory");
250 }
251#endif /* CONFIG_PPC_ISERIES */
252
253 get_paca()->stab_rr = SLB_NUM_BOLTED;
254} 253}
diff --git a/arch/powerpc/oprofile/Makefile b/arch/powerpc/oprofile/Makefile
index 0b5df9c96ae0..4ccef2d5530c 100644
--- a/arch/powerpc/oprofile/Makefile
+++ b/arch/powerpc/oprofile/Makefile
@@ -11,6 +11,7 @@ DRIVER_OBJS := $(addprefix ../../../drivers/oprofile/, \
11 timer_int.o ) 11 timer_int.o )
12 12
13oprofile-y := $(DRIVER_OBJS) common.o backtrace.o 13oprofile-y := $(DRIVER_OBJS) common.o backtrace.o
14oprofile-$(CONFIG_PPC_CELL_NATIVE) += op_model_cell.o
14oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o 15oprofile-$(CONFIG_PPC64) += op_model_rs64.o op_model_power4.o
15oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o 16oprofile-$(CONFIG_FSL_BOOKE) += op_model_fsl_booke.o
16oprofile-$(CONFIG_6xx) += op_model_7450.o 17oprofile-$(CONFIG_6xx) += op_model_7450.o
diff --git a/arch/powerpc/oprofile/common.c b/arch/powerpc/oprofile/common.c
index 63bbef3b63f1..b6d82390b6a6 100644
--- a/arch/powerpc/oprofile/common.c
+++ b/arch/powerpc/oprofile/common.c
@@ -69,7 +69,10 @@ static void op_powerpc_cpu_start(void *dummy)
69 69
70static int op_powerpc_start(void) 70static int op_powerpc_start(void)
71{ 71{
72 on_each_cpu(op_powerpc_cpu_start, NULL, 0, 1); 72 if (model->global_start)
73 model->global_start(ctr);
74 if (model->start)
75 on_each_cpu(op_powerpc_cpu_start, NULL, 0, 1);
73 return 0; 76 return 0;
74} 77}
75 78
@@ -80,7 +83,10 @@ static inline void op_powerpc_cpu_stop(void *dummy)
80 83
81static void op_powerpc_stop(void) 84static void op_powerpc_stop(void)
82{ 85{
83 on_each_cpu(op_powerpc_cpu_stop, NULL, 0, 1); 86 if (model->stop)
87 on_each_cpu(op_powerpc_cpu_stop, NULL, 0, 1);
88 if (model->global_stop)
89 model->global_stop();
84} 90}
85 91
86static int op_powerpc_create_files(struct super_block *sb, struct dentry *root) 92static int op_powerpc_create_files(struct super_block *sb, struct dentry *root)
@@ -141,6 +147,11 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
141 147
142 switch (cur_cpu_spec->oprofile_type) { 148 switch (cur_cpu_spec->oprofile_type) {
143#ifdef CONFIG_PPC64 149#ifdef CONFIG_PPC64
150#ifdef CONFIG_PPC_CELL_NATIVE
151 case PPC_OPROFILE_CELL:
152 model = &op_model_cell;
153 break;
154#endif
144 case PPC_OPROFILE_RS64: 155 case PPC_OPROFILE_RS64:
145 model = &op_model_rs64; 156 model = &op_model_rs64;
146 break; 157 break;
diff --git a/arch/powerpc/oprofile/op_model_cell.c b/arch/powerpc/oprofile/op_model_cell.c
new file mode 100644
index 000000000000..2eb15f388103
--- /dev/null
+++ b/arch/powerpc/oprofile/op_model_cell.c
@@ -0,0 +1,724 @@
1/*
2 * Cell Broadband Engine OProfile Support
3 *
4 * (C) Copyright IBM Corporation 2006
5 *
6 * Author: David Erb (djerb@us.ibm.com)
7 * Modifications:
8 * Carl Love <carll@us.ibm.com>
9 * Maynard Johnson <maynardj@us.ibm.com>
10 *
11 * This program is free software; you can redistribute it and/or
12 * modify it under the terms of the GNU General Public License
13 * as published by the Free Software Foundation; either version
14 * 2 of the License, or (at your option) any later version.
15 */
16
17#include <linux/cpufreq.h>
18#include <linux/delay.h>
19#include <linux/init.h>
20#include <linux/jiffies.h>
21#include <linux/kthread.h>
22#include <linux/oprofile.h>
23#include <linux/percpu.h>
24#include <linux/smp.h>
25#include <linux/spinlock.h>
26#include <linux/timer.h>
27#include <asm/cell-pmu.h>
28#include <asm/cputable.h>
29#include <asm/firmware.h>
30#include <asm/io.h>
31#include <asm/oprofile_impl.h>
32#include <asm/processor.h>
33#include <asm/prom.h>
34#include <asm/ptrace.h>
35#include <asm/reg.h>
36#include <asm/rtas.h>
37#include <asm/system.h>
38
39#include "../platforms/cell/interrupt.h"
40
41#define PPU_CYCLES_EVENT_NUM 1 /* event number for CYCLES */
42#define CBE_COUNT_ALL_CYCLES 0x42800000 /* PPU cycle event specifier */
43
44#define NUM_THREADS 2
45#define VIRT_CNTR_SW_TIME_NS 100000000 // 0.5 seconds
46
47struct pmc_cntrl_data {
48 unsigned long vcntr;
49 unsigned long evnts;
50 unsigned long masks;
51 unsigned long enabled;
52};
53
54/*
55 * ibm,cbe-perftools rtas parameters
56 */
57
58struct pm_signal {
59 u16 cpu; /* Processor to modify */
60 u16 sub_unit; /* hw subunit this applies to (if applicable) */
61 u16 signal_group; /* Signal Group to Enable/Disable */
62 u8 bus_word; /* Enable/Disable on this Trace/Trigger/Event
63 * Bus Word(s) (bitmask)
64 */
65 u8 bit; /* Trigger/Event bit (if applicable) */
66};
67
68/*
69 * rtas call arguments
70 */
71enum {
72 SUBFUNC_RESET = 1,
73 SUBFUNC_ACTIVATE = 2,
74 SUBFUNC_DEACTIVATE = 3,
75
76 PASSTHRU_IGNORE = 0,
77 PASSTHRU_ENABLE = 1,
78 PASSTHRU_DISABLE = 2,
79};
80
81struct pm_cntrl {
82 u16 enable;
83 u16 stop_at_max;
84 u16 trace_mode;
85 u16 freeze;
86 u16 count_mode;
87};
88
89static struct {
90 u32 group_control;
91 u32 debug_bus_control;
92 struct pm_cntrl pm_cntrl;
93 u32 pm07_cntrl[NR_PHYS_CTRS];
94} pm_regs;
95
96
97#define GET_SUB_UNIT(x) ((x & 0x0000f000) >> 12)
98#define GET_BUS_WORD(x) ((x & 0x000000f0) >> 4)
99#define GET_BUS_TYPE(x) ((x & 0x00000300) >> 8)
100#define GET_POLARITY(x) ((x & 0x00000002) >> 1)
101#define GET_COUNT_CYCLES(x) (x & 0x00000001)
102#define GET_INPUT_CONTROL(x) ((x & 0x00000004) >> 2)
103
104
105static DEFINE_PER_CPU(unsigned long[NR_PHYS_CTRS], pmc_values);
106
107static struct pmc_cntrl_data pmc_cntrl[NUM_THREADS][NR_PHYS_CTRS];
108
109/* Interpetation of hdw_thread:
110 * 0 - even virtual cpus 0, 2, 4,...
111 * 1 - odd virtual cpus 1, 3, 5, ...
112 */
113static u32 hdw_thread;
114
115static u32 virt_cntr_inter_mask;
116static struct timer_list timer_virt_cntr;
117
118/* pm_signal needs to be global since it is initialized in
119 * cell_reg_setup at the time when the necessary information
120 * is available.
121 */
122static struct pm_signal pm_signal[NR_PHYS_CTRS];
123static int pm_rtas_token;
124
125static u32 reset_value[NR_PHYS_CTRS];
126static int num_counters;
127static int oprofile_running;
128static spinlock_t virt_cntr_lock = SPIN_LOCK_UNLOCKED;
129
130static u32 ctr_enabled;
131
132static unsigned char trace_bus[4];
133static unsigned char input_bus[2];
134
135/*
136 * Firmware interface functions
137 */
138static int
139rtas_ibm_cbe_perftools(int subfunc, int passthru,
140 void *address, unsigned long length)
141{
142 u64 paddr = __pa(address);
143
144 return rtas_call(pm_rtas_token, 5, 1, NULL, subfunc, passthru,
145 paddr >> 32, paddr & 0xffffffff, length);
146}
147
148static void pm_rtas_reset_signals(u32 node)
149{
150 int ret;
151 struct pm_signal pm_signal_local;
152
153 /* The debug bus is being set to the passthru disable state.
154 * However, the FW still expects atleast one legal signal routing
155 * entry or it will return an error on the arguments. If we don't
156 * supply a valid entry, we must ignore all return values. Ignoring
157 * all return values means we might miss an error we should be
158 * concerned about.
159 */
160
161 /* fw expects physical cpu #. */
162 pm_signal_local.cpu = node;
163 pm_signal_local.signal_group = 21;
164 pm_signal_local.bus_word = 1;
165 pm_signal_local.sub_unit = 0;
166 pm_signal_local.bit = 0;
167
168 ret = rtas_ibm_cbe_perftools(SUBFUNC_RESET, PASSTHRU_DISABLE,
169 &pm_signal_local,
170 sizeof(struct pm_signal));
171
172 if (ret)
173 printk(KERN_WARNING "%s: rtas returned: %d\n",
174 __FUNCTION__, ret);
175}
176
177static void pm_rtas_activate_signals(u32 node, u32 count)
178{
179 int ret;
180 int j;
181 struct pm_signal pm_signal_local[NR_PHYS_CTRS];
182
183 for (j = 0; j < count; j++) {
184 /* fw expects physical cpu # */
185 pm_signal_local[j].cpu = node;
186 pm_signal_local[j].signal_group = pm_signal[j].signal_group;
187 pm_signal_local[j].bus_word = pm_signal[j].bus_word;
188 pm_signal_local[j].sub_unit = pm_signal[j].sub_unit;
189 pm_signal_local[j].bit = pm_signal[j].bit;
190 }
191
192 ret = rtas_ibm_cbe_perftools(SUBFUNC_ACTIVATE, PASSTHRU_ENABLE,
193 pm_signal_local,
194 count * sizeof(struct pm_signal));
195
196 if (ret)
197 printk(KERN_WARNING "%s: rtas returned: %d\n",
198 __FUNCTION__, ret);
199}
200
201/*
202 * PM Signal functions
203 */
204static void set_pm_event(u32 ctr, int event, u32 unit_mask)
205{
206 struct pm_signal *p;
207 u32 signal_bit;
208 u32 bus_word, bus_type, count_cycles, polarity, input_control;
209 int j, i;
210
211 if (event == PPU_CYCLES_EVENT_NUM) {
212 /* Special Event: Count all cpu cycles */
213 pm_regs.pm07_cntrl[ctr] = CBE_COUNT_ALL_CYCLES;
214 p = &(pm_signal[ctr]);
215 p->signal_group = 21;
216 p->bus_word = 1;
217 p->sub_unit = 0;
218 p->bit = 0;
219 goto out;
220 } else {
221 pm_regs.pm07_cntrl[ctr] = 0;
222 }
223
224 bus_word = GET_BUS_WORD(unit_mask);
225 bus_type = GET_BUS_TYPE(unit_mask);
226 count_cycles = GET_COUNT_CYCLES(unit_mask);
227 polarity = GET_POLARITY(unit_mask);
228 input_control = GET_INPUT_CONTROL(unit_mask);
229 signal_bit = (event % 100);
230
231 p = &(pm_signal[ctr]);
232
233 p->signal_group = event / 100;
234 p->bus_word = bus_word;
235 p->sub_unit = unit_mask & 0x0000f000;
236
237 pm_regs.pm07_cntrl[ctr] = 0;
238 pm_regs.pm07_cntrl[ctr] |= PM07_CTR_COUNT_CYCLES(count_cycles);
239 pm_regs.pm07_cntrl[ctr] |= PM07_CTR_POLARITY(polarity);
240 pm_regs.pm07_cntrl[ctr] |= PM07_CTR_INPUT_CONTROL(input_control);
241
242 if (input_control == 0) {
243 if (signal_bit > 31) {
244 signal_bit -= 32;
245 if (bus_word == 0x3)
246 bus_word = 0x2;
247 else if (bus_word == 0xc)
248 bus_word = 0x8;
249 }
250
251 if ((bus_type == 0) && p->signal_group >= 60)
252 bus_type = 2;
253 if ((bus_type == 1) && p->signal_group >= 50)
254 bus_type = 0;
255
256 pm_regs.pm07_cntrl[ctr] |= PM07_CTR_INPUT_MUX(signal_bit);
257 } else {
258 pm_regs.pm07_cntrl[ctr] = 0;
259 p->bit = signal_bit;
260 }
261
262 for (i = 0; i < 4; i++) {
263 if (bus_word & (1 << i)) {
264 pm_regs.debug_bus_control |=
265 (bus_type << (31 - (2 * i) + 1));
266
267 for (j = 0; j < 2; j++) {
268 if (input_bus[j] == 0xff) {
269 input_bus[j] = i;
270 pm_regs.group_control |=
271 (i << (31 - i));
272 break;
273 }
274 }
275 }
276 }
277out:
278 ;
279}
280
281static void write_pm_cntrl(int cpu, struct pm_cntrl *pm_cntrl)
282{
283 /* Oprofile will use 32 bit counters, set bits 7:10 to 0 */
284 u32 val = 0;
285 if (pm_cntrl->enable == 1)
286 val |= CBE_PM_ENABLE_PERF_MON;
287
288 if (pm_cntrl->stop_at_max == 1)
289 val |= CBE_PM_STOP_AT_MAX;
290
291 if (pm_cntrl->trace_mode == 1)
292 val |= CBE_PM_TRACE_MODE_SET(pm_cntrl->trace_mode);
293
294 if (pm_cntrl->freeze == 1)
295 val |= CBE_PM_FREEZE_ALL_CTRS;
296
297 /* Routine set_count_mode must be called previously to set
298 * the count mode based on the user selection of user and kernel.
299 */
300 val |= CBE_PM_COUNT_MODE_SET(pm_cntrl->count_mode);
301 cbe_write_pm(cpu, pm_control, val);
302}
303
304static inline void
305set_count_mode(u32 kernel, u32 user, struct pm_cntrl *pm_cntrl)
306{
307 /* The user must specify user and kernel if they want them. If
308 * neither is specified, OProfile will count in hypervisor mode
309 */
310 if (kernel) {
311 if (user)
312 pm_cntrl->count_mode = CBE_COUNT_ALL_MODES;
313 else
314 pm_cntrl->count_mode = CBE_COUNT_SUPERVISOR_MODE;
315 } else {
316 if (user)
317 pm_cntrl->count_mode = CBE_COUNT_PROBLEM_MODE;
318 else
319 pm_cntrl->count_mode = CBE_COUNT_HYPERVISOR_MODE;
320 }
321}
322
323static inline void enable_ctr(u32 cpu, u32 ctr, u32 * pm07_cntrl)
324{
325
326 pm07_cntrl[ctr] |= PM07_CTR_ENABLE(1);
327 cbe_write_pm07_control(cpu, ctr, pm07_cntrl[ctr]);
328}
329
330/*
331 * Oprofile is expected to collect data on all CPUs simultaneously.
332 * However, there is one set of performance counters per node. There are
333 * two hardware threads or virtual CPUs on each node. Hence, OProfile must
334 * multiplex in time the performance counter collection on the two virtual
335 * CPUs. The multiplexing of the performance counters is done by this
336 * virtual counter routine.
337 *
338 * The pmc_values used below is defined as 'per-cpu' but its use is
339 * more akin to 'per-node'. We need to store two sets of counter
340 * values per node -- one for the previous run and one for the next.
341 * The per-cpu[NR_PHYS_CTRS] gives us the storage we need. Each odd/even
342 * pair of per-cpu arrays is used for storing the previous and next
343 * pmc values for a given node.
344 * NOTE: We use the per-cpu variable to improve cache performance.
345 */
346static void cell_virtual_cntr(unsigned long data)
347{
348 /* This routine will alternate loading the virtual counters for
349 * virtual CPUs
350 */
351 int i, prev_hdw_thread, next_hdw_thread;
352 u32 cpu;
353 unsigned long flags;
354
355 /* Make sure that the interrupt_hander and
356 * the virt counter are not both playing with
357 * the counters on the same node.
358 */
359
360 spin_lock_irqsave(&virt_cntr_lock, flags);
361
362 prev_hdw_thread = hdw_thread;
363
364 /* switch the cpu handling the interrupts */
365 hdw_thread = 1 ^ hdw_thread;
366 next_hdw_thread = hdw_thread;
367
368 /* The following is done only once per each node, but
369 * we need cpu #, not node #, to pass to the cbe_xxx functions.
370 */
371 for_each_online_cpu(cpu) {
372 if (cbe_get_hw_thread_id(cpu))
373 continue;
374
375 /* stop counters, save counter values, restore counts
376 * for previous thread
377 */
378 cbe_disable_pm(cpu);
379 cbe_disable_pm_interrupts(cpu);
380 for (i = 0; i < num_counters; i++) {
381 per_cpu(pmc_values, cpu + prev_hdw_thread)[i]
382 = cbe_read_ctr(cpu, i);
383
384 if (per_cpu(pmc_values, cpu + next_hdw_thread)[i]
385 == 0xFFFFFFFF)
386 /* If the cntr value is 0xffffffff, we must
387 * reset that to 0xfffffff0 when the current
388 * thread is restarted. This will generate a new
389 * interrupt and make sure that we never restore
390 * the counters to the max value. If the counters
391 * were restored to the max value, they do not
392 * increment and no interrupts are generated. Hence
393 * no more samples will be collected on that cpu.
394 */
395 cbe_write_ctr(cpu, i, 0xFFFFFFF0);
396 else
397 cbe_write_ctr(cpu, i,
398 per_cpu(pmc_values,
399 cpu +
400 next_hdw_thread)[i]);
401 }
402
403 /* Switch to the other thread. Change the interrupt
404 * and control regs to be scheduled on the CPU
405 * corresponding to the thread to execute.
406 */
407 for (i = 0; i < num_counters; i++) {
408 if (pmc_cntrl[next_hdw_thread][i].enabled) {
409 /* There are some per thread events.
410 * Must do the set event, enable_cntr
411 * for each cpu.
412 */
413 set_pm_event(i,
414 pmc_cntrl[next_hdw_thread][i].evnts,
415 pmc_cntrl[next_hdw_thread][i].masks);
416 enable_ctr(cpu, i,
417 pm_regs.pm07_cntrl);
418 } else {
419 cbe_write_pm07_control(cpu, i, 0);
420 }
421 }
422
423 /* Enable interrupts on the CPU thread that is starting */
424 cbe_enable_pm_interrupts(cpu, next_hdw_thread,
425 virt_cntr_inter_mask);
426 cbe_enable_pm(cpu);
427 }
428
429 spin_unlock_irqrestore(&virt_cntr_lock, flags);
430
431 mod_timer(&timer_virt_cntr, jiffies + HZ / 10);
432}
433
434static void start_virt_cntrs(void)
435{
436 init_timer(&timer_virt_cntr);
437 timer_virt_cntr.function = cell_virtual_cntr;
438 timer_virt_cntr.data = 0UL;
439 timer_virt_cntr.expires = jiffies + HZ / 10;
440 add_timer(&timer_virt_cntr);
441}
442
443/* This function is called once for all cpus combined */
444static void
445cell_reg_setup(struct op_counter_config *ctr,
446 struct op_system_config *sys, int num_ctrs)
447{
448 int i, j, cpu;
449
450 pm_rtas_token = rtas_token("ibm,cbe-perftools");
451 if (pm_rtas_token == RTAS_UNKNOWN_SERVICE) {
452 printk(KERN_WARNING "%s: RTAS_UNKNOWN_SERVICE\n",
453 __FUNCTION__);
454 goto out;
455 }
456
457 num_counters = num_ctrs;
458
459 pm_regs.group_control = 0;
460 pm_regs.debug_bus_control = 0;
461
462 /* setup the pm_control register */
463 memset(&pm_regs.pm_cntrl, 0, sizeof(struct pm_cntrl));
464 pm_regs.pm_cntrl.stop_at_max = 1;
465 pm_regs.pm_cntrl.trace_mode = 0;
466 pm_regs.pm_cntrl.freeze = 1;
467
468 set_count_mode(sys->enable_kernel, sys->enable_user,
469 &pm_regs.pm_cntrl);
470
471 /* Setup the thread 0 events */
472 for (i = 0; i < num_ctrs; ++i) {
473
474 pmc_cntrl[0][i].evnts = ctr[i].event;
475 pmc_cntrl[0][i].masks = ctr[i].unit_mask;
476 pmc_cntrl[0][i].enabled = ctr[i].enabled;
477 pmc_cntrl[0][i].vcntr = i;
478
479 for_each_possible_cpu(j)
480 per_cpu(pmc_values, j)[i] = 0;
481 }
482
483 /* Setup the thread 1 events, map the thread 0 event to the
484 * equivalent thread 1 event.
485 */
486 for (i = 0; i < num_ctrs; ++i) {
487 if ((ctr[i].event >= 2100) && (ctr[i].event <= 2111))
488 pmc_cntrl[1][i].evnts = ctr[i].event + 19;
489 else if (ctr[i].event == 2203)
490 pmc_cntrl[1][i].evnts = ctr[i].event;
491 else if ((ctr[i].event >= 2200) && (ctr[i].event <= 2215))
492 pmc_cntrl[1][i].evnts = ctr[i].event + 16;
493 else
494 pmc_cntrl[1][i].evnts = ctr[i].event;
495
496 pmc_cntrl[1][i].masks = ctr[i].unit_mask;
497 pmc_cntrl[1][i].enabled = ctr[i].enabled;
498 pmc_cntrl[1][i].vcntr = i;
499 }
500
501 for (i = 0; i < 4; i++)
502 trace_bus[i] = 0xff;
503
504 for (i = 0; i < 2; i++)
505 input_bus[i] = 0xff;
506
507 /* Our counters count up, and "count" refers to
508 * how much before the next interrupt, and we interrupt
509 * on overflow. So we calculate the starting value
510 * which will give us "count" until overflow.
511 * Then we set the events on the enabled counters.
512 */
513 for (i = 0; i < num_counters; ++i) {
514 /* start with virtual counter set 0 */
515 if (pmc_cntrl[0][i].enabled) {
516 /* Using 32bit counters, reset max - count */
517 reset_value[i] = 0xFFFFFFFF - ctr[i].count;
518 set_pm_event(i,
519 pmc_cntrl[0][i].evnts,
520 pmc_cntrl[0][i].masks);
521
522 /* global, used by cell_cpu_setup */
523 ctr_enabled |= (1 << i);
524 }
525 }
526
527 /* initialize the previous counts for the virtual cntrs */
528 for_each_online_cpu(cpu)
529 for (i = 0; i < num_counters; ++i) {
530 per_cpu(pmc_values, cpu)[i] = reset_value[i];
531 }
532out:
533 ;
534}
535
536/* This function is called once for each cpu */
537static void cell_cpu_setup(struct op_counter_config *cntr)
538{
539 u32 cpu = smp_processor_id();
540 u32 num_enabled = 0;
541 int i;
542
543 /* There is one performance monitor per processor chip (i.e. node),
544 * so we only need to perform this function once per node.
545 */
546 if (cbe_get_hw_thread_id(cpu))
547 goto out;
548
549 if (pm_rtas_token == RTAS_UNKNOWN_SERVICE) {
550 printk(KERN_WARNING "%s: RTAS_UNKNOWN_SERVICE\n",
551 __FUNCTION__);
552 goto out;
553 }
554
555 /* Stop all counters */
556 cbe_disable_pm(cpu);
557 cbe_disable_pm_interrupts(cpu);
558
559 cbe_write_pm(cpu, pm_interval, 0);
560 cbe_write_pm(cpu, pm_start_stop, 0);
561 cbe_write_pm(cpu, group_control, pm_regs.group_control);
562 cbe_write_pm(cpu, debug_bus_control, pm_regs.debug_bus_control);
563 write_pm_cntrl(cpu, &pm_regs.pm_cntrl);
564
565 for (i = 0; i < num_counters; ++i) {
566 if (ctr_enabled & (1 << i)) {
567 pm_signal[num_enabled].cpu = cbe_cpu_to_node(cpu);
568 num_enabled++;
569 }
570 }
571
572 pm_rtas_activate_signals(cbe_cpu_to_node(cpu), num_enabled);
573out:
574 ;
575}
576
577static void cell_global_start(struct op_counter_config *ctr)
578{
579 u32 cpu;
580 u32 interrupt_mask = 0;
581 u32 i;
582
583 /* This routine gets called once for the system.
584 * There is one performance monitor per node, so we
585 * only need to perform this function once per node.
586 */
587 for_each_online_cpu(cpu) {
588 if (cbe_get_hw_thread_id(cpu))
589 continue;
590
591 interrupt_mask = 0;
592
593 for (i = 0; i < num_counters; ++i) {
594 if (ctr_enabled & (1 << i)) {
595 cbe_write_ctr(cpu, i, reset_value[i]);
596 enable_ctr(cpu, i, pm_regs.pm07_cntrl);
597 interrupt_mask |=
598 CBE_PM_CTR_OVERFLOW_INTR(i);
599 } else {
600 /* Disable counter */
601 cbe_write_pm07_control(cpu, i, 0);
602 }
603 }
604
605 cbe_clear_pm_interrupts(cpu);
606 cbe_enable_pm_interrupts(cpu, hdw_thread, interrupt_mask);
607 cbe_enable_pm(cpu);
608 }
609
610 virt_cntr_inter_mask = interrupt_mask;
611 oprofile_running = 1;
612 smp_wmb();
613
614 /* NOTE: start_virt_cntrs will result in cell_virtual_cntr() being
615 * executed which manipulates the PMU. We start the "virtual counter"
616 * here so that we do not need to synchronize access to the PMU in
617 * the above for-loop.
618 */
619 start_virt_cntrs();
620}
621
622static void cell_global_stop(void)
623{
624 int cpu;
625
626 /* This routine will be called once for the system.
627 * There is one performance monitor per node, so we
628 * only need to perform this function once per node.
629 */
630 del_timer_sync(&timer_virt_cntr);
631 oprofile_running = 0;
632 smp_wmb();
633
634 for_each_online_cpu(cpu) {
635 if (cbe_get_hw_thread_id(cpu))
636 continue;
637
638 cbe_sync_irq(cbe_cpu_to_node(cpu));
639 /* Stop the counters */
640 cbe_disable_pm(cpu);
641
642 /* Deactivate the signals */
643 pm_rtas_reset_signals(cbe_cpu_to_node(cpu));
644
645 /* Deactivate interrupts */
646 cbe_disable_pm_interrupts(cpu);
647 }
648}
649
650static void
651cell_handle_interrupt(struct pt_regs *regs, struct op_counter_config *ctr)
652{
653 u32 cpu;
654 u64 pc;
655 int is_kernel;
656 unsigned long flags = 0;
657 u32 interrupt_mask;
658 int i;
659
660 cpu = smp_processor_id();
661
662 /* Need to make sure the interrupt handler and the virt counter
663 * routine are not running at the same time. See the
664 * cell_virtual_cntr() routine for additional comments.
665 */
666 spin_lock_irqsave(&virt_cntr_lock, flags);
667
668 /* Need to disable and reenable the performance counters
669 * to get the desired behavior from the hardware. This
670 * is hardware specific.
671 */
672
673 cbe_disable_pm(cpu);
674
675 interrupt_mask = cbe_clear_pm_interrupts(cpu);
676
677 /* If the interrupt mask has been cleared, then the virt cntr
678 * has cleared the interrupt. When the thread that generated
679 * the interrupt is restored, the data count will be restored to
680 * 0xffffff0 to cause the interrupt to be regenerated.
681 */
682
683 if ((oprofile_running == 1) && (interrupt_mask != 0)) {
684 pc = regs->nip;
685 is_kernel = is_kernel_addr(pc);
686
687 for (i = 0; i < num_counters; ++i) {
688 if ((interrupt_mask & CBE_PM_CTR_OVERFLOW_INTR(i))
689 && ctr[i].enabled) {
690 oprofile_add_pc(pc, is_kernel, i);
691 cbe_write_ctr(cpu, i, reset_value[i]);
692 }
693 }
694
695 /* The counters were frozen by the interrupt.
696 * Reenable the interrupt and restart the counters.
697 * If there was a race between the interrupt handler and
698 * the virtual counter routine. The virutal counter
699 * routine may have cleared the interrupts. Hence must
700 * use the virt_cntr_inter_mask to re-enable the interrupts.
701 */
702 cbe_enable_pm_interrupts(cpu, hdw_thread,
703 virt_cntr_inter_mask);
704
705 /* The writes to the various performance counters only writes
706 * to a latch. The new values (interrupt setting bits, reset
707 * counter value etc.) are not copied to the actual registers
708 * until the performance monitor is enabled. In order to get
709 * this to work as desired, the permormance monitor needs to
710 * be disabled while writting to the latches. This is a
711 * HW design issue.
712 */
713 cbe_enable_pm(cpu);
714 }
715 spin_unlock_irqrestore(&virt_cntr_lock, flags);
716}
717
718struct op_powerpc_model op_model_cell = {
719 .reg_setup = cell_reg_setup,
720 .cpu_setup = cell_cpu_setup,
721 .global_start = cell_global_start,
722 .global_stop = cell_global_stop,
723 .handle_interrupt = cell_handle_interrupt,
724};
diff --git a/arch/powerpc/platforms/52xx/Makefile b/arch/powerpc/platforms/52xx/Makefile
new file mode 100644
index 000000000000..a46184a0c750
--- /dev/null
+++ b/arch/powerpc/platforms/52xx/Makefile
@@ -0,0 +1,9 @@
1#
2# Makefile for 52xx based boards
3#
4ifeq ($(CONFIG_PPC_MERGE),y)
5obj-y += mpc52xx_pic.o mpc52xx_common.o
6endif
7
8obj-$(CONFIG_PPC_EFIKA) += efika-setup.o efika-pci.o
9obj-$(CONFIG_PPC_LITE5200) += lite5200.o
diff --git a/arch/powerpc/platforms/52xx/efika-pci.c b/arch/powerpc/platforms/52xx/efika-pci.c
new file mode 100644
index 000000000000..62e05b2a9227
--- /dev/null
+++ b/arch/powerpc/platforms/52xx/efika-pci.c
@@ -0,0 +1,119 @@
1
2#include <linux/kernel.h>
3#include <linux/pci.h>
4#include <linux/string.h>
5#include <linux/init.h>
6
7#include <asm/io.h>
8#include <asm/irq.h>
9#include <asm/prom.h>
10#include <asm/machdep.h>
11#include <asm/sections.h>
12#include <asm/pci-bridge.h>
13#include <asm/rtas.h>
14
15#include "efika.h"
16
17#ifdef CONFIG_PCI
18/*
19 * Access functions for PCI config space using RTAS calls.
20 */
21static int rtas_read_config(struct pci_bus *bus, unsigned int devfn, int offset,
22 int len, u32 * val)
23{
24 struct pci_controller *hose = bus->sysdata;
25 unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
26 | (((bus->number - hose->first_busno) & 0xff) << 16)
27 | (hose->index << 24);
28 int ret = -1;
29 int rval;
30
31 rval = rtas_call(rtas_token("read-pci-config"), 2, 2, &ret, addr, len);
32 *val = ret;
33 return rval ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
34}
35
36static int rtas_write_config(struct pci_bus *bus, unsigned int devfn,
37 int offset, int len, u32 val)
38{
39 struct pci_controller *hose = bus->sysdata;
40 unsigned long addr = (offset & 0xff) | ((devfn & 0xff) << 8)
41 | (((bus->number - hose->first_busno) & 0xff) << 16)
42 | (hose->index << 24);
43 int rval;
44
45 rval = rtas_call(rtas_token("write-pci-config"), 3, 1, NULL,
46 addr, len, val);
47 return rval ? PCIBIOS_DEVICE_NOT_FOUND : PCIBIOS_SUCCESSFUL;
48}
49
50static struct pci_ops rtas_pci_ops = {
51 rtas_read_config,
52 rtas_write_config
53};
54
55void __init efika_pcisetup(void)
56{
57 const int *bus_range;
58 int len;
59 struct pci_controller *hose;
60 struct device_node *root;
61 struct device_node *pcictrl;
62
63 root = of_find_node_by_path("/");
64 if (root == NULL) {
65 printk(KERN_WARNING EFIKA_PLATFORM_NAME
66 ": Unable to find the root node\n");
67 return;
68 }
69
70 for (pcictrl = NULL;;) {
71 pcictrl = of_get_next_child(root, pcictrl);
72 if ((pcictrl == NULL) || (strcmp(pcictrl->name, "pci") == 0))
73 break;
74 }
75
76 of_node_put(root);
77
78 if (pcictrl == NULL) {
79 printk(KERN_WARNING EFIKA_PLATFORM_NAME
80 ": Unable to find the PCI bridge node\n");
81 return;
82 }
83
84 bus_range = get_property(pcictrl, "bus-range", &len);
85 if (bus_range == NULL || len < 2 * sizeof(int)) {
86 printk(KERN_WARNING EFIKA_PLATFORM_NAME
87 ": Can't get bus-range for %s\n", pcictrl->full_name);
88 return;
89 }
90
91 if (bus_range[1] == bus_range[0])
92 printk(KERN_INFO EFIKA_PLATFORM_NAME ": PCI bus %d",
93 bus_range[0]);
94 else
95 printk(KERN_INFO EFIKA_PLATFORM_NAME ": PCI buses %d..%d",
96 bus_range[0], bus_range[1]);
97 printk(" controlled by %s\n", pcictrl->full_name);
98 printk("\n");
99
100 hose = pcibios_alloc_controller();
101 if (!hose) {
102 printk(KERN_WARNING EFIKA_PLATFORM_NAME
103 ": Can't allocate PCI controller structure for %s\n",
104 pcictrl->full_name);
105 return;
106 }
107
108 hose->arch_data = of_node_get(pcictrl);
109 hose->first_busno = bus_range[0];
110 hose->last_busno = bus_range[1];
111 hose->ops = &rtas_pci_ops;
112
113 pci_process_bridge_OF_ranges(hose, pcictrl, 0);
114}
115
116#else
117void __init efika_pcisetup(void)
118{}
119#endif
diff --git a/arch/powerpc/platforms/52xx/efika-setup.c b/arch/powerpc/platforms/52xx/efika-setup.c
new file mode 100644
index 000000000000..110c980ed1e0
--- /dev/null
+++ b/arch/powerpc/platforms/52xx/efika-setup.c
@@ -0,0 +1,150 @@
1/*
2 *
3 * Efika 5K2 platform setup
4 * Some code really inspired from the lite5200b platform.
5 *
6 * Copyright (C) 2006 bplan GmbH
7 *
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
11 *
12 */
13
14#include <linux/errno.h>
15#include <linux/kernel.h>
16#include <linux/slab.h>
17#include <linux/reboot.h>
18#include <linux/init.h>
19#include <linux/utsrelease.h>
20#include <linux/seq_file.h>
21#include <linux/root_dev.h>
22#include <linux/initrd.h>
23#include <linux/timer.h>
24#include <linux/pci.h>
25
26#include <asm/pgtable.h>
27#include <asm/prom.h>
28#include <asm/time.h>
29#include <asm/machdep.h>
30#include <asm/rtas.h>
31#include <asm/of_device.h>
32#include <asm/of_platform.h>
33#include <asm/mpc52xx.h>
34
35#include "efika.h"
36
37static void efika_show_cpuinfo(struct seq_file *m)
38{
39 struct device_node *root;
40 const char *revision = NULL;
41 const char *codegendescription = NULL;
42 const char *codegenvendor = NULL;
43
44 root = of_find_node_by_path("/");
45 if (root) {
46 revision = get_property(root, "revision", NULL);
47 codegendescription =
48 get_property(root, "CODEGEN,description", NULL);
49 codegenvendor = get_property(root, "CODEGEN,vendor", NULL);
50
51 of_node_put(root);
52 }
53
54 if (codegendescription)
55 seq_printf(m, "machine\t\t: %s\n", codegendescription);
56 else
57 seq_printf(m, "machine\t\t: Efika\n");
58
59 if (revision)
60 seq_printf(m, "revision\t: %s\n", revision);
61
62 if (codegenvendor)
63 seq_printf(m, "vendor\t\t: %s\n", codegenvendor);
64
65 of_node_put(root);
66}
67
68static void __init efika_setup_arch(void)
69{
70 rtas_initialize();
71
72#ifdef CONFIG_BLK_DEV_INITRD
73 initrd_below_start_ok = 1;
74
75 if (initrd_start)
76 ROOT_DEV = Root_RAM0;
77 else
78#endif
79 ROOT_DEV = Root_SDA2; /* sda2 (sda1 is for the kernel) */
80
81 efika_pcisetup();
82
83 if (ppc_md.progress)
84 ppc_md.progress("Linux/PPC " UTS_RELEASE " runnung on Efika ;-)\n", 0x0);
85}
86
87static void __init efika_init(void)
88{
89 struct device_node *np;
90 struct device_node *cnp = NULL;
91 const u32 *base;
92
93 /* Find every child of the SOC node and add it to of_platform */
94 np = of_find_node_by_name(NULL, "builtin");
95 if (np) {
96 char name[BUS_ID_SIZE];
97 while ((cnp = of_get_next_child(np, cnp))) {
98 strcpy(name, cnp->name);
99
100 base = get_property(cnp, "reg", NULL);
101 if (base == NULL)
102 continue;
103
104 snprintf(name+strlen(name), BUS_ID_SIZE, "@%x", *base);
105 of_platform_device_create(cnp, name, NULL);
106
107 printk(KERN_INFO EFIKA_PLATFORM_NAME" : Added %s (type '%s' at '%s') to the known devices\n", name, cnp->type, cnp->full_name);
108 }
109 }
110
111 if (ppc_md.progress)
112 ppc_md.progress(" Have fun with your Efika! ", 0x7777);
113}
114
115static int __init efika_probe(void)
116{
117 char *model = of_get_flat_dt_prop(of_get_flat_dt_root(),
118 "model", NULL);
119
120 if (model == NULL)
121 return 0;
122 if (strcmp(model, "EFIKA5K2"))
123 return 0;
124
125 ISA_DMA_THRESHOLD = ~0L;
126 DMA_MODE_READ = 0x44;
127 DMA_MODE_WRITE = 0x48;
128
129 return 1;
130}
131
132define_machine(efika)
133{
134 .name = EFIKA_PLATFORM_NAME,
135 .probe = efika_probe,
136 .setup_arch = efika_setup_arch,
137 .init = efika_init,
138 .show_cpuinfo = efika_show_cpuinfo,
139 .init_IRQ = mpc52xx_init_irq,
140 .get_irq = mpc52xx_get_irq,
141 .restart = rtas_restart,
142 .power_off = rtas_power_off,
143 .halt = rtas_halt,
144 .set_rtc_time = rtas_set_rtc_time,
145 .get_rtc_time = rtas_get_rtc_time,
146 .progress = rtas_progress,
147 .get_boot_time = rtas_get_boot_time,
148 .calibrate_decr = generic_calibrate_decr,
149 .phys_mem_access_prot = pci_phys_mem_access_prot,
150};
diff --git a/arch/powerpc/platforms/52xx/efika.h b/arch/powerpc/platforms/52xx/efika.h
new file mode 100644
index 000000000000..2f060fd097d7
--- /dev/null
+++ b/arch/powerpc/platforms/52xx/efika.h
@@ -0,0 +1,19 @@
1/*
2 * Efika 5K2 platform setup - Header file
3 *
4 * Copyright (C) 2006 bplan GmbH
5 *
6 * This file is licensed under the terms of the GNU General Public License
7 * version 2. This program is licensed "as is" without any warranty of any
8 * kind, whether express or implied.
9 *
10 */
11
12#ifndef __ARCH_POWERPC_EFIKA__
13#define __ARCH_POWERPC_EFIKA__
14
15#define EFIKA_PLATFORM_NAME "Efika"
16
17extern void __init efika_pcisetup(void);
18
19#endif
diff --git a/arch/powerpc/platforms/52xx/lite5200.c b/arch/powerpc/platforms/52xx/lite5200.c
new file mode 100644
index 000000000000..a375c15b4315
--- /dev/null
+++ b/arch/powerpc/platforms/52xx/lite5200.c
@@ -0,0 +1,162 @@
1/*
2 * Freescale Lite5200 board support
3 *
4 * Written by: Grant Likely <grant.likely@secretlab.ca>
5 *
6 * Copyright (C) Secret Lab Technologies Ltd. 2006. All rights reserved.
7 * Copyright (C) Freescale Semicondutor, Inc. 2006. All rights reserved.
8 *
9 * Description:
10 * This program is free software; you can redistribute it and/or modify it
11 * under the terms of the GNU General Public License as published by the
12 * Free Software Foundation; either version 2 of the License, or (at your
13 * option) any later version.
14 */
15
16#undef DEBUG
17
18#include <linux/stddef.h>
19#include <linux/kernel.h>
20#include <linux/init.h>
21#include <linux/errno.h>
22#include <linux/reboot.h>
23#include <linux/pci.h>
24#include <linux/kdev_t.h>
25#include <linux/major.h>
26#include <linux/console.h>
27#include <linux/delay.h>
28#include <linux/seq_file.h>
29#include <linux/root_dev.h>
30#include <linux/initrd.h>
31
32#include <asm/system.h>
33#include <asm/atomic.h>
34#include <asm/time.h>
35#include <asm/io.h>
36#include <asm/machdep.h>
37#include <asm/ipic.h>
38#include <asm/bootinfo.h>
39#include <asm/irq.h>
40#include <asm/prom.h>
41#include <asm/udbg.h>
42#include <sysdev/fsl_soc.h>
43#include <asm/qe.h>
44#include <asm/qe_ic.h>
45#include <asm/of_platform.h>
46
47#include <asm/mpc52xx.h>
48
49/* ************************************************************************
50 *
51 * Setup the architecture
52 *
53 */
54
55static void __init
56lite52xx_setup_cpu(void)
57{
58 struct mpc52xx_gpio __iomem *gpio;
59 u32 port_config;
60
61 /* Map zones */
62 gpio = mpc52xx_find_and_map("mpc52xx-gpio");
63 if (!gpio) {
64 printk(KERN_ERR __FILE__ ": "
65 "Error while mapping GPIO register for port config. "
66 "Expect some abnormal behavior\n");
67 goto error;
68 }
69
70 /* Set port config */
71 port_config = in_be32(&gpio->port_config);
72
73 port_config &= ~0x00800000; /* 48Mhz internal, pin is GPIO */
74
75 port_config &= ~0x00007000; /* USB port : Differential mode */
76 port_config |= 0x00001000; /* USB 1 only */
77
78 port_config &= ~0x03000000; /* ATA CS is on csb_4/5 */
79 port_config |= 0x01000000;
80
81 pr_debug("port_config: old:%x new:%x\n",
82 in_be32(&gpio->port_config), port_config);
83 out_be32(&gpio->port_config, port_config);
84
85 /* Unmap zone */
86error:
87 iounmap(gpio);
88}
89
90static void __init lite52xx_setup_arch(void)
91{
92 struct device_node *np;
93
94 if (ppc_md.progress)
95 ppc_md.progress("lite52xx_setup_arch()", 0);
96
97 np = of_find_node_by_type(NULL, "cpu");
98 if (np) {
99 unsigned int *fp =
100 (int *)get_property(np, "clock-frequency", NULL);
101 if (fp != 0)
102 loops_per_jiffy = *fp / HZ;
103 else
104 loops_per_jiffy = 50000000 / HZ;
105 of_node_put(np);
106 }
107
108 /* CPU & Port mux setup */
109 mpc52xx_setup_cpu(); /* Generic */
110 lite52xx_setup_cpu(); /* Platorm specific */
111
112#ifdef CONFIG_BLK_DEV_INITRD
113 if (initrd_start)
114 ROOT_DEV = Root_RAM0;
115 else
116#endif
117#ifdef CONFIG_ROOT_NFS
118 ROOT_DEV = Root_NFS;
119#else
120 ROOT_DEV = Root_HDA1;
121#endif
122
123}
124
125void lite52xx_show_cpuinfo(struct seq_file *m)
126{
127 struct device_node* np = of_find_all_nodes(NULL);
128 const char *model = NULL;
129
130 if (np)
131 model = get_property(np, "model", NULL);
132
133 seq_printf(m, "vendor\t\t: Freescale Semiconductor\n");
134 seq_printf(m, "machine\t\t: %s\n", model ? model : "unknown");
135
136 of_node_put(np);
137}
138
139/*
140 * Called very early, MMU is off, device-tree isn't unflattened
141 */
142static int __init lite52xx_probe(void)
143{
144 unsigned long node = of_get_flat_dt_root();
145 const char *model = of_get_flat_dt_prop(node, "model", NULL);
146
147 if (!of_flat_dt_is_compatible(node, "lite52xx"))
148 return 0;
149 pr_debug("%s board w/ mpc52xx found\n", model ? model : "unknown");
150
151 return 1;
152}
153
154define_machine(lite52xx) {
155 .name = "lite52xx",
156 .probe = lite52xx_probe,
157 .setup_arch = lite52xx_setup_arch,
158 .init_IRQ = mpc52xx_init_irq,
159 .get_irq = mpc52xx_get_irq,
160 .show_cpuinfo = lite52xx_show_cpuinfo,
161 .calibrate_decr = generic_calibrate_decr,
162};
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c
new file mode 100644
index 000000000000..8331ff457770
--- /dev/null
+++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
@@ -0,0 +1,126 @@
1/*
2 *
3 * Utility functions for the Freescale MPC52xx.
4 *
5 * Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com>
6 *
7 * This file is licensed under the terms of the GNU General Public License
8 * version 2. This program is licensed "as is" without any warranty of any
9 * kind, whether express or implied.
10 *
11 */
12
13#undef DEBUG
14
15#include <linux/kernel.h>
16
17#include <asm/io.h>
18#include <asm/prom.h>
19#include <asm/of_platform.h>
20#include <asm/mpc52xx.h>
21
22
23void __iomem *
24mpc52xx_find_and_map(const char *compatible)
25{
26 struct device_node *ofn;
27 const u32 *regaddr_p;
28 u64 regaddr64, size64;
29
30 ofn = of_find_compatible_node(NULL, NULL, compatible);
31 if (!ofn)
32 return NULL;
33
34 regaddr_p = of_get_address(ofn, 0, &size64, NULL);
35 if (!regaddr_p) {
36 of_node_put(ofn);
37 return NULL;
38 }
39
40 regaddr64 = of_translate_address(ofn, regaddr_p);
41
42 of_node_put(ofn);
43
44 return ioremap((u32)regaddr64, (u32)size64);
45}
46EXPORT_SYMBOL(mpc52xx_find_and_map);
47
48
49/**
50 * mpc52xx_find_ipb_freq - Find the IPB bus frequency for a device
51 * @node: device node
52 *
53 * Returns IPB bus frequency, or 0 if the bus frequency cannot be found.
54 */
55unsigned int
56mpc52xx_find_ipb_freq(struct device_node *node)
57{
58 struct device_node *np;
59 const unsigned int *p_ipb_freq = NULL;
60
61 of_node_get(node);
62 while (node) {
63 p_ipb_freq = get_property(node, "bus-frequency", NULL);
64 if (p_ipb_freq)
65 break;
66
67 np = of_get_parent(node);
68 of_node_put(node);
69 node = np;
70 }
71 if (node)
72 of_node_put(node);
73
74 return p_ipb_freq ? *p_ipb_freq : 0;
75}
76EXPORT_SYMBOL(mpc52xx_find_ipb_freq);
77
78
79void __init
80mpc52xx_setup_cpu(void)
81{
82 struct mpc52xx_cdm __iomem *cdm;
83 struct mpc52xx_xlb __iomem *xlb;
84
85 /* Map zones */
86 cdm = mpc52xx_find_and_map("mpc52xx-cdm");
87 xlb = mpc52xx_find_and_map("mpc52xx-xlb");
88
89 if (!cdm || !xlb) {
90 printk(KERN_ERR __FILE__ ": "
91 "Error while mapping CDM/XLB during mpc52xx_setup_cpu. "
92 "Expect some abnormal behavior\n");
93 goto unmap_regs;
94 }
95
96 /* Use internal 48 Mhz */
97 out_8(&cdm->ext_48mhz_en, 0x00);
98 out_8(&cdm->fd_enable, 0x01);
99 if (in_be32(&cdm->rstcfg) & 0x40) /* Assumes 33Mhz clock */
100 out_be16(&cdm->fd_counters, 0x0001);
101 else
102 out_be16(&cdm->fd_counters, 0x5555);
103
104 /* Configure the XLB Arbiter priorities */
105 out_be32(&xlb->master_pri_enable, 0xff);
106 out_be32(&xlb->master_priority, 0x11111111);
107
108 /* Disable XLB pipelining */
109 /* (cfr errate 292. We could do this only just before ATA PIO
110 transaction and re-enable it afterwards ...) */
111 out_be32(&xlb->config, in_be32(&xlb->config) | MPC52xx_XLB_CFG_PLDIS);
112
113 /* Unmap zones */
114unmap_regs:
115 if (cdm) iounmap(cdm);
116 if (xlb) iounmap(xlb);
117}
118
119static int __init
120mpc52xx_declare_of_platform_devices(void)
121{
122 /* Find every child of the SOC node and add it to of_platform */
123 return of_platform_bus_probe(NULL, NULL, NULL);
124}
125
126device_initcall(mpc52xx_declare_of_platform_devices);
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.c b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
new file mode 100644
index 000000000000..cd91a6c3aafa
--- /dev/null
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.c
@@ -0,0 +1,473 @@
1/*
2 *
3 * Programmable Interrupt Controller functions for the Freescale MPC52xx.
4 *
5 * Copyright (C) 2006 bplan GmbH
6 *
7 * Based on the code from the 2.4 kernel by
8 * Dale Farnsworth <dfarnsworth@mvista.com> and Kent Borg.
9 *
10 * Copyright (C) 2004 Sylvain Munaut <tnt@246tNt.com>
11 * Copyright (C) 2003 Montavista Software, Inc
12 *
13 * This file is licensed under the terms of the GNU General Public License
14 * version 2. This program is licensed "as is" without any warranty of any
15 * kind, whether express or implied.
16 *
17 */
18
19#undef DEBUG
20
21#include <linux/stddef.h>
22#include <linux/init.h>
23#include <linux/sched.h>
24#include <linux/signal.h>
25#include <linux/stddef.h>
26#include <linux/delay.h>
27#include <linux/irq.h>
28#include <linux/hardirq.h>
29
30#include <asm/io.h>
31#include <asm/processor.h>
32#include <asm/system.h>
33#include <asm/irq.h>
34#include <asm/prom.h>
35#include <asm/mpc52xx.h>
36#include "mpc52xx_pic.h"
37
38/*
39 *
40*/
41
42static struct mpc52xx_intr __iomem *intr;
43static struct mpc52xx_sdma __iomem *sdma;
44static struct irq_host *mpc52xx_irqhost = NULL;
45
46static unsigned char mpc52xx_map_senses[4] = {
47 IRQ_TYPE_LEVEL_HIGH,
48 IRQ_TYPE_EDGE_RISING,
49 IRQ_TYPE_EDGE_FALLING,
50 IRQ_TYPE_LEVEL_LOW,
51};
52
53/*
54 *
55*/
56
57static inline void io_be_setbit(u32 __iomem *addr, int bitno)
58{
59 out_be32(addr, in_be32(addr) | (1 << bitno));
60}
61
62static inline void io_be_clrbit(u32 __iomem *addr, int bitno)
63{
64 out_be32(addr, in_be32(addr) & ~(1 << bitno));
65}
66
67/*
68 * IRQ[0-3] interrupt irq_chip
69*/
70
71static void mpc52xx_extirq_mask(unsigned int virq)
72{
73 int irq;
74 int l2irq;
75
76 irq = irq_map[virq].hwirq;
77 l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
78
79 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
80
81 io_be_clrbit(&intr->ctrl, 11 - l2irq);
82}
83
84static void mpc52xx_extirq_unmask(unsigned int virq)
85{
86 int irq;
87 int l2irq;
88
89 irq = irq_map[virq].hwirq;
90 l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
91
92 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
93
94 io_be_setbit(&intr->ctrl, 11 - l2irq);
95}
96
97static void mpc52xx_extirq_ack(unsigned int virq)
98{
99 int irq;
100 int l2irq;
101
102 irq = irq_map[virq].hwirq;
103 l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
104
105 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
106
107 io_be_setbit(&intr->ctrl, 27-l2irq);
108}
109
110static struct irq_chip mpc52xx_extirq_irqchip = {
111 .typename = " MPC52xx IRQ[0-3] ",
112 .mask = mpc52xx_extirq_mask,
113 .unmask = mpc52xx_extirq_unmask,
114 .ack = mpc52xx_extirq_ack,
115};
116
117/*
118 * Main interrupt irq_chip
119*/
120
121static void mpc52xx_main_mask(unsigned int virq)
122{
123 int irq;
124 int l2irq;
125
126 irq = irq_map[virq].hwirq;
127 l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
128
129 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
130
131 io_be_setbit(&intr->main_mask, 15 - l2irq);
132}
133
134static void mpc52xx_main_unmask(unsigned int virq)
135{
136 int irq;
137 int l2irq;
138
139 irq = irq_map[virq].hwirq;
140 l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
141
142 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
143
144 io_be_clrbit(&intr->main_mask, 15 - l2irq);
145}
146
147static struct irq_chip mpc52xx_main_irqchip = {
148 .typename = "MPC52xx Main",
149 .mask = mpc52xx_main_mask,
150 .mask_ack = mpc52xx_main_mask,
151 .unmask = mpc52xx_main_unmask,
152};
153
154/*
155 * Peripherals interrupt irq_chip
156*/
157
158static void mpc52xx_periph_mask(unsigned int virq)
159{
160 int irq;
161 int l2irq;
162
163 irq = irq_map[virq].hwirq;
164 l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
165
166 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
167
168 io_be_setbit(&intr->per_mask, 31 - l2irq);
169}
170
171static void mpc52xx_periph_unmask(unsigned int virq)
172{
173 int irq;
174 int l2irq;
175
176 irq = irq_map[virq].hwirq;
177 l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
178
179 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
180
181 io_be_clrbit(&intr->per_mask, 31 - l2irq);
182}
183
184static struct irq_chip mpc52xx_periph_irqchip = {
185 .typename = "MPC52xx Peripherals",
186 .mask = mpc52xx_periph_mask,
187 .mask_ack = mpc52xx_periph_mask,
188 .unmask = mpc52xx_periph_unmask,
189};
190
191/*
192 * SDMA interrupt irq_chip
193*/
194
195static void mpc52xx_sdma_mask(unsigned int virq)
196{
197 int irq;
198 int l2irq;
199
200 irq = irq_map[virq].hwirq;
201 l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
202
203 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
204
205 io_be_setbit(&sdma->IntMask, l2irq);
206}
207
208static void mpc52xx_sdma_unmask(unsigned int virq)
209{
210 int irq;
211 int l2irq;
212
213 irq = irq_map[virq].hwirq;
214 l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
215
216 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
217
218 io_be_clrbit(&sdma->IntMask, l2irq);
219}
220
221static void mpc52xx_sdma_ack(unsigned int virq)
222{
223 int irq;
224 int l2irq;
225
226 irq = irq_map[virq].hwirq;
227 l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
228
229 pr_debug("%s: irq=%x. l2=%d\n", __func__, irq, l2irq);
230
231 out_be32(&sdma->IntPend, 1 << l2irq);
232}
233
234static struct irq_chip mpc52xx_sdma_irqchip = {
235 .typename = "MPC52xx SDMA",
236 .mask = mpc52xx_sdma_mask,
237 .unmask = mpc52xx_sdma_unmask,
238 .ack = mpc52xx_sdma_ack,
239};
240
241/*
242 * irq_host
243*/
244
245static int mpc52xx_irqhost_match(struct irq_host *h, struct device_node *node)
246{
247 pr_debug("%s: node=%p\n", __func__, node);
248 return mpc52xx_irqhost->host_data == node;
249}
250
251static int mpc52xx_irqhost_xlate(struct irq_host *h, struct device_node *ct,
252 u32 * intspec, unsigned int intsize,
253 irq_hw_number_t * out_hwirq,
254 unsigned int *out_flags)
255{
256 int intrvect_l1;
257 int intrvect_l2;
258 int intrvect_type;
259 int intrvect_linux;
260
261 if (intsize != 3)
262 return -1;
263
264 intrvect_l1 = (int)intspec[0];
265 intrvect_l2 = (int)intspec[1];
266 intrvect_type = (int)intspec[2];
267
268 intrvect_linux =
269 (intrvect_l1 << MPC52xx_IRQ_L1_OFFSET) & MPC52xx_IRQ_L1_MASK;
270 intrvect_linux |=
271 (intrvect_l2 << MPC52xx_IRQ_L2_OFFSET) & MPC52xx_IRQ_L2_MASK;
272
273 pr_debug("return %x, l1=%d, l2=%d\n", intrvect_linux, intrvect_l1,
274 intrvect_l2);
275
276 *out_hwirq = intrvect_linux;
277 *out_flags = mpc52xx_map_senses[intrvect_type];
278
279 return 0;
280}
281
282/*
283 * this function retrieves the correct IRQ type out
284 * of the MPC regs
285 * Only externals IRQs needs this
286*/
287static int mpc52xx_irqx_gettype(int irq)
288{
289 int type;
290 u32 ctrl_reg;
291
292 ctrl_reg = in_be32(&intr->ctrl);
293 type = (ctrl_reg >> (22 - irq * 2)) & 0x3;
294
295 return mpc52xx_map_senses[type];
296}
297
298static int mpc52xx_irqhost_map(struct irq_host *h, unsigned int virq,
299 irq_hw_number_t irq)
300{
301 int l1irq;
302 int l2irq;
303 struct irq_chip *good_irqchip;
304 void *good_handle;
305 int type;
306
307 l1irq = (irq & MPC52xx_IRQ_L1_MASK) >> MPC52xx_IRQ_L1_OFFSET;
308 l2irq = (irq & MPC52xx_IRQ_L2_MASK) >> MPC52xx_IRQ_L2_OFFSET;
309
310 /*
311 * Most of ours IRQs will be level low
312 * Only external IRQs on some platform may be others
313 */
314 type = IRQ_TYPE_LEVEL_LOW;
315
316 switch (l1irq) {
317 case MPC52xx_IRQ_L1_CRIT:
318 pr_debug("%s: Critical. l2=%x\n", __func__, l2irq);
319
320 BUG_ON(l2irq != 0);
321
322 type = mpc52xx_irqx_gettype(l2irq);
323 good_irqchip = &mpc52xx_extirq_irqchip;
324 break;
325
326 case MPC52xx_IRQ_L1_MAIN:
327 pr_debug("%s: Main IRQ[1-3] l2=%x\n", __func__, l2irq);
328
329 if ((l2irq >= 1) && (l2irq <= 3)) {
330 type = mpc52xx_irqx_gettype(l2irq);
331 good_irqchip = &mpc52xx_extirq_irqchip;
332 } else {
333 good_irqchip = &mpc52xx_main_irqchip;
334 }
335 break;
336
337 case MPC52xx_IRQ_L1_PERP:
338 pr_debug("%s: Peripherals. l2=%x\n", __func__, l2irq);
339 good_irqchip = &mpc52xx_periph_irqchip;
340 break;
341
342 case MPC52xx_IRQ_L1_SDMA:
343 pr_debug("%s: SDMA. l2=%x\n", __func__, l2irq);
344 good_irqchip = &mpc52xx_sdma_irqchip;
345 break;
346
347 default:
348 pr_debug("%s: Error, unknown L1 IRQ (0x%x)\n", __func__, l1irq);
349 printk(KERN_ERR "Unknow IRQ!\n");
350 return -EINVAL;
351 }
352
353 switch (type) {
354 case IRQ_TYPE_EDGE_FALLING:
355 case IRQ_TYPE_EDGE_RISING:
356 good_handle = handle_edge_irq;
357 break;
358 default:
359 good_handle = handle_level_irq;
360 }
361
362 set_irq_chip_and_handler(virq, good_irqchip, good_handle);
363
364 pr_debug("%s: virq=%x, hw=%x. type=%x\n", __func__, virq,
365 (int)irq, type);
366
367 return 0;
368}
369
370static struct irq_host_ops mpc52xx_irqhost_ops = {
371 .match = mpc52xx_irqhost_match,
372 .xlate = mpc52xx_irqhost_xlate,
373 .map = mpc52xx_irqhost_map,
374};
375
376/*
377 * init (public)
378*/
379
380void __init mpc52xx_init_irq(void)
381{
382 u32 intr_ctrl;
383 struct device_node *picnode;
384
385 /* Remap the necessary zones */
386 picnode = of_find_compatible_node(NULL, NULL, "mpc52xx-pic");
387
388 intr = mpc52xx_find_and_map("mpc52xx-pic");
389 if (!intr)
390 panic(__FILE__ ": find_and_map failed on 'mpc52xx-pic'. "
391 "Check node !");
392
393 sdma = mpc52xx_find_and_map("mpc52xx-bestcomm");
394 if (!sdma)
395 panic(__FILE__ ": find_and_map failed on 'mpc52xx-bestcomm'. "
396 "Check node !");
397
398 /* Disable all interrupt sources. */
399 out_be32(&sdma->IntPend, 0xffffffff); /* 1 means clear pending */
400 out_be32(&sdma->IntMask, 0xffffffff); /* 1 means disabled */
401 out_be32(&intr->per_mask, 0x7ffffc00); /* 1 means disabled */
402 out_be32(&intr->main_mask, 0x00010fff); /* 1 means disabled */
403 intr_ctrl = in_be32(&intr->ctrl);
404 intr_ctrl &= 0x00ff0000; /* Keeps IRQ[0-3] config */
405 intr_ctrl |= 0x0f000000 | /* clear IRQ 0-3 */
406 0x00001000 | /* MEE master external enable */
407 0x00000000 | /* 0 means disable IRQ 0-3 */
408 0x00000001; /* CEb route critical normally */
409 out_be32(&intr->ctrl, intr_ctrl);
410
411 /* Zero a bunch of the priority settings. */
412 out_be32(&intr->per_pri1, 0);
413 out_be32(&intr->per_pri2, 0);
414 out_be32(&intr->per_pri3, 0);
415 out_be32(&intr->main_pri1, 0);
416 out_be32(&intr->main_pri2, 0);
417
418 /*
419 * As last step, add an irq host to translate the real
420 * hw irq information provided by the ofw to linux virq
421 */
422
423 mpc52xx_irqhost = irq_alloc_host(IRQ_HOST_MAP_LINEAR,
424 MPC52xx_IRQ_HIGHTESTHWIRQ,
425 &mpc52xx_irqhost_ops, -1);
426
427 if (!mpc52xx_irqhost)
428 panic(__FILE__ ": Cannot allocate the IRQ host\n");
429
430 mpc52xx_irqhost->host_data = picnode;
431 printk(KERN_INFO "MPC52xx PIC is up and running!\n");
432}
433
434/*
435 * get_irq (public)
436*/
437unsigned int mpc52xx_get_irq(void)
438{
439 u32 status;
440 int irq = NO_IRQ_IGNORE;
441
442 status = in_be32(&intr->enc_status);
443 if (status & 0x00000400) { /* critical */
444 irq = (status >> 8) & 0x3;
445 if (irq == 2) /* high priority peripheral */
446 goto peripheral;
447 irq |= (MPC52xx_IRQ_L1_CRIT << MPC52xx_IRQ_L1_OFFSET) &
448 MPC52xx_IRQ_L1_MASK;
449 } else if (status & 0x00200000) { /* main */
450 irq = (status >> 16) & 0x1f;
451 if (irq == 4) /* low priority peripheral */
452 goto peripheral;
453 irq |= (MPC52xx_IRQ_L1_MAIN << MPC52xx_IRQ_L1_OFFSET) &
454 MPC52xx_IRQ_L1_MASK;
455 } else if (status & 0x20000000) { /* peripheral */
456 peripheral:
457 irq = (status >> 24) & 0x1f;
458 if (irq == 0) { /* bestcomm */
459 status = in_be32(&sdma->IntPend);
460 irq = ffs(status) - 1;
461 irq |= (MPC52xx_IRQ_L1_SDMA << MPC52xx_IRQ_L1_OFFSET) &
462 MPC52xx_IRQ_L1_MASK;
463 } else {
464 irq |= (MPC52xx_IRQ_L1_PERP << MPC52xx_IRQ_L1_OFFSET) &
465 MPC52xx_IRQ_L1_MASK;
466 }
467 }
468
469 pr_debug("%s: irq=%x. virq=%d\n", __func__, irq,
470 irq_linear_revmap(mpc52xx_irqhost, irq));
471
472 return irq_linear_revmap(mpc52xx_irqhost, irq);
473}
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_pic.h b/arch/powerpc/platforms/52xx/mpc52xx_pic.h
new file mode 100644
index 000000000000..1a26bcdb3049
--- /dev/null
+++ b/arch/powerpc/platforms/52xx/mpc52xx_pic.h
@@ -0,0 +1,53 @@
1/*
2 * Header file for Freescale MPC52xx Interrupt controller
3 *
4 * Copyright (C) 2004-2005 Sylvain Munaut <tnt@246tNt.com>
5 * Copyright (C) 2003 MontaVista, Software, Inc.
6 *
7 * This file is licensed under the terms of the GNU General Public License
8 * version 2. This program is licensed "as is" without any warranty of any
9 * kind, whether express or implied.
10 */
11
12#ifndef __POWERPC_SYSDEV_MPC52xx_PIC_H__
13#define __POWERPC_SYSDEV_MPC52xx_PIC_H__
14
15#include <asm/types.h>
16
17
18/* HW IRQ mapping */
19#define MPC52xx_IRQ_L1_CRIT (0)
20#define MPC52xx_IRQ_L1_MAIN (1)
21#define MPC52xx_IRQ_L1_PERP (2)
22#define MPC52xx_IRQ_L1_SDMA (3)
23
24#define MPC52xx_IRQ_L1_OFFSET (6)
25#define MPC52xx_IRQ_L1_MASK (0x00c0)
26
27#define MPC52xx_IRQ_L2_OFFSET (0)
28#define MPC52xx_IRQ_L2_MASK (0x003f)
29
30#define MPC52xx_IRQ_HIGHTESTHWIRQ (0xd0)
31
32
33/* Interrupt controller Register set */
34struct mpc52xx_intr {
35 u32 per_mask; /* INTR + 0x00 */
36 u32 per_pri1; /* INTR + 0x04 */
37 u32 per_pri2; /* INTR + 0x08 */
38 u32 per_pri3; /* INTR + 0x0c */
39 u32 ctrl; /* INTR + 0x10 */
40 u32 main_mask; /* INTR + 0x14 */
41 u32 main_pri1; /* INTR + 0x18 */
42 u32 main_pri2; /* INTR + 0x1c */
43 u32 reserved1; /* INTR + 0x20 */
44 u32 enc_status; /* INTR + 0x24 */
45 u32 crit_status; /* INTR + 0x28 */
46 u32 main_status; /* INTR + 0x2c */
47 u32 per_status; /* INTR + 0x30 */
48 u32 reserved2; /* INTR + 0x34 */
49 u32 per_error; /* INTR + 0x38 */
50};
51
52#endif /* __POWERPC_SYSDEV_MPC52xx_PIC_H__ */
53
diff --git a/arch/powerpc/platforms/82xx/mpc82xx_ads.c b/arch/powerpc/platforms/82xx/mpc82xx_ads.c
index bb9acbb98176..ea880f1f0dcd 100644
--- a/arch/powerpc/platforms/82xx/mpc82xx_ads.c
+++ b/arch/powerpc/platforms/82xx/mpc82xx_ads.c
@@ -515,16 +515,6 @@ static int m82xx_pci_exclude_device(u_char bus, u_char devfn)
515 return PCIBIOS_SUCCESSFUL; 515 return PCIBIOS_SUCCESSFUL;
516} 516}
517 517
518static void
519__init mpc82xx_pcibios_fixup(void)
520{
521 struct pci_dev *dev = NULL;
522
523 for_each_pci_dev(dev) {
524 pci_read_irq_line(dev);
525 }
526}
527
528void __init add_bridge(struct device_node *np) 518void __init add_bridge(struct device_node *np)
529{ 519{
530 int len; 520 int len;
@@ -597,9 +587,6 @@ static void __init mpc82xx_ads_setup_arch(void)
597 add_bridge(np); 587 add_bridge(np);
598 588
599 of_node_put(np); 589 of_node_put(np);
600 ppc_md.pci_map_irq = NULL;
601 ppc_md.pcibios_fixup = mpc82xx_pcibios_fixup;
602 ppc_md.pcibios_fixup_bus = NULL;
603#endif 590#endif
604 591
605#ifdef CONFIG_ROOT_NFS 592#ifdef CONFIG_ROOT_NFS
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c
index a43ac71ab740..f58c9780b66f 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c
@@ -97,8 +97,6 @@ static void __init mpc832x_sys_setup_arch(void)
97#ifdef CONFIG_PCI 97#ifdef CONFIG_PCI
98 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 98 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
99 add_bridge(np); 99 add_bridge(np);
100
101 ppc_md.pci_swizzle = common_swizzle;
102 ppc_md.pci_exclude_device = mpc83xx_exclude_device; 100 ppc_md.pci_exclude_device = mpc83xx_exclude_device;
103#endif 101#endif
104 102
diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c
index e2bcaaf6b329..314c42ac6048 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_itx.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c
@@ -118,7 +118,4 @@ define_machine(mpc834x_itx) {
118 .time_init = mpc83xx_time_init, 118 .time_init = mpc83xx_time_init,
119 .calibrate_decr = generic_calibrate_decr, 119 .calibrate_decr = generic_calibrate_decr,
120 .progress = udbg_progress, 120 .progress = udbg_progress,
121#ifdef CONFIG_PCI
122 .pcibios_fixup = mpc83xx_pcibios_fixup,
123#endif
124}; 121};
diff --git a/arch/powerpc/platforms/83xx/mpc834x_sys.c b/arch/powerpc/platforms/83xx/mpc834x_sys.c
index 677196187a4e..80b735a414d9 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_sys.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_sys.c
@@ -137,7 +137,4 @@ define_machine(mpc834x_sys) {
137 .time_init = mpc83xx_time_init, 137 .time_init = mpc83xx_time_init,
138 .calibrate_decr = generic_calibrate_decr, 138 .calibrate_decr = generic_calibrate_decr,
139 .progress = udbg_progress, 139 .progress = udbg_progress,
140#ifdef CONFIG_PCI
141 .pcibios_fixup = mpc83xx_pcibios_fixup,
142#endif
143}; 140};
diff --git a/arch/powerpc/platforms/83xx/mpc8360e_pb.c b/arch/powerpc/platforms/83xx/mpc8360e_pb.c
index 1a523c81c06e..7bfd47ad7233 100644
--- a/arch/powerpc/platforms/83xx/mpc8360e_pb.c
+++ b/arch/powerpc/platforms/83xx/mpc8360e_pb.c
@@ -102,8 +102,6 @@ static void __init mpc8360_sys_setup_arch(void)
102#ifdef CONFIG_PCI 102#ifdef CONFIG_PCI
103 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 103 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
104 add_bridge(np); 104 add_bridge(np);
105
106 ppc_md.pci_swizzle = common_swizzle;
107 ppc_md.pci_exclude_device = mpc83xx_exclude_device; 105 ppc_md.pci_exclude_device = mpc83xx_exclude_device;
108#endif 106#endif
109 107
diff --git a/arch/powerpc/platforms/83xx/mpc83xx.h b/arch/powerpc/platforms/83xx/mpc83xx.h
index 2c82bca9bfbb..01cae106912b 100644
--- a/arch/powerpc/platforms/83xx/mpc83xx.h
+++ b/arch/powerpc/platforms/83xx/mpc83xx.h
@@ -11,7 +11,6 @@
11 11
12extern int add_bridge(struct device_node *dev); 12extern int add_bridge(struct device_node *dev);
13extern int mpc83xx_exclude_device(u_char bus, u_char devfn); 13extern int mpc83xx_exclude_device(u_char bus, u_char devfn);
14extern void mpc83xx_pcibios_fixup(void);
15extern void mpc83xx_restart(char *cmd); 14extern void mpc83xx_restart(char *cmd);
16extern long mpc83xx_time_init(void); 15extern long mpc83xx_time_init(void);
17 16
diff --git a/arch/powerpc/platforms/83xx/pci.c b/arch/powerpc/platforms/83xx/pci.c
index 4557ac5255c1..9c3650555144 100644
--- a/arch/powerpc/platforms/83xx/pci.c
+++ b/arch/powerpc/platforms/83xx/pci.c
@@ -45,15 +45,6 @@ int mpc83xx_exclude_device(u_char bus, u_char devfn)
45 return PCIBIOS_SUCCESSFUL; 45 return PCIBIOS_SUCCESSFUL;
46} 46}
47 47
48void __init mpc83xx_pcibios_fixup(void)
49{
50 struct pci_dev *dev = NULL;
51
52 /* map all the PCI irqs */
53 for_each_pci_dev(dev)
54 pci_read_irq_line(dev);
55}
56
57int __init add_bridge(struct device_node *dev) 48int __init add_bridge(struct device_node *dev)
58{ 49{
59 int len; 50 int len;
diff --git a/arch/powerpc/platforms/85xx/misc.c b/arch/powerpc/platforms/85xx/misc.c
index 26c5e822c7c8..3e62fcb04c1c 100644
--- a/arch/powerpc/platforms/85xx/misc.c
+++ b/arch/powerpc/platforms/85xx/misc.c
@@ -21,11 +21,3 @@ void mpc85xx_restart(char *cmd)
21 local_irq_disable(); 21 local_irq_disable();
22 abort(); 22 abort();
23} 23}
24
25/* For now this is a pass through */
26phys_addr_t fixup_bigphys_addr(phys_addr_t addr, phys_addr_t size)
27{
28 return addr;
29};
30
31EXPORT_SYMBOL(fixup_bigphys_addr);
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
index d3e669d69c73..bda2e55e6c4c 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
@@ -53,15 +53,6 @@ mpc85xx_exclude_device(u_char bus, u_char devfn)
53 else 53 else
54 return PCIBIOS_SUCCESSFUL; 54 return PCIBIOS_SUCCESSFUL;
55} 55}
56
57void __init
58mpc85xx_pcibios_fixup(void)
59{
60 struct pci_dev *dev = NULL;
61
62 for_each_pci_dev(dev)
63 pci_read_irq_line(dev);
64}
65#endif /* CONFIG_PCI */ 56#endif /* CONFIG_PCI */
66 57
67#ifdef CONFIG_CPM2 58#ifdef CONFIG_CPM2
@@ -253,8 +244,6 @@ static void __init mpc85xx_ads_setup_arch(void)
253#ifdef CONFIG_PCI 244#ifdef CONFIG_PCI
254 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 245 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
255 add_bridge(np); 246 add_bridge(np);
256
257 ppc_md.pcibios_fixup = mpc85xx_pcibios_fixup;
258 ppc_md.pci_exclude_device = mpc85xx_exclude_device; 247 ppc_md.pci_exclude_device = mpc85xx_exclude_device;
259#endif 248#endif
260 249
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index 1a1c226ad4d9..f4dd5f2f8a28 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -398,15 +398,6 @@ mpc86xx_hpcn_show_cpuinfo(struct seq_file *m)
398} 398}
399 399
400 400
401void __init mpc86xx_hpcn_pcibios_fixup(void)
402{
403 struct pci_dev *dev = NULL;
404
405 for_each_pci_dev(dev)
406 pci_read_irq_line(dev);
407}
408
409
410/* 401/*
411 * Called very early, device-tree isn't unflattened 402 * Called very early, device-tree isn't unflattened
412 */ 403 */
@@ -461,7 +452,6 @@ define_machine(mpc86xx_hpcn) {
461 .setup_arch = mpc86xx_hpcn_setup_arch, 452 .setup_arch = mpc86xx_hpcn_setup_arch,
462 .init_IRQ = mpc86xx_hpcn_init_irq, 453 .init_IRQ = mpc86xx_hpcn_init_irq,
463 .show_cpuinfo = mpc86xx_hpcn_show_cpuinfo, 454 .show_cpuinfo = mpc86xx_hpcn_show_cpuinfo,
464 .pcibios_fixup = mpc86xx_hpcn_pcibios_fixup,
465 .get_irq = mpic_get_irq, 455 .get_irq = mpic_get_irq,
466 .restart = mpc86xx_restart, 456 .restart = mpc86xx_restart,
467 .time_init = mpc86xx_time_init, 457 .time_init = mpc86xx_time_init,
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile
index e58fa953a50b..44d95eaf22e6 100644
--- a/arch/powerpc/platforms/Makefile
+++ b/arch/powerpc/platforms/Makefile
@@ -7,12 +7,14 @@ endif
7endif 7endif
8obj-$(CONFIG_PPC_CHRP) += chrp/ 8obj-$(CONFIG_PPC_CHRP) += chrp/
9obj-$(CONFIG_4xx) += 4xx/ 9obj-$(CONFIG_4xx) += 4xx/
10obj-$(CONFIG_PPC_MPC52xx) += 52xx/
10obj-$(CONFIG_PPC_83xx) += 83xx/ 11obj-$(CONFIG_PPC_83xx) += 83xx/
11obj-$(CONFIG_PPC_85xx) += 85xx/ 12obj-$(CONFIG_PPC_85xx) += 85xx/
12obj-$(CONFIG_PPC_86xx) += 86xx/ 13obj-$(CONFIG_PPC_86xx) += 86xx/
13obj-$(CONFIG_PPC_PSERIES) += pseries/ 14obj-$(CONFIG_PPC_PSERIES) += pseries/
14obj-$(CONFIG_PPC_ISERIES) += iseries/ 15obj-$(CONFIG_PPC_ISERIES) += iseries/
15obj-$(CONFIG_PPC_MAPLE) += maple/ 16obj-$(CONFIG_PPC_MAPLE) += maple/
16obj-$(CONFIG_PPC_PASEMI) += pasemi/ 17obj-$(CONFIG_PPC_PASEMI) += pasemi/
17obj-$(CONFIG_PPC_CELL) += cell/ 18obj-$(CONFIG_PPC_CELL) += cell/
19obj-$(CONFIG_PPC_PS3) += ps3/
18obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/ 20obj-$(CONFIG_EMBEDDED6xx) += embedded6xx/
diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig
index 3e430b489bb7..06a85b704331 100644
--- a/arch/powerpc/platforms/cell/Kconfig
+++ b/arch/powerpc/platforms/cell/Kconfig
@@ -20,4 +20,18 @@ config CBE_RAS
20 bool "RAS features for bare metal Cell BE" 20 bool "RAS features for bare metal Cell BE"
21 default y 21 default y
22 22
23config CBE_THERM
24 tristate "CBE thermal support"
25 default m
26 depends on CBE_RAS
27
28config CBE_CPUFREQ
29 tristate "CBE frequency scaling"
30 depends on CBE_RAS && CPU_FREQ
31 default m
32 help
33 This adds the cpufreq driver for Cell BE processors.
34 For details, take a look at <file:Documentation/cpu-freq/>.
35 If you don't have such processor, say N
36
23endmenu 37endmenu
diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile
index c89cdd67383b..f90e8337796c 100644
--- a/arch/powerpc/platforms/cell/Makefile
+++ b/arch/powerpc/platforms/cell/Makefile
@@ -1,7 +1,11 @@
1obj-$(CONFIG_PPC_CELL_NATIVE) += interrupt.o iommu.o setup.o \ 1obj-$(CONFIG_PPC_CELL_NATIVE) += interrupt.o iommu.o setup.o \
2 cbe_regs.o spider-pic.o pervasive.o 2 cbe_regs.o spider-pic.o \
3 pervasive.o pmu.o io-workarounds.o
3obj-$(CONFIG_CBE_RAS) += ras.o 4obj-$(CONFIG_CBE_RAS) += ras.o
4 5
6obj-$(CONFIG_CBE_THERM) += cbe_thermal.o
7obj-$(CONFIG_CBE_CPUFREQ) += cbe_cpufreq.o
8
5ifeq ($(CONFIG_SMP),y) 9ifeq ($(CONFIG_SMP),y)
6obj-$(CONFIG_PPC_CELL_NATIVE) += smp.o 10obj-$(CONFIG_PPC_CELL_NATIVE) += smp.o
7endif 11endif
@@ -11,5 +15,6 @@ spufs-modular-$(CONFIG_SPU_FS) += spu_syscalls.o
11spu-priv1-$(CONFIG_PPC_CELL_NATIVE) += spu_priv1_mmio.o 15spu-priv1-$(CONFIG_PPC_CELL_NATIVE) += spu_priv1_mmio.o
12 16
13obj-$(CONFIG_SPU_BASE) += spu_callbacks.o spu_base.o \ 17obj-$(CONFIG_SPU_BASE) += spu_callbacks.o spu_base.o \
18 spu_coredump.o \
14 $(spufs-modular-m) \ 19 $(spufs-modular-m) \
15 $(spu-priv1-y) spufs/ 20 $(spu-priv1-y) spufs/
diff --git a/arch/powerpc/platforms/cell/cbe_cpufreq.c b/arch/powerpc/platforms/cell/cbe_cpufreq.c
new file mode 100644
index 000000000000..a3850fd1e94c
--- /dev/null
+++ b/arch/powerpc/platforms/cell/cbe_cpufreq.c
@@ -0,0 +1,248 @@
1/*
2 * cpufreq driver for the cell processor
3 *
4 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
5 *
6 * Author: Christian Krafft <krafft@de.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/cpufreq.h>
24#include <linux/timer.h>
25
26#include <asm/hw_irq.h>
27#include <asm/io.h>
28#include <asm/processor.h>
29#include <asm/prom.h>
30#include <asm/time.h>
31
32#include "cbe_regs.h"
33
34static DEFINE_MUTEX(cbe_switch_mutex);
35
36
37/* the CBE supports an 8 step frequency scaling */
38static struct cpufreq_frequency_table cbe_freqs[] = {
39 {1, 0},
40 {2, 0},
41 {3, 0},
42 {4, 0},
43 {5, 0},
44 {6, 0},
45 {8, 0},
46 {10, 0},
47 {0, CPUFREQ_TABLE_END},
48};
49
50/* to write to MIC register */
51static u64 MIC_Slow_Fast_Timer_table[] = {
52 [0 ... 7] = 0x007fc00000000000ull,
53};
54
55/* more values for the MIC */
56static u64 MIC_Slow_Next_Timer_table[] = {
57 0x0000240000000000ull,
58 0x0000268000000000ull,
59 0x000029C000000000ull,
60 0x00002D0000000000ull,
61 0x0000300000000000ull,
62 0x0000334000000000ull,
63 0x000039C000000000ull,
64 0x00003FC000000000ull,
65};
66
67/*
68 * hardware specific functions
69 */
70
71static int get_pmode(int cpu)
72{
73 int ret;
74 struct cbe_pmd_regs __iomem *pmd_regs;
75
76 pmd_regs = cbe_get_cpu_pmd_regs(cpu);
77 ret = in_be64(&pmd_regs->pmsr) & 0x07;
78
79 return ret;
80}
81
82static int set_pmode(int cpu, unsigned int pmode)
83{
84 struct cbe_pmd_regs __iomem *pmd_regs;
85 struct cbe_mic_tm_regs __iomem *mic_tm_regs;
86 u64 flags;
87 u64 value;
88
89 local_irq_save(flags);
90
91 mic_tm_regs = cbe_get_cpu_mic_tm_regs(cpu);
92 pmd_regs = cbe_get_cpu_pmd_regs(cpu);
93
94 pr_debug("pm register is mapped at %p\n", &pmd_regs->pmcr);
95 pr_debug("mic register is mapped at %p\n", &mic_tm_regs->slow_fast_timer_0);
96
97 out_be64(&mic_tm_regs->slow_fast_timer_0, MIC_Slow_Fast_Timer_table[pmode]);
98 out_be64(&mic_tm_regs->slow_fast_timer_1, MIC_Slow_Fast_Timer_table[pmode]);
99
100 out_be64(&mic_tm_regs->slow_next_timer_0, MIC_Slow_Next_Timer_table[pmode]);
101 out_be64(&mic_tm_regs->slow_next_timer_1, MIC_Slow_Next_Timer_table[pmode]);
102
103 value = in_be64(&pmd_regs->pmcr);
104 /* set bits to zero */
105 value &= 0xFFFFFFFFFFFFFFF8ull;
106 /* set bits to next pmode */
107 value |= pmode;
108
109 out_be64(&pmd_regs->pmcr, value);
110
111 /* wait until new pmode appears in status register */
112 value = in_be64(&pmd_regs->pmsr) & 0x07;
113 while(value != pmode) {
114 cpu_relax();
115 value = in_be64(&pmd_regs->pmsr) & 0x07;
116 }
117
118 local_irq_restore(flags);
119
120 return 0;
121}
122
123/*
124 * cpufreq functions
125 */
126
127static int cbe_cpufreq_cpu_init (struct cpufreq_policy *policy)
128{
129 u32 *max_freq;
130 int i, cur_pmode;
131 struct device_node *cpu;
132
133 cpu = of_get_cpu_node(policy->cpu, NULL);
134
135 if(!cpu)
136 return -ENODEV;
137
138 pr_debug("init cpufreq on CPU %d\n", policy->cpu);
139
140 max_freq = (u32*) get_property(cpu, "clock-frequency", NULL);
141
142 if(!max_freq)
143 return -EINVAL;
144
145 // we need the freq in kHz
146 *max_freq /= 1000;
147
148 pr_debug("max clock-frequency is at %u kHz\n", *max_freq);
149 pr_debug("initializing frequency table\n");
150
151 // initialize frequency table
152 for (i=0; cbe_freqs[i].frequency!=CPUFREQ_TABLE_END; i++) {
153 cbe_freqs[i].frequency = *max_freq / cbe_freqs[i].index;
154 pr_debug("%d: %d\n", i, cbe_freqs[i].frequency);
155 }
156
157 policy->governor = CPUFREQ_DEFAULT_GOVERNOR;
158 /* if DEBUG is enabled set_pmode() measures the correct latency of a transition */
159 policy->cpuinfo.transition_latency = 25000;
160
161 cur_pmode = get_pmode(policy->cpu);
162 pr_debug("current pmode is at %d\n",cur_pmode);
163
164 policy->cur = cbe_freqs[cur_pmode].frequency;
165
166#ifdef CONFIG_SMP
167 policy->cpus = cpu_sibling_map[policy->cpu];
168#endif
169
170 cpufreq_frequency_table_get_attr (cbe_freqs, policy->cpu);
171
172 /* this ensures that policy->cpuinfo_min and policy->cpuinfo_max are set correctly */
173 return cpufreq_frequency_table_cpuinfo (policy, cbe_freqs);
174}
175
176static int cbe_cpufreq_cpu_exit(struct cpufreq_policy *policy)
177{
178 cpufreq_frequency_table_put_attr(policy->cpu);
179 return 0;
180}
181
182static int cbe_cpufreq_verify(struct cpufreq_policy *policy)
183{
184 return cpufreq_frequency_table_verify(policy, cbe_freqs);
185}
186
187
188static int cbe_cpufreq_target(struct cpufreq_policy *policy, unsigned int target_freq,
189 unsigned int relation)
190{
191 int rc;
192 struct cpufreq_freqs freqs;
193 int cbe_pmode_new;
194
195 cpufreq_frequency_table_target(policy,
196 cbe_freqs,
197 target_freq,
198 relation,
199 &cbe_pmode_new);
200
201 freqs.old = policy->cur;
202 freqs.new = cbe_freqs[cbe_pmode_new].frequency;
203 freqs.cpu = policy->cpu;
204
205 mutex_lock (&cbe_switch_mutex);
206 cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE);
207
208 pr_debug("setting frequency for cpu %d to %d kHz, 1/%d of max frequency\n",
209 policy->cpu,
210 cbe_freqs[cbe_pmode_new].frequency,
211 cbe_freqs[cbe_pmode_new].index);
212
213 rc = set_pmode(policy->cpu, cbe_pmode_new);
214 cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE);
215 mutex_unlock(&cbe_switch_mutex);
216
217 return rc;
218}
219
220static struct cpufreq_driver cbe_cpufreq_driver = {
221 .verify = cbe_cpufreq_verify,
222 .target = cbe_cpufreq_target,
223 .init = cbe_cpufreq_cpu_init,
224 .exit = cbe_cpufreq_cpu_exit,
225 .name = "cbe-cpufreq",
226 .owner = THIS_MODULE,
227 .flags = CPUFREQ_CONST_LOOPS,
228};
229
230/*
231 * module init and destoy
232 */
233
234static int __init cbe_cpufreq_init(void)
235{
236 return cpufreq_register_driver(&cbe_cpufreq_driver);
237}
238
239static void __exit cbe_cpufreq_exit(void)
240{
241 cpufreq_unregister_driver(&cbe_cpufreq_driver);
242}
243
244module_init(cbe_cpufreq_init);
245module_exit(cbe_cpufreq_exit);
246
247MODULE_LICENSE("GPL");
248MODULE_AUTHOR("Christian Krafft <krafft@de.ibm.com>");
diff --git a/arch/powerpc/platforms/cell/cbe_regs.c b/arch/powerpc/platforms/cell/cbe_regs.c
index 2f194ba29899..9a0ee62691d5 100644
--- a/arch/powerpc/platforms/cell/cbe_regs.c
+++ b/arch/powerpc/platforms/cell/cbe_regs.c
@@ -8,6 +8,7 @@
8 8
9#include <linux/percpu.h> 9#include <linux/percpu.h>
10#include <linux/types.h> 10#include <linux/types.h>
11#include <linux/module.h>
11 12
12#include <asm/io.h> 13#include <asm/io.h>
13#include <asm/pgtable.h> 14#include <asm/pgtable.h>
@@ -16,8 +17,6 @@
16 17
17#include "cbe_regs.h" 18#include "cbe_regs.h"
18 19
19#define MAX_CBE 2
20
21/* 20/*
22 * Current implementation uses "cpu" nodes. We build our own mapping 21 * Current implementation uses "cpu" nodes. We build our own mapping
23 * array of cpu numbers to cpu nodes locally for now to allow interrupt 22 * array of cpu numbers to cpu nodes locally for now to allow interrupt
@@ -30,6 +29,8 @@ static struct cbe_regs_map
30 struct device_node *cpu_node; 29 struct device_node *cpu_node;
31 struct cbe_pmd_regs __iomem *pmd_regs; 30 struct cbe_pmd_regs __iomem *pmd_regs;
32 struct cbe_iic_regs __iomem *iic_regs; 31 struct cbe_iic_regs __iomem *iic_regs;
32 struct cbe_mic_tm_regs __iomem *mic_tm_regs;
33 struct cbe_pmd_shadow_regs pmd_shadow_regs;
33} cbe_regs_maps[MAX_CBE]; 34} cbe_regs_maps[MAX_CBE];
34static int cbe_regs_map_count; 35static int cbe_regs_map_count;
35 36
@@ -42,6 +43,19 @@ static struct cbe_thread_map
42static struct cbe_regs_map *cbe_find_map(struct device_node *np) 43static struct cbe_regs_map *cbe_find_map(struct device_node *np)
43{ 44{
44 int i; 45 int i;
46 struct device_node *tmp_np;
47
48 if (strcasecmp(np->type, "spe") == 0) {
49 if (np->data == NULL) {
50 /* walk up path until cpu node was found */
51 tmp_np = np->parent;
52 while (tmp_np != NULL && strcasecmp(tmp_np->type, "cpu") != 0)
53 tmp_np = tmp_np->parent;
54
55 np->data = cbe_find_map(tmp_np);
56 }
57 return np->data;
58 }
45 59
46 for (i = 0; i < cbe_regs_map_count; i++) 60 for (i = 0; i < cbe_regs_map_count; i++)
47 if (cbe_regs_maps[i].cpu_node == np) 61 if (cbe_regs_maps[i].cpu_node == np)
@@ -56,6 +70,7 @@ struct cbe_pmd_regs __iomem *cbe_get_pmd_regs(struct device_node *np)
56 return NULL; 70 return NULL;
57 return map->pmd_regs; 71 return map->pmd_regs;
58} 72}
73EXPORT_SYMBOL_GPL(cbe_get_pmd_regs);
59 74
60struct cbe_pmd_regs __iomem *cbe_get_cpu_pmd_regs(int cpu) 75struct cbe_pmd_regs __iomem *cbe_get_cpu_pmd_regs(int cpu)
61{ 76{
@@ -64,7 +79,23 @@ struct cbe_pmd_regs __iomem *cbe_get_cpu_pmd_regs(int cpu)
64 return NULL; 79 return NULL;
65 return map->pmd_regs; 80 return map->pmd_regs;
66} 81}
82EXPORT_SYMBOL_GPL(cbe_get_cpu_pmd_regs);
67 83
84struct cbe_pmd_shadow_regs *cbe_get_pmd_shadow_regs(struct device_node *np)
85{
86 struct cbe_regs_map *map = cbe_find_map(np);
87 if (map == NULL)
88 return NULL;
89 return &map->pmd_shadow_regs;
90}
91
92struct cbe_pmd_shadow_regs *cbe_get_cpu_pmd_shadow_regs(int cpu)
93{
94 struct cbe_regs_map *map = cbe_thread_map[cpu].regs;
95 if (map == NULL)
96 return NULL;
97 return &map->pmd_shadow_regs;
98}
68 99
69struct cbe_iic_regs __iomem *cbe_get_iic_regs(struct device_node *np) 100struct cbe_iic_regs __iomem *cbe_get_iic_regs(struct device_node *np)
70{ 101{
@@ -73,6 +104,7 @@ struct cbe_iic_regs __iomem *cbe_get_iic_regs(struct device_node *np)
73 return NULL; 104 return NULL;
74 return map->iic_regs; 105 return map->iic_regs;
75} 106}
107
76struct cbe_iic_regs __iomem *cbe_get_cpu_iic_regs(int cpu) 108struct cbe_iic_regs __iomem *cbe_get_cpu_iic_regs(int cpu)
77{ 109{
78 struct cbe_regs_map *map = cbe_thread_map[cpu].regs; 110 struct cbe_regs_map *map = cbe_thread_map[cpu].regs;
@@ -81,6 +113,36 @@ struct cbe_iic_regs __iomem *cbe_get_cpu_iic_regs(int cpu)
81 return map->iic_regs; 113 return map->iic_regs;
82} 114}
83 115
116struct cbe_mic_tm_regs __iomem *cbe_get_mic_tm_regs(struct device_node *np)
117{
118 struct cbe_regs_map *map = cbe_find_map(np);
119 if (map == NULL)
120 return NULL;
121 return map->mic_tm_regs;
122}
123
124struct cbe_mic_tm_regs __iomem *cbe_get_cpu_mic_tm_regs(int cpu)
125{
126 struct cbe_regs_map *map = cbe_thread_map[cpu].regs;
127 if (map == NULL)
128 return NULL;
129 return map->mic_tm_regs;
130}
131EXPORT_SYMBOL_GPL(cbe_get_cpu_mic_tm_regs);
132
133/* FIXME
134 * This is little more than a stub at the moment. It should be
135 * fleshed out so that it works for both SMT and non-SMT, no
136 * matter if the passed cpu is odd or even.
137 * For SMT enabled, returns 0 for even-numbered cpu; otherwise 1.
138 * For SMT disabled, returns 0 for all cpus.
139 */
140u32 cbe_get_hw_thread_id(int cpu)
141{
142 return (cpu & 1);
143}
144EXPORT_SYMBOL_GPL(cbe_get_hw_thread_id);
145
84void __init cbe_regs_init(void) 146void __init cbe_regs_init(void)
85{ 147{
86 int i; 148 int i;
@@ -119,6 +181,11 @@ void __init cbe_regs_init(void)
119 prop = get_property(cpu, "iic", NULL); 181 prop = get_property(cpu, "iic", NULL);
120 if (prop != NULL) 182 if (prop != NULL)
121 map->iic_regs = ioremap(prop->address, prop->len); 183 map->iic_regs = ioremap(prop->address, prop->len);
184
185 prop = (struct address_prop *)get_property(cpu, "mic-tm",
186 NULL);
187 if (prop != NULL)
188 map->mic_tm_regs = ioremap(prop->address, prop->len);
122 } 189 }
123} 190}
124 191
diff --git a/arch/powerpc/platforms/cell/cbe_regs.h b/arch/powerpc/platforms/cell/cbe_regs.h
index e76e4a6af5bc..440a7ecc66ea 100644
--- a/arch/powerpc/platforms/cell/cbe_regs.h
+++ b/arch/powerpc/platforms/cell/cbe_regs.h
@@ -4,12 +4,19 @@
4 * This file is intended to hold the various register definitions for CBE 4 * This file is intended to hold the various register definitions for CBE
5 * on-chip system devices (memory controller, IO controller, etc...) 5 * on-chip system devices (memory controller, IO controller, etc...)
6 * 6 *
7 * (C) Copyright IBM Corporation 2001,2006
8 *
9 * Authors: Maximino Aguilar (maguilar@us.ibm.com)
10 * David J. Erb (djerb@us.ibm.com)
11 *
7 * (c) 2006 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp. 12 * (c) 2006 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp.
8 */ 13 */
9 14
10#ifndef CBE_REGS_H 15#ifndef CBE_REGS_H
11#define CBE_REGS_H 16#define CBE_REGS_H
12 17
18#include <asm/cell-pmu.h>
19
13/* 20/*
14 * 21 *
15 * Some HID register definitions 22 * Some HID register definitions
@@ -22,6 +29,7 @@
22#define HID0_CBE_THERM_INT_EN 0x0000000400000000ul 29#define HID0_CBE_THERM_INT_EN 0x0000000400000000ul
23#define HID0_CBE_SYSERR_INT_EN 0x0000000200000000ul 30#define HID0_CBE_SYSERR_INT_EN 0x0000000200000000ul
24 31
32#define MAX_CBE 2
25 33
26/* 34/*
27 * 35 *
@@ -29,51 +37,124 @@
29 * 37 *
30 */ 38 */
31 39
40union spe_reg {
41 u64 val;
42 u8 spe[8];
43};
44
45union ppe_spe_reg {
46 u64 val;
47 struct {
48 u32 ppe;
49 u32 spe;
50 };
51};
52
53
32struct cbe_pmd_regs { 54struct cbe_pmd_regs {
33 u8 pad_0x0000_0x0800[0x0800 - 0x0000]; /* 0x0000 */ 55 /* Debug Bus Control */
56 u64 pad_0x0000; /* 0x0000 */
57
58 u64 group_control; /* 0x0008 */
59
60 u8 pad_0x0010_0x00a8 [0x00a8 - 0x0010]; /* 0x0010 */
61
62 u64 debug_bus_control; /* 0x00a8 */
63
64 u8 pad_0x00b0_0x0100 [0x0100 - 0x00b0]; /* 0x00b0 */
65
66 u64 trace_aux_data; /* 0x0100 */
67 u64 trace_buffer_0_63; /* 0x0108 */
68 u64 trace_buffer_64_127; /* 0x0110 */
69 u64 trace_address; /* 0x0118 */
70 u64 ext_tr_timer; /* 0x0120 */
71
72 u8 pad_0x0128_0x0400 [0x0400 - 0x0128]; /* 0x0128 */
73
74 /* Performance Monitor */
75 u64 pm_status; /* 0x0400 */
76 u64 pm_control; /* 0x0408 */
77 u64 pm_interval; /* 0x0410 */
78 u64 pm_ctr[4]; /* 0x0418 */
79 u64 pm_start_stop; /* 0x0438 */
80 u64 pm07_control[8]; /* 0x0440 */
81
82 u8 pad_0x0480_0x0800 [0x0800 - 0x0480]; /* 0x0480 */
34 83
35 /* Thermal Sensor Registers */ 84 /* Thermal Sensor Registers */
36 u64 ts_ctsr1; /* 0x0800 */ 85 union spe_reg ts_ctsr1; /* 0x0800 */
37 u64 ts_ctsr2; /* 0x0808 */ 86 u64 ts_ctsr2; /* 0x0808 */
38 u64 ts_mtsr1; /* 0x0810 */ 87 union spe_reg ts_mtsr1; /* 0x0810 */
39 u64 ts_mtsr2; /* 0x0818 */ 88 u64 ts_mtsr2; /* 0x0818 */
40 u64 ts_itr1; /* 0x0820 */ 89 union spe_reg ts_itr1; /* 0x0820 */
41 u64 ts_itr2; /* 0x0828 */ 90 u64 ts_itr2; /* 0x0828 */
42 u64 ts_gitr; /* 0x0830 */ 91 u64 ts_gitr; /* 0x0830 */
43 u64 ts_isr; /* 0x0838 */ 92 u64 ts_isr; /* 0x0838 */
44 u64 ts_imr; /* 0x0840 */ 93 u64 ts_imr; /* 0x0840 */
45 u64 tm_cr1; /* 0x0848 */ 94 union spe_reg tm_cr1; /* 0x0848 */
46 u64 tm_cr2; /* 0x0850 */ 95 u64 tm_cr2; /* 0x0850 */
47 u64 tm_simr; /* 0x0858 */ 96 u64 tm_simr; /* 0x0858 */
48 u64 tm_tpr; /* 0x0860 */ 97 union ppe_spe_reg tm_tpr; /* 0x0860 */
49 u64 tm_str1; /* 0x0868 */ 98 union spe_reg tm_str1; /* 0x0868 */
50 u64 tm_str2; /* 0x0870 */ 99 u64 tm_str2; /* 0x0870 */
51 u64 tm_tsr; /* 0x0878 */ 100 union ppe_spe_reg tm_tsr; /* 0x0878 */
52 101
53 /* Power Management */ 102 /* Power Management */
54 u64 pm_control; /* 0x0880 */ 103 u64 pmcr; /* 0x0880 */
55#define CBE_PMD_PAUSE_ZERO_CONTROL 0x10000 104#define CBE_PMD_PAUSE_ZERO_CONTROL 0x10000
56 u64 pm_status; /* 0x0888 */ 105 u64 pmsr; /* 0x0888 */
57 106
58 /* Time Base Register */ 107 /* Time Base Register */
59 u64 tbr; /* 0x0890 */ 108 u64 tbr; /* 0x0890 */
60 109
61 u8 pad_0x0898_0x0c00 [0x0c00 - 0x0898]; /* 0x0898 */ 110 u8 pad_0x0898_0x0c00 [0x0c00 - 0x0898]; /* 0x0898 */
62 111
63 /* Fault Isolation Registers */ 112 /* Fault Isolation Registers */
64 u64 checkstop_fir; /* 0x0c00 */ 113 u64 checkstop_fir; /* 0x0c00 */
65 u64 recoverable_fir; 114 u64 recoverable_fir; /* 0x0c08 */
66 u64 spec_att_mchk_fir; 115 u64 spec_att_mchk_fir; /* 0x0c10 */
67 u64 fir_mode_reg; 116 u64 fir_mode_reg; /* 0x0c18 */
68 u64 fir_enable_mask; 117 u64 fir_enable_mask; /* 0x0c20 */
69 118
70 u8 pad_0x0c28_0x1000 [0x1000 - 0x0c28]; /* 0x0c28 */ 119 u8 pad_0x0c28_0x1000 [0x1000 - 0x0c28]; /* 0x0c28 */
71}; 120};
72 121
73extern struct cbe_pmd_regs __iomem *cbe_get_pmd_regs(struct device_node *np); 122extern struct cbe_pmd_regs __iomem *cbe_get_pmd_regs(struct device_node *np);
74extern struct cbe_pmd_regs __iomem *cbe_get_cpu_pmd_regs(int cpu); 123extern struct cbe_pmd_regs __iomem *cbe_get_cpu_pmd_regs(int cpu);
75 124
76/* 125/*
126 * PMU shadow registers
127 *
128 * Many of the registers in the performance monitoring unit are write-only,
129 * so we need to save a copy of what we write to those registers.
130 *
131 * The actual data counters are read/write. However, writing to the counters
132 * only takes effect if the PMU is enabled. Otherwise the value is stored in
133 * a hardware latch until the next time the PMU is enabled. So we save a copy
134 * of the counter values if we need to read them back while the PMU is
135 * disabled. The counter_value_in_latch field is a bitmap indicating which
136 * counters currently have a value waiting to be written.
137 */
138
139struct cbe_pmd_shadow_regs {
140 u32 group_control;
141 u32 debug_bus_control;
142 u32 trace_address;
143 u32 ext_tr_timer;
144 u32 pm_status;
145 u32 pm_control;
146 u32 pm_interval;
147 u32 pm_start_stop;
148 u32 pm07_control[NR_CTRS];
149
150 u32 pm_ctr[NR_PHYS_CTRS];
151 u32 counter_value_in_latch;
152};
153
154extern struct cbe_pmd_shadow_regs *cbe_get_pmd_shadow_regs(struct device_node *np);
155extern struct cbe_pmd_shadow_regs *cbe_get_cpu_pmd_shadow_regs(int cpu);
156
157/*
77 * 158 *
78 * IIC unit register definitions 159 * IIC unit register definitions
79 * 160 *
@@ -102,18 +183,28 @@ struct cbe_iic_regs {
102 183
103 /* IIC interrupt registers */ 184 /* IIC interrupt registers */
104 struct cbe_iic_thread_regs thread[2]; /* 0x0400 */ 185 struct cbe_iic_thread_regs thread[2]; /* 0x0400 */
105 u64 iic_ir; /* 0x0440 */ 186
106 u64 iic_is; /* 0x0448 */ 187 u64 iic_ir; /* 0x0440 */
188#define CBE_IIC_IR_PRIO(x) (((x) & 0xf) << 12)
189#define CBE_IIC_IR_DEST_NODE(x) (((x) & 0xf) << 4)
190#define CBE_IIC_IR_DEST_UNIT(x) ((x) & 0xf)
191#define CBE_IIC_IR_IOC_0 0x0
192#define CBE_IIC_IR_IOC_1S 0xb
193#define CBE_IIC_IR_PT_0 0xe
194#define CBE_IIC_IR_PT_1 0xf
195
196 u64 iic_is; /* 0x0448 */
197#define CBE_IIC_IS_PMI 0x2
107 198
108 u8 pad_0x0450_0x0500[0x0500 - 0x0450]; /* 0x0450 */ 199 u8 pad_0x0450_0x0500[0x0500 - 0x0450]; /* 0x0450 */
109 200
110 /* IOC FIR */ 201 /* IOC FIR */
111 u64 ioc_fir_reset; /* 0x0500 */ 202 u64 ioc_fir_reset; /* 0x0500 */
112 u64 ioc_fir_set; 203 u64 ioc_fir_set; /* 0x0508 */
113 u64 ioc_checkstop_enable; 204 u64 ioc_checkstop_enable; /* 0x0510 */
114 u64 ioc_fir_error_mask; 205 u64 ioc_fir_error_mask; /* 0x0518 */
115 u64 ioc_syserr_enable; 206 u64 ioc_syserr_enable; /* 0x0520 */
116 u64 ioc_fir; 207 u64 ioc_fir; /* 0x0528 */
117 208
118 u8 pad_0x0530_0x1000[0x1000 - 0x0530]; /* 0x0530 */ 209 u8 pad_0x0530_0x1000[0x1000 - 0x0530]; /* 0x0530 */
119}; 210};
@@ -122,6 +213,48 @@ extern struct cbe_iic_regs __iomem *cbe_get_iic_regs(struct device_node *np);
122extern struct cbe_iic_regs __iomem *cbe_get_cpu_iic_regs(int cpu); 213extern struct cbe_iic_regs __iomem *cbe_get_cpu_iic_regs(int cpu);
123 214
124 215
216struct cbe_mic_tm_regs {
217 u8 pad_0x0000_0x0040[0x0040 - 0x0000]; /* 0x0000 */
218
219 u64 mic_ctl_cnfg2; /* 0x0040 */
220#define CBE_MIC_ENABLE_AUX_TRC 0x8000000000000000LL
221#define CBE_MIC_DISABLE_PWR_SAV_2 0x0200000000000000LL
222#define CBE_MIC_DISABLE_AUX_TRC_WRAP 0x0100000000000000LL
223#define CBE_MIC_ENABLE_AUX_TRC_INT 0x0080000000000000LL
224
225 u64 pad_0x0048; /* 0x0048 */
226
227 u64 mic_aux_trc_base; /* 0x0050 */
228 u64 mic_aux_trc_max_addr; /* 0x0058 */
229 u64 mic_aux_trc_cur_addr; /* 0x0060 */
230 u64 mic_aux_trc_grf_addr; /* 0x0068 */
231 u64 mic_aux_trc_grf_data; /* 0x0070 */
232
233 u64 pad_0x0078; /* 0x0078 */
234
235 u64 mic_ctl_cnfg_0; /* 0x0080 */
236#define CBE_MIC_DISABLE_PWR_SAV_0 0x8000000000000000LL
237
238 u64 pad_0x0088; /* 0x0088 */
239
240 u64 slow_fast_timer_0; /* 0x0090 */
241 u64 slow_next_timer_0; /* 0x0098 */
242
243 u8 pad_0x00a0_0x01c0[0x01c0 - 0x0a0]; /* 0x00a0 */
244
245 u64 mic_ctl_cnfg_1; /* 0x01c0 */
246#define CBE_MIC_DISABLE_PWR_SAV_1 0x8000000000000000LL
247 u64 pad_0x01c8; /* 0x01c8 */
248
249 u64 slow_fast_timer_1; /* 0x01d0 */
250 u64 slow_next_timer_1; /* 0x01d8 */
251
252 u8 pad_0x01e0_0x1000[0x1000 - 0x01e0]; /* 0x01e0 */
253};
254
255extern struct cbe_mic_tm_regs __iomem *cbe_get_mic_tm_regs(struct device_node *np);
256extern struct cbe_mic_tm_regs __iomem *cbe_get_cpu_mic_tm_regs(int cpu);
257
125/* Init this module early */ 258/* Init this module early */
126extern void cbe_regs_init(void); 259extern void cbe_regs_init(void);
127 260
diff --git a/arch/powerpc/platforms/cell/cbe_thermal.c b/arch/powerpc/platforms/cell/cbe_thermal.c
new file mode 100644
index 000000000000..616a0a3fd0e2
--- /dev/null
+++ b/arch/powerpc/platforms/cell/cbe_thermal.c
@@ -0,0 +1,226 @@
1/*
2 * thermal support for the cell processor
3 *
4 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
5 *
6 * Author: Christian Krafft <krafft@de.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/module.h>
24#include <linux/sysdev.h>
25#include <linux/kernel.h>
26#include <linux/cpu.h>
27#include <asm/spu.h>
28#include <asm/io.h>
29#include <asm/prom.h>
30
31#include "cbe_regs.h"
32#include "spu_priv1_mmio.h"
33
34static struct cbe_pmd_regs __iomem *get_pmd_regs(struct sys_device *sysdev)
35{
36 struct spu *spu;
37
38 spu = container_of(sysdev, struct spu, sysdev);
39
40 return cbe_get_pmd_regs(spu_devnode(spu));
41}
42
43/* returns the value for a given spu in a given register */
44static u8 spu_read_register_value(struct sys_device *sysdev, union spe_reg __iomem *reg)
45{
46 unsigned int *id;
47 union spe_reg value;
48 struct spu *spu;
49
50 /* getting the id from the reg attribute will not work on future device-tree layouts
51 * in future we should store the id to the spu struct and use it here */
52 spu = container_of(sysdev, struct spu, sysdev);
53 id = (unsigned int *)get_property(spu_devnode(spu), "reg", NULL);
54 value.val = in_be64(&reg->val);
55
56 return value.spe[*id];
57}
58
59static ssize_t spu_show_temp(struct sys_device *sysdev, char *buf)
60{
61 int value;
62 struct cbe_pmd_regs __iomem *pmd_regs;
63
64 pmd_regs = get_pmd_regs(sysdev);
65
66 value = spu_read_register_value(sysdev, &pmd_regs->ts_ctsr1);
67 /* clear all other bits */
68 value &= 0x3F;
69 /* temp is stored in steps of 2 degrees */
70 value *= 2;
71 /* base temp is 65 degrees */
72 value += 65;
73
74 return sprintf(buf, "%d\n", (int) value);
75}
76
77static ssize_t ppe_show_temp(struct sys_device *sysdev, char *buf, int pos)
78{
79 struct cbe_pmd_regs __iomem *pmd_regs;
80 u64 value;
81
82 pmd_regs = cbe_get_cpu_pmd_regs(sysdev->id);
83 value = in_be64(&pmd_regs->ts_ctsr2);
84
85 /* access the corresponding byte */
86 value >>= pos;
87 /* clear all other bits */
88 value &= 0x3F;
89 /* temp is stored in steps of 2 degrees */
90 value *= 2;
91 /* base temp is 65 degrees */
92 value += 65;
93
94 return sprintf(buf, "%d\n", (int) value);
95}
96
97
98/* shows the temperature of the DTS on the PPE,
99 * located near the linear thermal sensor */
100static ssize_t ppe_show_temp0(struct sys_device *sysdev, char *buf)
101{
102 return ppe_show_temp(sysdev, buf, 32);
103}
104
105/* shows the temperature of the second DTS on the PPE */
106static ssize_t ppe_show_temp1(struct sys_device *sysdev, char *buf)
107{
108 return ppe_show_temp(sysdev, buf, 0);
109}
110
111static struct sysdev_attribute attr_spu_temperature = {
112 .attr = {.name = "temperature", .mode = 0400 },
113 .show = spu_show_temp,
114};
115
116static struct attribute *spu_attributes[] = {
117 &attr_spu_temperature.attr,
118};
119
120static struct attribute_group spu_attribute_group = {
121 .name = "thermal",
122 .attrs = spu_attributes,
123};
124
125static struct sysdev_attribute attr_ppe_temperature0 = {
126 .attr = {.name = "temperature0", .mode = 0400 },
127 .show = ppe_show_temp0,
128};
129
130static struct sysdev_attribute attr_ppe_temperature1 = {
131 .attr = {.name = "temperature1", .mode = 0400 },
132 .show = ppe_show_temp1,
133};
134
135static struct attribute *ppe_attributes[] = {
136 &attr_ppe_temperature0.attr,
137 &attr_ppe_temperature1.attr,
138};
139
140static struct attribute_group ppe_attribute_group = {
141 .name = "thermal",
142 .attrs = ppe_attributes,
143};
144
145/*
146 * initialize throttling with default values
147 */
148static void __init init_default_values(void)
149{
150 int cpu;
151 struct cbe_pmd_regs __iomem *pmd_regs;
152 struct sys_device *sysdev;
153 union ppe_spe_reg tpr;
154 union spe_reg str1;
155 u64 str2;
156 union spe_reg cr1;
157 u64 cr2;
158
159 /* TPR defaults */
160 /* ppe
161 * 1F - no full stop
162 * 08 - dynamic throttling starts if over 80 degrees
163 * 03 - dynamic throttling ceases if below 70 degrees */
164 tpr.ppe = 0x1F0803;
165 /* spe
166 * 10 - full stopped when over 96 degrees
167 * 08 - dynamic throttling starts if over 80 degrees
168 * 03 - dynamic throttling ceases if below 70 degrees
169 */
170 tpr.spe = 0x100803;
171
172 /* STR defaults */
173 /* str1
174 * 10 - stop 16 of 32 cycles
175 */
176 str1.val = 0x1010101010101010ull;
177 /* str2
178 * 10 - stop 16 of 32 cycles
179 */
180 str2 = 0x10;
181
182 /* CR defaults */
183 /* cr1
184 * 4 - normal operation
185 */
186 cr1.val = 0x0404040404040404ull;
187 /* cr2
188 * 4 - normal operation
189 */
190 cr2 = 0x04;
191
192 for_each_possible_cpu (cpu) {
193 pr_debug("processing cpu %d\n", cpu);
194 sysdev = get_cpu_sysdev(cpu);
195 pmd_regs = cbe_get_cpu_pmd_regs(sysdev->id);
196
197 out_be64(&pmd_regs->tm_str2, str2);
198 out_be64(&pmd_regs->tm_str1.val, str1.val);
199 out_be64(&pmd_regs->tm_tpr.val, tpr.val);
200 out_be64(&pmd_regs->tm_cr1.val, cr1.val);
201 out_be64(&pmd_regs->tm_cr2, cr2);
202 }
203}
204
205
206static int __init thermal_init(void)
207{
208 init_default_values();
209
210 spu_add_sysdev_attr_group(&spu_attribute_group);
211 cpu_add_sysdev_attr_group(&ppe_attribute_group);
212
213 return 0;
214}
215module_init(thermal_init);
216
217static void __exit thermal_exit(void)
218{
219 spu_remove_sysdev_attr_group(&spu_attribute_group);
220 cpu_remove_sysdev_attr_group(&ppe_attribute_group);
221}
222module_exit(thermal_exit);
223
224MODULE_LICENSE("GPL");
225MODULE_AUTHOR("Christian Krafft <krafft@de.ibm.com>");
226
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c
index a914c12b4060..6666d037eb44 100644
--- a/arch/powerpc/platforms/cell/interrupt.c
+++ b/arch/powerpc/platforms/cell/interrupt.c
@@ -396,3 +396,19 @@ void __init iic_init_IRQ(void)
396 /* Enable on current CPU */ 396 /* Enable on current CPU */
397 iic_setup_cpu(); 397 iic_setup_cpu();
398} 398}
399
400void iic_set_interrupt_routing(int cpu, int thread, int priority)
401{
402 struct cbe_iic_regs __iomem *iic_regs = cbe_get_cpu_iic_regs(cpu);
403 u64 iic_ir = 0;
404 int node = cpu >> 1;
405
406 /* Set which node and thread will handle the next interrupt */
407 iic_ir |= CBE_IIC_IR_PRIO(priority) |
408 CBE_IIC_IR_DEST_NODE(node);
409 if (thread == 0)
410 iic_ir |= CBE_IIC_IR_DEST_UNIT(CBE_IIC_IR_PT_0);
411 else
412 iic_ir |= CBE_IIC_IR_DEST_UNIT(CBE_IIC_IR_PT_1);
413 out_be64(&iic_regs->iic_ir, iic_ir);
414}
diff --git a/arch/powerpc/platforms/cell/interrupt.h b/arch/powerpc/platforms/cell/interrupt.h
index 9ba1d3c17b4b..942dc39d6045 100644
--- a/arch/powerpc/platforms/cell/interrupt.h
+++ b/arch/powerpc/platforms/cell/interrupt.h
@@ -83,5 +83,7 @@ extern u8 iic_get_target_id(int cpu);
83 83
84extern void spider_init_IRQ(void); 84extern void spider_init_IRQ(void);
85 85
86extern void iic_set_interrupt_routing(int cpu, int thread, int priority);
87
86#endif 88#endif
87#endif /* ASM_CELL_PIC_H */ 89#endif /* ASM_CELL_PIC_H */
diff --git a/arch/powerpc/platforms/cell/io-workarounds.c b/arch/powerpc/platforms/cell/io-workarounds.c
new file mode 100644
index 000000000000..580d42595912
--- /dev/null
+++ b/arch/powerpc/platforms/cell/io-workarounds.c
@@ -0,0 +1,346 @@
1/*
2 * Copyright (C) 2006 Benjamin Herrenschmidt <benh@kernel.crashing.org>
3 * IBM, Corp.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License version 2 as
7 * published by the Free Software Foundation.
8 */
9#undef DEBUG
10
11#include <linux/kernel.h>
12#include <linux/mm.h>
13#include <linux/pci.h>
14#include <asm/io.h>
15#include <asm/machdep.h>
16#include <asm/pci-bridge.h>
17#include <asm/ppc-pci.h>
18
19
20#define SPIDER_PCI_REG_BASE 0xd000
21#define SPIDER_PCI_VCI_CNTL_STAT 0x0110
22#define SPIDER_PCI_DUMMY_READ 0x0810
23#define SPIDER_PCI_DUMMY_READ_BASE 0x0814
24
25/* Undefine that to re-enable bogus prefetch
26 *
27 * Without that workaround, the chip will do bogus prefetch past
28 * page boundary from system memory. This setting will disable that,
29 * though the documentation is unclear as to the consequences of doing
30 * so, either purely performances, or possible misbehaviour... It's not
31 * clear wether the chip can handle unaligned accesses at all without
32 * prefetching enabled.
33 *
34 * For now, things appear to be behaving properly with that prefetching
35 * disabled and IDE, possibly because IDE isn't doing any unaligned
36 * access.
37 */
38#define SPIDER_DISABLE_PREFETCH
39
40#define MAX_SPIDERS 2
41
42static struct spider_pci_bus {
43 void __iomem *regs;
44 unsigned long mmio_start;
45 unsigned long mmio_end;
46 unsigned long pio_vstart;
47 unsigned long pio_vend;
48} spider_pci_busses[MAX_SPIDERS];
49static int spider_pci_count;
50
51static struct spider_pci_bus *spider_pci_find(unsigned long vaddr,
52 unsigned long paddr)
53{
54 int i;
55
56 for (i = 0; i < spider_pci_count; i++) {
57 struct spider_pci_bus *bus = &spider_pci_busses[i];
58 if (paddr && paddr >= bus->mmio_start && paddr < bus->mmio_end)
59 return bus;
60 if (vaddr && vaddr >= bus->pio_vstart && vaddr < bus->pio_vend)
61 return bus;
62 }
63 return NULL;
64}
65
66static void spider_io_flush(const volatile void __iomem *addr)
67{
68 struct spider_pci_bus *bus;
69 int token;
70
71 /* Get platform token (set by ioremap) from address */
72 token = PCI_GET_ADDR_TOKEN(addr);
73
74 /* Fast path if we have a non-0 token, it indicates which bus we
75 * are on.
76 *
77 * If the token is 0, that means either the the ioremap was done
78 * before we initialized this layer, or it's a PIO operation. We
79 * fallback to a low path in this case. Hopefully, internal devices
80 * which are ioremap'ed early should use in_XX/out_XX functions
81 * instead of the PCI ones and thus not suffer from the slowdown.
82 *
83 * Also note that currently, the workaround will not work for areas
84 * that are not mapped with PTEs (bolted in the hash table). This
85 * is the case for ioremaps done very early at boot (before
86 * mem_init_done) and includes the mapping of the ISA IO space.
87 *
88 * Fortunately, none of the affected devices is expected to do DMA
89 * and thus there should be no problem in practice.
90 *
91 * In order to improve performances, we only do the PTE search for
92 * addresses falling in the PHB IO space area. That means it will
93 * not work for hotplug'ed PHBs but those don't exist with Spider.
94 */
95 if (token && token <= spider_pci_count)
96 bus = &spider_pci_busses[token - 1];
97 else {
98 unsigned long vaddr, paddr;
99 pte_t *ptep;
100
101 /* Fixup physical address */
102 vaddr = (unsigned long)PCI_FIX_ADDR(addr);
103
104 /* Check if it's in allowed range for PIO */
105 if (vaddr < PHBS_IO_BASE || vaddr >= IMALLOC_BASE)
106 return;
107
108 /* Try to find a PTE. If not, clear the paddr, we'll do
109 * a vaddr only lookup (PIO only)
110 */
111 ptep = find_linux_pte(init_mm.pgd, vaddr);
112 if (ptep == NULL)
113 paddr = 0;
114 else
115 paddr = pte_pfn(*ptep) << PAGE_SHIFT;
116
117 bus = spider_pci_find(vaddr, paddr);
118 if (bus == NULL)
119 return;
120 }
121
122 /* Now do the workaround
123 */
124 (void)in_be32(bus->regs + SPIDER_PCI_DUMMY_READ);
125}
126
127static u8 spider_readb(const volatile void __iomem *addr)
128{
129 u8 val = __do_readb(addr);
130 spider_io_flush(addr);
131 return val;
132}
133
134static u16 spider_readw(const volatile void __iomem *addr)
135{
136 u16 val = __do_readw(addr);
137 spider_io_flush(addr);
138 return val;
139}
140
141static u32 spider_readl(const volatile void __iomem *addr)
142{
143 u32 val = __do_readl(addr);
144 spider_io_flush(addr);
145 return val;
146}
147
148static u64 spider_readq(const volatile void __iomem *addr)
149{
150 u64 val = __do_readq(addr);
151 spider_io_flush(addr);
152 return val;
153}
154
155static u16 spider_readw_be(const volatile void __iomem *addr)
156{
157 u16 val = __do_readw_be(addr);
158 spider_io_flush(addr);
159 return val;
160}
161
162static u32 spider_readl_be(const volatile void __iomem *addr)
163{
164 u32 val = __do_readl_be(addr);
165 spider_io_flush(addr);
166 return val;
167}
168
169static u64 spider_readq_be(const volatile void __iomem *addr)
170{
171 u64 val = __do_readq_be(addr);
172 spider_io_flush(addr);
173 return val;
174}
175
176static void spider_readsb(const volatile void __iomem *addr, void *buf,
177 unsigned long count)
178{
179 __do_readsb(addr, buf, count);
180 spider_io_flush(addr);
181}
182
183static void spider_readsw(const volatile void __iomem *addr, void *buf,
184 unsigned long count)
185{
186 __do_readsw(addr, buf, count);
187 spider_io_flush(addr);
188}
189
190static void spider_readsl(const volatile void __iomem *addr, void *buf,
191 unsigned long count)
192{
193 __do_readsl(addr, buf, count);
194 spider_io_flush(addr);
195}
196
197static void spider_memcpy_fromio(void *dest, const volatile void __iomem *src,
198 unsigned long n)
199{
200 __do_memcpy_fromio(dest, src, n);
201 spider_io_flush(src);
202}
203
204
205static void __iomem * spider_ioremap(unsigned long addr, unsigned long size,
206 unsigned long flags)
207{
208 struct spider_pci_bus *bus;
209 void __iomem *res = __ioremap(addr, size, flags);
210 int busno;
211
212 pr_debug("spider_ioremap(0x%lx, 0x%lx, 0x%lx) -> 0x%p\n",
213 addr, size, flags, res);
214
215 bus = spider_pci_find(0, addr);
216 if (bus != NULL) {
217 busno = bus - spider_pci_busses;
218 pr_debug(" found bus %d, setting token\n", busno);
219 PCI_SET_ADDR_TOKEN(res, busno + 1);
220 }
221 pr_debug(" result=0x%p\n", res);
222
223 return res;
224}
225
226static void __init spider_pci_setup_chip(struct spider_pci_bus *bus)
227{
228#ifdef SPIDER_DISABLE_PREFETCH
229 u32 val = in_be32(bus->regs + SPIDER_PCI_VCI_CNTL_STAT);
230 pr_debug(" PVCI_Control_Status was 0x%08x\n", val);
231 out_be32(bus->regs + SPIDER_PCI_VCI_CNTL_STAT, val | 0x8);
232#endif
233
234 /* Configure the dummy address for the workaround */
235 out_be32(bus->regs + SPIDER_PCI_DUMMY_READ_BASE, 0x80000000);
236}
237
238static void __init spider_pci_add_one(struct pci_controller *phb)
239{
240 struct spider_pci_bus *bus = &spider_pci_busses[spider_pci_count];
241 struct device_node *np = phb->arch_data;
242 struct resource rsrc;
243 void __iomem *regs;
244
245 if (spider_pci_count >= MAX_SPIDERS) {
246 printk(KERN_ERR "Too many spider bridges, workarounds"
247 " disabled for %s\n", np->full_name);
248 return;
249 }
250
251 /* Get the registers for the beast */
252 if (of_address_to_resource(np, 0, &rsrc)) {
253 printk(KERN_ERR "Failed to get registers for spider %s"
254 " workarounds disabled\n", np->full_name);
255 return;
256 }
257
258 /* Mask out some useless bits in there to get to the base of the
259 * spider chip
260 */
261 rsrc.start &= ~0xfffffffful;
262
263 /* Map them */
264 regs = ioremap(rsrc.start + SPIDER_PCI_REG_BASE, 0x1000);
265 if (regs == NULL) {
266 printk(KERN_ERR "Failed to map registers for spider %s"
267 " workarounds disabled\n", np->full_name);
268 return;
269 }
270
271 spider_pci_count++;
272
273 /* We assume spiders only have one MMIO resource */
274 bus->mmio_start = phb->mem_resources[0].start;
275 bus->mmio_end = phb->mem_resources[0].end + 1;
276
277 bus->pio_vstart = (unsigned long)phb->io_base_virt;
278 bus->pio_vend = bus->pio_vstart + phb->pci_io_size;
279
280 bus->regs = regs;
281
282 printk(KERN_INFO "PCI: Spider MMIO workaround for %s\n",np->full_name);
283
284 pr_debug(" mmio (P) = 0x%016lx..0x%016lx\n",
285 bus->mmio_start, bus->mmio_end);
286 pr_debug(" pio (V) = 0x%016lx..0x%016lx\n",
287 bus->pio_vstart, bus->pio_vend);
288 pr_debug(" regs (P) = 0x%016lx (V) = 0x%p\n",
289 rsrc.start + SPIDER_PCI_REG_BASE, bus->regs);
290
291 spider_pci_setup_chip(bus);
292}
293
294static struct ppc_pci_io __initdata spider_pci_io = {
295 .readb = spider_readb,
296 .readw = spider_readw,
297 .readl = spider_readl,
298 .readq = spider_readq,
299 .readw_be = spider_readw_be,
300 .readl_be = spider_readl_be,
301 .readq_be = spider_readq_be,
302 .readsb = spider_readsb,
303 .readsw = spider_readsw,
304 .readsl = spider_readsl,
305 .memcpy_fromio = spider_memcpy_fromio,
306};
307
308static int __init spider_pci_workaround_init(void)
309{
310 struct pci_controller *phb;
311
312 if (!machine_is(cell))
313 return 0;
314
315 /* Find spider bridges. We assume they have been all probed
316 * in setup_arch(). If that was to change, we would need to
317 * update this code to cope with dynamically added busses
318 */
319 list_for_each_entry(phb, &hose_list, list_node) {
320 struct device_node *np = phb->arch_data;
321 const char *model = get_property(np, "model", NULL);
322
323 /* If no model property or name isn't exactly "pci", skip */
324 if (model == NULL || strcmp(np->name, "pci"))
325 continue;
326 /* If model is not "Spider", skip */
327 if (strcmp(model, "Spider"))
328 continue;
329 spider_pci_add_one(phb);
330 }
331
332 /* No Spider PCI found, exit */
333 if (spider_pci_count == 0)
334 return 0;
335
336 /* Setup IO callbacks. We only setup MMIO reads. PIO reads will
337 * fallback to MMIO reads (though without a token, thus slower)
338 */
339 ppc_pci_io = spider_pci_io;
340
341 /* Setup ioremap callback */
342 ppc_md.ioremap = spider_ioremap;
343
344 return 0;
345}
346arch_initcall(spider_pci_workaround_init);
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c
index aca4c3db0dde..b43466ba8096 100644
--- a/arch/powerpc/platforms/cell/iommu.c
+++ b/arch/powerpc/platforms/cell/iommu.c
@@ -1,514 +1,747 @@
1/* 1/*
2 * IOMMU implementation for Cell Broadband Processor Architecture 2 * IOMMU implementation for Cell Broadband Processor Architecture
3 * We just establish a linear mapping at boot by setting all the
4 * IOPT cache entries in the CPU.
5 * The mapping functions should be identical to pci_direct_iommu,
6 * except for the handling of the high order bit that is required
7 * by the Spider bridge. These should be split into a separate
8 * file at the point where we get a different bridge chip.
9 * 3 *
10 * Copyright (C) 2005 IBM Deutschland Entwicklung GmbH, 4 * (C) Copyright IBM Corporation 2006
11 * Arnd Bergmann <arndb@de.ibm.com>
12 * 5 *
13 * Based on linear mapping 6 * Author: Jeremy Kerr <jk@ozlabs.org>
14 * Copyright (C) 2003 Benjamin Herrenschmidt (benh@kernel.crashing.org)
15 * 7 *
16 * This program is free software; you can redistribute it and/or 8 * This program is free software; you can redistribute it and/or modify
17 * modify it under the terms of the GNU General Public License 9 * it under the terms of the GNU General Public License as published by
18 * as published by the Free Software Foundation; either version 10 * the Free Software Foundation; either version 2, or (at your option)
19 * 2 of the License, or (at your option) any later version. 11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */ 21 */
21 22
22#undef DEBUG 23#undef DEBUG
23 24
24#include <linux/kernel.h> 25#include <linux/kernel.h>
25#include <linux/pci.h>
26#include <linux/delay.h>
27#include <linux/string.h>
28#include <linux/init.h> 26#include <linux/init.h>
29#include <linux/bootmem.h> 27#include <linux/interrupt.h>
30#include <linux/mm.h> 28#include <linux/notifier.h>
31#include <linux/dma-mapping.h>
32#include <linux/kernel.h>
33#include <linux/compiler.h>
34 29
35#include <asm/sections.h>
36#include <asm/iommu.h>
37#include <asm/io.h>
38#include <asm/prom.h> 30#include <asm/prom.h>
39#include <asm/pci-bridge.h> 31#include <asm/iommu.h>
40#include <asm/machdep.h> 32#include <asm/machdep.h>
41#include <asm/pmac_feature.h> 33#include <asm/pci-bridge.h>
42#include <asm/abs_addr.h>
43#include <asm/system.h>
44#include <asm/ppc-pci.h>
45#include <asm/udbg.h> 34#include <asm/udbg.h>
35#include <asm/of_platform.h>
36#include <asm/lmb.h>
46 37
47#include "iommu.h" 38#include "cbe_regs.h"
39#include "interrupt.h"
48 40
49static inline unsigned long 41/* Define CELL_IOMMU_REAL_UNMAP to actually unmap non-used pages
50get_iopt_entry(unsigned long real_address, unsigned long ioid, 42 * instead of leaving them mapped to some dummy page. This can be
51 unsigned long prot) 43 * enabled once the appropriate workarounds for spider bugs have
52{ 44 * been enabled
53 return (prot & IOPT_PROT_MASK) 45 */
54 | (IOPT_COHERENT) 46#define CELL_IOMMU_REAL_UNMAP
55 | (IOPT_ORDER_VC)
56 | (real_address & IOPT_RPN_MASK)
57 | (ioid & IOPT_IOID_MASK);
58}
59 47
60typedef struct { 48/* Define CELL_IOMMU_STRICT_PROTECTION to enforce protection of
61 unsigned long val; 49 * IO PTEs based on the transfer direction. That can be enabled
62} ioste; 50 * once spider-net has been fixed to pass the correct direction
51 * to the DMA mapping functions
52 */
53#define CELL_IOMMU_STRICT_PROTECTION
54
55
56#define NR_IOMMUS 2
57
58/* IOC mmap registers */
59#define IOC_Reg_Size 0x2000
60
61#define IOC_IOPT_CacheInvd 0x908
62#define IOC_IOPT_CacheInvd_NE_Mask 0xffe0000000000000ul
63#define IOC_IOPT_CacheInvd_IOPTE_Mask 0x000003fffffffff8ul
64#define IOC_IOPT_CacheInvd_Busy 0x0000000000000001ul
65
66#define IOC_IOST_Origin 0x918
67#define IOC_IOST_Origin_E 0x8000000000000000ul
68#define IOC_IOST_Origin_HW 0x0000000000000800ul
69#define IOC_IOST_Origin_HL 0x0000000000000400ul
70
71#define IOC_IO_ExcpStat 0x920
72#define IOC_IO_ExcpStat_V 0x8000000000000000ul
73#define IOC_IO_ExcpStat_SPF_Mask 0x6000000000000000ul
74#define IOC_IO_ExcpStat_SPF_S 0x6000000000000000ul
75#define IOC_IO_ExcpStat_SPF_P 0x4000000000000000ul
76#define IOC_IO_ExcpStat_ADDR_Mask 0x00000007fffff000ul
77#define IOC_IO_ExcpStat_RW_Mask 0x0000000000000800ul
78#define IOC_IO_ExcpStat_IOID_Mask 0x00000000000007fful
79
80#define IOC_IO_ExcpMask 0x928
81#define IOC_IO_ExcpMask_SFE 0x4000000000000000ul
82#define IOC_IO_ExcpMask_PFE 0x2000000000000000ul
83
84#define IOC_IOCmd_Offset 0x1000
85
86#define IOC_IOCmd_Cfg 0xc00
87#define IOC_IOCmd_Cfg_TE 0x0000800000000000ul
88
89
90/* Segment table entries */
91#define IOSTE_V 0x8000000000000000ul /* valid */
92#define IOSTE_H 0x4000000000000000ul /* cache hint */
93#define IOSTE_PT_Base_RPN_Mask 0x3ffffffffffff000ul /* base RPN of IOPT */
94#define IOSTE_NPPT_Mask 0x0000000000000fe0ul /* no. pages in IOPT */
95#define IOSTE_PS_Mask 0x0000000000000007ul /* page size */
96#define IOSTE_PS_4K 0x0000000000000001ul /* - 4kB */
97#define IOSTE_PS_64K 0x0000000000000003ul /* - 64kB */
98#define IOSTE_PS_1M 0x0000000000000005ul /* - 1MB */
99#define IOSTE_PS_16M 0x0000000000000007ul /* - 16MB */
100
101/* Page table entries */
102#define IOPTE_PP_W 0x8000000000000000ul /* protection: write */
103#define IOPTE_PP_R 0x4000000000000000ul /* protection: read */
104#define IOPTE_M 0x2000000000000000ul /* coherency required */
105#define IOPTE_SO_R 0x1000000000000000ul /* ordering: writes */
106#define IOPTE_SO_RW 0x1800000000000000ul /* ordering: r & w */
107#define IOPTE_RPN_Mask 0x07fffffffffff000ul /* RPN */
108#define IOPTE_H 0x0000000000000800ul /* cache hint */
109#define IOPTE_IOID_Mask 0x00000000000007fful /* ioid */
110
111
112/* IOMMU sizing */
113#define IO_SEGMENT_SHIFT 28
114#define IO_PAGENO_BITS (IO_SEGMENT_SHIFT - IOMMU_PAGE_SHIFT)
115
116/* The high bit needs to be set on every DMA address */
117#define SPIDER_DMA_OFFSET 0x80000000ul
118
119struct iommu_window {
120 struct list_head list;
121 struct cbe_iommu *iommu;
122 unsigned long offset;
123 unsigned long size;
124 unsigned long pte_offset;
125 unsigned int ioid;
126 struct iommu_table table;
127};
63 128
64static inline ioste 129#define NAMESIZE 8
65mk_ioste(unsigned long val) 130struct cbe_iommu {
66{ 131 int nid;
67 ioste ioste = { .val = val, }; 132 char name[NAMESIZE];
68 return ioste; 133 void __iomem *xlate_regs;
69} 134 void __iomem *cmd_regs;
135 unsigned long *stab;
136 unsigned long *ptab;
137 void *pad_page;
138 struct list_head windows;
139};
140
141/* Static array of iommus, one per node
142 * each contains a list of windows, keyed from dma_window property
143 * - on bus setup, look for a matching window, or create one
144 * - on dev setup, assign iommu_table ptr
145 */
146static struct cbe_iommu iommus[NR_IOMMUS];
147static int cbe_nr_iommus;
70 148
71static inline ioste 149static void invalidate_tce_cache(struct cbe_iommu *iommu, unsigned long *pte,
72get_iost_entry(unsigned long iopt_base, unsigned long io_address, unsigned page_size) 150 long n_ptes)
73{ 151{
74 unsigned long ps; 152 unsigned long *reg, val;
75 unsigned long iostep; 153 long n;
76 unsigned long nnpt;
77 unsigned long shift;
78
79 switch (page_size) {
80 case 0x1000000:
81 ps = IOST_PS_16M;
82 nnpt = 0; /* one page per segment */
83 shift = 5; /* segment has 16 iopt entries */
84 break;
85
86 case 0x100000:
87 ps = IOST_PS_1M;
88 nnpt = 0; /* one page per segment */
89 shift = 1; /* segment has 256 iopt entries */
90 break;
91
92 case 0x10000:
93 ps = IOST_PS_64K;
94 nnpt = 0x07; /* 8 pages per io page table */
95 shift = 0; /* all entries are used */
96 break;
97
98 case 0x1000:
99 ps = IOST_PS_4K;
100 nnpt = 0x7f; /* 128 pages per io page table */
101 shift = 0; /* all entries are used */
102 break;
103
104 default: /* not a known compile time constant */
105 {
106 /* BUILD_BUG_ON() is not usable here */
107 extern void __get_iost_entry_bad_page_size(void);
108 __get_iost_entry_bad_page_size();
109 }
110 break;
111 }
112 154
113 iostep = iopt_base + 155 reg = iommu->xlate_regs + IOC_IOPT_CacheInvd;
114 /* need 8 bytes per iopte */
115 (((io_address / page_size * 8)
116 /* align io page tables on 4k page boundaries */
117 << shift)
118 /* nnpt+1 pages go into each iopt */
119 & ~(nnpt << 12));
120
121 nnpt++; /* this seems to work, but the documentation is not clear
122 about wether we put nnpt or nnpt-1 into the ioste bits.
123 In theory, this can't work for 4k pages. */
124 return mk_ioste(IOST_VALID_MASK
125 | (iostep & IOST_PT_BASE_MASK)
126 | ((nnpt << 5) & IOST_NNPT_MASK)
127 | (ps & IOST_PS_MASK));
128}
129 156
130/* compute the address of an io pte */ 157 while (n_ptes > 0) {
131static inline unsigned long 158 /* we can invalidate up to 1 << 11 PTEs at once */
132get_ioptep(ioste iost_entry, unsigned long io_address) 159 n = min(n_ptes, 1l << 11);
133{ 160 val = (((n /*- 1*/) << 53) & IOC_IOPT_CacheInvd_NE_Mask)
134 unsigned long iopt_base; 161 | (__pa(pte) & IOC_IOPT_CacheInvd_IOPTE_Mask)
135 unsigned long page_size; 162 | IOC_IOPT_CacheInvd_Busy;
136 unsigned long page_number;
137 unsigned long iopt_offset;
138
139 iopt_base = iost_entry.val & IOST_PT_BASE_MASK;
140 page_size = iost_entry.val & IOST_PS_MASK;
141
142 /* decode page size to compute page number */
143 page_number = (io_address & 0x0fffffff) >> (10 + 2 * page_size);
144 /* page number is an offset into the io page table */
145 iopt_offset = (page_number << 3) & 0x7fff8ul;
146 return iopt_base + iopt_offset;
147}
148 163
149/* compute the tag field of the iopt cache entry */ 164 out_be64(reg, val);
150static inline unsigned long 165 while (in_be64(reg) & IOC_IOPT_CacheInvd_Busy)
151get_ioc_tag(ioste iost_entry, unsigned long io_address) 166 ;
152{
153 unsigned long iopte = get_ioptep(iost_entry, io_address);
154 167
155 return IOPT_VALID_MASK 168 n_ptes -= n;
156 | ((iopte & 0x00000000000000ff8ul) >> 3) 169 pte += n;
157 | ((iopte & 0x0000003fffffc0000ul) >> 9); 170 }
158} 171}
159 172
160/* compute the hashed 6 bit index for the 4-way associative pte cache */ 173static void tce_build_cell(struct iommu_table *tbl, long index, long npages,
161static inline unsigned long 174 unsigned long uaddr, enum dma_data_direction direction)
162get_ioc_hash(ioste iost_entry, unsigned long io_address)
163{ 175{
164 unsigned long iopte = get_ioptep(iost_entry, io_address); 176 int i;
165 177 unsigned long *io_pte, base_pte;
166 return ((iopte & 0x000000000000001f8ul) >> 3) 178 struct iommu_window *window =
167 ^ ((iopte & 0x00000000000020000ul) >> 17) 179 container_of(tbl, struct iommu_window, table);
168 ^ ((iopte & 0x00000000000010000ul) >> 15) 180
169 ^ ((iopte & 0x00000000000008000ul) >> 13) 181 /* implementing proper protection causes problems with the spidernet
170 ^ ((iopte & 0x00000000000004000ul) >> 11) 182 * driver - check mapping directions later, but allow read & write by
171 ^ ((iopte & 0x00000000000002000ul) >> 9) 183 * default for now.*/
172 ^ ((iopte & 0x00000000000001000ul) >> 7); 184#ifdef CELL_IOMMU_STRICT_PROTECTION
185 /* to avoid referencing a global, we use a trick here to setup the
186 * protection bit. "prot" is setup to be 3 fields of 4 bits apprended
187 * together for each of the 3 supported direction values. It is then
188 * shifted left so that the fields matching the desired direction
189 * lands on the appropriate bits, and other bits are masked out.
190 */
191 const unsigned long prot = 0xc48;
192 base_pte =
193 ((prot << (52 + 4 * direction)) & (IOPTE_PP_W | IOPTE_PP_R))
194 | IOPTE_M | IOPTE_SO_RW | (window->ioid & IOPTE_IOID_Mask);
195#else
196 base_pte = IOPTE_PP_W | IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW |
197 (window->ioid & IOPTE_IOID_Mask);
198#endif
199
200 io_pte = (unsigned long *)tbl->it_base + (index - window->pte_offset);
201
202 for (i = 0; i < npages; i++, uaddr += IOMMU_PAGE_SIZE)
203 io_pte[i] = base_pte | (__pa(uaddr) & IOPTE_RPN_Mask);
204
205 mb();
206
207 invalidate_tce_cache(window->iommu, io_pte, npages);
208
209 pr_debug("tce_build_cell(index=%lx,n=%lx,dir=%d,base_pte=%lx)\n",
210 index, npages, direction, base_pte);
173} 211}
174 212
175/* same as above, but pretend that we have a simpler 1-way associative 213static void tce_free_cell(struct iommu_table *tbl, long index, long npages)
176 pte cache with an 8 bit index */
177static inline unsigned long
178get_ioc_hash_1way(ioste iost_entry, unsigned long io_address)
179{ 214{
180 unsigned long iopte = get_ioptep(iost_entry, io_address);
181
182 return ((iopte & 0x000000000000001f8ul) >> 3)
183 ^ ((iopte & 0x00000000000020000ul) >> 17)
184 ^ ((iopte & 0x00000000000010000ul) >> 15)
185 ^ ((iopte & 0x00000000000008000ul) >> 13)
186 ^ ((iopte & 0x00000000000004000ul) >> 11)
187 ^ ((iopte & 0x00000000000002000ul) >> 9)
188 ^ ((iopte & 0x00000000000001000ul) >> 7)
189 ^ ((iopte & 0x0000000000000c000ul) >> 8);
190}
191 215
192static inline ioste 216 int i;
193get_iost_cache(void __iomem *base, unsigned long index) 217 unsigned long *io_pte, pte;
194{ 218 struct iommu_window *window =
195 unsigned long __iomem *p = (base + IOC_ST_CACHE_DIR); 219 container_of(tbl, struct iommu_window, table);
196 return mk_ioste(in_be64(&p[index]));
197}
198 220
199static inline void 221 pr_debug("tce_free_cell(index=%lx,n=%lx)\n", index, npages);
200set_iost_cache(void __iomem *base, unsigned long index, ioste ste)
201{
202 unsigned long __iomem *p = (base + IOC_ST_CACHE_DIR);
203 pr_debug("ioste %02lx was %016lx, store %016lx", index,
204 get_iost_cache(base, index).val, ste.val);
205 out_be64(&p[index], ste.val);
206 pr_debug(" now %016lx\n", get_iost_cache(base, index).val);
207}
208 222
209static inline unsigned long 223#ifdef CELL_IOMMU_REAL_UNMAP
210get_iopt_cache(void __iomem *base, unsigned long index, unsigned long *tag) 224 pte = 0;
211{ 225#else
212 unsigned long __iomem *tags = (void *)(base + IOC_PT_CACHE_DIR); 226 /* spider bridge does PCI reads after freeing - insert a mapping
213 unsigned long __iomem *p = (void *)(base + IOC_PT_CACHE_REG); 227 * to a scratch page instead of an invalid entry */
228 pte = IOPTE_PP_R | IOPTE_M | IOPTE_SO_RW | __pa(window->iommu->pad_page)
229 | (window->ioid & IOPTE_IOID_Mask);
230#endif
214 231
215 *tag = tags[index]; 232 io_pte = (unsigned long *)tbl->it_base + (index - window->pte_offset);
216 rmb();
217 return *p;
218}
219 233
220static inline void 234 for (i = 0; i < npages; i++)
221set_iopt_cache(void __iomem *base, unsigned long index, 235 io_pte[i] = pte;
222 unsigned long tag, unsigned long val) 236
223{ 237 mb();
224 unsigned long __iomem *tags = base + IOC_PT_CACHE_DIR;
225 unsigned long __iomem *p = base + IOC_PT_CACHE_REG;
226 238
227 out_be64(p, val); 239 invalidate_tce_cache(window->iommu, io_pte, npages);
228 out_be64(&tags[index], tag);
229} 240}
230 241
231static inline void 242static irqreturn_t ioc_interrupt(int irq, void *data)
232set_iost_origin(void __iomem *base)
233{ 243{
234 unsigned long __iomem *p = base + IOC_ST_ORIGIN; 244 unsigned long stat;
235 unsigned long origin = IOSTO_ENABLE | IOSTO_SW; 245 struct cbe_iommu *iommu = data;
236 246
237 pr_debug("iost_origin %016lx, now %016lx\n", in_be64(p), origin); 247 stat = in_be64(iommu->xlate_regs + IOC_IO_ExcpStat);
238 out_be64(p, origin); 248
249 /* Might want to rate limit it */
250 printk(KERN_ERR "iommu: DMA exception 0x%016lx\n", stat);
251 printk(KERN_ERR " V=%d, SPF=[%c%c], RW=%s, IOID=0x%04x\n",
252 !!(stat & IOC_IO_ExcpStat_V),
253 (stat & IOC_IO_ExcpStat_SPF_S) ? 'S' : ' ',
254 (stat & IOC_IO_ExcpStat_SPF_P) ? 'P' : ' ',
255 (stat & IOC_IO_ExcpStat_RW_Mask) ? "Read" : "Write",
256 (unsigned int)(stat & IOC_IO_ExcpStat_IOID_Mask));
257 printk(KERN_ERR " page=0x%016lx\n",
258 stat & IOC_IO_ExcpStat_ADDR_Mask);
259
260 /* clear interrupt */
261 stat &= ~IOC_IO_ExcpStat_V;
262 out_be64(iommu->xlate_regs + IOC_IO_ExcpStat, stat);
263
264 return IRQ_HANDLED;
239} 265}
240 266
241static inline void 267static int cell_iommu_find_ioc(int nid, unsigned long *base)
242set_iocmd_config(void __iomem *base)
243{ 268{
244 unsigned long __iomem *p = base + 0xc00; 269 struct device_node *np;
245 unsigned long conf; 270 struct resource r;
271
272 *base = 0;
273
274 /* First look for new style /be nodes */
275 for_each_node_by_name(np, "ioc") {
276 if (of_node_to_nid(np) != nid)
277 continue;
278 if (of_address_to_resource(np, 0, &r)) {
279 printk(KERN_ERR "iommu: can't get address for %s\n",
280 np->full_name);
281 continue;
282 }
283 *base = r.start;
284 of_node_put(np);
285 return 0;
286 }
246 287
247 conf = in_be64(p); 288 /* Ok, let's try the old way */
248 pr_debug("iost_conf %016lx, now %016lx\n", conf, conf | IOCMD_CONF_TE); 289 for_each_node_by_type(np, "cpu") {
249 out_be64(p, conf | IOCMD_CONF_TE); 290 const unsigned int *nidp;
291 const unsigned long *tmp;
292
293 nidp = get_property(np, "node-id", NULL);
294 if (nidp && *nidp == nid) {
295 tmp = get_property(np, "ioc-translation", NULL);
296 if (tmp) {
297 *base = *tmp;
298 of_node_put(np);
299 return 0;
300 }
301 }
302 }
303
304 return -ENODEV;
250} 305}
251 306
252static void enable_mapping(void __iomem *base, void __iomem *mmio_base) 307static void cell_iommu_setup_hardware(struct cbe_iommu *iommu, unsigned long size)
253{ 308{
254 set_iocmd_config(base); 309 struct page *page;
255 set_iost_origin(mmio_base); 310 int ret, i;
256} 311 unsigned long reg, segments, pages_per_segment, ptab_size, n_pte_pages;
312 unsigned long xlate_base;
313 unsigned int virq;
314
315 if (cell_iommu_find_ioc(iommu->nid, &xlate_base))
316 panic("%s: missing IOC register mappings for node %d\n",
317 __FUNCTION__, iommu->nid);
318
319 iommu->xlate_regs = ioremap(xlate_base, IOC_Reg_Size);
320 iommu->cmd_regs = iommu->xlate_regs + IOC_IOCmd_Offset;
321
322 segments = size >> IO_SEGMENT_SHIFT;
323 pages_per_segment = 1ull << IO_PAGENO_BITS;
324
325 pr_debug("%s: iommu[%d]: segments: %lu, pages per segment: %lu\n",
326 __FUNCTION__, iommu->nid, segments, pages_per_segment);
327
328 /* set up the segment table */
329 page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0);
330 BUG_ON(!page);
331 iommu->stab = page_address(page);
332 clear_page(iommu->stab);
333
334 /* ... and the page tables. Since these are contiguous, we can treat
335 * the page tables as one array of ptes, like pSeries does.
336 */
337 ptab_size = segments * pages_per_segment * sizeof(unsigned long);
338 pr_debug("%s: iommu[%d]: ptab_size: %lu, order: %d\n", __FUNCTION__,
339 iommu->nid, ptab_size, get_order(ptab_size));
340 page = alloc_pages_node(iommu->nid, GFP_KERNEL, get_order(ptab_size));
341 BUG_ON(!page);
342
343 iommu->ptab = page_address(page);
344 memset(iommu->ptab, 0, ptab_size);
345
346 /* allocate a bogus page for the end of each mapping */
347 page = alloc_pages_node(iommu->nid, GFP_KERNEL, 0);
348 BUG_ON(!page);
349 iommu->pad_page = page_address(page);
350 clear_page(iommu->pad_page);
351
352 /* number of pages needed for a page table */
353 n_pte_pages = (pages_per_segment *
354 sizeof(unsigned long)) >> IOMMU_PAGE_SHIFT;
355
356 pr_debug("%s: iommu[%d]: stab at %p, ptab at %p, n_pte_pages: %lu\n",
357 __FUNCTION__, iommu->nid, iommu->stab, iommu->ptab,
358 n_pte_pages);
359
360 /* initialise the STEs */
361 reg = IOSTE_V | ((n_pte_pages - 1) << 5);
362
363 if (IOMMU_PAGE_SIZE == 0x1000)
364 reg |= IOSTE_PS_4K;
365 else if (IOMMU_PAGE_SIZE == 0x10000)
366 reg |= IOSTE_PS_64K;
367 else {
368 extern void __unknown_page_size_error(void);
369 __unknown_page_size_error();
370 }
371
372 pr_debug("Setting up IOMMU stab:\n");
373 for (i = 0; i * (1ul << IO_SEGMENT_SHIFT) < size; i++) {
374 iommu->stab[i] = reg |
375 (__pa(iommu->ptab) + n_pte_pages * IOMMU_PAGE_SIZE * i);
376 pr_debug("\t[%d] 0x%016lx\n", i, iommu->stab[i]);
377 }
257 378
258static void iommu_dev_setup_null(struct pci_dev *d) { } 379 /* ensure that the STEs have updated */
259static void iommu_bus_setup_null(struct pci_bus *b) { } 380 mb();
260 381
261struct cell_iommu { 382 /* setup interrupts for the iommu. */
262 unsigned long base; 383 reg = in_be64(iommu->xlate_regs + IOC_IO_ExcpStat);
263 unsigned long mmio_base; 384 out_be64(iommu->xlate_regs + IOC_IO_ExcpStat,
264 void __iomem *mapped_base; 385 reg & ~IOC_IO_ExcpStat_V);
265 void __iomem *mapped_mmio_base; 386 out_be64(iommu->xlate_regs + IOC_IO_ExcpMask,
266}; 387 IOC_IO_ExcpMask_PFE | IOC_IO_ExcpMask_SFE);
267 388
268static struct cell_iommu cell_iommus[NR_CPUS]; 389 virq = irq_create_mapping(NULL,
390 IIC_IRQ_IOEX_ATI | (iommu->nid << IIC_IRQ_NODE_SHIFT));
391 BUG_ON(virq == NO_IRQ);
269 392
270/* initialize the iommu to support a simple linear mapping 393 ret = request_irq(virq, ioc_interrupt, IRQF_DISABLED,
271 * for each DMA window used by any device. For now, we 394 iommu->name, iommu);
272 * happen to know that there is only one DMA window in use, 395 BUG_ON(ret);
273 * starting at iopt_phys_offset. */
274static void cell_do_map_iommu(struct cell_iommu *iommu,
275 unsigned int ioid,
276 unsigned long map_start,
277 unsigned long map_size)
278{
279 unsigned long io_address, real_address;
280 void __iomem *ioc_base, *ioc_mmio_base;
281 ioste ioste;
282 unsigned long index;
283 396
284 /* we pretend the io page table was at a very high address */ 397 /* set the IOC segment table origin register (and turn on the iommu) */
285 const unsigned long fake_iopt = 0x10000000000ul; 398 reg = IOC_IOST_Origin_E | __pa(iommu->stab) | IOC_IOST_Origin_HW;
286 const unsigned long io_page_size = 0x1000000; /* use 16M pages */ 399 out_be64(iommu->xlate_regs + IOC_IOST_Origin, reg);
287 const unsigned long io_segment_size = 0x10000000; /* 256M */ 400 in_be64(iommu->xlate_regs + IOC_IOST_Origin);
288 401
289 ioc_base = iommu->mapped_base; 402 /* turn on IO translation */
290 ioc_mmio_base = iommu->mapped_mmio_base; 403 reg = in_be64(iommu->cmd_regs + IOC_IOCmd_Cfg) | IOC_IOCmd_Cfg_TE;
291 404 out_be64(iommu->cmd_regs + IOC_IOCmd_Cfg, reg);
292 for (real_address = 0, io_address = map_start;
293 io_address <= map_start + map_size;
294 real_address += io_page_size, io_address += io_page_size) {
295 ioste = get_iost_entry(fake_iopt, io_address, io_page_size);
296 if ((real_address % io_segment_size) == 0) /* segment start */
297 set_iost_cache(ioc_mmio_base,
298 io_address >> 28, ioste);
299 index = get_ioc_hash_1way(ioste, io_address);
300 pr_debug("addr %08lx, index %02lx, ioste %016lx\n",
301 io_address, index, ioste.val);
302 set_iopt_cache(ioc_mmio_base,
303 get_ioc_hash_1way(ioste, io_address),
304 get_ioc_tag(ioste, io_address),
305 get_iopt_entry(real_address, ioid, IOPT_PROT_RW));
306 }
307} 405}
308 406
309static void iommu_devnode_setup(struct device_node *d) 407#if 0/* Unused for now */
408static struct iommu_window *find_window(struct cbe_iommu *iommu,
409 unsigned long offset, unsigned long size)
310{ 410{
311 const unsigned int *ioid; 411 struct iommu_window *window;
312 unsigned long map_start, map_size, token;
313 const unsigned long *dma_window;
314 struct cell_iommu *iommu;
315 412
316 ioid = get_property(d, "ioid", NULL); 413 /* todo: check for overlapping (but not equal) windows) */
317 if (!ioid)
318 pr_debug("No ioid entry found !\n");
319 414
320 dma_window = get_property(d, "ibm,dma-window", NULL); 415 list_for_each_entry(window, &(iommu->windows), list) {
321 if (!dma_window) 416 if (window->offset == offset && window->size == size)
322 pr_debug("No ibm,dma-window entry found !\n"); 417 return window;
418 }
323 419
324 map_start = dma_window[1]; 420 return NULL;
325 map_size = dma_window[2]; 421}
326 token = dma_window[0] >> 32; 422#endif
327 423
328 iommu = &cell_iommus[token]; 424static struct iommu_window * __init
425cell_iommu_setup_window(struct cbe_iommu *iommu, struct device_node *np,
426 unsigned long offset, unsigned long size,
427 unsigned long pte_offset)
428{
429 struct iommu_window *window;
430 const unsigned int *ioid;
329 431
330 cell_do_map_iommu(iommu, *ioid, map_start, map_size); 432 ioid = get_property(np, "ioid", NULL);
433 if (ioid == NULL)
434 printk(KERN_WARNING "iommu: missing ioid for %s using 0\n",
435 np->full_name);
436
437 window = kmalloc_node(sizeof(*window), GFP_KERNEL, iommu->nid);
438 BUG_ON(window == NULL);
439
440 window->offset = offset;
441 window->size = size;
442 window->ioid = ioid ? *ioid : 0;
443 window->iommu = iommu;
444 window->pte_offset = pte_offset;
445
446 window->table.it_blocksize = 16;
447 window->table.it_base = (unsigned long)iommu->ptab;
448 window->table.it_index = iommu->nid;
449 window->table.it_offset = (offset >> IOMMU_PAGE_SHIFT) +
450 window->pte_offset;
451 window->table.it_size = size >> IOMMU_PAGE_SHIFT;
452
453 iommu_init_table(&window->table, iommu->nid);
454
455 pr_debug("\tioid %d\n", window->ioid);
456 pr_debug("\tblocksize %ld\n", window->table.it_blocksize);
457 pr_debug("\tbase 0x%016lx\n", window->table.it_base);
458 pr_debug("\toffset 0x%lx\n", window->table.it_offset);
459 pr_debug("\tsize %ld\n", window->table.it_size);
460
461 list_add(&window->list, &iommu->windows);
462
463 if (offset != 0)
464 return window;
465
466 /* We need to map and reserve the first IOMMU page since it's used
467 * by the spider workaround. In theory, we only need to do that when
468 * running on spider but it doesn't really matter.
469 *
470 * This code also assumes that we have a window that starts at 0,
471 * which is the case on all spider based blades.
472 */
473 __set_bit(0, window->table.it_map);
474 tce_build_cell(&window->table, window->table.it_offset, 1,
475 (unsigned long)iommu->pad_page, DMA_TO_DEVICE);
476 window->table.it_hint = window->table.it_blocksize;
477
478 return window;
331} 479}
332 480
333static void iommu_bus_setup(struct pci_bus *b) 481static struct cbe_iommu *cell_iommu_for_node(int nid)
334{ 482{
335 struct device_node *d = (struct device_node *)b->sysdata; 483 int i;
336 iommu_devnode_setup(d);
337}
338 484
485 for (i = 0; i < cbe_nr_iommus; i++)
486 if (iommus[i].nid == nid)
487 return &iommus[i];
488 return NULL;
489}
339 490
340static int cell_map_iommu_hardcoded(int num_nodes) 491static void cell_dma_dev_setup(struct device *dev)
341{ 492{
342 struct cell_iommu *iommu = NULL; 493 struct iommu_window *window;
343 494 struct cbe_iommu *iommu;
344 pr_debug("%s(%d): Using hardcoded defaults\n", __FUNCTION__, __LINE__); 495 struct dev_archdata *archdata = &dev->archdata;
496
497 /* If we run without iommu, no need to do anything */
498 if (pci_dma_ops == &dma_direct_ops)
499 return;
500
501 /* Current implementation uses the first window available in that
502 * node's iommu. We -might- do something smarter later though it may
503 * never be necessary
504 */
505 iommu = cell_iommu_for_node(archdata->numa_node);
506 if (iommu == NULL || list_empty(&iommu->windows)) {
507 printk(KERN_ERR "iommu: missing iommu for %s (node %d)\n",
508 archdata->of_node ? archdata->of_node->full_name : "?",
509 archdata->numa_node);
510 return;
511 }
512 window = list_entry(iommu->windows.next, struct iommu_window, list);
345 513
346 /* node 0 */ 514 archdata->dma_data = &window->table;
347 iommu = &cell_iommus[0]; 515}
348 iommu->mapped_base = ioremap(0x20000511000ul, 0x1000);
349 iommu->mapped_mmio_base = ioremap(0x20000510000ul, 0x1000);
350 516
351 enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base); 517static void cell_pci_dma_dev_setup(struct pci_dev *dev)
518{
519 cell_dma_dev_setup(&dev->dev);
520}
352 521
353 cell_do_map_iommu(iommu, 0x048a, 522static int cell_of_bus_notify(struct notifier_block *nb, unsigned long action,
354 0x20000000ul,0x20000000ul); 523 void *data)
524{
525 struct device *dev = data;
355 526
356 if (num_nodes < 2) 527 /* We are only intereted in device addition */
528 if (action != BUS_NOTIFY_ADD_DEVICE)
357 return 0; 529 return 0;
358 530
359 /* node 1 */ 531 /* We use the PCI DMA ops */
360 iommu = &cell_iommus[1]; 532 dev->archdata.dma_ops = pci_dma_ops;
361 iommu->mapped_base = ioremap(0x30000511000ul, 0x1000);
362 iommu->mapped_mmio_base = ioremap(0x30000510000ul, 0x1000);
363
364 enable_mapping(iommu->mapped_base, iommu->mapped_mmio_base);
365 533
366 cell_do_map_iommu(iommu, 0x048a, 534 cell_dma_dev_setup(dev);
367 0x20000000,0x20000000ul);
368 535
369 return 0; 536 return 0;
370} 537}
371 538
539static struct notifier_block cell_of_bus_notifier = {
540 .notifier_call = cell_of_bus_notify
541};
372 542
373static int cell_map_iommu(void) 543static int __init cell_iommu_get_window(struct device_node *np,
544 unsigned long *base,
545 unsigned long *size)
374{ 546{
375 unsigned int num_nodes = 0; 547 const void *dma_window;
376 const unsigned int *node_id; 548 unsigned long index;
377 const unsigned long *base, *mmio_base;
378 struct device_node *dn;
379 struct cell_iommu *iommu = NULL;
380
381 /* determine number of nodes (=iommus) */
382 pr_debug("%s(%d): determining number of nodes...", __FUNCTION__, __LINE__);
383 for(dn = of_find_node_by_type(NULL, "cpu");
384 dn;
385 dn = of_find_node_by_type(dn, "cpu")) {
386 node_id = get_property(dn, "node-id", NULL);
387
388 if (num_nodes < *node_id)
389 num_nodes = *node_id;
390 }
391
392 num_nodes++;
393 pr_debug("%i found.\n", num_nodes);
394 549
395 /* map the iommu registers for each node */ 550 /* Use ibm,dma-window if available, else, hard code ! */
396 pr_debug("%s(%d): Looping through nodes\n", __FUNCTION__, __LINE__); 551 dma_window = get_property(np, "ibm,dma-window", NULL);
397 for(dn = of_find_node_by_type(NULL, "cpu"); 552 if (dma_window == NULL) {
398 dn; 553 *base = 0;
399 dn = of_find_node_by_type(dn, "cpu")) { 554 *size = 0x80000000u;
555 return -ENODEV;
556 }
400 557
401 node_id = get_property(dn, "node-id", NULL); 558 of_parse_dma_window(np, dma_window, &index, base, size);
402 base = get_property(dn, "ioc-cache", NULL); 559 return 0;
403 mmio_base = get_property(dn, "ioc-translation", NULL); 560}
404 561
405 if (!base || !mmio_base || !node_id) 562static void __init cell_iommu_init_one(struct device_node *np, unsigned long offset)
406 return cell_map_iommu_hardcoded(num_nodes); 563{
564 struct cbe_iommu *iommu;
565 unsigned long base, size;
566 int nid, i;
567
568 /* Get node ID */
569 nid = of_node_to_nid(np);
570 if (nid < 0) {
571 printk(KERN_ERR "iommu: failed to get node for %s\n",
572 np->full_name);
573 return;
574 }
575 pr_debug("iommu: setting up iommu for node %d (%s)\n",
576 nid, np->full_name);
577
578 /* XXX todo: If we can have multiple windows on the same IOMMU, which
579 * isn't the case today, we probably want here to check wether the
580 * iommu for that node is already setup.
581 * However, there might be issue with getting the size right so let's
582 * ignore that for now. We might want to completely get rid of the
583 * multiple window support since the cell iommu supports per-page ioids
584 */
585
586 if (cbe_nr_iommus >= NR_IOMMUS) {
587 printk(KERN_ERR "iommu: too many IOMMUs detected ! (%s)\n",
588 np->full_name);
589 return;
590 }
407 591
408 iommu = &cell_iommus[*node_id]; 592 /* Init base fields */
409 iommu->base = *base; 593 i = cbe_nr_iommus++;
410 iommu->mmio_base = *mmio_base; 594 iommu = &iommus[i];
595 iommu->stab = 0;
596 iommu->nid = nid;
597 snprintf(iommu->name, sizeof(iommu->name), "iommu%d", i);
598 INIT_LIST_HEAD(&iommu->windows);
411 599
412 iommu->mapped_base = ioremap(*base, 0x1000); 600 /* Obtain a window for it */
413 iommu->mapped_mmio_base = ioremap(*mmio_base, 0x1000); 601 cell_iommu_get_window(np, &base, &size);
414 602
415 enable_mapping(iommu->mapped_base, 603 pr_debug("\ttranslating window 0x%lx...0x%lx\n",
416 iommu->mapped_mmio_base); 604 base, base + size - 1);
417 605
418 /* everything else will be done in iommu_bus_setup */ 606 /* Initialize the hardware */
419 } 607 cell_iommu_setup_hardware(iommu, size);
420 608
421 return 1; 609 /* Setup the iommu_table */
610 cell_iommu_setup_window(iommu, np, base, size,
611 offset >> IOMMU_PAGE_SHIFT);
422} 612}
423 613
424static void *cell_alloc_coherent(struct device *hwdev, size_t size, 614static void __init cell_disable_iommus(void)
425 dma_addr_t *dma_handle, gfp_t flag)
426{ 615{
427 void *ret; 616 int node;
428 617 unsigned long base, val;
429 ret = (void *)__get_free_pages(flag, get_order(size)); 618 void __iomem *xregs, *cregs;
430 if (ret != NULL) { 619
431 memset(ret, 0, size); 620 /* Make sure IOC translation is disabled on all nodes */
432 *dma_handle = virt_to_abs(ret) | CELL_DMA_VALID; 621 for_each_online_node(node) {
622 if (cell_iommu_find_ioc(node, &base))
623 continue;
624 xregs = ioremap(base, IOC_Reg_Size);
625 if (xregs == NULL)
626 continue;
627 cregs = xregs + IOC_IOCmd_Offset;
628
629 pr_debug("iommu: cleaning up iommu on node %d\n", node);
630
631 out_be64(xregs + IOC_IOST_Origin, 0);
632 (void)in_be64(xregs + IOC_IOST_Origin);
633 val = in_be64(cregs + IOC_IOCmd_Cfg);
634 val &= ~IOC_IOCmd_Cfg_TE;
635 out_be64(cregs + IOC_IOCmd_Cfg, val);
636 (void)in_be64(cregs + IOC_IOCmd_Cfg);
637
638 iounmap(xregs);
433 } 639 }
434 return ret;
435} 640}
436 641
437static void cell_free_coherent(struct device *hwdev, size_t size, 642static int __init cell_iommu_init_disabled(void)
438 void *vaddr, dma_addr_t dma_handle)
439{ 643{
440 free_pages((unsigned long)vaddr, get_order(size)); 644 struct device_node *np = NULL;
441} 645 unsigned long base = 0, size;
646
647 /* When no iommu is present, we use direct DMA ops */
648 pci_dma_ops = &dma_direct_ops;
649
650 /* First make sure all IOC translation is turned off */
651 cell_disable_iommus();
652
653 /* If we have no Axon, we set up the spider DMA magic offset */
654 if (of_find_node_by_name(NULL, "axon") == NULL)
655 dma_direct_offset = SPIDER_DMA_OFFSET;
656
657 /* Now we need to check to see where the memory is mapped
658 * in PCI space. We assume that all busses use the same dma
659 * window which is always the case so far on Cell, thus we
660 * pick up the first pci-internal node we can find and check
661 * the DMA window from there.
662 */
663 for_each_node_by_name(np, "axon") {
664 if (np->parent == NULL || np->parent->parent != NULL)
665 continue;
666 if (cell_iommu_get_window(np, &base, &size) == 0)
667 break;
668 }
669 if (np == NULL) {
670 for_each_node_by_name(np, "pci-internal") {
671 if (np->parent == NULL || np->parent->parent != NULL)
672 continue;
673 if (cell_iommu_get_window(np, &base, &size) == 0)
674 break;
675 }
676 }
677 of_node_put(np);
678
679 /* If we found a DMA window, we check if it's big enough to enclose
680 * all of physical memory. If not, we force enable IOMMU
681 */
682 if (np && size < lmb_end_of_DRAM()) {
683 printk(KERN_WARNING "iommu: force-enabled, dma window"
684 " (%ldMB) smaller than total memory (%ldMB)\n",
685 size >> 20, lmb_end_of_DRAM() >> 20);
686 return -ENODEV;
687 }
442 688
443static dma_addr_t cell_map_single(struct device *hwdev, void *ptr, 689 dma_direct_offset += base;
444 size_t size, enum dma_data_direction direction)
445{
446 return virt_to_abs(ptr) | CELL_DMA_VALID;
447}
448 690
449static void cell_unmap_single(struct device *hwdev, dma_addr_t dma_addr, 691 printk("iommu: disabled, direct DMA offset is 0x%lx\n",
450 size_t size, enum dma_data_direction direction) 692 dma_direct_offset);
451{ 693
694 return 0;
452} 695}
453 696
454static int cell_map_sg(struct device *hwdev, struct scatterlist *sg, 697static int __init cell_iommu_init(void)
455 int nents, enum dma_data_direction direction)
456{ 698{
457 int i; 699 struct device_node *np;
700
701 if (!machine_is(cell))
702 return -ENODEV;
703
704 /* If IOMMU is disabled or we have little enough RAM to not need
705 * to enable it, we setup a direct mapping.
706 *
707 * Note: should we make sure we have the IOMMU actually disabled ?
708 */
709 if (iommu_is_off ||
710 (!iommu_force_on && lmb_end_of_DRAM() <= 0x80000000ull))
711 if (cell_iommu_init_disabled() == 0)
712 goto bail;
713
714 /* Setup various ppc_md. callbacks */
715 ppc_md.pci_dma_dev_setup = cell_pci_dma_dev_setup;
716 ppc_md.tce_build = tce_build_cell;
717 ppc_md.tce_free = tce_free_cell;
718
719 /* Create an iommu for each /axon node. */
720 for_each_node_by_name(np, "axon") {
721 if (np->parent == NULL || np->parent->parent != NULL)
722 continue;
723 cell_iommu_init_one(np, 0);
724 }
458 725
459 for (i = 0; i < nents; i++, sg++) { 726 /* Create an iommu for each toplevel /pci-internal node for
460 sg->dma_address = (page_to_phys(sg->page) + sg->offset) 727 * old hardware/firmware
461 | CELL_DMA_VALID; 728 */
462 sg->dma_length = sg->length; 729 for_each_node_by_name(np, "pci-internal") {
730 if (np->parent == NULL || np->parent->parent != NULL)
731 continue;
732 cell_iommu_init_one(np, SPIDER_DMA_OFFSET);
463 } 733 }
464 734
465 return nents; 735 /* Setup default PCI iommu ops */
466} 736 pci_dma_ops = &dma_iommu_ops;
467 737
468static void cell_unmap_sg(struct device *hwdev, struct scatterlist *sg, 738 bail:
469 int nents, enum dma_data_direction direction) 739 /* Register callbacks on OF platform device addition/removal
470{ 740 * to handle linking them to the right DMA operations
471} 741 */
742 bus_register_notifier(&of_platform_bus_type, &cell_of_bus_notifier);
472 743
473static int cell_dma_supported(struct device *dev, u64 mask) 744 return 0;
474{
475 return mask < 0x100000000ull;
476} 745}
746arch_initcall(cell_iommu_init);
477 747
478static struct dma_mapping_ops cell_iommu_ops = {
479 .alloc_coherent = cell_alloc_coherent,
480 .free_coherent = cell_free_coherent,
481 .map_single = cell_map_single,
482 .unmap_single = cell_unmap_single,
483 .map_sg = cell_map_sg,
484 .unmap_sg = cell_unmap_sg,
485 .dma_supported = cell_dma_supported,
486};
487
488void cell_init_iommu(void)
489{
490 int setup_bus = 0;
491
492 if (of_find_node_by_path("/mambo")) {
493 pr_info("Not using iommu on systemsim\n");
494 } else {
495
496 if (!(of_chosen &&
497 get_property(of_chosen, "linux,iommu-off", NULL)))
498 setup_bus = cell_map_iommu();
499
500 if (setup_bus) {
501 pr_debug("%s: IOMMU mapping activated\n", __FUNCTION__);
502 ppc_md.iommu_dev_setup = iommu_dev_setup_null;
503 ppc_md.iommu_bus_setup = iommu_bus_setup;
504 } else {
505 pr_debug("%s: IOMMU mapping activated, "
506 "no device action necessary\n", __FUNCTION__);
507 /* Direct I/O, IOMMU off */
508 ppc_md.iommu_dev_setup = iommu_dev_setup_null;
509 ppc_md.iommu_bus_setup = iommu_bus_setup_null;
510 }
511 }
512
513 pci_dma_ops = cell_iommu_ops;
514}
diff --git a/arch/powerpc/platforms/cell/iommu.h b/arch/powerpc/platforms/cell/iommu.h
deleted file mode 100644
index 490d77abfe85..000000000000
--- a/arch/powerpc/platforms/cell/iommu.h
+++ /dev/null
@@ -1,65 +0,0 @@
1#ifndef CELL_IOMMU_H
2#define CELL_IOMMU_H
3
4/* some constants */
5enum {
6 /* segment table entries */
7 IOST_VALID_MASK = 0x8000000000000000ul,
8 IOST_TAG_MASK = 0x3000000000000000ul,
9 IOST_PT_BASE_MASK = 0x000003fffffff000ul,
10 IOST_NNPT_MASK = 0x0000000000000fe0ul,
11 IOST_PS_MASK = 0x000000000000000ful,
12
13 IOST_PS_4K = 0x1,
14 IOST_PS_64K = 0x3,
15 IOST_PS_1M = 0x5,
16 IOST_PS_16M = 0x7,
17
18 /* iopt tag register */
19 IOPT_VALID_MASK = 0x0000000200000000ul,
20 IOPT_TAG_MASK = 0x00000001fffffffful,
21
22 /* iopt cache register */
23 IOPT_PROT_MASK = 0xc000000000000000ul,
24 IOPT_PROT_NONE = 0x0000000000000000ul,
25 IOPT_PROT_READ = 0x4000000000000000ul,
26 IOPT_PROT_WRITE = 0x8000000000000000ul,
27 IOPT_PROT_RW = 0xc000000000000000ul,
28 IOPT_COHERENT = 0x2000000000000000ul,
29
30 IOPT_ORDER_MASK = 0x1800000000000000ul,
31 /* order access to same IOID/VC on same address */
32 IOPT_ORDER_ADDR = 0x0800000000000000ul,
33 /* similar, but only after a write access */
34 IOPT_ORDER_WRITES = 0x1000000000000000ul,
35 /* Order all accesses to same IOID/VC */
36 IOPT_ORDER_VC = 0x1800000000000000ul,
37
38 IOPT_RPN_MASK = 0x000003fffffff000ul,
39 IOPT_HINT_MASK = 0x0000000000000800ul,
40 IOPT_IOID_MASK = 0x00000000000007fful,
41
42 IOSTO_ENABLE = 0x8000000000000000ul,
43 IOSTO_ORIGIN = 0x000003fffffff000ul,
44 IOSTO_HW = 0x0000000000000800ul,
45 IOSTO_SW = 0x0000000000000400ul,
46
47 IOCMD_CONF_TE = 0x0000800000000000ul,
48
49 /* memory mapped registers */
50 IOC_PT_CACHE_DIR = 0x000,
51 IOC_ST_CACHE_DIR = 0x800,
52 IOC_PT_CACHE_REG = 0x910,
53 IOC_ST_ORIGIN = 0x918,
54 IOC_CONF = 0x930,
55
56 /* The high bit needs to be set on every DMA address,
57 only 2GB are addressable */
58 CELL_DMA_VALID = 0x80000000,
59 CELL_DMA_MASK = 0x7fffffff,
60};
61
62
63void cell_init_iommu(void);
64
65#endif
diff --git a/arch/powerpc/platforms/cell/pervasive.c b/arch/powerpc/platforms/cell/pervasive.c
index 9f2e4ed20a57..8c20f0fb8651 100644
--- a/arch/powerpc/platforms/cell/pervasive.c
+++ b/arch/powerpc/platforms/cell/pervasive.c
@@ -38,32 +38,25 @@
38#include "pervasive.h" 38#include "pervasive.h"
39#include "cbe_regs.h" 39#include "cbe_regs.h"
40 40
41static DEFINE_SPINLOCK(cbe_pervasive_lock); 41static void cbe_power_save(void)
42
43static void __init cbe_enable_pause_zero(void)
44{ 42{
45 unsigned long thread_switch_control; 43 unsigned long ctrl, thread_switch_control;
46 unsigned long temp_register;
47 struct cbe_pmd_regs __iomem *pregs;
48
49 spin_lock_irq(&cbe_pervasive_lock);
50 pregs = cbe_get_cpu_pmd_regs(smp_processor_id());
51 if (pregs == NULL)
52 goto out;
53 44
54 pr_debug("Power Management: CPU %d\n", smp_processor_id()); 45 /*
55 46 * We need to hard disable interrupts, but we also need to mark them
56 /* Enable Pause(0) control bit */ 47 * hard disabled in the PACA so that the local_irq_enable() done by
57 temp_register = in_be64(&pregs->pm_control); 48 * our caller upon return propertly hard enables.
49 */
50 hard_irq_disable();
51 get_paca()->hard_enabled = 0;
58 52
59 out_be64(&pregs->pm_control, 53 ctrl = mfspr(SPRN_CTRLF);
60 temp_register | CBE_PMD_PAUSE_ZERO_CONTROL);
61 54
62 /* Enable DEC and EE interrupt request */ 55 /* Enable DEC and EE interrupt request */
63 thread_switch_control = mfspr(SPRN_TSC_CELL); 56 thread_switch_control = mfspr(SPRN_TSC_CELL);
64 thread_switch_control |= TSC_CELL_EE_ENABLE | TSC_CELL_EE_BOOST; 57 thread_switch_control |= TSC_CELL_EE_ENABLE | TSC_CELL_EE_BOOST;
65 58
66 switch ((mfspr(SPRN_CTRLF) & CTRL_CT)) { 59 switch (ctrl & CTRL_CT) {
67 case CTRL_CT0: 60 case CTRL_CT0:
68 thread_switch_control |= TSC_CELL_DEC_ENABLE_0; 61 thread_switch_control |= TSC_CELL_DEC_ENABLE_0;
69 break; 62 break;
@@ -75,58 +68,21 @@ static void __init cbe_enable_pause_zero(void)
75 __FUNCTION__); 68 __FUNCTION__);
76 break; 69 break;
77 } 70 }
78
79 mtspr(SPRN_TSC_CELL, thread_switch_control); 71 mtspr(SPRN_TSC_CELL, thread_switch_control);
80 72
81out: 73 /*
82 spin_unlock_irq(&cbe_pervasive_lock); 74 * go into low thread priority, medium priority will be
83} 75 * restored for us after wake-up.
84 76 */
85static void cbe_idle(void) 77 HMT_low();
86{
87 unsigned long ctrl;
88 78
89 /* Why do we do that on every idle ? Couldn't that be done once for 79 /*
90 * all or do we lose the state some way ? Also, the pm_control 80 * atomically disable thread execution and runlatch.
91 * register setting, that can't be set once at boot ? We really want 81 * External and Decrementer exceptions are still handled when the
92 * to move that away in order to implement a simple powersave 82 * thread is disabled but now enter in cbe_system_reset_exception()
93 */ 83 */
94 cbe_enable_pause_zero(); 84 ctrl &= ~(CTRL_RUNLATCH | CTRL_TE);
95 85 mtspr(SPRN_CTRLT, ctrl);
96 while (1) {
97 if (!need_resched()) {
98 local_irq_disable();
99 while (!need_resched()) {
100 /* go into low thread priority */
101 HMT_low();
102
103 /*
104 * atomically disable thread execution
105 * and runlatch.
106 * External and Decrementer exceptions
107 * are still handled when the thread
108 * is disabled but now enter in
109 * cbe_system_reset_exception()
110 */
111 ctrl = mfspr(SPRN_CTRLF);
112 ctrl &= ~(CTRL_RUNLATCH | CTRL_TE);
113 mtspr(SPRN_CTRLT, ctrl);
114 }
115 /* restore thread prio */
116 HMT_medium();
117 local_irq_enable();
118 }
119
120 /*
121 * turn runlatch on again before scheduling the
122 * process we just woke up
123 */
124 ppc64_runlatch_on();
125
126 preempt_enable_no_resched();
127 schedule();
128 preempt_disable();
129 }
130} 86}
131 87
132static int cbe_system_reset_exception(struct pt_regs *regs) 88static int cbe_system_reset_exception(struct pt_regs *regs)
@@ -158,9 +114,20 @@ static int cbe_system_reset_exception(struct pt_regs *regs)
158 114
159void __init cbe_pervasive_init(void) 115void __init cbe_pervasive_init(void)
160{ 116{
117 int cpu;
161 if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO)) 118 if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO))
162 return; 119 return;
163 120
164 ppc_md.idle_loop = cbe_idle; 121 for_each_possible_cpu(cpu) {
122 struct cbe_pmd_regs __iomem *regs = cbe_get_cpu_pmd_regs(cpu);
123 if (!regs)
124 continue;
125
126 /* Enable Pause(0) control bit */
127 out_be64(&regs->pmcr, in_be64(&regs->pmcr) |
128 CBE_PMD_PAUSE_ZERO_CONTROL);
129 }
130
131 ppc_md.power_save = cbe_power_save;
165 ppc_md.system_reset_exception = cbe_system_reset_exception; 132 ppc_md.system_reset_exception = cbe_system_reset_exception;
166} 133}
diff --git a/arch/powerpc/platforms/cell/pmu.c b/arch/powerpc/platforms/cell/pmu.c
new file mode 100644
index 000000000000..99c612025e8f
--- /dev/null
+++ b/arch/powerpc/platforms/cell/pmu.c
@@ -0,0 +1,429 @@
1/*
2 * Cell Broadband Engine Performance Monitor
3 *
4 * (C) Copyright IBM Corporation 2001,2006
5 *
6 * Author:
7 * David Erb (djerb@us.ibm.com)
8 * Kevin Corry (kevcorry@us.ibm.com)
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
13 * any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25#include <linux/interrupt.h>
26#include <linux/types.h>
27#include <asm/io.h>
28#include <asm/irq_regs.h>
29#include <asm/machdep.h>
30#include <asm/pmc.h>
31#include <asm/reg.h>
32#include <asm/spu.h>
33
34#include "cbe_regs.h"
35#include "interrupt.h"
36
37/*
38 * When writing to write-only mmio addresses, save a shadow copy. All of the
39 * registers are 32-bit, but stored in the upper-half of a 64-bit field in
40 * pmd_regs.
41 */
42
43#define WRITE_WO_MMIO(reg, x) \
44 do { \
45 u32 _x = (x); \
46 struct cbe_pmd_regs __iomem *pmd_regs; \
47 struct cbe_pmd_shadow_regs *shadow_regs; \
48 pmd_regs = cbe_get_cpu_pmd_regs(cpu); \
49 shadow_regs = cbe_get_cpu_pmd_shadow_regs(cpu); \
50 out_be64(&(pmd_regs->reg), (((u64)_x) << 32)); \
51 shadow_regs->reg = _x; \
52 } while (0)
53
54#define READ_SHADOW_REG(val, reg) \
55 do { \
56 struct cbe_pmd_shadow_regs *shadow_regs; \
57 shadow_regs = cbe_get_cpu_pmd_shadow_regs(cpu); \
58 (val) = shadow_regs->reg; \
59 } while (0)
60
61#define READ_MMIO_UPPER32(val, reg) \
62 do { \
63 struct cbe_pmd_regs __iomem *pmd_regs; \
64 pmd_regs = cbe_get_cpu_pmd_regs(cpu); \
65 (val) = (u32)(in_be64(&pmd_regs->reg) >> 32); \
66 } while (0)
67
68/*
69 * Physical counter registers.
70 * Each physical counter can act as one 32-bit counter or two 16-bit counters.
71 */
72
73u32 cbe_read_phys_ctr(u32 cpu, u32 phys_ctr)
74{
75 u32 val_in_latch, val = 0;
76
77 if (phys_ctr < NR_PHYS_CTRS) {
78 READ_SHADOW_REG(val_in_latch, counter_value_in_latch);
79
80 /* Read the latch or the actual counter, whichever is newer. */
81 if (val_in_latch & (1 << phys_ctr)) {
82 READ_SHADOW_REG(val, pm_ctr[phys_ctr]);
83 } else {
84 READ_MMIO_UPPER32(val, pm_ctr[phys_ctr]);
85 }
86 }
87
88 return val;
89}
90EXPORT_SYMBOL_GPL(cbe_read_phys_ctr);
91
92void cbe_write_phys_ctr(u32 cpu, u32 phys_ctr, u32 val)
93{
94 struct cbe_pmd_shadow_regs *shadow_regs;
95 u32 pm_ctrl;
96
97 if (phys_ctr < NR_PHYS_CTRS) {
98 /* Writing to a counter only writes to a hardware latch.
99 * The new value is not propagated to the actual counter
100 * until the performance monitor is enabled.
101 */
102 WRITE_WO_MMIO(pm_ctr[phys_ctr], val);
103
104 pm_ctrl = cbe_read_pm(cpu, pm_control);
105 if (pm_ctrl & CBE_PM_ENABLE_PERF_MON) {
106 /* The counters are already active, so we need to
107 * rewrite the pm_control register to "re-enable"
108 * the PMU.
109 */
110 cbe_write_pm(cpu, pm_control, pm_ctrl);
111 } else {
112 shadow_regs = cbe_get_cpu_pmd_shadow_regs(cpu);
113 shadow_regs->counter_value_in_latch |= (1 << phys_ctr);
114 }
115 }
116}
117EXPORT_SYMBOL_GPL(cbe_write_phys_ctr);
118
119/*
120 * "Logical" counter registers.
121 * These will read/write 16-bits or 32-bits depending on the
122 * current size of the counter. Counters 4 - 7 are always 16-bit.
123 */
124
125u32 cbe_read_ctr(u32 cpu, u32 ctr)
126{
127 u32 val;
128 u32 phys_ctr = ctr & (NR_PHYS_CTRS - 1);
129
130 val = cbe_read_phys_ctr(cpu, phys_ctr);
131
132 if (cbe_get_ctr_size(cpu, phys_ctr) == 16)
133 val = (ctr < NR_PHYS_CTRS) ? (val >> 16) : (val & 0xffff);
134
135 return val;
136}
137EXPORT_SYMBOL_GPL(cbe_read_ctr);
138
139void cbe_write_ctr(u32 cpu, u32 ctr, u32 val)
140{
141 u32 phys_ctr;
142 u32 phys_val;
143
144 phys_ctr = ctr & (NR_PHYS_CTRS - 1);
145
146 if (cbe_get_ctr_size(cpu, phys_ctr) == 16) {
147 phys_val = cbe_read_phys_ctr(cpu, phys_ctr);
148
149 if (ctr < NR_PHYS_CTRS)
150 val = (val << 16) | (phys_val & 0xffff);
151 else
152 val = (val & 0xffff) | (phys_val & 0xffff0000);
153 }
154
155 cbe_write_phys_ctr(cpu, phys_ctr, val);
156}
157EXPORT_SYMBOL_GPL(cbe_write_ctr);
158
159/*
160 * Counter-control registers.
161 * Each "logical" counter has a corresponding control register.
162 */
163
164u32 cbe_read_pm07_control(u32 cpu, u32 ctr)
165{
166 u32 pm07_control = 0;
167
168 if (ctr < NR_CTRS)
169 READ_SHADOW_REG(pm07_control, pm07_control[ctr]);
170
171 return pm07_control;
172}
173EXPORT_SYMBOL_GPL(cbe_read_pm07_control);
174
175void cbe_write_pm07_control(u32 cpu, u32 ctr, u32 val)
176{
177 if (ctr < NR_CTRS)
178 WRITE_WO_MMIO(pm07_control[ctr], val);
179}
180EXPORT_SYMBOL_GPL(cbe_write_pm07_control);
181
182/*
183 * Other PMU control registers. Most of these are write-only.
184 */
185
186u32 cbe_read_pm(u32 cpu, enum pm_reg_name reg)
187{
188 u32 val = 0;
189
190 switch (reg) {
191 case group_control:
192 READ_SHADOW_REG(val, group_control);
193 break;
194
195 case debug_bus_control:
196 READ_SHADOW_REG(val, debug_bus_control);
197 break;
198
199 case trace_address:
200 READ_MMIO_UPPER32(val, trace_address);
201 break;
202
203 case ext_tr_timer:
204 READ_SHADOW_REG(val, ext_tr_timer);
205 break;
206
207 case pm_status:
208 READ_MMIO_UPPER32(val, pm_status);
209 break;
210
211 case pm_control:
212 READ_SHADOW_REG(val, pm_control);
213 break;
214
215 case pm_interval:
216 READ_SHADOW_REG(val, pm_interval);
217 break;
218
219 case pm_start_stop:
220 READ_SHADOW_REG(val, pm_start_stop);
221 break;
222 }
223
224 return val;
225}
226EXPORT_SYMBOL_GPL(cbe_read_pm);
227
228void cbe_write_pm(u32 cpu, enum pm_reg_name reg, u32 val)
229{
230 switch (reg) {
231 case group_control:
232 WRITE_WO_MMIO(group_control, val);
233 break;
234
235 case debug_bus_control:
236 WRITE_WO_MMIO(debug_bus_control, val);
237 break;
238
239 case trace_address:
240 WRITE_WO_MMIO(trace_address, val);
241 break;
242
243 case ext_tr_timer:
244 WRITE_WO_MMIO(ext_tr_timer, val);
245 break;
246
247 case pm_status:
248 WRITE_WO_MMIO(pm_status, val);
249 break;
250
251 case pm_control:
252 WRITE_WO_MMIO(pm_control, val);
253 break;
254
255 case pm_interval:
256 WRITE_WO_MMIO(pm_interval, val);
257 break;
258
259 case pm_start_stop:
260 WRITE_WO_MMIO(pm_start_stop, val);
261 break;
262 }
263}
264EXPORT_SYMBOL_GPL(cbe_write_pm);
265
266/*
267 * Get/set the size of a physical counter to either 16 or 32 bits.
268 */
269
270u32 cbe_get_ctr_size(u32 cpu, u32 phys_ctr)
271{
272 u32 pm_ctrl, size = 0;
273
274 if (phys_ctr < NR_PHYS_CTRS) {
275 pm_ctrl = cbe_read_pm(cpu, pm_control);
276 size = (pm_ctrl & CBE_PM_16BIT_CTR(phys_ctr)) ? 16 : 32;
277 }
278
279 return size;
280}
281EXPORT_SYMBOL_GPL(cbe_get_ctr_size);
282
283void cbe_set_ctr_size(u32 cpu, u32 phys_ctr, u32 ctr_size)
284{
285 u32 pm_ctrl;
286
287 if (phys_ctr < NR_PHYS_CTRS) {
288 pm_ctrl = cbe_read_pm(cpu, pm_control);
289 switch (ctr_size) {
290 case 16:
291 pm_ctrl |= CBE_PM_16BIT_CTR(phys_ctr);
292 break;
293
294 case 32:
295 pm_ctrl &= ~CBE_PM_16BIT_CTR(phys_ctr);
296 break;
297 }
298 cbe_write_pm(cpu, pm_control, pm_ctrl);
299 }
300}
301EXPORT_SYMBOL_GPL(cbe_set_ctr_size);
302
303/*
304 * Enable/disable the entire performance monitoring unit.
305 * When we enable the PMU, all pending writes to counters get committed.
306 */
307
308void cbe_enable_pm(u32 cpu)
309{
310 struct cbe_pmd_shadow_regs *shadow_regs;
311 u32 pm_ctrl;
312
313 shadow_regs = cbe_get_cpu_pmd_shadow_regs(cpu);
314 shadow_regs->counter_value_in_latch = 0;
315
316 pm_ctrl = cbe_read_pm(cpu, pm_control) | CBE_PM_ENABLE_PERF_MON;
317 cbe_write_pm(cpu, pm_control, pm_ctrl);
318}
319EXPORT_SYMBOL_GPL(cbe_enable_pm);
320
321void cbe_disable_pm(u32 cpu)
322{
323 u32 pm_ctrl;
324 pm_ctrl = cbe_read_pm(cpu, pm_control) & ~CBE_PM_ENABLE_PERF_MON;
325 cbe_write_pm(cpu, pm_control, pm_ctrl);
326}
327EXPORT_SYMBOL_GPL(cbe_disable_pm);
328
329/*
330 * Reading from the trace_buffer.
331 * The trace buffer is two 64-bit registers. Reading from
332 * the second half automatically increments the trace_address.
333 */
334
335void cbe_read_trace_buffer(u32 cpu, u64 *buf)
336{
337 struct cbe_pmd_regs __iomem *pmd_regs = cbe_get_cpu_pmd_regs(cpu);
338
339 *buf++ = in_be64(&pmd_regs->trace_buffer_0_63);
340 *buf++ = in_be64(&pmd_regs->trace_buffer_64_127);
341}
342EXPORT_SYMBOL_GPL(cbe_read_trace_buffer);
343
344/*
345 * Enabling/disabling interrupts for the entire performance monitoring unit.
346 */
347
348u32 cbe_query_pm_interrupts(u32 cpu)
349{
350 return cbe_read_pm(cpu, pm_status);
351}
352EXPORT_SYMBOL_GPL(cbe_query_pm_interrupts);
353
354u32 cbe_clear_pm_interrupts(u32 cpu)
355{
356 /* Reading pm_status clears the interrupt bits. */
357 return cbe_query_pm_interrupts(cpu);
358}
359EXPORT_SYMBOL_GPL(cbe_clear_pm_interrupts);
360
361void cbe_enable_pm_interrupts(u32 cpu, u32 thread, u32 mask)
362{
363 /* Set which node and thread will handle the next interrupt. */
364 iic_set_interrupt_routing(cpu, thread, 0);
365
366 /* Enable the interrupt bits in the pm_status register. */
367 if (mask)
368 cbe_write_pm(cpu, pm_status, mask);
369}
370EXPORT_SYMBOL_GPL(cbe_enable_pm_interrupts);
371
372void cbe_disable_pm_interrupts(u32 cpu)
373{
374 cbe_clear_pm_interrupts(cpu);
375 cbe_write_pm(cpu, pm_status, 0);
376}
377EXPORT_SYMBOL_GPL(cbe_disable_pm_interrupts);
378
379static irqreturn_t cbe_pm_irq(int irq, void *dev_id)
380{
381 perf_irq(get_irq_regs());
382 return IRQ_HANDLED;
383}
384
385int __init cbe_init_pm_irq(void)
386{
387 unsigned int irq;
388 int rc, node;
389
390 for_each_node(node) {
391 irq = irq_create_mapping(NULL, IIC_IRQ_IOEX_PMI |
392 (node << IIC_IRQ_NODE_SHIFT));
393 if (irq == NO_IRQ) {
394 printk("ERROR: Unable to allocate irq for node %d\n",
395 node);
396 return -EINVAL;
397 }
398
399 rc = request_irq(irq, cbe_pm_irq,
400 IRQF_DISABLED, "cbe-pmu-0", NULL);
401 if (rc) {
402 printk("ERROR: Request for irq on node %d failed\n",
403 node);
404 return rc;
405 }
406 }
407
408 return 0;
409}
410arch_initcall(cbe_init_pm_irq);
411
412void cbe_sync_irq(int node)
413{
414 unsigned int irq;
415
416 irq = irq_find_mapping(NULL,
417 IIC_IRQ_IOEX_PMI
418 | (node << IIC_IRQ_NODE_SHIFT));
419
420 if (irq == NO_IRQ) {
421 printk(KERN_WARNING "ERROR, unable to get existing irq %d " \
422 "for node %d\n", irq, node);
423 return;
424 }
425
426 synchronize_irq(irq);
427}
428EXPORT_SYMBOL_GPL(cbe_sync_irq);
429
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c
index 22c228a49c33..36989c2eee66 100644
--- a/arch/powerpc/platforms/cell/setup.c
+++ b/arch/powerpc/platforms/cell/setup.c
@@ -50,9 +50,10 @@
50#include <asm/spu.h> 50#include <asm/spu.h>
51#include <asm/spu_priv1.h> 51#include <asm/spu_priv1.h>
52#include <asm/udbg.h> 52#include <asm/udbg.h>
53#include <asm/mpic.h>
54#include <asm/of_platform.h>
53 55
54#include "interrupt.h" 56#include "interrupt.h"
55#include "iommu.h"
56#include "cbe_regs.h" 57#include "cbe_regs.h"
57#include "pervasive.h" 58#include "pervasive.h"
58#include "ras.h" 59#include "ras.h"
@@ -80,24 +81,72 @@ static void cell_progress(char *s, unsigned short hex)
80 printk("*** %04x : %s\n", hex, s ? s : ""); 81 printk("*** %04x : %s\n", hex, s ? s : "");
81} 82}
82 83
83static void __init cell_pcibios_fixup(void) 84static int __init cell_publish_devices(void)
84{ 85{
85 struct pci_dev *dev = NULL; 86 if (!machine_is(cell))
87 return 0;
88
89 /* Publish OF platform devices for southbridge IOs */
90 of_platform_bus_probe(NULL, NULL, NULL);
91
92 return 0;
93}
94device_initcall(cell_publish_devices);
95
96static void cell_mpic_cascade(unsigned int irq, struct irq_desc *desc)
97{
98 struct mpic *mpic = desc->handler_data;
99 unsigned int virq;
100
101 virq = mpic_get_one_irq(mpic);
102 if (virq != NO_IRQ)
103 generic_handle_irq(virq);
104 desc->chip->eoi(irq);
105}
86 106
87 for_each_pci_dev(dev) 107static void __init mpic_init_IRQ(void)
88 pci_read_irq_line(dev); 108{
109 struct device_node *dn;
110 struct mpic *mpic;
111 unsigned int virq;
112
113 for (dn = NULL;
114 (dn = of_find_node_by_name(dn, "interrupt-controller"));) {
115 if (!device_is_compatible(dn, "CBEA,platform-open-pic"))
116 continue;
117
118 /* The MPIC driver will get everything it needs from the
119 * device-tree, just pass 0 to all arguments
120 */
121 mpic = mpic_alloc(dn, 0, 0, 0, 0, " MPIC ");
122 if (mpic == NULL)
123 continue;
124 mpic_init(mpic);
125
126 virq = irq_of_parse_and_map(dn, 0);
127 if (virq == NO_IRQ)
128 continue;
129
130 printk(KERN_INFO "%s : hooking up to IRQ %d\n",
131 dn->full_name, virq);
132 set_irq_data(virq, mpic);
133 set_irq_chained_handler(virq, cell_mpic_cascade);
134 }
89} 135}
90 136
137
91static void __init cell_init_irq(void) 138static void __init cell_init_irq(void)
92{ 139{
93 iic_init_IRQ(); 140 iic_init_IRQ();
94 spider_init_IRQ(); 141 spider_init_IRQ();
142 mpic_init_IRQ();
95} 143}
96 144
97static void __init cell_setup_arch(void) 145static void __init cell_setup_arch(void)
98{ 146{
99#ifdef CONFIG_SPU_BASE 147#ifdef CONFIG_SPU_BASE
100 spu_priv1_ops = &spu_priv1_mmio_ops; 148 spu_priv1_ops = &spu_priv1_mmio_ops;
149 spu_management_ops = &spu_management_of_ops;
101#endif 150#endif
102 151
103 cbe_regs_init(); 152 cbe_regs_init();
@@ -109,7 +158,6 @@ static void __init cell_setup_arch(void)
109#ifdef CONFIG_SMP 158#ifdef CONFIG_SMP
110 smp_init_cell(); 159 smp_init_cell();
111#endif 160#endif
112
113 /* init to some ~sane value until calibrate_delay() runs */ 161 /* init to some ~sane value until calibrate_delay() runs */
114 loops_per_jiffy = 50000000; 162 loops_per_jiffy = 50000000;
115 163
@@ -129,19 +177,6 @@ static void __init cell_setup_arch(void)
129 mmio_nvram_init(); 177 mmio_nvram_init();
130} 178}
131 179
132/*
133 * Early initialization. Relocation is on but do not reference unbolted pages
134 */
135static void __init cell_init_early(void)
136{
137 DBG(" -> cell_init_early()\n");
138
139 cell_init_iommu();
140
141 DBG(" <- cell_init_early()\n");
142}
143
144
145static int __init cell_probe(void) 180static int __init cell_probe(void)
146{ 181{
147 unsigned long root = of_get_flat_dt_root(); 182 unsigned long root = of_get_flat_dt_root();
@@ -168,7 +203,6 @@ define_machine(cell) {
168 .name = "Cell", 203 .name = "Cell",
169 .probe = cell_probe, 204 .probe = cell_probe,
170 .setup_arch = cell_setup_arch, 205 .setup_arch = cell_setup_arch,
171 .init_early = cell_init_early,
172 .show_cpuinfo = cell_show_cpuinfo, 206 .show_cpuinfo = cell_show_cpuinfo,
173 .restart = rtas_restart, 207 .restart = rtas_restart,
174 .power_off = rtas_power_off, 208 .power_off = rtas_power_off,
@@ -180,7 +214,7 @@ define_machine(cell) {
180 .check_legacy_ioport = cell_check_legacy_ioport, 214 .check_legacy_ioport = cell_check_legacy_ioport,
181 .progress = cell_progress, 215 .progress = cell_progress,
182 .init_IRQ = cell_init_irq, 216 .init_IRQ = cell_init_irq,
183 .pcibios_fixup = cell_pcibios_fixup, 217 .pci_setup_phb = rtas_setup_phb,
184#ifdef CONFIG_KEXEC 218#ifdef CONFIG_KEXEC
185 .machine_kexec = default_machine_kexec, 219 .machine_kexec = default_machine_kexec,
186 .machine_kexec_prepare = default_machine_kexec_prepare, 220 .machine_kexec_prepare = default_machine_kexec_prepare,
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c
index 7aa809d5a244..bd7bffc3ddd0 100644
--- a/arch/powerpc/platforms/cell/spu_base.c
+++ b/arch/powerpc/platforms/cell/spu_base.c
@@ -25,22 +25,17 @@
25#include <linux/interrupt.h> 25#include <linux/interrupt.h>
26#include <linux/list.h> 26#include <linux/list.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/pci.h>
29#include <linux/poll.h>
30#include <linux/ptrace.h> 28#include <linux/ptrace.h>
31#include <linux/slab.h> 29#include <linux/slab.h>
32#include <linux/wait.h> 30#include <linux/wait.h>
33 31#include <linux/mm.h>
34#include <asm/firmware.h> 32#include <linux/io.h>
35#include <asm/io.h>
36#include <asm/prom.h>
37#include <linux/mutex.h> 33#include <linux/mutex.h>
38#include <asm/spu.h> 34#include <asm/spu.h>
39#include <asm/spu_priv1.h> 35#include <asm/spu_priv1.h>
40#include <asm/mmu_context.h> 36#include <asm/xmon.h>
41
42#include "interrupt.h"
43 37
38const struct spu_management_ops *spu_management_ops;
44const struct spu_priv1_ops *spu_priv1_ops; 39const struct spu_priv1_ops *spu_priv1_ops;
45 40
46EXPORT_SYMBOL_GPL(spu_priv1_ops); 41EXPORT_SYMBOL_GPL(spu_priv1_ops);
@@ -89,7 +84,30 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea)
89 printk("%s: invalid access during switch!\n", __func__); 84 printk("%s: invalid access during switch!\n", __func__);
90 return 1; 85 return 1;
91 } 86 }
92 if (!mm || (REGION_ID(ea) != USER_REGION_ID)) { 87 esid = (ea & ESID_MASK) | SLB_ESID_V;
88
89 switch(REGION_ID(ea)) {
90 case USER_REGION_ID:
91#ifdef CONFIG_HUGETLB_PAGE
92 if (in_hugepage_area(mm->context, ea))
93 llp = mmu_psize_defs[mmu_huge_psize].sllp;
94 else
95#endif
96 llp = mmu_psize_defs[mmu_virtual_psize].sllp;
97 vsid = (get_vsid(mm->context.id, ea) << SLB_VSID_SHIFT) |
98 SLB_VSID_USER | llp;
99 break;
100 case VMALLOC_REGION_ID:
101 llp = mmu_psize_defs[mmu_virtual_psize].sllp;
102 vsid = (get_kernel_vsid(ea) << SLB_VSID_SHIFT) |
103 SLB_VSID_KERNEL | llp;
104 break;
105 case KERNEL_REGION_ID:
106 llp = mmu_psize_defs[mmu_linear_psize].sllp;
107 vsid = (get_kernel_vsid(ea) << SLB_VSID_SHIFT) |
108 SLB_VSID_KERNEL | llp;
109 break;
110 default:
93 /* Future: support kernel segments so that drivers 111 /* Future: support kernel segments so that drivers
94 * can use SPUs. 112 * can use SPUs.
95 */ 113 */
@@ -97,16 +115,6 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea)
97 return 1; 115 return 1;
98 } 116 }
99 117
100 esid = (ea & ESID_MASK) | SLB_ESID_V;
101#ifdef CONFIG_HUGETLB_PAGE
102 if (in_hugepage_area(mm->context, ea))
103 llp = mmu_psize_defs[mmu_huge_psize].sllp;
104 else
105#endif
106 llp = mmu_psize_defs[mmu_virtual_psize].sllp;
107 vsid = (get_vsid(mm->context.id, ea) << SLB_VSID_SHIFT) |
108 SLB_VSID_USER | llp;
109
110 out_be64(&priv2->slb_index_W, spu->slb_replace); 118 out_be64(&priv2->slb_index_W, spu->slb_replace);
111 out_be64(&priv2->slb_vsid_RW, vsid); 119 out_be64(&priv2->slb_vsid_RW, vsid);
112 out_be64(&priv2->slb_esid_RW, esid); 120 out_be64(&priv2->slb_esid_RW, esid);
@@ -320,6 +328,7 @@ static void spu_free_irqs(struct spu *spu)
320} 328}
321 329
322static struct list_head spu_list[MAX_NUMNODES]; 330static struct list_head spu_list[MAX_NUMNODES];
331static LIST_HEAD(spu_full_list);
323static DEFINE_MUTEX(spu_mutex); 332static DEFINE_MUTEX(spu_mutex);
324 333
325static void spu_init_channels(struct spu *spu) 334static void spu_init_channels(struct spu *spu)
@@ -364,8 +373,7 @@ struct spu *spu_alloc_node(int node)
364 if (!list_empty(&spu_list[node])) { 373 if (!list_empty(&spu_list[node])) {
365 spu = list_entry(spu_list[node].next, struct spu, list); 374 spu = list_entry(spu_list[node].next, struct spu, list);
366 list_del_init(&spu->list); 375 list_del_init(&spu->list);
367 pr_debug("Got SPU %x %d %d\n", 376 pr_debug("Got SPU %d %d\n", spu->number, spu->node);
368 spu->isrc, spu->number, spu->node);
369 spu_init_channels(spu); 377 spu_init_channels(spu);
370 } 378 }
371 mutex_unlock(&spu_mutex); 379 mutex_unlock(&spu_mutex);
@@ -493,280 +501,65 @@ int spu_irq_class_1_bottom(struct spu *spu)
493 if (!error) { 501 if (!error) {
494 spu_restart_dma(spu); 502 spu_restart_dma(spu);
495 } else { 503 } else {
496 __spu_trap_invalid_dma(spu); 504 spu->dma_callback(spu, SPE_EVENT_SPE_DATA_STORAGE);
497 } 505 }
498 return ret; 506 return ret;
499} 507}
500 508
501static int __init find_spu_node_id(struct device_node *spe) 509struct sysdev_class spu_sysdev_class = {
502{ 510 set_kset_name("spu")
503 const unsigned int *id; 511};
504 struct device_node *cpu;
505 cpu = spe->parent->parent;
506 id = get_property(cpu, "node-id", NULL);
507 return id ? *id : 0;
508}
509
510static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe,
511 const char *prop)
512{
513 static DEFINE_MUTEX(add_spumem_mutex);
514
515 const struct address_prop {
516 unsigned long address;
517 unsigned int len;
518 } __attribute__((packed)) *p;
519 int proplen;
520
521 unsigned long start_pfn, nr_pages;
522 struct pglist_data *pgdata;
523 struct zone *zone;
524 int ret;
525
526 p = get_property(spe, prop, &proplen);
527 WARN_ON(proplen != sizeof (*p));
528
529 start_pfn = p->address >> PAGE_SHIFT;
530 nr_pages = ((unsigned long)p->len + PAGE_SIZE - 1) >> PAGE_SHIFT;
531
532 pgdata = NODE_DATA(spu->nid);
533 zone = pgdata->node_zones;
534
535 /* XXX rethink locking here */
536 mutex_lock(&add_spumem_mutex);
537 ret = __add_pages(zone, start_pfn, nr_pages);
538 mutex_unlock(&add_spumem_mutex);
539
540 return ret;
541}
542 512
543static void __iomem * __init map_spe_prop(struct spu *spu, 513int spu_add_sysdev_attr(struct sysdev_attribute *attr)
544 struct device_node *n, const char *name)
545{ 514{
546 const struct address_prop { 515 struct spu *spu;
547 unsigned long address; 516 mutex_lock(&spu_mutex);
548 unsigned int len;
549 } __attribute__((packed)) *prop;
550
551 const void *p;
552 int proplen;
553 void __iomem *ret = NULL;
554 int err = 0;
555
556 p = get_property(n, name, &proplen);
557 if (proplen != sizeof (struct address_prop))
558 return NULL;
559
560 prop = p;
561
562 err = cell_spuprop_present(spu, n, name);
563 if (err && (err != -EEXIST))
564 goto out;
565
566 ret = ioremap(prop->address, prop->len);
567
568 out:
569 return ret;
570}
571 517
572static void spu_unmap(struct spu *spu) 518 list_for_each_entry(spu, &spu_full_list, full_list)
573{ 519 sysdev_create_file(&spu->sysdev, attr);
574 iounmap(spu->priv2);
575 iounmap(spu->priv1);
576 iounmap(spu->problem);
577 iounmap((__force u8 __iomem *)spu->local_store);
578}
579 520
580/* This function shall be abstracted for HV platforms */ 521 mutex_unlock(&spu_mutex);
581static int __init spu_map_interrupts_old(struct spu *spu, struct device_node *np) 522 return 0;
582{
583 unsigned int isrc;
584 const u32 *tmp;
585
586 /* Get the interrupt source unit from the device-tree */
587 tmp = get_property(np, "isrc", NULL);
588 if (!tmp)
589 return -ENODEV;
590 isrc = tmp[0];
591
592 /* Add the node number */
593 isrc |= spu->node << IIC_IRQ_NODE_SHIFT;
594 spu->isrc = isrc;
595
596 /* Now map interrupts of all 3 classes */
597 spu->irqs[0] = irq_create_mapping(NULL, IIC_IRQ_CLASS_0 | isrc);
598 spu->irqs[1] = irq_create_mapping(NULL, IIC_IRQ_CLASS_1 | isrc);
599 spu->irqs[2] = irq_create_mapping(NULL, IIC_IRQ_CLASS_2 | isrc);
600
601 /* Right now, we only fail if class 2 failed */
602 return spu->irqs[2] == NO_IRQ ? -EINVAL : 0;
603} 523}
524EXPORT_SYMBOL_GPL(spu_add_sysdev_attr);
604 525
605static int __init spu_map_device_old(struct spu *spu, struct device_node *node) 526int spu_add_sysdev_attr_group(struct attribute_group *attrs)
606{ 527{
607 const char *prop; 528 struct spu *spu;
608 int ret; 529 mutex_lock(&spu_mutex);
609
610 ret = -ENODEV;
611 spu->name = get_property(node, "name", NULL);
612 if (!spu->name)
613 goto out;
614
615 prop = get_property(node, "local-store", NULL);
616 if (!prop)
617 goto out;
618 spu->local_store_phys = *(unsigned long *)prop;
619
620 /* we use local store as ram, not io memory */
621 spu->local_store = (void __force *)
622 map_spe_prop(spu, node, "local-store");
623 if (!spu->local_store)
624 goto out;
625
626 prop = get_property(node, "problem", NULL);
627 if (!prop)
628 goto out_unmap;
629 spu->problem_phys = *(unsigned long *)prop;
630
631 spu->problem= map_spe_prop(spu, node, "problem");
632 if (!spu->problem)
633 goto out_unmap;
634
635 spu->priv1= map_spe_prop(spu, node, "priv1");
636 /* priv1 is not available on a hypervisor */
637
638 spu->priv2= map_spe_prop(spu, node, "priv2");
639 if (!spu->priv2)
640 goto out_unmap;
641 ret = 0;
642 goto out;
643
644out_unmap:
645 spu_unmap(spu);
646out:
647 return ret;
648}
649 530
650static int __init spu_map_interrupts(struct spu *spu, struct device_node *np) 531 list_for_each_entry(spu, &spu_full_list, full_list)
651{ 532 sysfs_create_group(&spu->sysdev.kobj, attrs);
652 struct of_irq oirq;
653 int ret;
654 int i;
655 533
656 for (i=0; i < 3; i++) { 534 mutex_unlock(&spu_mutex);
657 ret = of_irq_map_one(np, i, &oirq);
658 if (ret) {
659 pr_debug("spu_new: failed to get irq %d\n", i);
660 goto err;
661 }
662 ret = -EINVAL;
663 pr_debug(" irq %d no 0x%x on %s\n", i, oirq.specifier[0],
664 oirq.controller->full_name);
665 spu->irqs[i] = irq_create_of_mapping(oirq.controller,
666 oirq.specifier, oirq.size);
667 if (spu->irqs[i] == NO_IRQ) {
668 pr_debug("spu_new: failed to map it !\n");
669 goto err;
670 }
671 }
672 return 0; 535 return 0;
673
674err:
675 pr_debug("failed to map irq %x for spu %s\n", *oirq.specifier, spu->name);
676 for (; i >= 0; i--) {
677 if (spu->irqs[i] != NO_IRQ)
678 irq_dispose_mapping(spu->irqs[i]);
679 }
680 return ret;
681} 536}
537EXPORT_SYMBOL_GPL(spu_add_sysdev_attr_group);
682 538
683static int spu_map_resource(struct device_node *node, int nr,
684 void __iomem** virt, unsigned long *phys)
685{
686 struct resource resource = { };
687 int ret;
688
689 ret = of_address_to_resource(node, nr, &resource);
690 if (ret)
691 goto out;
692 539
693 if (phys) 540void spu_remove_sysdev_attr(struct sysdev_attribute *attr)
694 *phys = resource.start;
695 *virt = ioremap(resource.start, resource.end - resource.start);
696 if (!*virt)
697 ret = -EINVAL;
698
699out:
700 return ret;
701}
702
703static int __init spu_map_device(struct spu *spu, struct device_node *node)
704{ 541{
705 int ret = -ENODEV; 542 struct spu *spu;
706 spu->name = get_property(node, "name", NULL); 543 mutex_lock(&spu_mutex);
707 if (!spu->name)
708 goto out;
709
710 ret = spu_map_resource(node, 0, (void __iomem**)&spu->local_store,
711 &spu->local_store_phys);
712 if (ret) {
713 pr_debug("spu_new: failed to map %s resource 0\n",
714 node->full_name);
715 goto out;
716 }
717 ret = spu_map_resource(node, 1, (void __iomem**)&spu->problem,
718 &spu->problem_phys);
719 if (ret) {
720 pr_debug("spu_new: failed to map %s resource 1\n",
721 node->full_name);
722 goto out_unmap;
723 }
724 ret = spu_map_resource(node, 2, (void __iomem**)&spu->priv2,
725 NULL);
726 if (ret) {
727 pr_debug("spu_new: failed to map %s resource 2\n",
728 node->full_name);
729 goto out_unmap;
730 }
731
732 if (!firmware_has_feature(FW_FEATURE_LPAR))
733 ret = spu_map_resource(node, 3, (void __iomem**)&spu->priv1,
734 NULL);
735 if (ret) {
736 pr_debug("spu_new: failed to map %s resource 3\n",
737 node->full_name);
738 goto out_unmap;
739 }
740 pr_debug("spu_new: %s maps:\n", node->full_name);
741 pr_debug(" local store : 0x%016lx -> 0x%p\n",
742 spu->local_store_phys, spu->local_store);
743 pr_debug(" problem state : 0x%016lx -> 0x%p\n",
744 spu->problem_phys, spu->problem);
745 pr_debug(" priv2 : 0x%p\n", spu->priv2);
746 pr_debug(" priv1 : 0x%p\n", spu->priv1);
747 544
748 return 0; 545 list_for_each_entry(spu, &spu_full_list, full_list)
546 sysdev_remove_file(&spu->sysdev, attr);
749 547
750out_unmap: 548 mutex_unlock(&spu_mutex);
751 spu_unmap(spu);
752out:
753 pr_debug("failed to map spe %s: %d\n", spu->name, ret);
754 return ret;
755} 549}
550EXPORT_SYMBOL_GPL(spu_remove_sysdev_attr);
756 551
757struct sysdev_class spu_sysdev_class = { 552void spu_remove_sysdev_attr_group(struct attribute_group *attrs)
758 set_kset_name("spu")
759};
760
761static ssize_t spu_show_isrc(struct sys_device *sysdev, char *buf)
762{ 553{
763 struct spu *spu = container_of(sysdev, struct spu, sysdev); 554 struct spu *spu;
764 return sprintf(buf, "%d\n", spu->isrc); 555 mutex_lock(&spu_mutex);
765 556
766} 557 list_for_each_entry(spu, &spu_full_list, full_list)
767static SYSDEV_ATTR(isrc, 0400, spu_show_isrc, NULL); 558 sysfs_remove_group(&spu->sysdev.kobj, attrs);
768 559
769extern int attach_sysdev_to_node(struct sys_device *dev, int nid); 560 mutex_unlock(&spu_mutex);
561}
562EXPORT_SYMBOL_GPL(spu_remove_sysdev_attr_group);
770 563
771static int spu_create_sysdev(struct spu *spu) 564static int spu_create_sysdev(struct spu *spu)
772{ 565{
@@ -781,21 +574,18 @@ static int spu_create_sysdev(struct spu *spu)
781 return ret; 574 return ret;
782 } 575 }
783 576
784 if (spu->isrc != 0) 577 sysfs_add_device_to_node(&spu->sysdev, spu->node);
785 sysdev_create_file(&spu->sysdev, &attr_isrc);
786 sysfs_add_device_to_node(&spu->sysdev, spu->nid);
787 578
788 return 0; 579 return 0;
789} 580}
790 581
791static void spu_destroy_sysdev(struct spu *spu) 582static void spu_destroy_sysdev(struct spu *spu)
792{ 583{
793 sysdev_remove_file(&spu->sysdev, &attr_isrc); 584 sysfs_remove_device_from_node(&spu->sysdev, spu->node);
794 sysfs_remove_device_from_node(&spu->sysdev, spu->nid);
795 sysdev_unregister(&spu->sysdev); 585 sysdev_unregister(&spu->sysdev);
796} 586}
797 587
798static int __init create_spu(struct device_node *spe) 588static int __init create_spu(void *data)
799{ 589{
800 struct spu *spu; 590 struct spu *spu;
801 int ret; 591 int ret;
@@ -806,57 +596,37 @@ static int __init create_spu(struct device_node *spe)
806 if (!spu) 596 if (!spu)
807 goto out; 597 goto out;
808 598
809 spu->node = find_spu_node_id(spe); 599 spin_lock_init(&spu->register_lock);
810 if (spu->node >= MAX_NUMNODES) { 600 mutex_lock(&spu_mutex);
811 printk(KERN_WARNING "SPE %s on node %d ignored," 601 spu->number = number++;
812 " node number too big\n", spe->full_name, spu->node); 602 mutex_unlock(&spu_mutex);
813 printk(KERN_WARNING "Check if CONFIG_NUMA is enabled.\n"); 603
814 return -ENODEV; 604 ret = spu_create_spu(spu, data);
815 }
816 spu->nid = of_node_to_nid(spe);
817 if (spu->nid == -1)
818 spu->nid = 0;
819 605
820 ret = spu_map_device(spu, spe);
821 /* try old method */
822 if (ret)
823 ret = spu_map_device_old(spu, spe);
824 if (ret) 606 if (ret)
825 goto out_free; 607 goto out_free;
826 608
827 ret = spu_map_interrupts(spu, spe); 609 spu_mfc_sdr_setup(spu);
828 if (ret)
829 ret = spu_map_interrupts_old(spu, spe);
830 if (ret)
831 goto out_unmap;
832 spin_lock_init(&spu->register_lock);
833 spu_mfc_sdr_set(spu, mfspr(SPRN_SDR1));
834 spu_mfc_sr1_set(spu, 0x33); 610 spu_mfc_sr1_set(spu, 0x33);
835 mutex_lock(&spu_mutex);
836
837 spu->number = number++;
838 ret = spu_request_irqs(spu); 611 ret = spu_request_irqs(spu);
839 if (ret) 612 if (ret)
840 goto out_unlock; 613 goto out_destroy;
841 614
842 ret = spu_create_sysdev(spu); 615 ret = spu_create_sysdev(spu);
843 if (ret) 616 if (ret)
844 goto out_free_irqs; 617 goto out_free_irqs;
845 618
619 mutex_lock(&spu_mutex);
846 list_add(&spu->list, &spu_list[spu->node]); 620 list_add(&spu->list, &spu_list[spu->node]);
621 list_add(&spu->full_list, &spu_full_list);
847 mutex_unlock(&spu_mutex); 622 mutex_unlock(&spu_mutex);
848 623
849 pr_debug(KERN_DEBUG "Using SPE %s %02x %p %p %p %p %d\n",
850 spu->name, spu->isrc, spu->local_store,
851 spu->problem, spu->priv1, spu->priv2, spu->number);
852 goto out; 624 goto out;
853 625
854out_free_irqs: 626out_free_irqs:
855 spu_free_irqs(spu); 627 spu_free_irqs(spu);
856out_unlock: 628out_destroy:
857 mutex_unlock(&spu_mutex); 629 spu_destroy_spu(spu);
858out_unmap:
859 spu_unmap(spu);
860out_free: 630out_free:
861 kfree(spu); 631 kfree(spu);
862out: 632out:
@@ -866,10 +636,11 @@ out:
866static void destroy_spu(struct spu *spu) 636static void destroy_spu(struct spu *spu)
867{ 637{
868 list_del_init(&spu->list); 638 list_del_init(&spu->list);
639 list_del_init(&spu->full_list);
869 640
870 spu_destroy_sysdev(spu); 641 spu_destroy_sysdev(spu);
871 spu_free_irqs(spu); 642 spu_free_irqs(spu);
872 spu_unmap(spu); 643 spu_destroy_spu(spu);
873 kfree(spu); 644 kfree(spu);
874} 645}
875 646
@@ -890,9 +661,11 @@ module_exit(cleanup_spu_base);
890 661
891static int __init init_spu_base(void) 662static int __init init_spu_base(void)
892{ 663{
893 struct device_node *node;
894 int i, ret; 664 int i, ret;
895 665
666 if (!spu_management_ops)
667 return 0;
668
896 /* create sysdev class for spus */ 669 /* create sysdev class for spus */
897 ret = sysdev_class_register(&spu_sysdev_class); 670 ret = sysdev_class_register(&spu_sysdev_class);
898 if (ret) 671 if (ret)
@@ -901,17 +674,17 @@ static int __init init_spu_base(void)
901 for (i = 0; i < MAX_NUMNODES; i++) 674 for (i = 0; i < MAX_NUMNODES; i++)
902 INIT_LIST_HEAD(&spu_list[i]); 675 INIT_LIST_HEAD(&spu_list[i]);
903 676
904 ret = -ENODEV; 677 ret = spu_enumerate_spus(create_spu);
905 for (node = of_find_node_by_type(NULL, "spe"); 678
906 node; node = of_find_node_by_type(node, "spe")) { 679 if (ret) {
907 ret = create_spu(node); 680 printk(KERN_WARNING "%s: Error initializing spus\n",
908 if (ret) { 681 __FUNCTION__);
909 printk(KERN_WARNING "%s: Error initializing %s\n", 682 cleanup_spu_base();
910 __FUNCTION__, node->name); 683 return ret;
911 cleanup_spu_base();
912 break;
913 }
914 } 684 }
685
686 xmon_register_spus(&spu_full_list);
687
915 return ret; 688 return ret;
916} 689}
917module_init(init_spu_base); 690module_init(init_spu_base);
diff --git a/arch/powerpc/platforms/cell/spu_coredump.c b/arch/powerpc/platforms/cell/spu_coredump.c
new file mode 100644
index 000000000000..6915b418ee73
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spu_coredump.c
@@ -0,0 +1,81 @@
1/*
2 * SPU core dump code
3 *
4 * (C) Copyright 2006 IBM Corp.
5 *
6 * Author: Dwayne Grant McConnell <decimal@us.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/file.h>
24#include <linux/module.h>
25#include <linux/syscalls.h>
26
27#include <asm/spu.h>
28
29static struct spu_coredump_calls spu_coredump_calls;
30static DEFINE_MUTEX(spu_coredump_mutex);
31
32int arch_notes_size(void)
33{
34 long ret;
35 struct module *owner = spu_coredump_calls.owner;
36
37 ret = -ENOSYS;
38 mutex_lock(&spu_coredump_mutex);
39 if (owner && try_module_get(owner)) {
40 ret = spu_coredump_calls.arch_notes_size();
41 module_put(owner);
42 }
43 mutex_unlock(&spu_coredump_mutex);
44 return ret;
45}
46
47void arch_write_notes(struct file *file)
48{
49 struct module *owner = spu_coredump_calls.owner;
50
51 mutex_lock(&spu_coredump_mutex);
52 if (owner && try_module_get(owner)) {
53 spu_coredump_calls.arch_write_notes(file);
54 module_put(owner);
55 }
56 mutex_unlock(&spu_coredump_mutex);
57}
58
59int register_arch_coredump_calls(struct spu_coredump_calls *calls)
60{
61 if (spu_coredump_calls.owner)
62 return -EBUSY;
63
64 mutex_lock(&spu_coredump_mutex);
65 spu_coredump_calls.arch_notes_size = calls->arch_notes_size;
66 spu_coredump_calls.arch_write_notes = calls->arch_write_notes;
67 spu_coredump_calls.owner = calls->owner;
68 mutex_unlock(&spu_coredump_mutex);
69 return 0;
70}
71EXPORT_SYMBOL_GPL(register_arch_coredump_calls);
72
73void unregister_arch_coredump_calls(struct spu_coredump_calls *calls)
74{
75 BUG_ON(spu_coredump_calls.owner != calls->owner);
76
77 mutex_lock(&spu_coredump_mutex);
78 spu_coredump_calls.owner = NULL;
79 mutex_unlock(&spu_coredump_mutex);
80}
81EXPORT_SYMBOL_GPL(unregister_arch_coredump_calls);
diff --git a/arch/powerpc/platforms/cell/spu_priv1_mmio.c b/arch/powerpc/platforms/cell/spu_priv1_mmio.c
index 71b69f0a1a48..a5de0430c56d 100644
--- a/arch/powerpc/platforms/cell/spu_priv1_mmio.c
+++ b/arch/powerpc/platforms/cell/spu_priv1_mmio.c
@@ -18,120 +18,498 @@
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */ 19 */
20 20
21#include <linux/interrupt.h>
22#include <linux/list.h>
21#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/ptrace.h>
25#include <linux/slab.h>
26#include <linux/wait.h>
27#include <linux/mm.h>
28#include <linux/io.h>
29#include <linux/mutex.h>
30#include <linux/device.h>
22 31
23#include <asm/io.h>
24#include <asm/spu.h> 32#include <asm/spu.h>
25#include <asm/spu_priv1.h> 33#include <asm/spu_priv1.h>
34#include <asm/firmware.h>
35#include <asm/prom.h>
26 36
27#include "interrupt.h" 37#include "interrupt.h"
38#include "spu_priv1_mmio.h"
39
40struct spu_pdata {
41 int nid;
42 struct device_node *devnode;
43 struct spu_priv1 __iomem *priv1;
44};
45
46static struct spu_pdata *spu_get_pdata(struct spu *spu)
47{
48 BUG_ON(!spu->pdata);
49 return spu->pdata;
50}
51
52struct device_node *spu_devnode(struct spu *spu)
53{
54 return spu_get_pdata(spu)->devnode;
55}
56
57EXPORT_SYMBOL_GPL(spu_devnode);
58
59static int __init find_spu_node_id(struct device_node *spe)
60{
61 const unsigned int *id;
62 struct device_node *cpu;
63 cpu = spe->parent->parent;
64 id = get_property(cpu, "node-id", NULL);
65 return id ? *id : 0;
66}
67
68static int __init cell_spuprop_present(struct spu *spu, struct device_node *spe,
69 const char *prop)
70{
71 static DEFINE_MUTEX(add_spumem_mutex);
72
73 const struct address_prop {
74 unsigned long address;
75 unsigned int len;
76 } __attribute__((packed)) *p;
77 int proplen;
78
79 unsigned long start_pfn, nr_pages;
80 struct pglist_data *pgdata;
81 struct zone *zone;
82 int ret;
83
84 p = get_property(spe, prop, &proplen);
85 WARN_ON(proplen != sizeof (*p));
86
87 start_pfn = p->address >> PAGE_SHIFT;
88 nr_pages = ((unsigned long)p->len + PAGE_SIZE - 1) >> PAGE_SHIFT;
89
90 pgdata = NODE_DATA(spu_get_pdata(spu)->nid);
91 zone = pgdata->node_zones;
92
93 /* XXX rethink locking here */
94 mutex_lock(&add_spumem_mutex);
95 ret = __add_pages(zone, start_pfn, nr_pages);
96 mutex_unlock(&add_spumem_mutex);
97
98 return ret;
99}
100
101static void __iomem * __init map_spe_prop(struct spu *spu,
102 struct device_node *n, const char *name)
103{
104 const struct address_prop {
105 unsigned long address;
106 unsigned int len;
107 } __attribute__((packed)) *prop;
108
109 const void *p;
110 int proplen;
111 void __iomem *ret = NULL;
112 int err = 0;
113
114 p = get_property(n, name, &proplen);
115 if (proplen != sizeof (struct address_prop))
116 return NULL;
117
118 prop = p;
119
120 err = cell_spuprop_present(spu, n, name);
121 if (err && (err != -EEXIST))
122 goto out;
123
124 ret = ioremap(prop->address, prop->len);
125
126 out:
127 return ret;
128}
129
130static void spu_unmap(struct spu *spu)
131{
132 iounmap(spu->priv2);
133 iounmap(spu_get_pdata(spu)->priv1);
134 iounmap(spu->problem);
135 iounmap((__force u8 __iomem *)spu->local_store);
136}
137
138static int __init spu_map_interrupts_old(struct spu *spu,
139 struct device_node *np)
140{
141 unsigned int isrc;
142 const u32 *tmp;
143
144 /* Get the interrupt source unit from the device-tree */
145 tmp = get_property(np, "isrc", NULL);
146 if (!tmp)
147 return -ENODEV;
148 isrc = tmp[0];
149
150 /* Add the node number */
151 isrc |= spu->node << IIC_IRQ_NODE_SHIFT;
152
153 /* Now map interrupts of all 3 classes */
154 spu->irqs[0] = irq_create_mapping(NULL, IIC_IRQ_CLASS_0 | isrc);
155 spu->irqs[1] = irq_create_mapping(NULL, IIC_IRQ_CLASS_1 | isrc);
156 spu->irqs[2] = irq_create_mapping(NULL, IIC_IRQ_CLASS_2 | isrc);
157
158 /* Right now, we only fail if class 2 failed */
159 return spu->irqs[2] == NO_IRQ ? -EINVAL : 0;
160}
161
162static int __init spu_map_device_old(struct spu *spu, struct device_node *node)
163{
164 const char *prop;
165 int ret;
166
167 ret = -ENODEV;
168 spu->name = get_property(node, "name", NULL);
169 if (!spu->name)
170 goto out;
171
172 prop = get_property(node, "local-store", NULL);
173 if (!prop)
174 goto out;
175 spu->local_store_phys = *(unsigned long *)prop;
176
177 /* we use local store as ram, not io memory */
178 spu->local_store = (void __force *)
179 map_spe_prop(spu, node, "local-store");
180 if (!spu->local_store)
181 goto out;
182
183 prop = get_property(node, "problem", NULL);
184 if (!prop)
185 goto out_unmap;
186 spu->problem_phys = *(unsigned long *)prop;
187
188 spu->problem= map_spe_prop(spu, node, "problem");
189 if (!spu->problem)
190 goto out_unmap;
191
192 spu_get_pdata(spu)->priv1= map_spe_prop(spu, node, "priv1");
193
194 spu->priv2= map_spe_prop(spu, node, "priv2");
195 if (!spu->priv2)
196 goto out_unmap;
197 ret = 0;
198 goto out;
199
200out_unmap:
201 spu_unmap(spu);
202out:
203 return ret;
204}
205
206static int __init spu_map_interrupts(struct spu *spu, struct device_node *np)
207{
208 struct of_irq oirq;
209 int ret;
210 int i;
211
212 for (i=0; i < 3; i++) {
213 ret = of_irq_map_one(np, i, &oirq);
214 if (ret) {
215 pr_debug("spu_new: failed to get irq %d\n", i);
216 goto err;
217 }
218 ret = -EINVAL;
219 pr_debug(" irq %d no 0x%x on %s\n", i, oirq.specifier[0],
220 oirq.controller->full_name);
221 spu->irqs[i] = irq_create_of_mapping(oirq.controller,
222 oirq.specifier, oirq.size);
223 if (spu->irqs[i] == NO_IRQ) {
224 pr_debug("spu_new: failed to map it !\n");
225 goto err;
226 }
227 }
228 return 0;
229
230err:
231 pr_debug("failed to map irq %x for spu %s\n", *oirq.specifier,
232 spu->name);
233 for (; i >= 0; i--) {
234 if (spu->irqs[i] != NO_IRQ)
235 irq_dispose_mapping(spu->irqs[i]);
236 }
237 return ret;
238}
239
240static int spu_map_resource(struct device_node *node, int nr,
241 void __iomem** virt, unsigned long *phys)
242{
243 struct resource resource = { };
244 int ret;
245
246 ret = of_address_to_resource(node, nr, &resource);
247 if (ret)
248 goto out;
249
250 if (phys)
251 *phys = resource.start;
252 *virt = ioremap(resource.start, resource.end - resource.start);
253 if (!*virt)
254 ret = -EINVAL;
255
256out:
257 return ret;
258}
259
260static int __init spu_map_device(struct spu *spu, struct device_node *node)
261{
262 int ret = -ENODEV;
263 spu->name = get_property(node, "name", NULL);
264 if (!spu->name)
265 goto out;
266
267 ret = spu_map_resource(node, 0, (void __iomem**)&spu->local_store,
268 &spu->local_store_phys);
269 if (ret) {
270 pr_debug("spu_new: failed to map %s resource 0\n",
271 node->full_name);
272 goto out;
273 }
274 ret = spu_map_resource(node, 1, (void __iomem**)&spu->problem,
275 &spu->problem_phys);
276 if (ret) {
277 pr_debug("spu_new: failed to map %s resource 1\n",
278 node->full_name);
279 goto out_unmap;
280 }
281 ret = spu_map_resource(node, 2, (void __iomem**)&spu->priv2,
282 NULL);
283 if (ret) {
284 pr_debug("spu_new: failed to map %s resource 2\n",
285 node->full_name);
286 goto out_unmap;
287 }
288 if (!firmware_has_feature(FW_FEATURE_LPAR))
289 ret = spu_map_resource(node, 3,
290 (void __iomem**)&spu_get_pdata(spu)->priv1, NULL);
291 if (ret) {
292 pr_debug("spu_new: failed to map %s resource 3\n",
293 node->full_name);
294 goto out_unmap;
295 }
296 pr_debug("spu_new: %s maps:\n", node->full_name);
297 pr_debug(" local store : 0x%016lx -> 0x%p\n",
298 spu->local_store_phys, spu->local_store);
299 pr_debug(" problem state : 0x%016lx -> 0x%p\n",
300 spu->problem_phys, spu->problem);
301 pr_debug(" priv2 : 0x%p\n", spu->priv2);
302 pr_debug(" priv1 : 0x%p\n",
303 spu_get_pdata(spu)->priv1);
304
305 return 0;
306
307out_unmap:
308 spu_unmap(spu);
309out:
310 pr_debug("failed to map spe %s: %d\n", spu->name, ret);
311 return ret;
312}
313
314static int __init of_enumerate_spus(int (*fn)(void *data))
315{
316 int ret;
317 struct device_node *node;
318
319 ret = -ENODEV;
320 for (node = of_find_node_by_type(NULL, "spe");
321 node; node = of_find_node_by_type(node, "spe")) {
322 ret = fn(node);
323 if (ret) {
324 printk(KERN_WARNING "%s: Error initializing %s\n",
325 __FUNCTION__, node->name);
326 break;
327 }
328 }
329 return ret;
330}
331
332static int __init of_create_spu(struct spu *spu, void *data)
333{
334 int ret;
335 struct device_node *spe = (struct device_node *)data;
336
337 spu->pdata = kzalloc(sizeof(struct spu_pdata),
338 GFP_KERNEL);
339 if (!spu->pdata) {
340 ret = -ENOMEM;
341 goto out;
342 }
343
344 spu->node = find_spu_node_id(spe);
345 if (spu->node >= MAX_NUMNODES) {
346 printk(KERN_WARNING "SPE %s on node %d ignored,"
347 " node number too big\n", spe->full_name, spu->node);
348 printk(KERN_WARNING "Check if CONFIG_NUMA is enabled.\n");
349 ret = -ENODEV;
350 goto out_free;
351 }
352
353 spu_get_pdata(spu)->nid = of_node_to_nid(spe);
354 if (spu_get_pdata(spu)->nid == -1)
355 spu_get_pdata(spu)->nid = 0;
356
357 ret = spu_map_device(spu, spe);
358 /* try old method */
359 if (ret)
360 ret = spu_map_device_old(spu, spe);
361 if (ret)
362 goto out_free;
363
364 ret = spu_map_interrupts(spu, spe);
365 if (ret)
366 ret = spu_map_interrupts_old(spu, spe);
367 if (ret)
368 goto out_unmap;
369
370 spu_get_pdata(spu)->devnode = of_node_get(spe);
371
372 pr_debug(KERN_DEBUG "Using SPE %s %p %p %p %p %d\n", spu->name,
373 spu->local_store, spu->problem, spu_get_pdata(spu)->priv1,
374 spu->priv2, spu->number);
375 goto out;
376
377out_unmap:
378 spu_unmap(spu);
379out_free:
380 kfree(spu->pdata);
381 spu->pdata = NULL;
382out:
383 return ret;
384}
385
386static int of_destroy_spu(struct spu *spu)
387{
388 spu_unmap(spu);
389 of_node_put(spu_get_pdata(spu)->devnode);
390 kfree(spu->pdata);
391 spu->pdata = NULL;
392 return 0;
393}
394
395const struct spu_management_ops spu_management_of_ops = {
396 .enumerate_spus = of_enumerate_spus,
397 .create_spu = of_create_spu,
398 .destroy_spu = of_destroy_spu,
399};
28 400
29static void int_mask_and(struct spu *spu, int class, u64 mask) 401static void int_mask_and(struct spu *spu, int class, u64 mask)
30{ 402{
31 u64 old_mask; 403 u64 old_mask;
32 404
33 old_mask = in_be64(&spu->priv1->int_mask_RW[class]); 405 old_mask = in_be64(&spu_get_pdata(spu)->priv1->int_mask_RW[class]);
34 out_be64(&spu->priv1->int_mask_RW[class], old_mask & mask); 406 out_be64(&spu_get_pdata(spu)->priv1->int_mask_RW[class],
407 old_mask & mask);
35} 408}
36 409
37static void int_mask_or(struct spu *spu, int class, u64 mask) 410static void int_mask_or(struct spu *spu, int class, u64 mask)
38{ 411{
39 u64 old_mask; 412 u64 old_mask;
40 413
41 old_mask = in_be64(&spu->priv1->int_mask_RW[class]); 414 old_mask = in_be64(&spu_get_pdata(spu)->priv1->int_mask_RW[class]);
42 out_be64(&spu->priv1->int_mask_RW[class], old_mask | mask); 415 out_be64(&spu_get_pdata(spu)->priv1->int_mask_RW[class],
416 old_mask | mask);
43} 417}
44 418
45static void int_mask_set(struct spu *spu, int class, u64 mask) 419static void int_mask_set(struct spu *spu, int class, u64 mask)
46{ 420{
47 out_be64(&spu->priv1->int_mask_RW[class], mask); 421 out_be64(&spu_get_pdata(spu)->priv1->int_mask_RW[class], mask);
48} 422}
49 423
50static u64 int_mask_get(struct spu *spu, int class) 424static u64 int_mask_get(struct spu *spu, int class)
51{ 425{
52 return in_be64(&spu->priv1->int_mask_RW[class]); 426 return in_be64(&spu_get_pdata(spu)->priv1->int_mask_RW[class]);
53} 427}
54 428
55static void int_stat_clear(struct spu *spu, int class, u64 stat) 429static void int_stat_clear(struct spu *spu, int class, u64 stat)
56{ 430{
57 out_be64(&spu->priv1->int_stat_RW[class], stat); 431 out_be64(&spu_get_pdata(spu)->priv1->int_stat_RW[class], stat);
58} 432}
59 433
60static u64 int_stat_get(struct spu *spu, int class) 434static u64 int_stat_get(struct spu *spu, int class)
61{ 435{
62 return in_be64(&spu->priv1->int_stat_RW[class]); 436 return in_be64(&spu_get_pdata(spu)->priv1->int_stat_RW[class]);
63} 437}
64 438
65static void cpu_affinity_set(struct spu *spu, int cpu) 439static void cpu_affinity_set(struct spu *spu, int cpu)
66{ 440{
67 u64 target = iic_get_target_id(cpu); 441 u64 target = iic_get_target_id(cpu);
68 u64 route = target << 48 | target << 32 | target << 16; 442 u64 route = target << 48 | target << 32 | target << 16;
69 out_be64(&spu->priv1->int_route_RW, route); 443 out_be64(&spu_get_pdata(spu)->priv1->int_route_RW, route);
70} 444}
71 445
72static u64 mfc_dar_get(struct spu *spu) 446static u64 mfc_dar_get(struct spu *spu)
73{ 447{
74 return in_be64(&spu->priv1->mfc_dar_RW); 448 return in_be64(&spu_get_pdata(spu)->priv1->mfc_dar_RW);
75} 449}
76 450
77static u64 mfc_dsisr_get(struct spu *spu) 451static u64 mfc_dsisr_get(struct spu *spu)
78{ 452{
79 return in_be64(&spu->priv1->mfc_dsisr_RW); 453 return in_be64(&spu_get_pdata(spu)->priv1->mfc_dsisr_RW);
80} 454}
81 455
82static void mfc_dsisr_set(struct spu *spu, u64 dsisr) 456static void mfc_dsisr_set(struct spu *spu, u64 dsisr)
83{ 457{
84 out_be64(&spu->priv1->mfc_dsisr_RW, dsisr); 458 out_be64(&spu_get_pdata(spu)->priv1->mfc_dsisr_RW, dsisr);
85} 459}
86 460
87static void mfc_sdr_set(struct spu *spu, u64 sdr) 461static void mfc_sdr_setup(struct spu *spu)
88{ 462{
89 out_be64(&spu->priv1->mfc_sdr_RW, sdr); 463 out_be64(&spu_get_pdata(spu)->priv1->mfc_sdr_RW, mfspr(SPRN_SDR1));
90} 464}
91 465
92static void mfc_sr1_set(struct spu *spu, u64 sr1) 466static void mfc_sr1_set(struct spu *spu, u64 sr1)
93{ 467{
94 out_be64(&spu->priv1->mfc_sr1_RW, sr1); 468 out_be64(&spu_get_pdata(spu)->priv1->mfc_sr1_RW, sr1);
95} 469}
96 470
97static u64 mfc_sr1_get(struct spu *spu) 471static u64 mfc_sr1_get(struct spu *spu)
98{ 472{
99 return in_be64(&spu->priv1->mfc_sr1_RW); 473 return in_be64(&spu_get_pdata(spu)->priv1->mfc_sr1_RW);
100} 474}
101 475
102static void mfc_tclass_id_set(struct spu *spu, u64 tclass_id) 476static void mfc_tclass_id_set(struct spu *spu, u64 tclass_id)
103{ 477{
104 out_be64(&spu->priv1->mfc_tclass_id_RW, tclass_id); 478 out_be64(&spu_get_pdata(spu)->priv1->mfc_tclass_id_RW, tclass_id);
105} 479}
106 480
107static u64 mfc_tclass_id_get(struct spu *spu) 481static u64 mfc_tclass_id_get(struct spu *spu)
108{ 482{
109 return in_be64(&spu->priv1->mfc_tclass_id_RW); 483 return in_be64(&spu_get_pdata(spu)->priv1->mfc_tclass_id_RW);
110} 484}
111 485
112static void tlb_invalidate(struct spu *spu) 486static void tlb_invalidate(struct spu *spu)
113{ 487{
114 out_be64(&spu->priv1->tlb_invalidate_entry_W, 0ul); 488 out_be64(&spu_get_pdata(spu)->priv1->tlb_invalidate_entry_W, 0ul);
115} 489}
116 490
117static void resource_allocation_groupID_set(struct spu *spu, u64 id) 491static void resource_allocation_groupID_set(struct spu *spu, u64 id)
118{ 492{
119 out_be64(&spu->priv1->resource_allocation_groupID_RW, id); 493 out_be64(&spu_get_pdata(spu)->priv1->resource_allocation_groupID_RW,
494 id);
120} 495}
121 496
122static u64 resource_allocation_groupID_get(struct spu *spu) 497static u64 resource_allocation_groupID_get(struct spu *spu)
123{ 498{
124 return in_be64(&spu->priv1->resource_allocation_groupID_RW); 499 return in_be64(
500 &spu_get_pdata(spu)->priv1->resource_allocation_groupID_RW);
125} 501}
126 502
127static void resource_allocation_enable_set(struct spu *spu, u64 enable) 503static void resource_allocation_enable_set(struct spu *spu, u64 enable)
128{ 504{
129 out_be64(&spu->priv1->resource_allocation_enable_RW, enable); 505 out_be64(&spu_get_pdata(spu)->priv1->resource_allocation_enable_RW,
506 enable);
130} 507}
131 508
132static u64 resource_allocation_enable_get(struct spu *spu) 509static u64 resource_allocation_enable_get(struct spu *spu)
133{ 510{
134 return in_be64(&spu->priv1->resource_allocation_enable_RW); 511 return in_be64(
512 &spu_get_pdata(spu)->priv1->resource_allocation_enable_RW);
135} 513}
136 514
137const struct spu_priv1_ops spu_priv1_mmio_ops = 515const struct spu_priv1_ops spu_priv1_mmio_ops =
@@ -146,7 +524,7 @@ const struct spu_priv1_ops spu_priv1_mmio_ops =
146 .mfc_dar_get = mfc_dar_get, 524 .mfc_dar_get = mfc_dar_get,
147 .mfc_dsisr_get = mfc_dsisr_get, 525 .mfc_dsisr_get = mfc_dsisr_get,
148 .mfc_dsisr_set = mfc_dsisr_set, 526 .mfc_dsisr_set = mfc_dsisr_set,
149 .mfc_sdr_set = mfc_sdr_set, 527 .mfc_sdr_setup = mfc_sdr_setup,
150 .mfc_sr1_set = mfc_sr1_set, 528 .mfc_sr1_set = mfc_sr1_set,
151 .mfc_sr1_get = mfc_sr1_get, 529 .mfc_sr1_get = mfc_sr1_get,
152 .mfc_tclass_id_set = mfc_tclass_id_set, 530 .mfc_tclass_id_set = mfc_tclass_id_set,
diff --git a/arch/powerpc/platforms/cell/spu_priv1_mmio.h b/arch/powerpc/platforms/cell/spu_priv1_mmio.h
new file mode 100644
index 000000000000..7b62bd1cc256
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spu_priv1_mmio.h
@@ -0,0 +1,26 @@
1/*
2 * spu hypervisor abstraction for direct hardware access.
3 *
4 * Copyright (C) 2006 Sony Computer Entertainment Inc.
5 * Copyright 2006 Sony Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#ifndef SPU_PRIV1_MMIO_H
22#define SPU_PRIV1_MMIO_H
23
24struct device_node *spu_devnode(struct spu *spu);
25
26#endif /* SPU_PRIV1_MMIO_H */
diff --git a/arch/powerpc/platforms/cell/spufs/Makefile b/arch/powerpc/platforms/cell/spufs/Makefile
index ecdfbb35f82e..472217d19faf 100644
--- a/arch/powerpc/platforms/cell/spufs/Makefile
+++ b/arch/powerpc/platforms/cell/spufs/Makefile
@@ -1,7 +1,7 @@
1obj-y += switch.o 1obj-y += switch.o
2 2
3obj-$(CONFIG_SPU_FS) += spufs.o 3obj-$(CONFIG_SPU_FS) += spufs.o
4spufs-y += inode.o file.o context.o syscalls.o 4spufs-y += inode.o file.o context.o syscalls.o coredump.o
5spufs-y += sched.o backing_ops.o hw_ops.o run.o gang.o 5spufs-y += sched.o backing_ops.o hw_ops.o run.o gang.o
6 6
7# Rules to build switch.o with the help of SPU tool chain 7# Rules to build switch.o with the help of SPU tool chain
diff --git a/arch/powerpc/platforms/cell/spufs/backing_ops.c b/arch/powerpc/platforms/cell/spufs/backing_ops.c
index 2d22cd59d6fc..1898f0d3a8b8 100644
--- a/arch/powerpc/platforms/cell/spufs/backing_ops.c
+++ b/arch/powerpc/platforms/cell/spufs/backing_ops.c
@@ -36,6 +36,7 @@
36#include <asm/io.h> 36#include <asm/io.h>
37#include <asm/spu.h> 37#include <asm/spu.h>
38#include <asm/spu_csa.h> 38#include <asm/spu_csa.h>
39#include <asm/spu_info.h>
39#include <asm/mmu_context.h> 40#include <asm/mmu_context.h>
40#include "spufs.h" 41#include "spufs.h"
41 42
@@ -267,6 +268,11 @@ static char *spu_backing_get_ls(struct spu_context *ctx)
267 return ctx->csa.lscsa->ls; 268 return ctx->csa.lscsa->ls;
268} 269}
269 270
271static u32 spu_backing_runcntl_read(struct spu_context *ctx)
272{
273 return ctx->csa.prob.spu_runcntl_RW;
274}
275
270static void spu_backing_runcntl_write(struct spu_context *ctx, u32 val) 276static void spu_backing_runcntl_write(struct spu_context *ctx, u32 val)
271{ 277{
272 spin_lock(&ctx->csa.register_lock); 278 spin_lock(&ctx->csa.register_lock);
@@ -279,9 +285,26 @@ static void spu_backing_runcntl_write(struct spu_context *ctx, u32 val)
279 spin_unlock(&ctx->csa.register_lock); 285 spin_unlock(&ctx->csa.register_lock);
280} 286}
281 287
282static void spu_backing_runcntl_stop(struct spu_context *ctx) 288static void spu_backing_master_start(struct spu_context *ctx)
289{
290 struct spu_state *csa = &ctx->csa;
291 u64 sr1;
292
293 spin_lock(&csa->register_lock);
294 sr1 = csa->priv1.mfc_sr1_RW | MFC_STATE1_MASTER_RUN_CONTROL_MASK;
295 csa->priv1.mfc_sr1_RW = sr1;
296 spin_unlock(&csa->register_lock);
297}
298
299static void spu_backing_master_stop(struct spu_context *ctx)
283{ 300{
284 spu_backing_runcntl_write(ctx, SPU_RUNCNTL_STOP); 301 struct spu_state *csa = &ctx->csa;
302 u64 sr1;
303
304 spin_lock(&csa->register_lock);
305 sr1 = csa->priv1.mfc_sr1_RW & ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
306 csa->priv1.mfc_sr1_RW = sr1;
307 spin_unlock(&csa->register_lock);
285} 308}
286 309
287static int spu_backing_set_mfc_query(struct spu_context * ctx, u32 mask, 310static int spu_backing_set_mfc_query(struct spu_context * ctx, u32 mask,
@@ -345,8 +368,10 @@ struct spu_context_ops spu_backing_ops = {
345 .npc_write = spu_backing_npc_write, 368 .npc_write = spu_backing_npc_write,
346 .status_read = spu_backing_status_read, 369 .status_read = spu_backing_status_read,
347 .get_ls = spu_backing_get_ls, 370 .get_ls = spu_backing_get_ls,
371 .runcntl_read = spu_backing_runcntl_read,
348 .runcntl_write = spu_backing_runcntl_write, 372 .runcntl_write = spu_backing_runcntl_write,
349 .runcntl_stop = spu_backing_runcntl_stop, 373 .master_start = spu_backing_master_start,
374 .master_stop = spu_backing_master_stop,
350 .set_mfc_query = spu_backing_set_mfc_query, 375 .set_mfc_query = spu_backing_set_mfc_query,
351 .read_mfc_tagstatus = spu_backing_read_mfc_tagstatus, 376 .read_mfc_tagstatus = spu_backing_read_mfc_tagstatus,
352 .get_mfc_free_elements = spu_backing_get_mfc_free_elements, 377 .get_mfc_free_elements = spu_backing_get_mfc_free_elements,
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c
index 034cf6af53a2..0870009f56db 100644
--- a/arch/powerpc/platforms/cell/spufs/context.c
+++ b/arch/powerpc/platforms/cell/spufs/context.c
@@ -120,6 +120,33 @@ void spu_unmap_mappings(struct spu_context *ctx)
120 unmap_mapping_range(ctx->signal2, 0, 0x4000, 1); 120 unmap_mapping_range(ctx->signal2, 0, 0x4000, 1);
121} 121}
122 122
123int spu_acquire_exclusive(struct spu_context *ctx)
124{
125 int ret = 0;
126
127 down_write(&ctx->state_sema);
128 /* ctx is about to be freed, can't acquire any more */
129 if (!ctx->owner) {
130 ret = -EINVAL;
131 goto out;
132 }
133
134 if (ctx->state == SPU_STATE_SAVED) {
135 ret = spu_activate(ctx, 0);
136 if (ret)
137 goto out;
138 ctx->state = SPU_STATE_RUNNABLE;
139 } else {
140 /* We need to exclude userspace access to the context. */
141 spu_unmap_mappings(ctx);
142 }
143
144out:
145 if (ret)
146 up_write(&ctx->state_sema);
147 return ret;
148}
149
123int spu_acquire_runnable(struct spu_context *ctx) 150int spu_acquire_runnable(struct spu_context *ctx)
124{ 151{
125 int ret = 0; 152 int ret = 0;
diff --git a/arch/powerpc/platforms/cell/spufs/coredump.c b/arch/powerpc/platforms/cell/spufs/coredump.c
new file mode 100644
index 000000000000..26945c491f6b
--- /dev/null
+++ b/arch/powerpc/platforms/cell/spufs/coredump.c
@@ -0,0 +1,238 @@
1/*
2 * SPU core dump code
3 *
4 * (C) Copyright 2006 IBM Corp.
5 *
6 * Author: Dwayne Grant McConnell <decimal@us.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#include <linux/elf.h>
24#include <linux/file.h>
25#include <linux/fs.h>
26#include <linux/list.h>
27#include <linux/module.h>
28#include <linux/syscalls.h>
29
30#include <asm/uaccess.h>
31
32#include "spufs.h"
33
34struct spufs_ctx_info {
35 struct list_head list;
36 int dfd;
37 int memsize; /* in bytes */
38 struct spu_context *ctx;
39};
40
41static LIST_HEAD(ctx_info_list);
42
43static ssize_t do_coredump_read(int num, struct spu_context *ctx, void __user *buffer,
44 size_t size, loff_t *off)
45{
46 u64 data;
47 int ret;
48
49 if (spufs_coredump_read[num].read)
50 return spufs_coredump_read[num].read(ctx, buffer, size, off);
51
52 data = spufs_coredump_read[num].get(ctx);
53 ret = copy_to_user(buffer, &data, 8);
54 return ret ? -EFAULT : 8;
55}
56
57/*
58 * These are the only things you should do on a core-file: use only these
59 * functions to write out all the necessary info.
60 */
61static int spufs_dump_write(struct file *file, const void *addr, int nr)
62{
63 return file->f_op->write(file, addr, nr, &file->f_pos) == nr;
64}
65
66static int spufs_dump_seek(struct file *file, loff_t off)
67{
68 if (file->f_op->llseek) {
69 if (file->f_op->llseek(file, off, 0) != off)
70 return 0;
71 } else
72 file->f_pos = off;
73 return 1;
74}
75
76static void spufs_fill_memsize(struct spufs_ctx_info *ctx_info)
77{
78 struct spu_context *ctx;
79 unsigned long long lslr;
80
81 ctx = ctx_info->ctx;
82 lslr = ctx->csa.priv2.spu_lslr_RW;
83 ctx_info->memsize = lslr + 1;
84}
85
86static int spufs_ctx_note_size(struct spufs_ctx_info *ctx_info)
87{
88 int dfd, memsize, i, sz, total = 0;
89 char *name;
90 char fullname[80];
91
92 dfd = ctx_info->dfd;
93 memsize = ctx_info->memsize;
94
95 for (i = 0; spufs_coredump_read[i].name; i++) {
96 name = spufs_coredump_read[i].name;
97 sz = spufs_coredump_read[i].size;
98
99 sprintf(fullname, "SPU/%d/%s", dfd, name);
100
101 total += sizeof(struct elf_note);
102 total += roundup(strlen(fullname) + 1, 4);
103 if (!strcmp(name, "mem"))
104 total += roundup(memsize, 4);
105 else
106 total += roundup(sz, 4);
107 }
108
109 return total;
110}
111
112static int spufs_add_one_context(struct file *file, int dfd)
113{
114 struct spu_context *ctx;
115 struct spufs_ctx_info *ctx_info;
116 int size;
117
118 ctx = SPUFS_I(file->f_dentry->d_inode)->i_ctx;
119 if (ctx->flags & SPU_CREATE_NOSCHED)
120 return 0;
121
122 ctx_info = kzalloc(sizeof(*ctx_info), GFP_KERNEL);
123 if (unlikely(!ctx_info))
124 return -ENOMEM;
125
126 ctx_info->dfd = dfd;
127 ctx_info->ctx = ctx;
128
129 spufs_fill_memsize(ctx_info);
130
131 size = spufs_ctx_note_size(ctx_info);
132 list_add(&ctx_info->list, &ctx_info_list);
133 return size;
134}
135
136/*
137 * The additional architecture-specific notes for Cell are various
138 * context files in the spu context.
139 *
140 * This function iterates over all open file descriptors and sees
141 * if they are a directory in spufs. In that case we use spufs
142 * internal functionality to dump them without needing to actually
143 * open the files.
144 */
145static int spufs_arch_notes_size(void)
146{
147 struct fdtable *fdt = files_fdtable(current->files);
148 int size = 0, fd;
149
150 for (fd = 0; fd < fdt->max_fdset && fd < fdt->max_fds; fd++) {
151 if (FD_ISSET(fd, fdt->open_fds)) {
152 struct file *file = fcheck(fd);
153
154 if (file && file->f_op == &spufs_context_fops) {
155 int rval = spufs_add_one_context(file, fd);
156 if (rval < 0)
157 break;
158 size += rval;
159 }
160 }
161 }
162
163 return size;
164}
165
166static void spufs_arch_write_note(struct spufs_ctx_info *ctx_info, int i,
167 struct file *file)
168{
169 struct spu_context *ctx;
170 loff_t pos = 0;
171 int sz, dfd, rc, total = 0;
172 const int bufsz = 4096;
173 char *name;
174 char fullname[80], *buf;
175 struct elf_note en;
176
177 buf = kmalloc(bufsz, GFP_KERNEL);
178 if (!buf)
179 return;
180
181 dfd = ctx_info->dfd;
182 name = spufs_coredump_read[i].name;
183
184 if (!strcmp(name, "mem"))
185 sz = ctx_info->memsize;
186 else
187 sz = spufs_coredump_read[i].size;
188
189 ctx = ctx_info->ctx;
190 if (!ctx) {
191 return;
192 }
193
194 sprintf(fullname, "SPU/%d/%s", dfd, name);
195 en.n_namesz = strlen(fullname) + 1;
196 en.n_descsz = sz;
197 en.n_type = NT_SPU;
198
199 if (!spufs_dump_write(file, &en, sizeof(en)))
200 return;
201 if (!spufs_dump_write(file, fullname, en.n_namesz))
202 return;
203 if (!spufs_dump_seek(file, roundup((unsigned long)file->f_pos, 4)))
204 return;
205
206 do {
207 rc = do_coredump_read(i, ctx, buf, bufsz, &pos);
208 if (rc > 0) {
209 if (!spufs_dump_write(file, buf, rc))
210 return;
211 total += rc;
212 }
213 } while (rc == bufsz && total < sz);
214
215 spufs_dump_seek(file, roundup((unsigned long)file->f_pos
216 - total + sz, 4));
217}
218
219static void spufs_arch_write_notes(struct file *file)
220{
221 int j;
222 struct spufs_ctx_info *ctx_info, *next;
223
224 list_for_each_entry_safe(ctx_info, next, &ctx_info_list, list) {
225 spu_acquire_saved(ctx_info->ctx);
226 for (j = 0; j < spufs_coredump_num_notes; j++)
227 spufs_arch_write_note(ctx_info, j, file);
228 spu_release(ctx_info->ctx);
229 list_del(&ctx_info->list);
230 kfree(ctx_info);
231 }
232}
233
234struct spu_coredump_calls spufs_coredump_calls = {
235 .arch_notes_size = spufs_arch_notes_size,
236 .arch_write_notes = spufs_arch_write_notes,
237 .owner = THIS_MODULE,
238};
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c
index 533e2723e184..347eff56fcbd 100644
--- a/arch/powerpc/platforms/cell/spufs/file.c
+++ b/arch/powerpc/platforms/cell/spufs/file.c
@@ -32,13 +32,13 @@
32#include <asm/io.h> 32#include <asm/io.h>
33#include <asm/semaphore.h> 33#include <asm/semaphore.h>
34#include <asm/spu.h> 34#include <asm/spu.h>
35#include <asm/spu_info.h>
35#include <asm/uaccess.h> 36#include <asm/uaccess.h>
36 37
37#include "spufs.h" 38#include "spufs.h"
38 39
39#define SPUFS_MMAP_4K (PAGE_SIZE == 0x1000) 40#define SPUFS_MMAP_4K (PAGE_SIZE == 0x1000)
40 41
41
42static int 42static int
43spufs_mem_open(struct inode *inode, struct file *file) 43spufs_mem_open(struct inode *inode, struct file *file)
44{ 44{
@@ -51,18 +51,23 @@ spufs_mem_open(struct inode *inode, struct file *file)
51} 51}
52 52
53static ssize_t 53static ssize_t
54__spufs_mem_read(struct spu_context *ctx, char __user *buffer,
55 size_t size, loff_t *pos)
56{
57 char *local_store = ctx->ops->get_ls(ctx);
58 return simple_read_from_buffer(buffer, size, pos, local_store,
59 LS_SIZE);
60}
61
62static ssize_t
54spufs_mem_read(struct file *file, char __user *buffer, 63spufs_mem_read(struct file *file, char __user *buffer,
55 size_t size, loff_t *pos) 64 size_t size, loff_t *pos)
56{ 65{
57 struct spu_context *ctx = file->private_data;
58 char *local_store;
59 int ret; 66 int ret;
67 struct spu_context *ctx = file->private_data;
60 68
61 spu_acquire(ctx); 69 spu_acquire(ctx);
62 70 ret = __spufs_mem_read(ctx, buffer, size, pos);
63 local_store = ctx->ops->get_ls(ctx);
64 ret = simple_read_from_buffer(buffer, size, pos, local_store, LS_SIZE);
65
66 spu_release(ctx); 71 spu_release(ctx);
67 return ret; 72 return ret;
68} 73}
@@ -104,11 +109,11 @@ spufs_mem_mmap_nopage(struct vm_area_struct *vma,
104 109
105 if (ctx->state == SPU_STATE_SAVED) { 110 if (ctx->state == SPU_STATE_SAVED) {
106 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 111 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
107 & ~(_PAGE_NO_CACHE | _PAGE_GUARDED)); 112 & ~_PAGE_NO_CACHE);
108 page = vmalloc_to_page(ctx->csa.lscsa->ls + offset); 113 page = vmalloc_to_page(ctx->csa.lscsa->ls + offset);
109 } else { 114 } else {
110 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 115 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
111 | _PAGE_NO_CACHE | _PAGE_GUARDED); 116 | _PAGE_NO_CACHE);
112 page = pfn_to_page((ctx->spu->local_store_phys + offset) 117 page = pfn_to_page((ctx->spu->local_store_phys + offset)
113 >> PAGE_SHIFT); 118 >> PAGE_SHIFT);
114 } 119 }
@@ -131,7 +136,7 @@ spufs_mem_mmap(struct file *file, struct vm_area_struct *vma)
131 if (!(vma->vm_flags & VM_SHARED)) 136 if (!(vma->vm_flags & VM_SHARED))
132 return -EINVAL; 137 return -EINVAL;
133 138
134 /* FIXME: */ 139 vma->vm_flags |= VM_IO;
135 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 140 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
136 | _PAGE_NO_CACHE); 141 | _PAGE_NO_CACHE);
137 142
@@ -200,7 +205,7 @@ static int spufs_cntl_mmap(struct file *file, struct vm_area_struct *vma)
200 if (!(vma->vm_flags & VM_SHARED)) 205 if (!(vma->vm_flags & VM_SHARED))
201 return -EINVAL; 206 return -EINVAL;
202 207
203 vma->vm_flags |= VM_RESERVED; 208 vma->vm_flags |= VM_IO;
204 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 209 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
205 | _PAGE_NO_CACHE | _PAGE_GUARDED); 210 | _PAGE_NO_CACHE | _PAGE_GUARDED);
206 211
@@ -261,18 +266,23 @@ spufs_regs_open(struct inode *inode, struct file *file)
261} 266}
262 267
263static ssize_t 268static ssize_t
269__spufs_regs_read(struct spu_context *ctx, char __user *buffer,
270 size_t size, loff_t *pos)
271{
272 struct spu_lscsa *lscsa = ctx->csa.lscsa;
273 return simple_read_from_buffer(buffer, size, pos,
274 lscsa->gprs, sizeof lscsa->gprs);
275}
276
277static ssize_t
264spufs_regs_read(struct file *file, char __user *buffer, 278spufs_regs_read(struct file *file, char __user *buffer,
265 size_t size, loff_t *pos) 279 size_t size, loff_t *pos)
266{ 280{
267 struct spu_context *ctx = file->private_data;
268 struct spu_lscsa *lscsa = ctx->csa.lscsa;
269 int ret; 281 int ret;
282 struct spu_context *ctx = file->private_data;
270 283
271 spu_acquire_saved(ctx); 284 spu_acquire_saved(ctx);
272 285 ret = __spufs_regs_read(ctx, buffer, size, pos);
273 ret = simple_read_from_buffer(buffer, size, pos,
274 lscsa->gprs, sizeof lscsa->gprs);
275
276 spu_release(ctx); 286 spu_release(ctx);
277 return ret; 287 return ret;
278} 288}
@@ -307,18 +317,23 @@ static struct file_operations spufs_regs_fops = {
307}; 317};
308 318
309static ssize_t 319static ssize_t
320__spufs_fpcr_read(struct spu_context *ctx, char __user * buffer,
321 size_t size, loff_t * pos)
322{
323 struct spu_lscsa *lscsa = ctx->csa.lscsa;
324 return simple_read_from_buffer(buffer, size, pos,
325 &lscsa->fpcr, sizeof(lscsa->fpcr));
326}
327
328static ssize_t
310spufs_fpcr_read(struct file *file, char __user * buffer, 329spufs_fpcr_read(struct file *file, char __user * buffer,
311 size_t size, loff_t * pos) 330 size_t size, loff_t * pos)
312{ 331{
313 struct spu_context *ctx = file->private_data;
314 struct spu_lscsa *lscsa = ctx->csa.lscsa;
315 int ret; 332 int ret;
333 struct spu_context *ctx = file->private_data;
316 334
317 spu_acquire_saved(ctx); 335 spu_acquire_saved(ctx);
318 336 ret = __spufs_fpcr_read(ctx, buffer, size, pos);
319 ret = simple_read_from_buffer(buffer, size, pos,
320 &lscsa->fpcr, sizeof(lscsa->fpcr));
321
322 spu_release(ctx); 337 spu_release(ctx);
323 return ret; 338 return ret;
324} 339}
@@ -718,23 +733,41 @@ static int spufs_signal1_open(struct inode *inode, struct file *file)
718 return nonseekable_open(inode, file); 733 return nonseekable_open(inode, file);
719} 734}
720 735
721static ssize_t spufs_signal1_read(struct file *file, char __user *buf, 736static ssize_t __spufs_signal1_read(struct spu_context *ctx, char __user *buf,
722 size_t len, loff_t *pos) 737 size_t len, loff_t *pos)
723{ 738{
724 struct spu_context *ctx = file->private_data; 739 int ret = 0;
725 u32 data; 740 u32 data;
726 741
727 if (len < 4) 742 if (len < 4)
728 return -EINVAL; 743 return -EINVAL;
729 744
730 spu_acquire(ctx); 745 if (ctx->csa.spu_chnlcnt_RW[3]) {
731 data = ctx->ops->signal1_read(ctx); 746 data = ctx->csa.spu_chnldata_RW[3];
732 spu_release(ctx); 747 ret = 4;
748 }
749
750 if (!ret)
751 goto out;
733 752
734 if (copy_to_user(buf, &data, 4)) 753 if (copy_to_user(buf, &data, 4))
735 return -EFAULT; 754 return -EFAULT;
736 755
737 return 4; 756out:
757 return ret;
758}
759
760static ssize_t spufs_signal1_read(struct file *file, char __user *buf,
761 size_t len, loff_t *pos)
762{
763 int ret;
764 struct spu_context *ctx = file->private_data;
765
766 spu_acquire_saved(ctx);
767 ret = __spufs_signal1_read(ctx, buf, len, pos);
768 spu_release(ctx);
769
770 return ret;
738} 771}
739 772
740static ssize_t spufs_signal1_write(struct file *file, const char __user *buf, 773static ssize_t spufs_signal1_write(struct file *file, const char __user *buf,
@@ -782,7 +815,7 @@ static int spufs_signal1_mmap(struct file *file, struct vm_area_struct *vma)
782 if (!(vma->vm_flags & VM_SHARED)) 815 if (!(vma->vm_flags & VM_SHARED))
783 return -EINVAL; 816 return -EINVAL;
784 817
785 vma->vm_flags |= VM_RESERVED; 818 vma->vm_flags |= VM_IO;
786 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 819 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
787 | _PAGE_NO_CACHE | _PAGE_GUARDED); 820 | _PAGE_NO_CACHE | _PAGE_GUARDED);
788 821
@@ -807,25 +840,41 @@ static int spufs_signal2_open(struct inode *inode, struct file *file)
807 return nonseekable_open(inode, file); 840 return nonseekable_open(inode, file);
808} 841}
809 842
810static ssize_t spufs_signal2_read(struct file *file, char __user *buf, 843static ssize_t __spufs_signal2_read(struct spu_context *ctx, char __user *buf,
811 size_t len, loff_t *pos) 844 size_t len, loff_t *pos)
812{ 845{
813 struct spu_context *ctx; 846 int ret = 0;
814 u32 data; 847 u32 data;
815 848
816 ctx = file->private_data;
817
818 if (len < 4) 849 if (len < 4)
819 return -EINVAL; 850 return -EINVAL;
820 851
821 spu_acquire(ctx); 852 if (ctx->csa.spu_chnlcnt_RW[4]) {
822 data = ctx->ops->signal2_read(ctx); 853 data = ctx->csa.spu_chnldata_RW[4];
823 spu_release(ctx); 854 ret = 4;
855 }
856
857 if (!ret)
858 goto out;
824 859
825 if (copy_to_user(buf, &data, 4)) 860 if (copy_to_user(buf, &data, 4))
826 return -EFAULT; 861 return -EFAULT;
827 862
828 return 4; 863out:
864 return ret;
865}
866
867static ssize_t spufs_signal2_read(struct file *file, char __user *buf,
868 size_t len, loff_t *pos)
869{
870 struct spu_context *ctx = file->private_data;
871 int ret;
872
873 spu_acquire_saved(ctx);
874 ret = __spufs_signal2_read(ctx, buf, len, pos);
875 spu_release(ctx);
876
877 return ret;
829} 878}
830 879
831static ssize_t spufs_signal2_write(struct file *file, const char __user *buf, 880static ssize_t spufs_signal2_write(struct file *file, const char __user *buf,
@@ -874,8 +923,7 @@ static int spufs_signal2_mmap(struct file *file, struct vm_area_struct *vma)
874 if (!(vma->vm_flags & VM_SHARED)) 923 if (!(vma->vm_flags & VM_SHARED))
875 return -EINVAL; 924 return -EINVAL;
876 925
877 /* FIXME: */ 926 vma->vm_flags |= VM_IO;
878 vma->vm_flags |= VM_RESERVED;
879 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 927 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
880 | _PAGE_NO_CACHE | _PAGE_GUARDED); 928 | _PAGE_NO_CACHE | _PAGE_GUARDED);
881 929
@@ -902,13 +950,19 @@ static void spufs_signal1_type_set(void *data, u64 val)
902 spu_release(ctx); 950 spu_release(ctx);
903} 951}
904 952
953static u64 __spufs_signal1_type_get(void *data)
954{
955 struct spu_context *ctx = data;
956 return ctx->ops->signal1_type_get(ctx);
957}
958
905static u64 spufs_signal1_type_get(void *data) 959static u64 spufs_signal1_type_get(void *data)
906{ 960{
907 struct spu_context *ctx = data; 961 struct spu_context *ctx = data;
908 u64 ret; 962 u64 ret;
909 963
910 spu_acquire(ctx); 964 spu_acquire(ctx);
911 ret = ctx->ops->signal1_type_get(ctx); 965 ret = __spufs_signal1_type_get(data);
912 spu_release(ctx); 966 spu_release(ctx);
913 967
914 return ret; 968 return ret;
@@ -925,13 +979,19 @@ static void spufs_signal2_type_set(void *data, u64 val)
925 spu_release(ctx); 979 spu_release(ctx);
926} 980}
927 981
982static u64 __spufs_signal2_type_get(void *data)
983{
984 struct spu_context *ctx = data;
985 return ctx->ops->signal2_type_get(ctx);
986}
987
928static u64 spufs_signal2_type_get(void *data) 988static u64 spufs_signal2_type_get(void *data)
929{ 989{
930 struct spu_context *ctx = data; 990 struct spu_context *ctx = data;
931 u64 ret; 991 u64 ret;
932 992
933 spu_acquire(ctx); 993 spu_acquire(ctx);
934 ret = ctx->ops->signal2_type_get(ctx); 994 ret = __spufs_signal2_type_get(data);
935 spu_release(ctx); 995 spu_release(ctx);
936 996
937 return ret; 997 return ret;
@@ -958,7 +1018,7 @@ static int spufs_mss_mmap(struct file *file, struct vm_area_struct *vma)
958 if (!(vma->vm_flags & VM_SHARED)) 1018 if (!(vma->vm_flags & VM_SHARED))
959 return -EINVAL; 1019 return -EINVAL;
960 1020
961 vma->vm_flags |= VM_RESERVED; 1021 vma->vm_flags |= VM_IO;
962 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 1022 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
963 | _PAGE_NO_CACHE | _PAGE_GUARDED); 1023 | _PAGE_NO_CACHE | _PAGE_GUARDED);
964 1024
@@ -1000,7 +1060,7 @@ static int spufs_psmap_mmap(struct file *file, struct vm_area_struct *vma)
1000 if (!(vma->vm_flags & VM_SHARED)) 1060 if (!(vma->vm_flags & VM_SHARED))
1001 return -EINVAL; 1061 return -EINVAL;
1002 1062
1003 vma->vm_flags |= VM_RESERVED; 1063 vma->vm_flags |= VM_IO;
1004 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 1064 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
1005 | _PAGE_NO_CACHE | _PAGE_GUARDED); 1065 | _PAGE_NO_CACHE | _PAGE_GUARDED);
1006 1066
@@ -1041,7 +1101,7 @@ static int spufs_mfc_mmap(struct file *file, struct vm_area_struct *vma)
1041 if (!(vma->vm_flags & VM_SHARED)) 1101 if (!(vma->vm_flags & VM_SHARED))
1042 return -EINVAL; 1102 return -EINVAL;
1043 1103
1044 vma->vm_flags |= VM_RESERVED; 1104 vma->vm_flags |= VM_IO;
1045 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) 1105 vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot)
1046 | _PAGE_NO_CACHE | _PAGE_GUARDED); 1106 | _PAGE_NO_CACHE | _PAGE_GUARDED);
1047 1107
@@ -1265,6 +1325,7 @@ static ssize_t spufs_mfc_write(struct file *file, const char __user *buffer,
1265 goto out; 1325 goto out;
1266 1326
1267 ctx->tagwait |= 1 << cmd.tag; 1327 ctx->tagwait |= 1 << cmd.tag;
1328 ret = size;
1268 1329
1269out: 1330out:
1270 return ret; 1331 return ret;
@@ -1360,7 +1421,8 @@ static u64 spufs_npc_get(void *data)
1360 spu_release(ctx); 1421 spu_release(ctx);
1361 return ret; 1422 return ret;
1362} 1423}
1363DEFINE_SIMPLE_ATTRIBUTE(spufs_npc_ops, spufs_npc_get, spufs_npc_set, "%llx\n") 1424DEFINE_SIMPLE_ATTRIBUTE(spufs_npc_ops, spufs_npc_get, spufs_npc_set,
1425 "0x%llx\n")
1364 1426
1365static void spufs_decr_set(void *data, u64 val) 1427static void spufs_decr_set(void *data, u64 val)
1366{ 1428{
@@ -1371,18 +1433,24 @@ static void spufs_decr_set(void *data, u64 val)
1371 spu_release(ctx); 1433 spu_release(ctx);
1372} 1434}
1373 1435
1374static u64 spufs_decr_get(void *data) 1436static u64 __spufs_decr_get(void *data)
1375{ 1437{
1376 struct spu_context *ctx = data; 1438 struct spu_context *ctx = data;
1377 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1439 struct spu_lscsa *lscsa = ctx->csa.lscsa;
1440 return lscsa->decr.slot[0];
1441}
1442
1443static u64 spufs_decr_get(void *data)
1444{
1445 struct spu_context *ctx = data;
1378 u64 ret; 1446 u64 ret;
1379 spu_acquire_saved(ctx); 1447 spu_acquire_saved(ctx);
1380 ret = lscsa->decr.slot[0]; 1448 ret = __spufs_decr_get(data);
1381 spu_release(ctx); 1449 spu_release(ctx);
1382 return ret; 1450 return ret;
1383} 1451}
1384DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_ops, spufs_decr_get, spufs_decr_set, 1452DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_ops, spufs_decr_get, spufs_decr_set,
1385 "%llx\n") 1453 "0x%llx\n")
1386 1454
1387static void spufs_decr_status_set(void *data, u64 val) 1455static void spufs_decr_status_set(void *data, u64 val)
1388{ 1456{
@@ -1393,62 +1461,76 @@ static void spufs_decr_status_set(void *data, u64 val)
1393 spu_release(ctx); 1461 spu_release(ctx);
1394} 1462}
1395 1463
1396static u64 spufs_decr_status_get(void *data) 1464static u64 __spufs_decr_status_get(void *data)
1397{ 1465{
1398 struct spu_context *ctx = data; 1466 struct spu_context *ctx = data;
1399 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1467 struct spu_lscsa *lscsa = ctx->csa.lscsa;
1468 return lscsa->decr_status.slot[0];
1469}
1470
1471static u64 spufs_decr_status_get(void *data)
1472{
1473 struct spu_context *ctx = data;
1400 u64 ret; 1474 u64 ret;
1401 spu_acquire_saved(ctx); 1475 spu_acquire_saved(ctx);
1402 ret = lscsa->decr_status.slot[0]; 1476 ret = __spufs_decr_status_get(data);
1403 spu_release(ctx); 1477 spu_release(ctx);
1404 return ret; 1478 return ret;
1405} 1479}
1406DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_status_ops, spufs_decr_status_get, 1480DEFINE_SIMPLE_ATTRIBUTE(spufs_decr_status_ops, spufs_decr_status_get,
1407 spufs_decr_status_set, "%llx\n") 1481 spufs_decr_status_set, "0x%llx\n")
1408 1482
1409static void spufs_spu_tag_mask_set(void *data, u64 val) 1483static void spufs_event_mask_set(void *data, u64 val)
1410{ 1484{
1411 struct spu_context *ctx = data; 1485 struct spu_context *ctx = data;
1412 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1486 struct spu_lscsa *lscsa = ctx->csa.lscsa;
1413 spu_acquire_saved(ctx); 1487 spu_acquire_saved(ctx);
1414 lscsa->tag_mask.slot[0] = (u32) val; 1488 lscsa->event_mask.slot[0] = (u32) val;
1415 spu_release(ctx); 1489 spu_release(ctx);
1416} 1490}
1417 1491
1418static u64 spufs_spu_tag_mask_get(void *data) 1492static u64 __spufs_event_mask_get(void *data)
1419{ 1493{
1420 struct spu_context *ctx = data; 1494 struct spu_context *ctx = data;
1421 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1495 struct spu_lscsa *lscsa = ctx->csa.lscsa;
1496 return lscsa->event_mask.slot[0];
1497}
1498
1499static u64 spufs_event_mask_get(void *data)
1500{
1501 struct spu_context *ctx = data;
1422 u64 ret; 1502 u64 ret;
1423 spu_acquire_saved(ctx); 1503 spu_acquire_saved(ctx);
1424 ret = lscsa->tag_mask.slot[0]; 1504 ret = __spufs_event_mask_get(data);
1425 spu_release(ctx); 1505 spu_release(ctx);
1426 return ret; 1506 return ret;
1427} 1507}
1428DEFINE_SIMPLE_ATTRIBUTE(spufs_spu_tag_mask_ops, spufs_spu_tag_mask_get, 1508DEFINE_SIMPLE_ATTRIBUTE(spufs_event_mask_ops, spufs_event_mask_get,
1429 spufs_spu_tag_mask_set, "%llx\n") 1509 spufs_event_mask_set, "0x%llx\n")
1430 1510
1431static void spufs_event_mask_set(void *data, u64 val) 1511static u64 __spufs_event_status_get(void *data)
1432{ 1512{
1433 struct spu_context *ctx = data; 1513 struct spu_context *ctx = data;
1434 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1514 struct spu_state *state = &ctx->csa;
1435 spu_acquire_saved(ctx); 1515 u64 stat;
1436 lscsa->event_mask.slot[0] = (u32) val; 1516 stat = state->spu_chnlcnt_RW[0];
1437 spu_release(ctx); 1517 if (stat)
1518 return state->spu_chnldata_RW[0];
1519 return 0;
1438} 1520}
1439 1521
1440static u64 spufs_event_mask_get(void *data) 1522static u64 spufs_event_status_get(void *data)
1441{ 1523{
1442 struct spu_context *ctx = data; 1524 struct spu_context *ctx = data;
1443 struct spu_lscsa *lscsa = ctx->csa.lscsa; 1525 u64 ret = 0;
1444 u64 ret; 1526
1445 spu_acquire_saved(ctx); 1527 spu_acquire_saved(ctx);
1446 ret = lscsa->event_mask.slot[0]; 1528 ret = __spufs_event_status_get(data);
1447 spu_release(ctx); 1529 spu_release(ctx);
1448 return ret; 1530 return ret;
1449} 1531}
1450DEFINE_SIMPLE_ATTRIBUTE(spufs_event_mask_ops, spufs_event_mask_get, 1532DEFINE_SIMPLE_ATTRIBUTE(spufs_event_status_ops, spufs_event_status_get,
1451 spufs_event_mask_set, "%llx\n") 1533 NULL, "0x%llx\n")
1452 1534
1453static void spufs_srr0_set(void *data, u64 val) 1535static void spufs_srr0_set(void *data, u64 val)
1454{ 1536{
@@ -1470,7 +1552,7 @@ static u64 spufs_srr0_get(void *data)
1470 return ret; 1552 return ret;
1471} 1553}
1472DEFINE_SIMPLE_ATTRIBUTE(spufs_srr0_ops, spufs_srr0_get, spufs_srr0_set, 1554DEFINE_SIMPLE_ATTRIBUTE(spufs_srr0_ops, spufs_srr0_get, spufs_srr0_set,
1473 "%llx\n") 1555 "0x%llx\n")
1474 1556
1475static u64 spufs_id_get(void *data) 1557static u64 spufs_id_get(void *data)
1476{ 1558{
@@ -1488,12 +1570,18 @@ static u64 spufs_id_get(void *data)
1488} 1570}
1489DEFINE_SIMPLE_ATTRIBUTE(spufs_id_ops, spufs_id_get, NULL, "0x%llx\n") 1571DEFINE_SIMPLE_ATTRIBUTE(spufs_id_ops, spufs_id_get, NULL, "0x%llx\n")
1490 1572
1491static u64 spufs_object_id_get(void *data) 1573static u64 __spufs_object_id_get(void *data)
1492{ 1574{
1493 struct spu_context *ctx = data; 1575 struct spu_context *ctx = data;
1494 return ctx->object_id; 1576 return ctx->object_id;
1495} 1577}
1496 1578
1579static u64 spufs_object_id_get(void *data)
1580{
1581 /* FIXME: Should there really be no locking here? */
1582 return __spufs_object_id_get(data);
1583}
1584
1497static void spufs_object_id_set(void *data, u64 id) 1585static void spufs_object_id_set(void *data, u64 id)
1498{ 1586{
1499 struct spu_context *ctx = data; 1587 struct spu_context *ctx = data;
@@ -1503,6 +1591,250 @@ static void spufs_object_id_set(void *data, u64 id)
1503DEFINE_SIMPLE_ATTRIBUTE(spufs_object_id_ops, spufs_object_id_get, 1591DEFINE_SIMPLE_ATTRIBUTE(spufs_object_id_ops, spufs_object_id_get,
1504 spufs_object_id_set, "0x%llx\n"); 1592 spufs_object_id_set, "0x%llx\n");
1505 1593
1594static u64 __spufs_lslr_get(void *data)
1595{
1596 struct spu_context *ctx = data;
1597 return ctx->csa.priv2.spu_lslr_RW;
1598}
1599
1600static u64 spufs_lslr_get(void *data)
1601{
1602 struct spu_context *ctx = data;
1603 u64 ret;
1604
1605 spu_acquire_saved(ctx);
1606 ret = __spufs_lslr_get(data);
1607 spu_release(ctx);
1608
1609 return ret;
1610}
1611DEFINE_SIMPLE_ATTRIBUTE(spufs_lslr_ops, spufs_lslr_get, NULL, "0x%llx\n")
1612
1613static int spufs_info_open(struct inode *inode, struct file *file)
1614{
1615 struct spufs_inode_info *i = SPUFS_I(inode);
1616 struct spu_context *ctx = i->i_ctx;
1617 file->private_data = ctx;
1618 return 0;
1619}
1620
1621static ssize_t __spufs_mbox_info_read(struct spu_context *ctx,
1622 char __user *buf, size_t len, loff_t *pos)
1623{
1624 u32 mbox_stat;
1625 u32 data;
1626
1627 mbox_stat = ctx->csa.prob.mb_stat_R;
1628 if (mbox_stat & 0x0000ff) {
1629 data = ctx->csa.prob.pu_mb_R;
1630 }
1631
1632 return simple_read_from_buffer(buf, len, pos, &data, sizeof data);
1633}
1634
1635static ssize_t spufs_mbox_info_read(struct file *file, char __user *buf,
1636 size_t len, loff_t *pos)
1637{
1638 int ret;
1639 struct spu_context *ctx = file->private_data;
1640
1641 if (!access_ok(VERIFY_WRITE, buf, len))
1642 return -EFAULT;
1643
1644 spu_acquire_saved(ctx);
1645 spin_lock(&ctx->csa.register_lock);
1646 ret = __spufs_mbox_info_read(ctx, buf, len, pos);
1647 spin_unlock(&ctx->csa.register_lock);
1648 spu_release(ctx);
1649
1650 return ret;
1651}
1652
1653static struct file_operations spufs_mbox_info_fops = {
1654 .open = spufs_info_open,
1655 .read = spufs_mbox_info_read,
1656 .llseek = generic_file_llseek,
1657};
1658
1659static ssize_t __spufs_ibox_info_read(struct spu_context *ctx,
1660 char __user *buf, size_t len, loff_t *pos)
1661{
1662 u32 ibox_stat;
1663 u32 data;
1664
1665 ibox_stat = ctx->csa.prob.mb_stat_R;
1666 if (ibox_stat & 0xff0000) {
1667 data = ctx->csa.priv2.puint_mb_R;
1668 }
1669
1670 return simple_read_from_buffer(buf, len, pos, &data, sizeof data);
1671}
1672
1673static ssize_t spufs_ibox_info_read(struct file *file, char __user *buf,
1674 size_t len, loff_t *pos)
1675{
1676 struct spu_context *ctx = file->private_data;
1677 int ret;
1678
1679 if (!access_ok(VERIFY_WRITE, buf, len))
1680 return -EFAULT;
1681
1682 spu_acquire_saved(ctx);
1683 spin_lock(&ctx->csa.register_lock);
1684 ret = __spufs_ibox_info_read(ctx, buf, len, pos);
1685 spin_unlock(&ctx->csa.register_lock);
1686 spu_release(ctx);
1687
1688 return ret;
1689}
1690
1691static struct file_operations spufs_ibox_info_fops = {
1692 .open = spufs_info_open,
1693 .read = spufs_ibox_info_read,
1694 .llseek = generic_file_llseek,
1695};
1696
1697static ssize_t __spufs_wbox_info_read(struct spu_context *ctx,
1698 char __user *buf, size_t len, loff_t *pos)
1699{
1700 int i, cnt;
1701 u32 data[4];
1702 u32 wbox_stat;
1703
1704 wbox_stat = ctx->csa.prob.mb_stat_R;
1705 cnt = 4 - ((wbox_stat & 0x00ff00) >> 8);
1706 for (i = 0; i < cnt; i++) {
1707 data[i] = ctx->csa.spu_mailbox_data[i];
1708 }
1709
1710 return simple_read_from_buffer(buf, len, pos, &data,
1711 cnt * sizeof(u32));
1712}
1713
1714static ssize_t spufs_wbox_info_read(struct file *file, char __user *buf,
1715 size_t len, loff_t *pos)
1716{
1717 struct spu_context *ctx = file->private_data;
1718 int ret;
1719
1720 if (!access_ok(VERIFY_WRITE, buf, len))
1721 return -EFAULT;
1722
1723 spu_acquire_saved(ctx);
1724 spin_lock(&ctx->csa.register_lock);
1725 ret = __spufs_wbox_info_read(ctx, buf, len, pos);
1726 spin_unlock(&ctx->csa.register_lock);
1727 spu_release(ctx);
1728
1729 return ret;
1730}
1731
1732static struct file_operations spufs_wbox_info_fops = {
1733 .open = spufs_info_open,
1734 .read = spufs_wbox_info_read,
1735 .llseek = generic_file_llseek,
1736};
1737
1738static ssize_t __spufs_dma_info_read(struct spu_context *ctx,
1739 char __user *buf, size_t len, loff_t *pos)
1740{
1741 struct spu_dma_info info;
1742 struct mfc_cq_sr *qp, *spuqp;
1743 int i;
1744
1745 info.dma_info_type = ctx->csa.priv2.spu_tag_status_query_RW;
1746 info.dma_info_mask = ctx->csa.lscsa->tag_mask.slot[0];
1747 info.dma_info_status = ctx->csa.spu_chnldata_RW[24];
1748 info.dma_info_stall_and_notify = ctx->csa.spu_chnldata_RW[25];
1749 info.dma_info_atomic_command_status = ctx->csa.spu_chnldata_RW[27];
1750 for (i = 0; i < 16; i++) {
1751 qp = &info.dma_info_command_data[i];
1752 spuqp = &ctx->csa.priv2.spuq[i];
1753
1754 qp->mfc_cq_data0_RW = spuqp->mfc_cq_data0_RW;
1755 qp->mfc_cq_data1_RW = spuqp->mfc_cq_data1_RW;
1756 qp->mfc_cq_data2_RW = spuqp->mfc_cq_data2_RW;
1757 qp->mfc_cq_data3_RW = spuqp->mfc_cq_data3_RW;
1758 }
1759
1760 return simple_read_from_buffer(buf, len, pos, &info,
1761 sizeof info);
1762}
1763
1764static ssize_t spufs_dma_info_read(struct file *file, char __user *buf,
1765 size_t len, loff_t *pos)
1766{
1767 struct spu_context *ctx = file->private_data;
1768 int ret;
1769
1770 if (!access_ok(VERIFY_WRITE, buf, len))
1771 return -EFAULT;
1772
1773 spu_acquire_saved(ctx);
1774 spin_lock(&ctx->csa.register_lock);
1775 ret = __spufs_dma_info_read(ctx, buf, len, pos);
1776 spin_unlock(&ctx->csa.register_lock);
1777 spu_release(ctx);
1778
1779 return ret;
1780}
1781
1782static struct file_operations spufs_dma_info_fops = {
1783 .open = spufs_info_open,
1784 .read = spufs_dma_info_read,
1785};
1786
1787static ssize_t __spufs_proxydma_info_read(struct spu_context *ctx,
1788 char __user *buf, size_t len, loff_t *pos)
1789{
1790 struct spu_proxydma_info info;
1791 struct mfc_cq_sr *qp, *puqp;
1792 int ret = sizeof info;
1793 int i;
1794
1795 if (len < ret)
1796 return -EINVAL;
1797
1798 if (!access_ok(VERIFY_WRITE, buf, len))
1799 return -EFAULT;
1800
1801 info.proxydma_info_type = ctx->csa.prob.dma_querytype_RW;
1802 info.proxydma_info_mask = ctx->csa.prob.dma_querymask_RW;
1803 info.proxydma_info_status = ctx->csa.prob.dma_tagstatus_R;
1804 for (i = 0; i < 8; i++) {
1805 qp = &info.proxydma_info_command_data[i];
1806 puqp = &ctx->csa.priv2.puq[i];
1807
1808 qp->mfc_cq_data0_RW = puqp->mfc_cq_data0_RW;
1809 qp->mfc_cq_data1_RW = puqp->mfc_cq_data1_RW;
1810 qp->mfc_cq_data2_RW = puqp->mfc_cq_data2_RW;
1811 qp->mfc_cq_data3_RW = puqp->mfc_cq_data3_RW;
1812 }
1813
1814 return simple_read_from_buffer(buf, len, pos, &info,
1815 sizeof info);
1816}
1817
1818static ssize_t spufs_proxydma_info_read(struct file *file, char __user *buf,
1819 size_t len, loff_t *pos)
1820{
1821 struct spu_context *ctx = file->private_data;
1822 int ret;
1823
1824 spu_acquire_saved(ctx);
1825 spin_lock(&ctx->csa.register_lock);
1826 ret = __spufs_proxydma_info_read(ctx, buf, len, pos);
1827 spin_unlock(&ctx->csa.register_lock);
1828 spu_release(ctx);
1829
1830 return ret;
1831}
1832
1833static struct file_operations spufs_proxydma_info_fops = {
1834 .open = spufs_info_open,
1835 .read = spufs_proxydma_info_read,
1836};
1837
1506struct tree_descr spufs_dir_contents[] = { 1838struct tree_descr spufs_dir_contents[] = {
1507 { "mem", &spufs_mem_fops, 0666, }, 1839 { "mem", &spufs_mem_fops, 0666, },
1508 { "regs", &spufs_regs_fops, 0666, }, 1840 { "regs", &spufs_regs_fops, 0666, },
@@ -1516,18 +1848,70 @@ struct tree_descr spufs_dir_contents[] = {
1516 { "signal2", &spufs_signal2_fops, 0666, }, 1848 { "signal2", &spufs_signal2_fops, 0666, },
1517 { "signal1_type", &spufs_signal1_type, 0666, }, 1849 { "signal1_type", &spufs_signal1_type, 0666, },
1518 { "signal2_type", &spufs_signal2_type, 0666, }, 1850 { "signal2_type", &spufs_signal2_type, 0666, },
1519 { "mss", &spufs_mss_fops, 0666, },
1520 { "mfc", &spufs_mfc_fops, 0666, },
1521 { "cntl", &spufs_cntl_fops, 0666, }, 1851 { "cntl", &spufs_cntl_fops, 0666, },
1522 { "npc", &spufs_npc_ops, 0666, },
1523 { "fpcr", &spufs_fpcr_fops, 0666, }, 1852 { "fpcr", &spufs_fpcr_fops, 0666, },
1853 { "lslr", &spufs_lslr_ops, 0444, },
1854 { "mfc", &spufs_mfc_fops, 0666, },
1855 { "mss", &spufs_mss_fops, 0666, },
1856 { "npc", &spufs_npc_ops, 0666, },
1857 { "srr0", &spufs_srr0_ops, 0666, },
1524 { "decr", &spufs_decr_ops, 0666, }, 1858 { "decr", &spufs_decr_ops, 0666, },
1525 { "decr_status", &spufs_decr_status_ops, 0666, }, 1859 { "decr_status", &spufs_decr_status_ops, 0666, },
1526 { "spu_tag_mask", &spufs_spu_tag_mask_ops, 0666, },
1527 { "event_mask", &spufs_event_mask_ops, 0666, }, 1860 { "event_mask", &spufs_event_mask_ops, 0666, },
1528 { "srr0", &spufs_srr0_ops, 0666, }, 1861 { "event_status", &spufs_event_status_ops, 0444, },
1862 { "psmap", &spufs_psmap_fops, 0666, },
1863 { "phys-id", &spufs_id_ops, 0666, },
1864 { "object-id", &spufs_object_id_ops, 0666, },
1865 { "mbox_info", &spufs_mbox_info_fops, 0444, },
1866 { "ibox_info", &spufs_ibox_info_fops, 0444, },
1867 { "wbox_info", &spufs_wbox_info_fops, 0444, },
1868 { "dma_info", &spufs_dma_info_fops, 0444, },
1869 { "proxydma_info", &spufs_proxydma_info_fops, 0444, },
1870 {},
1871};
1872
1873struct tree_descr spufs_dir_nosched_contents[] = {
1874 { "mem", &spufs_mem_fops, 0666, },
1875 { "mbox", &spufs_mbox_fops, 0444, },
1876 { "ibox", &spufs_ibox_fops, 0444, },
1877 { "wbox", &spufs_wbox_fops, 0222, },
1878 { "mbox_stat", &spufs_mbox_stat_fops, 0444, },
1879 { "ibox_stat", &spufs_ibox_stat_fops, 0444, },
1880 { "wbox_stat", &spufs_wbox_stat_fops, 0444, },
1881 { "signal1", &spufs_signal1_fops, 0666, },
1882 { "signal2", &spufs_signal2_fops, 0666, },
1883 { "signal1_type", &spufs_signal1_type, 0666, },
1884 { "signal2_type", &spufs_signal2_type, 0666, },
1885 { "mss", &spufs_mss_fops, 0666, },
1886 { "mfc", &spufs_mfc_fops, 0666, },
1887 { "cntl", &spufs_cntl_fops, 0666, },
1888 { "npc", &spufs_npc_ops, 0666, },
1529 { "psmap", &spufs_psmap_fops, 0666, }, 1889 { "psmap", &spufs_psmap_fops, 0666, },
1530 { "phys-id", &spufs_id_ops, 0666, }, 1890 { "phys-id", &spufs_id_ops, 0666, },
1531 { "object-id", &spufs_object_id_ops, 0666, }, 1891 { "object-id", &spufs_object_id_ops, 0666, },
1532 {}, 1892 {},
1533}; 1893};
1894
1895struct spufs_coredump_reader spufs_coredump_read[] = {
1896 { "regs", __spufs_regs_read, NULL, 128 * 16 },
1897 { "fpcr", __spufs_fpcr_read, NULL, 16 },
1898 { "lslr", NULL, __spufs_lslr_get, 11 },
1899 { "decr", NULL, __spufs_decr_get, 11 },
1900 { "decr_status", NULL, __spufs_decr_status_get, 11 },
1901 { "mem", __spufs_mem_read, NULL, 256 * 1024, },
1902 { "signal1", __spufs_signal1_read, NULL, 4 },
1903 { "signal1_type", NULL, __spufs_signal1_type_get, 2 },
1904 { "signal2", __spufs_signal2_read, NULL, 4 },
1905 { "signal2_type", NULL, __spufs_signal2_type_get, 2 },
1906 { "event_mask", NULL, __spufs_event_mask_get, 8 },
1907 { "event_status", NULL, __spufs_event_status_get, 8 },
1908 { "mbox_info", __spufs_mbox_info_read, NULL, 4 },
1909 { "ibox_info", __spufs_ibox_info_read, NULL, 4 },
1910 { "wbox_info", __spufs_wbox_info_read, NULL, 16 },
1911 { "dma_info", __spufs_dma_info_read, NULL, 69 * 8 },
1912 { "proxydma_info", __spufs_proxydma_info_read, NULL, 35 * 8 },
1913 { "object-id", NULL, __spufs_object_id_get, 19 },
1914 { },
1915};
1916int spufs_coredump_num_notes = ARRAY_SIZE(spufs_coredump_read) - 1;
1917
diff --git a/arch/powerpc/platforms/cell/spufs/hw_ops.c b/arch/powerpc/platforms/cell/spufs/hw_ops.c
index d805ffed892d..ae42e03b8c86 100644
--- a/arch/powerpc/platforms/cell/spufs/hw_ops.c
+++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c
@@ -135,21 +135,11 @@ static int spu_hw_wbox_write(struct spu_context *ctx, u32 data)
135 return ret; 135 return ret;
136} 136}
137 137
138static u32 spu_hw_signal1_read(struct spu_context *ctx)
139{
140 return in_be32(&ctx->spu->problem->signal_notify1);
141}
142
143static void spu_hw_signal1_write(struct spu_context *ctx, u32 data) 138static void spu_hw_signal1_write(struct spu_context *ctx, u32 data)
144{ 139{
145 out_be32(&ctx->spu->problem->signal_notify1, data); 140 out_be32(&ctx->spu->problem->signal_notify1, data);
146} 141}
147 142
148static u32 spu_hw_signal2_read(struct spu_context *ctx)
149{
150 return in_be32(&ctx->spu->problem->signal_notify2);
151}
152
153static void spu_hw_signal2_write(struct spu_context *ctx, u32 data) 143static void spu_hw_signal2_write(struct spu_context *ctx, u32 data)
154{ 144{
155 out_be32(&ctx->spu->problem->signal_notify2, data); 145 out_be32(&ctx->spu->problem->signal_notify2, data);
@@ -217,21 +207,42 @@ static char *spu_hw_get_ls(struct spu_context *ctx)
217 return ctx->spu->local_store; 207 return ctx->spu->local_store;
218} 208}
219 209
220static void spu_hw_runcntl_write(struct spu_context *ctx, u32 val) 210static u32 spu_hw_runcntl_read(struct spu_context *ctx)
221{ 211{
222 eieio(); 212 return in_be32(&ctx->spu->problem->spu_runcntl_RW);
223 out_be32(&ctx->spu->problem->spu_runcntl_RW, val);
224} 213}
225 214
226static void spu_hw_runcntl_stop(struct spu_context *ctx) 215static void spu_hw_runcntl_write(struct spu_context *ctx, u32 val)
227{ 216{
228 spin_lock_irq(&ctx->spu->register_lock); 217 spin_lock_irq(&ctx->spu->register_lock);
229 out_be32(&ctx->spu->problem->spu_runcntl_RW, SPU_RUNCNTL_STOP); 218 if (val & SPU_RUNCNTL_ISOLATE)
230 while (in_be32(&ctx->spu->problem->spu_status_R) & SPU_STATUS_RUNNING) 219 out_be64(&ctx->spu->priv2->spu_privcntl_RW, 4LL);
231 cpu_relax(); 220 out_be32(&ctx->spu->problem->spu_runcntl_RW, val);
232 spin_unlock_irq(&ctx->spu->register_lock); 221 spin_unlock_irq(&ctx->spu->register_lock);
233} 222}
234 223
224static void spu_hw_master_start(struct spu_context *ctx)
225{
226 struct spu *spu = ctx->spu;
227 u64 sr1;
228
229 spin_lock_irq(&spu->register_lock);
230 sr1 = spu_mfc_sr1_get(spu) | MFC_STATE1_MASTER_RUN_CONTROL_MASK;
231 spu_mfc_sr1_set(spu, sr1);
232 spin_unlock_irq(&spu->register_lock);
233}
234
235static void spu_hw_master_stop(struct spu_context *ctx)
236{
237 struct spu *spu = ctx->spu;
238 u64 sr1;
239
240 spin_lock_irq(&spu->register_lock);
241 sr1 = spu_mfc_sr1_get(spu) & ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
242 spu_mfc_sr1_set(spu, sr1);
243 spin_unlock_irq(&spu->register_lock);
244}
245
235static int spu_hw_set_mfc_query(struct spu_context * ctx, u32 mask, u32 mode) 246static int spu_hw_set_mfc_query(struct spu_context * ctx, u32 mask, u32 mode)
236{ 247{
237 struct spu_problem __iomem *prob = ctx->spu->problem; 248 struct spu_problem __iomem *prob = ctx->spu->problem;
@@ -291,9 +302,7 @@ struct spu_context_ops spu_hw_ops = {
291 .mbox_stat_poll = spu_hw_mbox_stat_poll, 302 .mbox_stat_poll = spu_hw_mbox_stat_poll,
292 .ibox_read = spu_hw_ibox_read, 303 .ibox_read = spu_hw_ibox_read,
293 .wbox_write = spu_hw_wbox_write, 304 .wbox_write = spu_hw_wbox_write,
294 .signal1_read = spu_hw_signal1_read,
295 .signal1_write = spu_hw_signal1_write, 305 .signal1_write = spu_hw_signal1_write,
296 .signal2_read = spu_hw_signal2_read,
297 .signal2_write = spu_hw_signal2_write, 306 .signal2_write = spu_hw_signal2_write,
298 .signal1_type_set = spu_hw_signal1_type_set, 307 .signal1_type_set = spu_hw_signal1_type_set,
299 .signal1_type_get = spu_hw_signal1_type_get, 308 .signal1_type_get = spu_hw_signal1_type_get,
@@ -303,8 +312,10 @@ struct spu_context_ops spu_hw_ops = {
303 .npc_write = spu_hw_npc_write, 312 .npc_write = spu_hw_npc_write,
304 .status_read = spu_hw_status_read, 313 .status_read = spu_hw_status_read,
305 .get_ls = spu_hw_get_ls, 314 .get_ls = spu_hw_get_ls,
315 .runcntl_read = spu_hw_runcntl_read,
306 .runcntl_write = spu_hw_runcntl_write, 316 .runcntl_write = spu_hw_runcntl_write,
307 .runcntl_stop = spu_hw_runcntl_stop, 317 .master_start = spu_hw_master_start,
318 .master_stop = spu_hw_master_stop,
308 .set_mfc_query = spu_hw_set_mfc_query, 319 .set_mfc_query = spu_hw_set_mfc_query,
309 .read_mfc_tagstatus = spu_hw_read_mfc_tagstatus, 320 .read_mfc_tagstatus = spu_hw_read_mfc_tagstatus,
310 .get_mfc_free_elements = spu_hw_get_mfc_free_elements, 321 .get_mfc_free_elements = spu_hw_get_mfc_free_elements,
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c
index 427d00a4f6a0..c7d010749a18 100644
--- a/arch/powerpc/platforms/cell/spufs/inode.c
+++ b/arch/powerpc/platforms/cell/spufs/inode.c
@@ -33,7 +33,7 @@
33#include <linux/slab.h> 33#include <linux/slab.h>
34#include <linux/parser.h> 34#include <linux/parser.h>
35 35
36#include <asm/io.h> 36#include <asm/prom.h>
37#include <asm/semaphore.h> 37#include <asm/semaphore.h>
38#include <asm/spu.h> 38#include <asm/spu.h>
39#include <asm/uaccess.h> 39#include <asm/uaccess.h>
@@ -41,6 +41,7 @@
41#include "spufs.h" 41#include "spufs.h"
42 42
43static kmem_cache_t *spufs_inode_cache; 43static kmem_cache_t *spufs_inode_cache;
44char *isolated_loader;
44 45
45static struct inode * 46static struct inode *
46spufs_alloc_inode(struct super_block *sb) 47spufs_alloc_inode(struct super_block *sb)
@@ -231,6 +232,7 @@ struct file_operations spufs_context_fops = {
231 .readdir = dcache_readdir, 232 .readdir = dcache_readdir,
232 .fsync = simple_sync_file, 233 .fsync = simple_sync_file,
233}; 234};
235EXPORT_SYMBOL_GPL(spufs_context_fops);
234 236
235static int 237static int
236spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags, 238spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags,
@@ -255,10 +257,14 @@ spufs_mkdir(struct inode *dir, struct dentry *dentry, unsigned int flags,
255 goto out_iput; 257 goto out_iput;
256 258
257 ctx->flags = flags; 259 ctx->flags = flags;
258
259 inode->i_op = &spufs_dir_inode_operations; 260 inode->i_op = &spufs_dir_inode_operations;
260 inode->i_fop = &simple_dir_operations; 261 inode->i_fop = &simple_dir_operations;
261 ret = spufs_fill_dir(dentry, spufs_dir_contents, mode, ctx); 262 if (flags & SPU_CREATE_NOSCHED)
263 ret = spufs_fill_dir(dentry, spufs_dir_nosched_contents,
264 mode, ctx);
265 else
266 ret = spufs_fill_dir(dentry, spufs_dir_contents, mode, ctx);
267
262 if (ret) 268 if (ret)
263 goto out_free_ctx; 269 goto out_free_ctx;
264 270
@@ -307,6 +313,20 @@ static int spufs_create_context(struct inode *inode,
307{ 313{
308 int ret; 314 int ret;
309 315
316 ret = -EPERM;
317 if ((flags & SPU_CREATE_NOSCHED) &&
318 !capable(CAP_SYS_NICE))
319 goto out_unlock;
320
321 ret = -EINVAL;
322 if ((flags & (SPU_CREATE_NOSCHED | SPU_CREATE_ISOLATE))
323 == SPU_CREATE_ISOLATE)
324 goto out_unlock;
325
326 ret = -ENODEV;
327 if ((flags & SPU_CREATE_ISOLATE) && !isolated_loader)
328 goto out_unlock;
329
310 ret = spufs_mkdir(inode, dentry, flags, mode & S_IRWXUGO); 330 ret = spufs_mkdir(inode, dentry, flags, mode & S_IRWXUGO);
311 if (ret) 331 if (ret)
312 goto out_unlock; 332 goto out_unlock;
@@ -540,6 +560,30 @@ spufs_parse_options(char *options, struct inode *root)
540 return 1; 560 return 1;
541} 561}
542 562
563static void
564spufs_init_isolated_loader(void)
565{
566 struct device_node *dn;
567 const char *loader;
568 int size;
569
570 dn = of_find_node_by_path("/spu-isolation");
571 if (!dn)
572 return;
573
574 loader = get_property(dn, "loader", &size);
575 if (!loader)
576 return;
577
578 /* kmalloc should align on a 16 byte boundary..* */
579 isolated_loader = kmalloc(size, GFP_KERNEL);
580 if (!isolated_loader)
581 return;
582
583 memcpy(isolated_loader, loader, size);
584 printk(KERN_INFO "spufs: SPU isolation mode enabled\n");
585}
586
543static int 587static int
544spufs_create_root(struct super_block *sb, void *data) 588spufs_create_root(struct super_block *sb, void *data)
545{ 589{
@@ -608,6 +652,7 @@ static struct file_system_type spufs_type = {
608static int __init spufs_init(void) 652static int __init spufs_init(void)
609{ 653{
610 int ret; 654 int ret;
655
611 ret = -ENOMEM; 656 ret = -ENOMEM;
612 spufs_inode_cache = kmem_cache_create("spufs_inode_cache", 657 spufs_inode_cache = kmem_cache_create("spufs_inode_cache",
613 sizeof(struct spufs_inode_info), 0, 658 sizeof(struct spufs_inode_info), 0,
@@ -625,6 +670,12 @@ static int __init spufs_init(void)
625 ret = register_spu_syscalls(&spufs_calls); 670 ret = register_spu_syscalls(&spufs_calls);
626 if (ret) 671 if (ret)
627 goto out_fs; 672 goto out_fs;
673 ret = register_arch_coredump_calls(&spufs_coredump_calls);
674 if (ret)
675 goto out_fs;
676
677 spufs_init_isolated_loader();
678
628 return 0; 679 return 0;
629out_fs: 680out_fs:
630 unregister_filesystem(&spufs_type); 681 unregister_filesystem(&spufs_type);
@@ -638,6 +689,7 @@ module_init(spufs_init);
638static void __exit spufs_exit(void) 689static void __exit spufs_exit(void)
639{ 690{
640 spu_sched_exit(); 691 spu_sched_exit();
692 unregister_arch_coredump_calls(&spufs_coredump_calls);
641 unregister_spu_syscalls(&spufs_calls); 693 unregister_spu_syscalls(&spufs_calls);
642 unregister_filesystem(&spufs_type); 694 unregister_filesystem(&spufs_type);
643 kmem_cache_destroy(spufs_inode_cache); 695 kmem_cache_destroy(spufs_inode_cache);
diff --git a/arch/powerpc/platforms/cell/spufs/run.c b/arch/powerpc/platforms/cell/spufs/run.c
index 63df8cf4ba16..1acc2ffef8c8 100644
--- a/arch/powerpc/platforms/cell/spufs/run.c
+++ b/arch/powerpc/platforms/cell/spufs/run.c
@@ -1,7 +1,11 @@
1#define DEBUG
2
1#include <linux/wait.h> 3#include <linux/wait.h>
2#include <linux/ptrace.h> 4#include <linux/ptrace.h>
3 5
4#include <asm/spu.h> 6#include <asm/spu.h>
7#include <asm/spu_priv1.h>
8#include <asm/io.h>
5#include <asm/unistd.h> 9#include <asm/unistd.h>
6 10
7#include "spufs.h" 11#include "spufs.h"
@@ -24,6 +28,7 @@ void spufs_dma_callback(struct spu *spu, int type)
24 } else { 28 } else {
25 switch (type) { 29 switch (type) {
26 case SPE_EVENT_DMA_ALIGNMENT: 30 case SPE_EVENT_DMA_ALIGNMENT:
31 case SPE_EVENT_SPE_DATA_STORAGE:
27 case SPE_EVENT_INVALID_DMA: 32 case SPE_EVENT_INVALID_DMA:
28 force_sig(SIGBUS, /* info, */ current); 33 force_sig(SIGBUS, /* info, */ current);
29 break; 34 break;
@@ -48,15 +53,122 @@ static inline int spu_stopped(struct spu_context *ctx, u32 * stat)
48 return (!(*stat & 0x1) || pte_fault || spu->class_0_pending) ? 1 : 0; 53 return (!(*stat & 0x1) || pte_fault || spu->class_0_pending) ? 1 : 0;
49} 54}
50 55
56static int spu_setup_isolated(struct spu_context *ctx)
57{
58 int ret;
59 u64 __iomem *mfc_cntl;
60 u64 sr1;
61 u32 status;
62 unsigned long timeout;
63 const u32 status_loading = SPU_STATUS_RUNNING
64 | SPU_STATUS_ISOLATED_STATE | SPU_STATUS_ISOLATED_LOAD_STATUS;
65
66 if (!isolated_loader)
67 return -ENODEV;
68
69 ret = spu_acquire_exclusive(ctx);
70 if (ret)
71 goto out;
72
73 mfc_cntl = &ctx->spu->priv2->mfc_control_RW;
74
75 /* purge the MFC DMA queue to ensure no spurious accesses before we
76 * enter kernel mode */
77 timeout = jiffies + HZ;
78 out_be64(mfc_cntl, MFC_CNTL_PURGE_DMA_REQUEST);
79 while ((in_be64(mfc_cntl) & MFC_CNTL_PURGE_DMA_STATUS_MASK)
80 != MFC_CNTL_PURGE_DMA_COMPLETE) {
81 if (time_after(jiffies, timeout)) {
82 printk(KERN_ERR "%s: timeout flushing MFC DMA queue\n",
83 __FUNCTION__);
84 ret = -EIO;
85 goto out_unlock;
86 }
87 cond_resched();
88 }
89
90 /* put the SPE in kernel mode to allow access to the loader */
91 sr1 = spu_mfc_sr1_get(ctx->spu);
92 sr1 &= ~MFC_STATE1_PROBLEM_STATE_MASK;
93 spu_mfc_sr1_set(ctx->spu, sr1);
94
95 /* start the loader */
96 ctx->ops->signal1_write(ctx, (unsigned long)isolated_loader >> 32);
97 ctx->ops->signal2_write(ctx,
98 (unsigned long)isolated_loader & 0xffffffff);
99
100 ctx->ops->runcntl_write(ctx,
101 SPU_RUNCNTL_RUNNABLE | SPU_RUNCNTL_ISOLATE);
102
103 ret = 0;
104 timeout = jiffies + HZ;
105 while (((status = ctx->ops->status_read(ctx)) & status_loading) ==
106 status_loading) {
107 if (time_after(jiffies, timeout)) {
108 printk(KERN_ERR "%s: timeout waiting for loader\n",
109 __FUNCTION__);
110 ret = -EIO;
111 goto out_drop_priv;
112 }
113 cond_resched();
114 }
115
116 if (!(status & SPU_STATUS_RUNNING)) {
117 /* If isolated LOAD has failed: run SPU, we will get a stop-and
118 * signal later. */
119 pr_debug("%s: isolated LOAD failed\n", __FUNCTION__);
120 ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_RUNNABLE);
121 ret = -EACCES;
122
123 } else if (!(status & SPU_STATUS_ISOLATED_STATE)) {
124 /* This isn't allowed by the CBEA, but check anyway */
125 pr_debug("%s: SPU fell out of isolated mode?\n", __FUNCTION__);
126 ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_STOP);
127 ret = -EINVAL;
128 }
129
130out_drop_priv:
131 /* Finished accessing the loader. Drop kernel mode */
132 sr1 |= MFC_STATE1_PROBLEM_STATE_MASK;
133 spu_mfc_sr1_set(ctx->spu, sr1);
134
135out_unlock:
136 spu_release_exclusive(ctx);
137out:
138 return ret;
139}
140
51static inline int spu_run_init(struct spu_context *ctx, u32 * npc) 141static inline int spu_run_init(struct spu_context *ctx, u32 * npc)
52{ 142{
53 int ret; 143 int ret;
144 unsigned long runcntl = SPU_RUNCNTL_RUNNABLE;
54 145
55 if ((ret = spu_acquire_runnable(ctx)) != 0) 146 ret = spu_acquire_runnable(ctx);
147 if (ret)
56 return ret; 148 return ret;
57 ctx->ops->npc_write(ctx, *npc); 149
58 ctx->ops->runcntl_write(ctx, SPU_RUNCNTL_RUNNABLE); 150 if (ctx->flags & SPU_CREATE_ISOLATE) {
59 return 0; 151 if (!(ctx->ops->status_read(ctx) & SPU_STATUS_ISOLATED_STATE)) {
152 /* Need to release ctx, because spu_setup_isolated will
153 * acquire it exclusively.
154 */
155 spu_release(ctx);
156 ret = spu_setup_isolated(ctx);
157 if (!ret)
158 ret = spu_acquire_runnable(ctx);
159 }
160
161 /* if userspace has set the runcntrl register (eg, to issue an
162 * isolated exit), we need to re-set it here */
163 runcntl = ctx->ops->runcntl_read(ctx) &
164 (SPU_RUNCNTL_RUNNABLE | SPU_RUNCNTL_ISOLATE);
165 if (runcntl == 0)
166 runcntl = SPU_RUNCNTL_RUNNABLE;
167 } else
168 ctx->ops->npc_write(ctx, *npc);
169
170 ctx->ops->runcntl_write(ctx, runcntl);
171 return ret;
60} 172}
61 173
62static inline int spu_run_fini(struct spu_context *ctx, u32 * npc, 174static inline int spu_run_fini(struct spu_context *ctx, u32 * npc,
@@ -70,13 +182,7 @@ static inline int spu_run_fini(struct spu_context *ctx, u32 * npc,
70 182
71 if (signal_pending(current)) 183 if (signal_pending(current))
72 ret = -ERESTARTSYS; 184 ret = -ERESTARTSYS;
73 if (unlikely(current->ptrace & PT_PTRACED)) { 185
74 if ((*status & SPU_STATUS_STOPPED_BY_STOP)
75 && (*status >> SPU_STOP_STATUS_SHIFT) == 0x3fff) {
76 force_sig(SIGTRAP, current);
77 ret = -ERESTARTSYS;
78 }
79 }
80 return ret; 186 return ret;
81} 187}
82 188
@@ -204,6 +310,7 @@ long spufs_run_spu(struct file *file, struct spu_context *ctx,
204 if (down_interruptible(&ctx->run_sema)) 310 if (down_interruptible(&ctx->run_sema))
205 return -ERESTARTSYS; 311 return -ERESTARTSYS;
206 312
313 ctx->ops->master_start(ctx);
207 ctx->event_return = 0; 314 ctx->event_return = 0;
208 ret = spu_run_init(ctx, npc); 315 ret = spu_run_init(ctx, npc);
209 if (ret) 316 if (ret)
@@ -223,7 +330,7 @@ long spufs_run_spu(struct file *file, struct spu_context *ctx,
223 if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) { 330 if (unlikely(ctx->state != SPU_STATE_RUNNABLE)) {
224 ret = spu_reacquire_runnable(ctx, npc, &status); 331 ret = spu_reacquire_runnable(ctx, npc, &status);
225 if (ret) 332 if (ret)
226 goto out; 333 goto out2;
227 continue; 334 continue;
228 } 335 }
229 ret = spu_process_events(ctx); 336 ret = spu_process_events(ctx);
@@ -231,12 +338,24 @@ long spufs_run_spu(struct file *file, struct spu_context *ctx,
231 } while (!ret && !(status & (SPU_STATUS_STOPPED_BY_STOP | 338 } while (!ret && !(status & (SPU_STATUS_STOPPED_BY_STOP |
232 SPU_STATUS_STOPPED_BY_HALT))); 339 SPU_STATUS_STOPPED_BY_HALT)));
233 340
234 ctx->ops->runcntl_stop(ctx); 341 ctx->ops->master_stop(ctx);
235 ret = spu_run_fini(ctx, npc, &status); 342 ret = spu_run_fini(ctx, npc, &status);
236 if (!ret)
237 ret = status;
238 spu_yield(ctx); 343 spu_yield(ctx);
239 344
345out2:
346 if ((ret == 0) ||
347 ((ret == -ERESTARTSYS) &&
348 ((status & SPU_STATUS_STOPPED_BY_HALT) ||
349 ((status & SPU_STATUS_STOPPED_BY_STOP) &&
350 (status >> SPU_STOP_STATUS_SHIFT != 0x2104)))))
351 ret = status;
352
353 if ((status & SPU_STATUS_STOPPED_BY_STOP)
354 && (status >> SPU_STOP_STATUS_SHIFT) == 0x3fff) {
355 force_sig(SIGTRAP, current);
356 ret = -ERESTARTSYS;
357 }
358
240out: 359out:
241 *event = ctx->event_return; 360 *event = ctx->event_return;
242 up(&ctx->run_sema); 361 up(&ctx->run_sema);
diff --git a/arch/powerpc/platforms/cell/spufs/spufs.h b/arch/powerpc/platforms/cell/spufs/spufs.h
index a0f55ca2d488..70fb13395c04 100644
--- a/arch/powerpc/platforms/cell/spufs/spufs.h
+++ b/arch/powerpc/platforms/cell/spufs/spufs.h
@@ -29,6 +29,7 @@
29 29
30#include <asm/spu.h> 30#include <asm/spu.h>
31#include <asm/spu_csa.h> 31#include <asm/spu_csa.h>
32#include <asm/spu_info.h>
32 33
33/* The magic number for our file system */ 34/* The magic number for our file system */
34enum { 35enum {
@@ -114,13 +115,19 @@ struct spu_context_ops {
114 void (*npc_write) (struct spu_context * ctx, u32 data); 115 void (*npc_write) (struct spu_context * ctx, u32 data);
115 u32(*status_read) (struct spu_context * ctx); 116 u32(*status_read) (struct spu_context * ctx);
116 char*(*get_ls) (struct spu_context * ctx); 117 char*(*get_ls) (struct spu_context * ctx);
118 u32 (*runcntl_read) (struct spu_context * ctx);
117 void (*runcntl_write) (struct spu_context * ctx, u32 data); 119 void (*runcntl_write) (struct spu_context * ctx, u32 data);
118 void (*runcntl_stop) (struct spu_context * ctx); 120 void (*master_start) (struct spu_context * ctx);
121 void (*master_stop) (struct spu_context * ctx);
119 int (*set_mfc_query)(struct spu_context * ctx, u32 mask, u32 mode); 122 int (*set_mfc_query)(struct spu_context * ctx, u32 mask, u32 mode);
120 u32 (*read_mfc_tagstatus)(struct spu_context * ctx); 123 u32 (*read_mfc_tagstatus)(struct spu_context * ctx);
121 u32 (*get_mfc_free_elements)(struct spu_context *ctx); 124 u32 (*get_mfc_free_elements)(struct spu_context *ctx);
122 int (*send_mfc_command)(struct spu_context *ctx, 125 int (*send_mfc_command)(struct spu_context * ctx,
123 struct mfc_dma_command *cmd); 126 struct mfc_dma_command * cmd);
127 void (*dma_info_read) (struct spu_context * ctx,
128 struct spu_dma_info * info);
129 void (*proxydma_info_read) (struct spu_context * ctx,
130 struct spu_proxydma_info * info);
124}; 131};
125 132
126extern struct spu_context_ops spu_hw_ops; 133extern struct spu_context_ops spu_hw_ops;
@@ -135,6 +142,7 @@ struct spufs_inode_info {
135 container_of(inode, struct spufs_inode_info, vfs_inode) 142 container_of(inode, struct spufs_inode_info, vfs_inode)
136 143
137extern struct tree_descr spufs_dir_contents[]; 144extern struct tree_descr spufs_dir_contents[];
145extern struct tree_descr spufs_dir_nosched_contents[];
138 146
139/* system call implementation */ 147/* system call implementation */
140long spufs_run_spu(struct file *file, 148long spufs_run_spu(struct file *file,
@@ -162,6 +170,12 @@ void spu_acquire(struct spu_context *ctx);
162void spu_release(struct spu_context *ctx); 170void spu_release(struct spu_context *ctx);
163int spu_acquire_runnable(struct spu_context *ctx); 171int spu_acquire_runnable(struct spu_context *ctx);
164void spu_acquire_saved(struct spu_context *ctx); 172void spu_acquire_saved(struct spu_context *ctx);
173int spu_acquire_exclusive(struct spu_context *ctx);
174
175static inline void spu_release_exclusive(struct spu_context *ctx)
176{
177 up_write(&ctx->state_sema);
178}
165 179
166int spu_activate(struct spu_context *ctx, u64 flags); 180int spu_activate(struct spu_context *ctx, u64 flags);
167void spu_deactivate(struct spu_context *ctx); 181void spu_deactivate(struct spu_context *ctx);
@@ -169,6 +183,8 @@ void spu_yield(struct spu_context *ctx);
169int __init spu_sched_init(void); 183int __init spu_sched_init(void);
170void __exit spu_sched_exit(void); 184void __exit spu_sched_exit(void);
171 185
186extern char *isolated_loader;
187
172/* 188/*
173 * spufs_wait 189 * spufs_wait
174 * Same as wait_event_interruptible(), except that here 190 * Same as wait_event_interruptible(), except that here
@@ -207,4 +223,15 @@ void spufs_stop_callback(struct spu *spu);
207void spufs_mfc_callback(struct spu *spu); 223void spufs_mfc_callback(struct spu *spu);
208void spufs_dma_callback(struct spu *spu, int type); 224void spufs_dma_callback(struct spu *spu, int type);
209 225
226extern struct spu_coredump_calls spufs_coredump_calls;
227struct spufs_coredump_reader {
228 char *name;
229 ssize_t (*read)(struct spu_context *ctx,
230 char __user *buffer, size_t size, loff_t *pos);
231 u64 (*get)(void *data);
232 size_t size;
233};
234extern struct spufs_coredump_reader spufs_coredump_read[];
235extern int spufs_coredump_num_notes;
236
210#endif 237#endif
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c
index 0f782ca662ba..c08981ff7fc6 100644
--- a/arch/powerpc/platforms/cell/spufs/switch.c
+++ b/arch/powerpc/platforms/cell/spufs/switch.c
@@ -102,7 +102,7 @@ static inline int check_spu_isolate(struct spu_state *csa, struct spu *spu)
102 * saved at this time. 102 * saved at this time.
103 */ 103 */
104 isolate_state = SPU_STATUS_ISOLATED_STATE | 104 isolate_state = SPU_STATUS_ISOLATED_STATE |
105 SPU_STATUS_ISOLATED_LOAD_STAUTUS | SPU_STATUS_ISOLATED_EXIT_STAUTUS; 105 SPU_STATUS_ISOLATED_LOAD_STATUS | SPU_STATUS_ISOLATED_EXIT_STATUS;
106 return (in_be32(&prob->spu_status_R) & isolate_state) ? 1 : 0; 106 return (in_be32(&prob->spu_status_R) & isolate_state) ? 1 : 0;
107} 107}
108 108
@@ -1046,12 +1046,12 @@ static inline int suspend_spe(struct spu_state *csa, struct spu *spu)
1046 */ 1046 */
1047 if (in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING) { 1047 if (in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING) {
1048 if (in_be32(&prob->spu_status_R) & 1048 if (in_be32(&prob->spu_status_R) &
1049 SPU_STATUS_ISOLATED_EXIT_STAUTUS) { 1049 SPU_STATUS_ISOLATED_EXIT_STATUS) {
1050 POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & 1050 POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) &
1051 SPU_STATUS_RUNNING); 1051 SPU_STATUS_RUNNING);
1052 } 1052 }
1053 if ((in_be32(&prob->spu_status_R) & 1053 if ((in_be32(&prob->spu_status_R) &
1054 SPU_STATUS_ISOLATED_LOAD_STAUTUS) 1054 SPU_STATUS_ISOLATED_LOAD_STATUS)
1055 || (in_be32(&prob->spu_status_R) & 1055 || (in_be32(&prob->spu_status_R) &
1056 SPU_STATUS_ISOLATED_STATE)) { 1056 SPU_STATUS_ISOLATED_STATE)) {
1057 out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_STOP); 1057 out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_STOP);
@@ -1085,7 +1085,7 @@ static inline void clear_spu_status(struct spu_state *csa, struct spu *spu)
1085 */ 1085 */
1086 if (!(in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING)) { 1086 if (!(in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING)) {
1087 if (in_be32(&prob->spu_status_R) & 1087 if (in_be32(&prob->spu_status_R) &
1088 SPU_STATUS_ISOLATED_EXIT_STAUTUS) { 1088 SPU_STATUS_ISOLATED_EXIT_STATUS) {
1089 spu_mfc_sr1_set(spu, 1089 spu_mfc_sr1_set(spu,
1090 MFC_STATE1_MASTER_RUN_CONTROL_MASK); 1090 MFC_STATE1_MASTER_RUN_CONTROL_MASK);
1091 eieio(); 1091 eieio();
@@ -1095,7 +1095,7 @@ static inline void clear_spu_status(struct spu_state *csa, struct spu *spu)
1095 SPU_STATUS_RUNNING); 1095 SPU_STATUS_RUNNING);
1096 } 1096 }
1097 if ((in_be32(&prob->spu_status_R) & 1097 if ((in_be32(&prob->spu_status_R) &
1098 SPU_STATUS_ISOLATED_LOAD_STAUTUS) 1098 SPU_STATUS_ISOLATED_LOAD_STATUS)
1099 || (in_be32(&prob->spu_status_R) & 1099 || (in_be32(&prob->spu_status_R) &
1100 SPU_STATUS_ISOLATED_STATE)) { 1100 SPU_STATUS_ISOLATED_STATE)) {
1101 spu_mfc_sr1_set(spu, 1101 spu_mfc_sr1_set(spu,
@@ -1916,6 +1916,51 @@ static void save_lscsa(struct spu_state *prev, struct spu *spu)
1916 wait_spu_stopped(prev, spu); /* Step 57. */ 1916 wait_spu_stopped(prev, spu); /* Step 57. */
1917} 1917}
1918 1918
1919static void force_spu_isolate_exit(struct spu *spu)
1920{
1921 struct spu_problem __iomem *prob = spu->problem;
1922 struct spu_priv2 __iomem *priv2 = spu->priv2;
1923
1924 /* Stop SPE execution and wait for completion. */
1925 out_be32(&prob->spu_runcntl_RW, SPU_RUNCNTL_STOP);
1926 iobarrier_rw();
1927 POLL_WHILE_TRUE(in_be32(&prob->spu_status_R) & SPU_STATUS_RUNNING);
1928
1929 /* Restart SPE master runcntl. */
1930 spu_mfc_sr1_set(spu, MFC_STATE1_MASTER_RUN_CONTROL_MASK);
1931 iobarrier_w();
1932
1933 /* Initiate isolate exit request and wait for completion. */
1934 out_be64(&priv2->spu_privcntl_RW, 4LL);
1935 iobarrier_w();
1936 out_be32(&prob->spu_runcntl_RW, 2);
1937 iobarrier_rw();
1938 POLL_WHILE_FALSE((in_be32(&prob->spu_status_R)
1939 & SPU_STATUS_STOPPED_BY_STOP));
1940
1941 /* Reset load request to normal. */
1942 out_be64(&priv2->spu_privcntl_RW, SPU_PRIVCNT_LOAD_REQUEST_NORMAL);
1943 iobarrier_w();
1944}
1945
1946/**
1947 * stop_spu_isolate
1948 * Check SPU run-control state and force isolated
1949 * exit function as necessary.
1950 */
1951static void stop_spu_isolate(struct spu *spu)
1952{
1953 struct spu_problem __iomem *prob = spu->problem;
1954
1955 if (in_be32(&prob->spu_status_R) & SPU_STATUS_ISOLATED_STATE) {
1956 /* The SPU is in isolated state; the only way
1957 * to get it out is to perform an isolated
1958 * exit (clean) operation.
1959 */
1960 force_spu_isolate_exit(spu);
1961 }
1962}
1963
1919static void harvest(struct spu_state *prev, struct spu *spu) 1964static void harvest(struct spu_state *prev, struct spu *spu)
1920{ 1965{
1921 /* 1966 /*
@@ -1928,6 +1973,7 @@ static void harvest(struct spu_state *prev, struct spu *spu)
1928 inhibit_user_access(prev, spu); /* Step 3. */ 1973 inhibit_user_access(prev, spu); /* Step 3. */
1929 terminate_spu_app(prev, spu); /* Step 4. */ 1974 terminate_spu_app(prev, spu); /* Step 4. */
1930 set_switch_pending(prev, spu); /* Step 5. */ 1975 set_switch_pending(prev, spu); /* Step 5. */
1976 stop_spu_isolate(spu); /* NEW. */
1931 remove_other_spu_access(prev, spu); /* Step 6. */ 1977 remove_other_spu_access(prev, spu); /* Step 6. */
1932 suspend_mfc(prev, spu); /* Step 7. */ 1978 suspend_mfc(prev, spu); /* Step 7. */
1933 wait_suspend_mfc_complete(prev, spu); /* Step 8. */ 1979 wait_suspend_mfc_complete(prev, spu); /* Step 8. */
@@ -2096,11 +2142,11 @@ int spu_save(struct spu_state *prev, struct spu *spu)
2096 acquire_spu_lock(spu); /* Step 1. */ 2142 acquire_spu_lock(spu); /* Step 1. */
2097 rc = __do_spu_save(prev, spu); /* Steps 2-53. */ 2143 rc = __do_spu_save(prev, spu); /* Steps 2-53. */
2098 release_spu_lock(spu); 2144 release_spu_lock(spu);
2099 if (rc) { 2145 if (rc != 0 && rc != 2 && rc != 6) {
2100 panic("%s failed on SPU[%d], rc=%d.\n", 2146 panic("%s failed on SPU[%d], rc=%d.\n",
2101 __func__, spu->number, rc); 2147 __func__, spu->number, rc);
2102 } 2148 }
2103 return rc; 2149 return 0;
2104} 2150}
2105EXPORT_SYMBOL_GPL(spu_save); 2151EXPORT_SYMBOL_GPL(spu_save);
2106 2152
@@ -2165,9 +2211,6 @@ static void init_priv1(struct spu_state *csa)
2165 MFC_STATE1_PROBLEM_STATE_MASK | 2211 MFC_STATE1_PROBLEM_STATE_MASK |
2166 MFC_STATE1_RELOCATE_MASK | MFC_STATE1_BUS_TLBIE_MASK; 2212 MFC_STATE1_RELOCATE_MASK | MFC_STATE1_BUS_TLBIE_MASK;
2167 2213
2168 /* Set storage description. */
2169 csa->priv1.mfc_sdr_RW = mfspr(SPRN_SDR1);
2170
2171 /* Enable OS-specific set of interrupts. */ 2214 /* Enable OS-specific set of interrupts. */
2172 csa->priv1.int_mask_class0_RW = CLASS0_ENABLE_DMA_ALIGNMENT_INTR | 2215 csa->priv1.int_mask_class0_RW = CLASS0_ENABLE_DMA_ALIGNMENT_INTR |
2173 CLASS0_ENABLE_INVALID_DMA_COMMAND_INTR | 2216 CLASS0_ENABLE_INVALID_DMA_COMMAND_INTR |
diff --git a/arch/powerpc/platforms/chrp/chrp.h b/arch/powerpc/platforms/chrp/chrp.h
index 996c28744e96..63f0aee4c158 100644
--- a/arch/powerpc/platforms/chrp/chrp.h
+++ b/arch/powerpc/platforms/chrp/chrp.h
@@ -9,4 +9,3 @@ extern long chrp_time_init(void);
9 9
10extern void chrp_find_bridges(void); 10extern void chrp_find_bridges(void);
11extern void chrp_event_scan(unsigned long); 11extern void chrp_event_scan(unsigned long);
12extern void chrp_pcibios_fixup(void);
diff --git a/arch/powerpc/platforms/chrp/pci.c b/arch/powerpc/platforms/chrp/pci.c
index 0f4340506c75..ddb4a116ea89 100644
--- a/arch/powerpc/platforms/chrp/pci.c
+++ b/arch/powerpc/platforms/chrp/pci.c
@@ -156,15 +156,6 @@ hydra_init(void)
156 return 1; 156 return 1;
157} 157}
158 158
159void __init
160chrp_pcibios_fixup(void)
161{
162 struct pci_dev *dev = NULL;
163
164 for_each_pci_dev(dev)
165 pci_read_irq_line(dev);
166}
167
168#define PRG_CL_RESET_VALID 0x00010000 159#define PRG_CL_RESET_VALID 0x00010000
169 160
170static void __init 161static void __init
diff --git a/arch/powerpc/platforms/chrp/setup.c b/arch/powerpc/platforms/chrp/setup.c
index 49b8dabcbc99..e1f51d455984 100644
--- a/arch/powerpc/platforms/chrp/setup.c
+++ b/arch/powerpc/platforms/chrp/setup.c
@@ -588,7 +588,6 @@ static int __init chrp_probe(void)
588 ISA_DMA_THRESHOLD = ~0L; 588 ISA_DMA_THRESHOLD = ~0L;
589 DMA_MODE_READ = 0x44; 589 DMA_MODE_READ = 0x44;
590 DMA_MODE_WRITE = 0x48; 590 DMA_MODE_WRITE = 0x48;
591 isa_io_base = CHRP_ISA_IO_BASE; /* default value */
592 591
593 return 1; 592 return 1;
594} 593}
@@ -600,7 +599,6 @@ define_machine(chrp) {
600 .init = chrp_init2, 599 .init = chrp_init2,
601 .show_cpuinfo = chrp_show_cpuinfo, 600 .show_cpuinfo = chrp_show_cpuinfo,
602 .init_IRQ = chrp_init_IRQ, 601 .init_IRQ = chrp_init_IRQ,
603 .pcibios_fixup = chrp_pcibios_fixup,
604 .restart = rtas_restart, 602 .restart = rtas_restart,
605 .power_off = rtas_power_off, 603 .power_off = rtas_power_off,
606 .halt = rtas_halt, 604 .halt = rtas_halt,
diff --git a/arch/powerpc/platforms/embedded6xx/Kconfig b/arch/powerpc/platforms/embedded6xx/Kconfig
index 234a861870a8..ddbe398fbd48 100644
--- a/arch/powerpc/platforms/embedded6xx/Kconfig
+++ b/arch/powerpc/platforms/embedded6xx/Kconfig
@@ -74,6 +74,18 @@ config SANDPOINT
74 Select SANDPOINT if configuring for a Motorola Sandpoint X3 74 Select SANDPOINT if configuring for a Motorola Sandpoint X3
75 (any flavor). 75 (any flavor).
76 76
77config LINKSTATION
78 bool "Linkstation / Kurobox(HG) from Buffalo"
79 select MPIC
80 select FSL_SOC
81 select PPC_UDBG_16550 if SERIAL_8250
82 help
83 Select LINKSTATION if configuring for one of PPC- (MPC8241)
84 based NAS systems from Buffalo Technology. So far only
85 KuroboxHG has been tested. In the future classical Kurobox,
86 Linkstation-I HD-HLAN and HD-HGLAN versions, and PPC-based
87 Terastation systems should be supported too.
88
77config MPC7448HPC2 89config MPC7448HPC2
78 bool "Freescale MPC7448HPC2(Taiga)" 90 bool "Freescale MPC7448HPC2(Taiga)"
79 select TSI108_BRIDGE 91 select TSI108_BRIDGE
@@ -146,15 +158,6 @@ config PQ2FADS
146 Select PQ2FADS if you wish to configure for a Freescale 158 Select PQ2FADS if you wish to configure for a Freescale
147 PQ2FADS board (-VR or -ZU). 159 PQ2FADS board (-VR or -ZU).
148 160
149config LITE5200
150 bool "Freescale LITE5200 / (IceCube)"
151 select PPC_MPC52xx
152 help
153 Support for the LITE5200 dev board for the MPC5200 from Freescale.
154 This is for the LITE5200 version 2.0 board. Don't know if it changes
155 much but it's only been tested on this board version. I think this
156 board is also known as IceCube.
157
158config EV64360 161config EV64360
159 bool "Marvell-EV64360BP" 162 bool "Marvell-EV64360BP"
160 help 163 help
@@ -172,9 +175,6 @@ config TQM8xxL
172 depends on 8xx && (TQM823L || TQM850L || FPS850L || TQM855L || TQM860L) 175 depends on 8xx && (TQM823L || TQM850L || FPS850L || TQM855L || TQM860L)
173 default y 176 default y
174 177
175config PPC_MPC52xx
176 bool
177
178config 8260 178config 8260
179 bool "CPM2 Support" if WILLOW 179 bool "CPM2 Support" if WILLOW
180 depends on 6xx 180 depends on 6xx
@@ -208,7 +208,7 @@ config PPC_GEN550
208 depends on SANDPOINT || SPRUCE || PPLUS || \ 208 depends on SANDPOINT || SPRUCE || PPLUS || \
209 PRPMC750 || PRPMC800 || LOPEC || \ 209 PRPMC750 || PRPMC800 || LOPEC || \
210 (EV64260 && !SERIAL_MPSC) || CHESTNUT || RADSTONE_PPC7D || \ 210 (EV64260 && !SERIAL_MPSC) || CHESTNUT || RADSTONE_PPC7D || \
211 83xx 211 83xx || LINKSTATION
212 default y 212 default y
213 213
214config FORCE 214config FORCE
@@ -282,13 +282,13 @@ config EPIC_SERIAL_MODE
282 282
283config MPC10X_BRIDGE 283config MPC10X_BRIDGE
284 bool 284 bool
285 depends on POWERPMC250 || LOPEC || SANDPOINT 285 depends on POWERPMC250 || LOPEC || SANDPOINT || LINKSTATION
286 select PPC_INDIRECT_PCI 286 select PPC_INDIRECT_PCI
287 default y 287 default y
288 288
289config MPC10X_OPENPIC 289config MPC10X_OPENPIC
290 bool 290 bool
291 depends on POWERPMC250 || LOPEC || SANDPOINT 291 depends on POWERPMC250 || LOPEC || SANDPOINT || LINKSTATION
292 default y 292 default y
293 293
294config MPC10X_STORE_GATHERING 294config MPC10X_STORE_GATHERING
diff --git a/arch/powerpc/platforms/embedded6xx/Makefile b/arch/powerpc/platforms/embedded6xx/Makefile
index fa499fe59291..d3d11a3cd656 100644
--- a/arch/powerpc/platforms/embedded6xx/Makefile
+++ b/arch/powerpc/platforms/embedded6xx/Makefile
@@ -2,3 +2,4 @@
2# Makefile for the 6xx/7xx/7xxxx linux kernel. 2# Makefile for the 6xx/7xx/7xxxx linux kernel.
3# 3#
4obj-$(CONFIG_MPC7448HPC2) += mpc7448_hpc2.o 4obj-$(CONFIG_MPC7448HPC2) += mpc7448_hpc2.o
5obj-$(CONFIG_LINKSTATION) += linkstation.o ls_uart.o
diff --git a/arch/powerpc/platforms/embedded6xx/linkstation.c b/arch/powerpc/platforms/embedded6xx/linkstation.c
new file mode 100644
index 000000000000..61599d919ea8
--- /dev/null
+++ b/arch/powerpc/platforms/embedded6xx/linkstation.c
@@ -0,0 +1,211 @@
1/*
2 * Board setup routines for the Buffalo Linkstation / Kurobox Platform.
3 *
4 * Copyright (C) 2006 G. Liakhovetski (g.liakhovetski@gmx.de)
5 *
6 * Based on sandpoint.c by Mark A. Greer
7 *
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of
10 * any kind, whether express or implied.
11 */
12
13#include <linux/kernel.h>
14#include <linux/pci.h>
15#include <linux/initrd.h>
16#include <linux/root_dev.h>
17#include <linux/mtd/physmap.h>
18
19#include <asm/time.h>
20#include <asm/prom.h>
21#include <asm/mpic.h>
22#include <asm/mpc10x.h>
23#include <asm/pci-bridge.h>
24
25static struct mtd_partition linkstation_physmap_partitions[] = {
26 {
27 .name = "mtd_firmimg",
28 .offset = 0x000000,
29 .size = 0x300000,
30 },
31 {
32 .name = "mtd_bootcode",
33 .offset = 0x300000,
34 .size = 0x070000,
35 },
36 {
37 .name = "mtd_status",
38 .offset = 0x370000,
39 .size = 0x010000,
40 },
41 {
42 .name = "mtd_conf",
43 .offset = 0x380000,
44 .size = 0x080000,
45 },
46 {
47 .name = "mtd_allflash",
48 .offset = 0x000000,
49 .size = 0x400000,
50 },
51 {
52 .name = "mtd_data",
53 .offset = 0x310000,
54 .size = 0x0f0000,
55 },
56};
57
58static int __init add_bridge(struct device_node *dev)
59{
60 int len;
61 struct pci_controller *hose;
62 int *bus_range;
63
64 printk("Adding PCI host bridge %s\n", dev->full_name);
65
66 bus_range = (int *) get_property(dev, "bus-range", &len);
67 if (bus_range == NULL || len < 2 * sizeof(int))
68 printk(KERN_WARNING "Can't get bus-range for %s, assume"
69 " bus 0\n", dev->full_name);
70
71 hose = pcibios_alloc_controller();
72 if (hose == NULL)
73 return -ENOMEM;
74 hose->first_busno = bus_range ? bus_range[0] : 0;
75 hose->last_busno = bus_range ? bus_range[1] : 0xff;
76 hose->arch_data = dev;
77 setup_indirect_pci(hose, 0xfec00000, 0xfee00000);
78
79 /* Interpret the "ranges" property */
80 /* This also maps the I/O region and sets isa_io/mem_base */
81 pci_process_bridge_OF_ranges(hose, dev, 1);
82
83 return 0;
84}
85
86static void __init linkstation_setup_arch(void)
87{
88 struct device_node *np;
89#ifdef CONFIG_MTD_PHYSMAP
90 physmap_set_partitions(linkstation_physmap_partitions,
91 ARRAY_SIZE(linkstation_physmap_partitions));
92#endif
93
94#ifdef CONFIG_BLK_DEV_INITRD
95 if (initrd_start)
96 ROOT_DEV = Root_RAM0;
97 else
98#endif
99#ifdef CONFIG_ROOT_NFS
100 ROOT_DEV = Root_NFS;
101#else
102 ROOT_DEV = Root_HDA1;
103#endif
104
105 /* Lookup PCI host bridges */
106 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
107 add_bridge(np);
108
109 printk(KERN_INFO "BUFFALO Network Attached Storage Series\n");
110 printk(KERN_INFO "(C) 2002-2005 BUFFALO INC.\n");
111}
112
113/*
114 * Interrupt setup and service. Interrrupts on the linkstation come
115 * from the four PCI slots plus onboard 8241 devices: I2C, DUART.
116 */
117static void __init linkstation_init_IRQ(void)
118{
119 struct mpic *mpic;
120 struct device_node *dnp;
121 void *prop;
122 int size;
123 phys_addr_t paddr;
124
125 dnp = of_find_node_by_type(NULL, "open-pic");
126 if (dnp == NULL)
127 return;
128
129 prop = (struct device_node *)get_property(dnp, "reg", &size);
130 paddr = (phys_addr_t)of_translate_address(dnp, prop);
131
132 mpic = mpic_alloc(dnp, paddr, MPIC_PRIMARY | MPIC_WANTS_RESET, 4, 32, " EPIC ");
133 BUG_ON(mpic == NULL);
134
135 /* PCI IRQs */
136 mpic_assign_isu(mpic, 0, paddr + 0x10200);
137
138 /* I2C */
139 mpic_assign_isu(mpic, 1, paddr + 0x11000);
140
141 /* ttyS0, ttyS1 */
142 mpic_assign_isu(mpic, 2, paddr + 0x11100);
143
144 mpic_init(mpic);
145}
146
147extern void avr_uart_configure(void);
148extern void avr_uart_send(const char);
149
150static void linkstation_restart(char *cmd)
151{
152 local_irq_disable();
153
154 /* Reset system via AVR */
155 avr_uart_configure();
156 /* Send reboot command */
157 avr_uart_send('C');
158
159 for(;;) /* Spin until reset happens */
160 avr_uart_send('G'); /* "kick" */
161}
162
163static void linkstation_power_off(void)
164{
165 local_irq_disable();
166
167 /* Power down system via AVR */
168 avr_uart_configure();
169 /* send shutdown command */
170 avr_uart_send('E');
171
172 for(;;) /* Spin until power-off happens */
173 avr_uart_send('G'); /* "kick" */
174 /* NOTREACHED */
175}
176
177static void linkstation_halt(void)
178{
179 linkstation_power_off();
180 /* NOTREACHED */
181}
182
183static void linkstation_show_cpuinfo(struct seq_file *m)
184{
185 seq_printf(m, "vendor\t\t: Buffalo Technology\n");
186 seq_printf(m, "machine\t\t: Linkstation I/Kurobox(HG)\n");
187}
188
189static int __init linkstation_probe(void)
190{
191 unsigned long root;
192
193 root = of_get_flat_dt_root();
194
195 if (!of_flat_dt_is_compatible(root, "linkstation"))
196 return 0;
197 return 1;
198}
199
200define_machine(linkstation){
201 .name = "Buffalo Linkstation",
202 .probe = linkstation_probe,
203 .setup_arch = linkstation_setup_arch,
204 .init_IRQ = linkstation_init_IRQ,
205 .show_cpuinfo = linkstation_show_cpuinfo,
206 .get_irq = mpic_get_irq,
207 .restart = linkstation_restart,
208 .power_off = linkstation_power_off,
209 .halt = linkstation_halt,
210 .calibrate_decr = generic_calibrate_decr,
211};
diff --git a/arch/powerpc/platforms/embedded6xx/ls_uart.c b/arch/powerpc/platforms/embedded6xx/ls_uart.c
new file mode 100644
index 000000000000..31bcdae84823
--- /dev/null
+++ b/arch/powerpc/platforms/embedded6xx/ls_uart.c
@@ -0,0 +1,131 @@
1#include <linux/workqueue.h>
2#include <linux/string.h>
3#include <linux/delay.h>
4#include <linux/serial_reg.h>
5#include <linux/serial_8250.h>
6#include <asm/io.h>
7#include <asm/mpc10x.h>
8#include <asm/ppc_sys.h>
9#include <asm/prom.h>
10#include <asm/termbits.h>
11
12static void __iomem *avr_addr;
13static unsigned long avr_clock;
14
15static struct work_struct wd_work;
16
17static void wd_stop(void *unused)
18{
19 const char string[] = "AAAAFFFFJJJJ>>>>VVVV>>>>ZZZZVVVVKKKK";
20 int i = 0, rescue = 8;
21 int len = strlen(string);
22
23 while (rescue--) {
24 int j;
25 char lsr = in_8(avr_addr + UART_LSR);
26
27 if (lsr & (UART_LSR_THRE | UART_LSR_TEMT)) {
28 for (j = 0; j < 16 && i < len; j++, i++)
29 out_8(avr_addr + UART_TX, string[i]);
30 if (i == len) {
31 /* Read "OK" back: 4ms for the last "KKKK"
32 plus a couple bytes back */
33 msleep(7);
34 printk("linkstation: disarming the AVR watchdog: ");
35 while (in_8(avr_addr + UART_LSR) & UART_LSR_DR)
36 printk("%c", in_8(avr_addr + UART_RX));
37 break;
38 }
39 }
40 msleep(17);
41 }
42 printk("\n");
43}
44
45#define AVR_QUOT(clock) ((clock) + 8 * 9600) / (16 * 9600)
46
47void avr_uart_configure(void)
48{
49 unsigned char cval = UART_LCR_WLEN8;
50 unsigned int quot = AVR_QUOT(avr_clock);
51
52 if (!avr_addr || !avr_clock)
53 return;
54
55 out_8(avr_addr + UART_LCR, cval); /* initialise UART */
56 out_8(avr_addr + UART_MCR, 0);
57 out_8(avr_addr + UART_IER, 0);
58
59 cval |= UART_LCR_STOP | UART_LCR_PARITY | UART_LCR_EPAR;
60
61 out_8(avr_addr + UART_LCR, cval); /* Set character format */
62
63 out_8(avr_addr + UART_LCR, cval | UART_LCR_DLAB); /* set DLAB */
64 out_8(avr_addr + UART_DLL, quot & 0xff); /* LS of divisor */
65 out_8(avr_addr + UART_DLM, quot >> 8); /* MS of divisor */
66 out_8(avr_addr + UART_LCR, cval); /* reset DLAB */
67 out_8(avr_addr + UART_FCR, UART_FCR_ENABLE_FIFO); /* enable FIFO */
68}
69
70void avr_uart_send(const char c)
71{
72 if (!avr_addr || !avr_clock)
73 return;
74
75 out_8(avr_addr + UART_TX, c);
76 out_8(avr_addr + UART_TX, c);
77 out_8(avr_addr + UART_TX, c);
78 out_8(avr_addr + UART_TX, c);
79}
80
81static void __init ls_uart_init(void)
82{
83 local_irq_disable();
84
85#ifndef CONFIG_SERIAL_8250
86 out_8(avr_addr + UART_FCR, UART_FCR_ENABLE_FIFO); /* enable FIFO */
87 out_8(avr_addr + UART_FCR, UART_FCR_ENABLE_FIFO |
88 UART_FCR_CLEAR_RCVR | UART_FCR_CLEAR_XMIT); /* clear FIFOs */
89 out_8(avr_addr + UART_FCR, 0);
90 out_8(avr_addr + UART_IER, 0);
91
92 /* Clear up interrupts */
93 (void) in_8(avr_addr + UART_LSR);
94 (void) in_8(avr_addr + UART_RX);
95 (void) in_8(avr_addr + UART_IIR);
96 (void) in_8(avr_addr + UART_MSR);
97#endif
98 avr_uart_configure();
99
100 local_irq_enable();
101}
102
103static int __init ls_uarts_init(void)
104{
105 struct device_node *avr;
106 phys_addr_t phys_addr;
107 int len;
108
109 avr = of_find_node_by_path("/soc10x/serial@80004500");
110 if (!avr)
111 return -EINVAL;
112
113 avr_clock = *(u32*)get_property(avr, "clock-frequency", &len);
114 phys_addr = ((u32*)get_property(avr, "reg", &len))[0];
115
116 if (!avr_clock || !phys_addr)
117 return -EINVAL;
118
119 avr_addr = ioremap(phys_addr, 32);
120 if (!avr_addr)
121 return -EFAULT;
122
123 ls_uart_init();
124
125 INIT_WORK(&wd_work, wd_stop, NULL);
126 schedule_work(&wd_work);
127
128 return 0;
129}
130
131late_initcall(ls_uarts_init);
diff --git a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
index bdb475c65cba..3fcc85f60fbf 100644
--- a/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
+++ b/arch/powerpc/platforms/embedded6xx/mpc7448_hpc2.c
@@ -60,7 +60,7 @@ pci_dram_offset = MPC7448_HPC2_PCI_MEM_OFFSET;
60 60
61extern int tsi108_setup_pci(struct device_node *dev); 61extern int tsi108_setup_pci(struct device_node *dev);
62extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val); 62extern void _nmask_and_or_msr(unsigned long nmask, unsigned long or_val);
63extern void tsi108_pci_int_init(void); 63extern void tsi108_pci_int_init(struct device_node *node);
64extern void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc); 64extern void tsi108_irq_cascade(unsigned int irq, struct irq_desc *desc);
65 65
66int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn) 66int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn)
@@ -71,65 +71,6 @@ int mpc7448_hpc2_exclude_device(u_char bus, u_char devfn)
71 return PCIBIOS_SUCCESSFUL; 71 return PCIBIOS_SUCCESSFUL;
72} 72}
73 73
74/*
75 * find pci slot by devfn in interrupt map of OF tree
76 */
77u8 find_slot_by_devfn(unsigned int *interrupt_map, unsigned int devfn)
78{
79 int i;
80 unsigned int tmp;
81 for (i = 0; i < 4; i++){
82 tmp = interrupt_map[i*4*7];
83 if ((tmp >> 11) == (devfn >> 3))
84 return i;
85 }
86 return i;
87}
88
89/*
90 * Scans the interrupt map for pci device
91 */
92void mpc7448_hpc2_fixup_irq(struct pci_dev *dev)
93{
94 struct pci_controller *hose;
95 struct device_node *node;
96 const unsigned int *interrupt;
97 int busnr;
98 int len;
99 u8 slot;
100 u8 pin;
101
102 /* Lookup the hose */
103 busnr = dev->bus->number;
104 hose = pci_bus_to_hose(busnr);
105 if (!hose)
106 printk(KERN_ERR "No pci hose found\n");
107
108 /* Check it has an OF node associated */
109 node = (struct device_node *) hose->arch_data;
110 if (!node)
111 printk(KERN_ERR "No pci node found\n");
112
113 interrupt = get_property(node, "interrupt-map", &len);
114 slot = find_slot_by_devfn(interrupt, dev->devfn);
115 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
116 if (pin == 0 || pin > 4)
117 pin = 1;
118 pin--;
119 dev->irq = interrupt[slot*4*7 + pin*7 + 5];
120 DBG("TSI_PCI: dev->irq = 0x%x\n", dev->irq);
121}
122/* temporary pci irq map fixup*/
123
124void __init mpc7448_hpc2_pcibios_fixup(void)
125{
126 struct pci_dev *dev = NULL;
127 for_each_pci_dev(dev) {
128 mpc7448_hpc2_fixup_irq(dev);
129 pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq);
130 }
131}
132
133static void __init mpc7448_hpc2_setup_arch(void) 74static void __init mpc7448_hpc2_setup_arch(void)
134{ 75{
135 struct device_node *cpu; 76 struct device_node *cpu;
@@ -192,9 +133,12 @@ static void __init mpc7448_hpc2_init_IRQ(void)
192{ 133{
193 struct mpic *mpic; 134 struct mpic *mpic;
194 phys_addr_t mpic_paddr = 0; 135 phys_addr_t mpic_paddr = 0;
136 struct device_node *tsi_pic;
137#ifdef CONFIG_PCI
195 unsigned int cascade_pci_irq; 138 unsigned int cascade_pci_irq;
196 struct device_node *tsi_pci; 139 struct device_node *tsi_pci;
197 struct device_node *tsi_pic; 140 struct device_node *cascade_node = NULL;
141#endif
198 142
199 tsi_pic = of_find_node_by_type(NULL, "open-pic"); 143 tsi_pic = of_find_node_by_type(NULL, "open-pic");
200 if (tsi_pic) { 144 if (tsi_pic) {
@@ -208,31 +152,41 @@ static void __init mpc7448_hpc2_init_IRQ(void)
208 return; 152 return;
209 } 153 }
210 154
211 DBG("%s: tsi108pic phys_addr = 0x%x\n", __FUNCTION__, 155 DBG("%s: tsi108 pic phys_addr = 0x%x\n", __FUNCTION__,
212 (u32) mpic_paddr); 156 (u32) mpic_paddr);
213 157
214 mpic = mpic_alloc(tsi_pic, mpic_paddr, 158 mpic = mpic_alloc(tsi_pic, mpic_paddr,
215 MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET | 159 MPIC_PRIMARY | MPIC_BIG_ENDIAN | MPIC_WANTS_RESET |
216 MPIC_SPV_EOI | MPIC_NO_PTHROU_DIS | MPIC_REGSET_TSI108, 160 MPIC_SPV_EOI | MPIC_NO_PTHROU_DIS | MPIC_REGSET_TSI108,
217 0, /* num_sources used */ 161 24,
218 0, /* num_sources used */ 162 NR_IRQS-4, /* num_sources used */
219 "Tsi108_PIC"); 163 "Tsi108_PIC");
220 164
221 BUG_ON(mpic == NULL); /* XXXX */ 165 BUG_ON(mpic == NULL);
166
167 mpic_assign_isu(mpic, 0, mpic_paddr + 0x100);
168
222 mpic_init(mpic); 169 mpic_init(mpic);
223 170
171#ifdef CONFIG_PCI
224 tsi_pci = of_find_node_by_type(NULL, "pci"); 172 tsi_pci = of_find_node_by_type(NULL, "pci");
225 if (tsi_pci == 0) { 173 if (tsi_pci == NULL) {
226 printk("%s: No tsi108 pci node found !\n", __FUNCTION__); 174 printk("%s: No tsi108 pci node found !\n", __FUNCTION__);
227 return; 175 return;
228 } 176 }
177 cascade_node = of_find_node_by_type(NULL, "pic-router");
178 if (cascade_node == NULL) {
179 printk("%s: No tsi108 pci cascade node found !\n", __FUNCTION__);
180 return;
181 }
229 182
230 cascade_pci_irq = irq_of_parse_and_map(tsi_pci, 0); 183 cascade_pci_irq = irq_of_parse_and_map(tsi_pci, 0);
184 DBG("%s: tsi108 cascade_pci_irq = 0x%x\n", __FUNCTION__,
185 (u32) cascade_pci_irq);
186 tsi108_pci_int_init(cascade_node);
231 set_irq_data(cascade_pci_irq, mpic); 187 set_irq_data(cascade_pci_irq, mpic);
232 set_irq_chained_handler(cascade_pci_irq, tsi108_irq_cascade); 188 set_irq_chained_handler(cascade_pci_irq, tsi108_irq_cascade);
233 189#endif
234 tsi108_pci_int_init();
235
236 /* Configure MPIC outputs to CPU0 */ 190 /* Configure MPIC outputs to CPU0 */
237 tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0); 191 tsi108_write_reg(TSI108_MPIC_OFFSET + 0x30c, 0);
238 of_node_put(tsi_pic); 192 of_node_put(tsi_pic);
@@ -290,7 +244,6 @@ static int mpc7448_machine_check_exception(struct pt_regs *regs)
290 return 1; 244 return 1;
291 } 245 }
292 return 0; 246 return 0;
293
294} 247}
295 248
296define_machine(mpc7448_hpc2){ 249define_machine(mpc7448_hpc2){
@@ -300,7 +253,6 @@ define_machine(mpc7448_hpc2){
300 .init_IRQ = mpc7448_hpc2_init_IRQ, 253 .init_IRQ = mpc7448_hpc2_init_IRQ,
301 .show_cpuinfo = mpc7448_hpc2_show_cpuinfo, 254 .show_cpuinfo = mpc7448_hpc2_show_cpuinfo,
302 .get_irq = mpic_get_irq, 255 .get_irq = mpic_get_irq,
303 .pcibios_fixup = mpc7448_hpc2_pcibios_fixup,
304 .restart = mpc7448_hpc2_restart, 256 .restart = mpc7448_hpc2_restart,
305 .calibrate_decr = generic_calibrate_decr, 257 .calibrate_decr = generic_calibrate_decr,
306 .machine_check_exception= mpc7448_machine_check_exception, 258 .machine_check_exception= mpc7448_machine_check_exception,
diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile
index dee4eb4d8bec..13ac3015d91c 100644
--- a/arch/powerpc/platforms/iseries/Makefile
+++ b/arch/powerpc/platforms/iseries/Makefile
@@ -1,5 +1,7 @@
1EXTRA_CFLAGS += -mno-minimal-toc 1EXTRA_CFLAGS += -mno-minimal-toc
2 2
3extra-y += dt.o
4
3obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o dt_mod.o mf.o lpevents.o \ 5obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o dt_mod.o mf.o lpevents.o \
4 hvcall.o proc.o htab.o iommu.o misc.o irq.o 6 hvcall.o proc.o htab.o iommu.o misc.o irq.o
5obj-$(CONFIG_PCI) += pci.o vpdinfo.o 7obj-$(CONFIG_PCI) += pci.o vpdinfo.o
@@ -7,5 +9,9 @@ obj-$(CONFIG_SMP) += smp.o
7obj-$(CONFIG_VIOPATH) += viopath.o 9obj-$(CONFIG_VIOPATH) += viopath.o
8obj-$(CONFIG_MODULES) += ksyms.o 10obj-$(CONFIG_MODULES) += ksyms.o
9 11
12quiet_cmd_dt_strings = DT_STR $@
13 cmd_dt_strings = $(OBJCOPY) --rename-section .rodata.str1.8=.dt_strings \
14 $< $@
15
10$(obj)/dt_mod.o: $(obj)/dt.o 16$(obj)/dt_mod.o: $(obj)/dt.o
11 @$(OBJCOPY) --rename-section .rodata.str1.8=.dt_strings $(obj)/dt.o $(obj)/dt_mod.o 17 $(call if_changed,dt_strings)
diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c
index e305deee7f44..9e8a334a518a 100644
--- a/arch/powerpc/platforms/iseries/dt.c
+++ b/arch/powerpc/platforms/iseries/dt.c
@@ -41,6 +41,7 @@
41#include "call_pci.h" 41#include "call_pci.h"
42#include "pci.h" 42#include "pci.h"
43#include "it_exp_vpd_panel.h" 43#include "it_exp_vpd_panel.h"
44#include "naca.h"
44 45
45#ifdef DEBUG 46#ifdef DEBUG
46#define DBG(fmt...) udbg_printf(fmt) 47#define DBG(fmt...) udbg_printf(fmt)
@@ -205,13 +206,11 @@ static void __init dt_prop_u32(struct iseries_flat_dt *dt, const char *name,
205 dt_prop(dt, name, &data, sizeof(u32)); 206 dt_prop(dt, name, &data, sizeof(u32));
206} 207}
207 208
208#ifdef notyet
209static void __init dt_prop_u64(struct iseries_flat_dt *dt, const char *name, 209static void __init dt_prop_u64(struct iseries_flat_dt *dt, const char *name,
210 u64 data) 210 u64 data)
211{ 211{
212 dt_prop(dt, name, &data, sizeof(u64)); 212 dt_prop(dt, name, &data, sizeof(u64));
213} 213}
214#endif
215 214
216static void __init dt_prop_u64_list(struct iseries_flat_dt *dt, 215static void __init dt_prop_u64_list(struct iseries_flat_dt *dt,
217 const char *name, u64 *data, int n) 216 const char *name, u64 *data, int n)
@@ -306,6 +305,17 @@ static void __init dt_model(struct iseries_flat_dt *dt)
306 dt_prop_u32(dt, "ibm,partition-no", HvLpConfig_getLpIndex()); 305 dt_prop_u32(dt, "ibm,partition-no", HvLpConfig_getLpIndex());
307} 306}
308 307
308static void __init dt_initrd(struct iseries_flat_dt *dt)
309{
310#ifdef CONFIG_BLK_DEV_INITRD
311 if (naca.xRamDisk) {
312 dt_prop_u64(dt, "linux,initrd-start", (u64)naca.xRamDisk);
313 dt_prop_u64(dt, "linux,initrd-end",
314 (u64)naca.xRamDisk + naca.xRamDiskSize * HW_PAGE_SIZE);
315 }
316#endif
317}
318
309static void __init dt_do_vdevice(struct iseries_flat_dt *dt, 319static void __init dt_do_vdevice(struct iseries_flat_dt *dt,
310 const char *name, u32 reg, int unit, 320 const char *name, u32 reg, int unit,
311 const char *type, const char *compat, int end) 321 const char *type, const char *compat, int end)
@@ -641,6 +651,7 @@ void * __init build_flat_dt(unsigned long phys_mem_size)
641 /* /chosen */ 651 /* /chosen */
642 dt_start_node(iseries_dt, "chosen"); 652 dt_start_node(iseries_dt, "chosen");
643 dt_prop_str(iseries_dt, "bootargs", cmd_line); 653 dt_prop_str(iseries_dt, "bootargs", cmd_line);
654 dt_initrd(iseries_dt);
644 dt_end_node(iseries_dt); 655 dt_end_node(iseries_dt);
645 656
646 dt_cpus(iseries_dt); 657 dt_cpus(iseries_dt);
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c
index 218817d13c5c..d7a756d5135c 100644
--- a/arch/powerpc/platforms/iseries/iommu.c
+++ b/arch/powerpc/platforms/iseries/iommu.c
@@ -27,6 +27,7 @@
27#include <linux/types.h> 27#include <linux/types.h>
28#include <linux/dma-mapping.h> 28#include <linux/dma-mapping.h>
29#include <linux/list.h> 29#include <linux/list.h>
30#include <linux/pci.h>
30 31
31#include <asm/iommu.h> 32#include <asm/iommu.h>
32#include <asm/tce.h> 33#include <asm/tce.h>
@@ -114,12 +115,10 @@ void iommu_table_getparms_iSeries(unsigned long busno,
114{ 115{
115 struct iommu_table_cb *parms; 116 struct iommu_table_cb *parms;
116 117
117 parms = kmalloc(sizeof(*parms), GFP_KERNEL); 118 parms = kzalloc(sizeof(*parms), GFP_KERNEL);
118 if (parms == NULL) 119 if (parms == NULL)
119 panic("PCI_DMA: TCE Table Allocation failed."); 120 panic("PCI_DMA: TCE Table Allocation failed.");
120 121
121 memset(parms, 0, sizeof(*parms));
122
123 parms->itc_busno = busno; 122 parms->itc_busno = busno;
124 parms->itc_slotno = slotno; 123 parms->itc_slotno = slotno;
125 parms->itc_virtbus = virtbus; 124 parms->itc_virtbus = virtbus;
@@ -168,7 +167,7 @@ static struct iommu_table *iommu_table_find(struct iommu_table * tbl)
168} 167}
169 168
170 169
171void iommu_devnode_init_iSeries(struct device_node *dn) 170void iommu_devnode_init_iSeries(struct pci_dev *pdev, struct device_node *dn)
172{ 171{
173 struct iommu_table *tbl; 172 struct iommu_table *tbl;
174 struct pci_dn *pdn = PCI_DN(dn); 173 struct pci_dn *pdn = PCI_DN(dn);
@@ -186,19 +185,14 @@ void iommu_devnode_init_iSeries(struct device_node *dn)
186 pdn->iommu_table = iommu_init_table(tbl, -1); 185 pdn->iommu_table = iommu_init_table(tbl, -1);
187 else 186 else
188 kfree(tbl); 187 kfree(tbl);
188 pdev->dev.archdata.dma_data = pdn->iommu_table;
189} 189}
190#endif 190#endif
191 191
192static void iommu_dev_setup_iSeries(struct pci_dev *dev) { }
193static void iommu_bus_setup_iSeries(struct pci_bus *bus) { }
194
195void iommu_init_early_iSeries(void) 192void iommu_init_early_iSeries(void)
196{ 193{
197 ppc_md.tce_build = tce_build_iSeries; 194 ppc_md.tce_build = tce_build_iSeries;
198 ppc_md.tce_free = tce_free_iSeries; 195 ppc_md.tce_free = tce_free_iSeries;
199 196
200 ppc_md.iommu_dev_setup = iommu_dev_setup_iSeries; 197 pci_dma_ops = &dma_iommu_ops;
201 ppc_md.iommu_bus_setup = iommu_bus_setup_iSeries;
202
203 pci_iommu_init();
204} 198}
diff --git a/arch/powerpc/platforms/iseries/ksyms.c b/arch/powerpc/platforms/iseries/ksyms.c
index a2200842f4e5..2430848b98e7 100644
--- a/arch/powerpc/platforms/iseries/ksyms.c
+++ b/arch/powerpc/platforms/iseries/ksyms.c
@@ -19,9 +19,3 @@ EXPORT_SYMBOL(HvCall4);
19EXPORT_SYMBOL(HvCall5); 19EXPORT_SYMBOL(HvCall5);
20EXPORT_SYMBOL(HvCall6); 20EXPORT_SYMBOL(HvCall6);
21EXPORT_SYMBOL(HvCall7); 21EXPORT_SYMBOL(HvCall7);
22
23#ifdef CONFIG_SMP
24EXPORT_SYMBOL(local_get_flags);
25EXPORT_SYMBOL(local_irq_disable);
26EXPORT_SYMBOL(local_irq_restore);
27#endif
diff --git a/arch/powerpc/platforms/iseries/misc.S b/arch/powerpc/platforms/iseries/misc.S
index 7641fc7e550a..2c6ff0fdac98 100644
--- a/arch/powerpc/platforms/iseries/misc.S
+++ b/arch/powerpc/platforms/iseries/misc.S
@@ -19,39 +19,8 @@
19 19
20 .text 20 .text
21 21
22/* unsigned long local_save_flags(void) */ 22/* Handle pending interrupts in interrupt context */
23_GLOBAL(local_get_flags) 23_GLOBAL(iseries_handle_interrupts)
24 lbz r3,PACAPROCENABLED(r13)
25 blr
26
27/* unsigned long local_irq_disable(void) */
28_GLOBAL(local_irq_disable)
29 lbz r3,PACAPROCENABLED(r13)
30 li r4,0
31 stb r4,PACAPROCENABLED(r13)
32 blr /* Done */
33
34/* void local_irq_restore(unsigned long flags) */
35_GLOBAL(local_irq_restore)
36 lbz r5,PACAPROCENABLED(r13)
37 /* Check if things are setup the way we want _already_. */
38 cmpw 0,r3,r5
39 beqlr
40 /* are we enabling interrupts? */
41 cmpdi 0,r3,0
42 stb r3,PACAPROCENABLED(r13)
43 beqlr
44 /* Check pending interrupts */
45 /* A decrementer, IPI or PMC interrupt may have occurred
46 * while we were in the hypervisor (which enables) */
47 ld r4,PACALPPACAPTR(r13)
48 ld r4,LPPACAANYINT(r4)
49 cmpdi r4,0
50 beqlr
51
52 /*
53 * Handle pending interrupts in interrupt context
54 */
55 li r0,0x5555 24 li r0,0x5555
56 sc 25 sc
57 blr 26 blr
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c
index 4aa165e010d9..4a06d9c34986 100644
--- a/arch/powerpc/platforms/iseries/pci.c
+++ b/arch/powerpc/platforms/iseries/pci.c
@@ -156,53 +156,6 @@ static void pci_Log_Error(char *Error_Text, int Bus, int SubBus,
156} 156}
157 157
158/* 158/*
159 * iSeries_pcibios_init
160 *
161 * Description:
162 * This function checks for all possible system PCI host bridges that connect
163 * PCI buses. The system hypervisor is queried as to the guest partition
164 * ownership status. A pci_controller is built for any bus which is partially
165 * owned or fully owned by this guest partition.
166 */
167void iSeries_pcibios_init(void)
168{
169 struct pci_controller *phb;
170 struct device_node *root = of_find_node_by_path("/");
171 struct device_node *node = NULL;
172
173 if (root == NULL) {
174 printk(KERN_CRIT "iSeries_pcibios_init: can't find root "
175 "of device tree\n");
176 return;
177 }
178 while ((node = of_get_next_child(root, node)) != NULL) {
179 HvBusNumber bus;
180 const u32 *busp;
181
182 if ((node->type == NULL) || (strcmp(node->type, "pci") != 0))
183 continue;
184
185 busp = get_property(node, "bus-range", NULL);
186 if (busp == NULL)
187 continue;
188 bus = *busp;
189 printk("bus %d appears to exist\n", bus);
190 phb = pcibios_alloc_controller(node);
191 if (phb == NULL)
192 continue;
193
194 phb->pci_mem_offset = phb->local_number = bus;
195 phb->first_busno = bus;
196 phb->last_busno = bus;
197 phb->ops = &iSeries_pci_ops;
198 }
199
200 of_node_put(root);
201
202 pci_devs_phb_init();
203}
204
205/*
206 * iSeries_pci_final_fixup(void) 159 * iSeries_pci_final_fixup(void)
207 */ 160 */
208void __init iSeries_pci_final_fixup(void) 161void __init iSeries_pci_final_fixup(void)
@@ -253,7 +206,7 @@ void __init iSeries_pci_final_fixup(void)
253 PCI_DN(node)->pcidev = pdev; 206 PCI_DN(node)->pcidev = pdev;
254 allocate_device_bars(pdev); 207 allocate_device_bars(pdev);
255 iSeries_Device_Information(pdev, DeviceCount); 208 iSeries_Device_Information(pdev, DeviceCount);
256 iommu_devnode_init_iSeries(node); 209 iommu_devnode_init_iSeries(pdev, node);
257 } else 210 } else
258 printk("PCI: Device Tree not found for 0x%016lX\n", 211 printk("PCI: Device Tree not found for 0x%016lX\n",
259 (unsigned long)pdev); 212 (unsigned long)pdev);
@@ -438,11 +391,7 @@ static inline struct device_node *xlate_iomm_address(
438/* 391/*
439 * Read MM I/O Instructions for the iSeries 392 * Read MM I/O Instructions for the iSeries
440 * On MM I/O error, all ones are returned and iSeries_pci_IoError is cal 393 * On MM I/O error, all ones are returned and iSeries_pci_IoError is cal
441 * else, data is returned in big Endian format. 394 * else, data is returned in Big Endian format.
442 *
443 * iSeries_Read_Byte = Read Byte ( 8 bit)
444 * iSeries_Read_Word = Read Word (16 bit)
445 * iSeries_Read_Long = Read Long (32 bit)
446 */ 395 */
447static u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress) 396static u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
448{ 397{
@@ -462,14 +411,15 @@ static u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress)
462 num_printed = 0; 411 num_printed = 0;
463 } 412 }
464 if (num_printed++ < 10) 413 if (num_printed++ < 10)
465 printk(KERN_ERR "iSeries_Read_Byte: invalid access at IO address %p\n", IoAddress); 414 printk(KERN_ERR "iSeries_Read_Byte: invalid access at IO address %p\n",
415 IoAddress);
466 return 0xff; 416 return 0xff;
467 } 417 }
468 do { 418 do {
469 HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, BarOffset, 0); 419 HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, BarOffset, 0);
470 } while (CheckReturnCode("RDB", DevNode, &retry, ret.rc) != 0); 420 } while (CheckReturnCode("RDB", DevNode, &retry, ret.rc) != 0);
471 421
472 return (u8)ret.value; 422 return ret.value;
473} 423}
474 424
475static u16 iSeries_Read_Word(const volatile void __iomem *IoAddress) 425static u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
@@ -490,7 +440,8 @@ static u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
490 num_printed = 0; 440 num_printed = 0;
491 } 441 }
492 if (num_printed++ < 10) 442 if (num_printed++ < 10)
493 printk(KERN_ERR "iSeries_Read_Word: invalid access at IO address %p\n", IoAddress); 443 printk(KERN_ERR "iSeries_Read_Word: invalid access at IO address %p\n",
444 IoAddress);
494 return 0xffff; 445 return 0xffff;
495 } 446 }
496 do { 447 do {
@@ -498,7 +449,7 @@ static u16 iSeries_Read_Word(const volatile void __iomem *IoAddress)
498 BarOffset, 0); 449 BarOffset, 0);
499 } while (CheckReturnCode("RDW", DevNode, &retry, ret.rc) != 0); 450 } while (CheckReturnCode("RDW", DevNode, &retry, ret.rc) != 0);
500 451
501 return swab16((u16)ret.value); 452 return ret.value;
502} 453}
503 454
504static u32 iSeries_Read_Long(const volatile void __iomem *IoAddress) 455static u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
@@ -519,7 +470,8 @@ static u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
519 num_printed = 0; 470 num_printed = 0;
520 } 471 }
521 if (num_printed++ < 10) 472 if (num_printed++ < 10)
522 printk(KERN_ERR "iSeries_Read_Long: invalid access at IO address %p\n", IoAddress); 473 printk(KERN_ERR "iSeries_Read_Long: invalid access at IO address %p\n",
474 IoAddress);
523 return 0xffffffff; 475 return 0xffffffff;
524 } 476 }
525 do { 477 do {
@@ -527,15 +479,12 @@ static u32 iSeries_Read_Long(const volatile void __iomem *IoAddress)
527 BarOffset, 0); 479 BarOffset, 0);
528 } while (CheckReturnCode("RDL", DevNode, &retry, ret.rc) != 0); 480 } while (CheckReturnCode("RDL", DevNode, &retry, ret.rc) != 0);
529 481
530 return swab32((u32)ret.value); 482 return ret.value;
531} 483}
532 484
533/* 485/*
534 * Write MM I/O Instructions for the iSeries 486 * Write MM I/O Instructions for the iSeries
535 * 487 *
536 * iSeries_Write_Byte = Write Byte (8 bit)
537 * iSeries_Write_Word = Write Word(16 bit)
538 * iSeries_Write_Long = Write Long(32 bit)
539 */ 488 */
540static void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress) 489static void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress)
541{ 490{
@@ -581,11 +530,12 @@ static void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress)
581 num_printed = 0; 530 num_printed = 0;
582 } 531 }
583 if (num_printed++ < 10) 532 if (num_printed++ < 10)
584 printk(KERN_ERR "iSeries_Write_Word: invalid access at IO address %p\n", IoAddress); 533 printk(KERN_ERR "iSeries_Write_Word: invalid access at IO address %p\n",
534 IoAddress);
585 return; 535 return;
586 } 536 }
587 do { 537 do {
588 rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0); 538 rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, data, 0);
589 } while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0); 539 } while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0);
590} 540}
591 541
@@ -607,231 +557,221 @@ static void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress)
607 num_printed = 0; 557 num_printed = 0;
608 } 558 }
609 if (num_printed++ < 10) 559 if (num_printed++ < 10)
610 printk(KERN_ERR "iSeries_Write_Long: invalid access at IO address %p\n", IoAddress); 560 printk(KERN_ERR "iSeries_Write_Long: invalid access at IO address %p\n",
561 IoAddress);
611 return; 562 return;
612 } 563 }
613 do { 564 do {
614 rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0); 565 rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, data, 0);
615 } while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0); 566 } while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0);
616} 567}
617 568
618extern unsigned char __raw_readb(const volatile void __iomem *addr) 569static u8 iseries_readb(const volatile void __iomem *addr)
619{ 570{
620 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); 571 return iSeries_Read_Byte(addr);
621
622 return *(volatile unsigned char __force *)addr;
623} 572}
624EXPORT_SYMBOL(__raw_readb);
625 573
626extern unsigned short __raw_readw(const volatile void __iomem *addr) 574static u16 iseries_readw(const volatile void __iomem *addr)
627{ 575{
628 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); 576 return le16_to_cpu(iSeries_Read_Word(addr));
629
630 return *(volatile unsigned short __force *)addr;
631} 577}
632EXPORT_SYMBOL(__raw_readw);
633 578
634extern unsigned int __raw_readl(const volatile void __iomem *addr) 579static u32 iseries_readl(const volatile void __iomem *addr)
635{ 580{
636 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); 581 return le32_to_cpu(iSeries_Read_Long(addr));
637
638 return *(volatile unsigned int __force *)addr;
639} 582}
640EXPORT_SYMBOL(__raw_readl);
641 583
642extern unsigned long __raw_readq(const volatile void __iomem *addr) 584static u16 iseries_readw_be(const volatile void __iomem *addr)
643{ 585{
644 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); 586 return iSeries_Read_Word(addr);
645
646 return *(volatile unsigned long __force *)addr;
647} 587}
648EXPORT_SYMBOL(__raw_readq);
649 588
650extern void __raw_writeb(unsigned char v, volatile void __iomem *addr) 589static u32 iseries_readl_be(const volatile void __iomem *addr)
651{ 590{
652 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); 591 return iSeries_Read_Long(addr);
653
654 *(volatile unsigned char __force *)addr = v;
655} 592}
656EXPORT_SYMBOL(__raw_writeb);
657 593
658extern void __raw_writew(unsigned short v, volatile void __iomem *addr) 594static void iseries_writeb(u8 data, volatile void __iomem *addr)
659{ 595{
660 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); 596 iSeries_Write_Byte(data, addr);
661
662 *(volatile unsigned short __force *)addr = v;
663} 597}
664EXPORT_SYMBOL(__raw_writew);
665 598
666extern void __raw_writel(unsigned int v, volatile void __iomem *addr) 599static void iseries_writew(u16 data, volatile void __iomem *addr)
667{ 600{
668 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); 601 iSeries_Write_Word(cpu_to_le16(data), addr);
669
670 *(volatile unsigned int __force *)addr = v;
671} 602}
672EXPORT_SYMBOL(__raw_writel);
673 603
674extern void __raw_writeq(unsigned long v, volatile void __iomem *addr) 604static void iseries_writel(u32 data, volatile void __iomem *addr)
675{ 605{
676 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); 606 iSeries_Write_Long(cpu_to_le32(data), addr);
677
678 *(volatile unsigned long __force *)addr = v;
679} 607}
680EXPORT_SYMBOL(__raw_writeq);
681 608
682int in_8(const volatile unsigned char __iomem *addr) 609static void iseries_writew_be(u16 data, volatile void __iomem *addr)
683{ 610{
684 if (firmware_has_feature(FW_FEATURE_ISERIES)) 611 iSeries_Write_Word(data, addr);
685 return iSeries_Read_Byte(addr);
686 return __in_8(addr);
687} 612}
688EXPORT_SYMBOL(in_8);
689 613
690void out_8(volatile unsigned char __iomem *addr, int val) 614static void iseries_writel_be(u32 data, volatile void __iomem *addr)
691{ 615{
692 if (firmware_has_feature(FW_FEATURE_ISERIES)) 616 iSeries_Write_Long(data, addr);
693 iSeries_Write_Byte(val, addr);
694 else
695 __out_8(addr, val);
696} 617}
697EXPORT_SYMBOL(out_8);
698 618
699int in_le16(const volatile unsigned short __iomem *addr) 619static void iseries_readsb(const volatile void __iomem *addr, void *buf,
620 unsigned long count)
700{ 621{
701 if (firmware_has_feature(FW_FEATURE_ISERIES)) 622 u8 *dst = buf;
702 return iSeries_Read_Word(addr); 623 while(count-- > 0)
703 return __in_le16(addr); 624 *(dst++) = iSeries_Read_Byte(addr);
704} 625}
705EXPORT_SYMBOL(in_le16);
706 626
707int in_be16(const volatile unsigned short __iomem *addr) 627static void iseries_readsw(const volatile void __iomem *addr, void *buf,
628 unsigned long count)
708{ 629{
709 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); 630 u16 *dst = buf;
710 631 while(count-- > 0)
711 return __in_be16(addr); 632 *(dst++) = iSeries_Read_Word(addr);
712} 633}
713EXPORT_SYMBOL(in_be16);
714 634
715void out_le16(volatile unsigned short __iomem *addr, int val) 635static void iseries_readsl(const volatile void __iomem *addr, void *buf,
636 unsigned long count)
716{ 637{
717 if (firmware_has_feature(FW_FEATURE_ISERIES)) 638 u32 *dst = buf;
718 iSeries_Write_Word(val, addr); 639 while(count-- > 0)
719 else 640 *(dst++) = iSeries_Read_Long(addr);
720 __out_le16(addr, val);
721} 641}
722EXPORT_SYMBOL(out_le16);
723 642
724void out_be16(volatile unsigned short __iomem *addr, int val) 643static void iseries_writesb(volatile void __iomem *addr, const void *buf,
644 unsigned long count)
725{ 645{
726 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); 646 const u8 *src = buf;
727 647 while(count-- > 0)
728 __out_be16(addr, val); 648 iSeries_Write_Byte(*(src++), addr);
729} 649}
730EXPORT_SYMBOL(out_be16);
731 650
732unsigned in_le32(const volatile unsigned __iomem *addr) 651static void iseries_writesw(volatile void __iomem *addr, const void *buf,
652 unsigned long count)
733{ 653{
734 if (firmware_has_feature(FW_FEATURE_ISERIES)) 654 const u16 *src = buf;
735 return iSeries_Read_Long(addr); 655 while(count-- > 0)
736 return __in_le32(addr); 656 iSeries_Write_Word(*(src++), addr);
737} 657}
738EXPORT_SYMBOL(in_le32);
739 658
740unsigned in_be32(const volatile unsigned __iomem *addr) 659static void iseries_writesl(volatile void __iomem *addr, const void *buf,
660 unsigned long count)
741{ 661{
742 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); 662 const u32 *src = buf;
743 663 while(count-- > 0)
744 return __in_be32(addr); 664 iSeries_Write_Long(*(src++), addr);
745} 665}
746EXPORT_SYMBOL(in_be32);
747 666
748void out_le32(volatile unsigned __iomem *addr, int val) 667static void iseries_memset_io(volatile void __iomem *addr, int c,
668 unsigned long n)
749{ 669{
750 if (firmware_has_feature(FW_FEATURE_ISERIES)) 670 volatile char __iomem *d = addr;
751 iSeries_Write_Long(val, addr);
752 else
753 __out_le32(addr, val);
754}
755EXPORT_SYMBOL(out_le32);
756 671
757void out_be32(volatile unsigned __iomem *addr, int val) 672 while (n-- > 0)
758{ 673 iSeries_Write_Byte(c, d++);
759 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
760
761 __out_be32(addr, val);
762} 674}
763EXPORT_SYMBOL(out_be32);
764 675
765unsigned long in_le64(const volatile unsigned long __iomem *addr) 676static void iseries_memcpy_fromio(void *dest, const volatile void __iomem *src,
677 unsigned long n)
766{ 678{
767 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); 679 char *d = dest;
680 const volatile char __iomem *s = src;
768 681
769 return __in_le64(addr); 682 while (n-- > 0)
683 *d++ = iSeries_Read_Byte(s++);
770} 684}
771EXPORT_SYMBOL(in_le64);
772 685
773unsigned long in_be64(const volatile unsigned long __iomem *addr) 686static void iseries_memcpy_toio(volatile void __iomem *dest, const void *src,
687 unsigned long n)
774{ 688{
775 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); 689 const char *s = src;
690 volatile char __iomem *d = dest;
776 691
777 return __in_be64(addr); 692 while (n-- > 0)
693 iSeries_Write_Byte(*s++, d++);
778} 694}
779EXPORT_SYMBOL(in_be64);
780
781void out_le64(volatile unsigned long __iomem *addr, unsigned long val)
782{
783 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES));
784 695
785 __out_le64(addr, val); 696/* We only set MMIO ops. The default PIO ops will be default
786} 697 * to the MMIO ops + pci_io_base which is 0 on iSeries as
787EXPORT_SYMBOL(out_le64); 698 * expected so both should work.
699 *
700 * Note that we don't implement the readq/writeq versions as
701 * I don't know of an HV call for doing so. Thus, the default
702 * operation will be used instead, which will fault a the value
703 * return by iSeries for MMIO addresses always hits a non mapped
704 * area. This is as good as the BUG() we used to have there.
705 */
706static struct ppc_pci_io __initdata iseries_pci_io = {
707 .readb = iseries_readb,
708 .readw = iseries_readw,
709 .readl = iseries_readl,
710 .readw_be = iseries_readw_be,
711 .readl_be = iseries_readl_be,
712 .writeb = iseries_writeb,
713 .writew = iseries_writew,
714 .writel = iseries_writel,
715 .writew_be = iseries_writew_be,
716 .writel_be = iseries_writel_be,
717 .readsb = iseries_readsb,
718 .readsw = iseries_readsw,
719 .readsl = iseries_readsl,
720 .writesb = iseries_writesb,
721 .writesw = iseries_writesw,
722 .writesl = iseries_writesl,
723 .memset_io = iseries_memset_io,
724 .memcpy_fromio = iseries_memcpy_fromio,
725 .memcpy_toio = iseries_memcpy_toio,
726};
788 727
789void out_be64(volatile unsigned long __iomem *addr, unsigned long val) 728/*
729 * iSeries_pcibios_init
730 *
731 * Description:
732 * This function checks for all possible system PCI host bridges that connect
733 * PCI buses. The system hypervisor is queried as to the guest partition
734 * ownership status. A pci_controller is built for any bus which is partially
735 * owned or fully owned by this guest partition.
736 */
737void __init iSeries_pcibios_init(void)
790{ 738{
791 BUG_ON(firmware_has_feature(FW_FEATURE_ISERIES)); 739 struct pci_controller *phb;
740 struct device_node *root = of_find_node_by_path("/");
741 struct device_node *node = NULL;
792 742
793 __out_be64(addr, val); 743 /* Install IO hooks */
794} 744 ppc_pci_io = iseries_pci_io;
795EXPORT_SYMBOL(out_be64);
796 745
797void memset_io(volatile void __iomem *addr, int c, unsigned long n) 746 if (root == NULL) {
798{ 747 printk(KERN_CRIT "iSeries_pcibios_init: can't find root "
799 if (firmware_has_feature(FW_FEATURE_ISERIES)) { 748 "of device tree\n");
800 volatile char __iomem *d = addr; 749 return;
750 }
751 while ((node = of_get_next_child(root, node)) != NULL) {
752 HvBusNumber bus;
753 const u32 *busp;
801 754
802 while (n-- > 0) { 755 if ((node->type == NULL) || (strcmp(node->type, "pci") != 0))
803 iSeries_Write_Byte(c, d++); 756 continue;
804 }
805 } else
806 eeh_memset_io(addr, c, n);
807}
808EXPORT_SYMBOL(memset_io);
809 757
810void memcpy_fromio(void *dest, const volatile void __iomem *src, 758 busp = get_property(node, "bus-range", NULL);
811 unsigned long n) 759 if (busp == NULL)
812{ 760 continue;
813 if (firmware_has_feature(FW_FEATURE_ISERIES)) { 761 bus = *busp;
814 char *d = dest; 762 printk("bus %d appears to exist\n", bus);
815 const volatile char __iomem *s = src; 763 phb = pcibios_alloc_controller(node);
764 if (phb == NULL)
765 continue;
816 766
817 while (n-- > 0) { 767 phb->pci_mem_offset = phb->local_number = bus;
818 *d++ = iSeries_Read_Byte(s++); 768 phb->first_busno = bus;
819 } 769 phb->last_busno = bus;
820 } else 770 phb->ops = &iSeries_pci_ops;
821 eeh_memcpy_fromio(dest, src, n); 771 }
822}
823EXPORT_SYMBOL(memcpy_fromio);
824 772
825void memcpy_toio(volatile void __iomem *dest, const void *src, unsigned long n) 773 of_node_put(root);
826{
827 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
828 const char *s = src;
829 volatile char __iomem *d = dest;
830 774
831 while (n-- > 0) { 775 pci_devs_phb_init();
832 iSeries_Write_Byte(*s++, d++);
833 }
834 } else
835 eeh_memcpy_toio(dest, src, n);
836} 776}
837EXPORT_SYMBOL(memcpy_toio); 777
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index 6f73469fd3b0..bdf2afbb60c1 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -21,7 +21,6 @@
21#include <linux/smp.h> 21#include <linux/smp.h>
22#include <linux/param.h> 22#include <linux/param.h>
23#include <linux/string.h> 23#include <linux/string.h>
24#include <linux/initrd.h>
25#include <linux/seq_file.h> 24#include <linux/seq_file.h>
26#include <linux/kdev_t.h> 25#include <linux/kdev_t.h>
27#include <linux/major.h> 26#include <linux/major.h>
@@ -80,8 +79,6 @@ extern void iSeries_pci_final_fixup(void);
80static void iSeries_pci_final_fixup(void) { } 79static void iSeries_pci_final_fixup(void) { }
81#endif 80#endif
82 81
83extern int rd_size; /* Defined in drivers/block/rd.c */
84
85extern unsigned long iSeries_recal_tb; 82extern unsigned long iSeries_recal_tb;
86extern unsigned long iSeries_recal_titan; 83extern unsigned long iSeries_recal_titan;
87 84
@@ -295,24 +292,6 @@ static void __init iSeries_init_early(void)
295{ 292{
296 DBG(" -> iSeries_init_early()\n"); 293 DBG(" -> iSeries_init_early()\n");
297 294
298#if defined(CONFIG_BLK_DEV_INITRD)
299 /*
300 * If the init RAM disk has been configured and there is
301 * a non-zero starting address for it, set it up
302 */
303 if (naca.xRamDisk) {
304 initrd_start = (unsigned long)__va(naca.xRamDisk);
305 initrd_end = initrd_start + naca.xRamDiskSize * HW_PAGE_SIZE;
306 initrd_below_start_ok = 1; // ramdisk in kernel space
307 ROOT_DEV = Root_RAM0;
308 if (((rd_size * 1024) / HW_PAGE_SIZE) < naca.xRamDiskSize)
309 rd_size = (naca.xRamDiskSize * HW_PAGE_SIZE) / 1024;
310 } else
311#endif /* CONFIG_BLK_DEV_INITRD */
312 {
313 /* ROOT_DEV = MKDEV(VIODASD_MAJOR, 1); */
314 }
315
316 iSeries_recal_tb = get_tb(); 295 iSeries_recal_tb = get_tb();
317 iSeries_recal_titan = HvCallXm_loadTod(); 296 iSeries_recal_titan = HvCallXm_loadTod();
318 297
@@ -331,17 +310,6 @@ static void __init iSeries_init_early(void)
331 310
332 mf_init(); 311 mf_init();
333 312
334 /* If we were passed an initrd, set the ROOT_DEV properly if the values
335 * look sensible. If not, clear initrd reference.
336 */
337#ifdef CONFIG_BLK_DEV_INITRD
338 if (initrd_start >= KERNELBASE && initrd_end >= KERNELBASE &&
339 initrd_end > initrd_start)
340 ROOT_DEV = Root_RAM0;
341 else
342 initrd_start = initrd_end = 0;
343#endif /* CONFIG_BLK_DEV_INITRD */
344
345 DBG(" <- iSeries_init_early()\n"); 313 DBG(" <- iSeries_init_early()\n");
346} 314}
347 315
@@ -649,6 +617,16 @@ static void iseries_dedicated_idle(void)
649void __init iSeries_init_IRQ(void) { } 617void __init iSeries_init_IRQ(void) { }
650#endif 618#endif
651 619
620static void __iomem *iseries_ioremap(phys_addr_t address, unsigned long size,
621 unsigned long flags)
622{
623 return (void __iomem *)address;
624}
625
626static void iseries_iounmap(volatile void __iomem *token)
627{
628}
629
652/* 630/*
653 * iSeries has no legacy IO, anything calling this function has to 631 * iSeries has no legacy IO, anything calling this function has to
654 * fail or bad things will happen 632 * fail or bad things will happen
@@ -665,6 +643,8 @@ static int __init iseries_probe(void)
665 return 0; 643 return 0;
666 644
667 hpte_init_iSeries(); 645 hpte_init_iSeries();
646 /* iSeries does not support 16M pages */
647 cur_cpu_spec->cpu_features &= ~CPU_FTR_16M_PAGE;
668 648
669 return 1; 649 return 1;
670} 650}
@@ -687,6 +667,8 @@ define_machine(iseries) {
687 .progress = iSeries_progress, 667 .progress = iSeries_progress,
688 .probe = iseries_probe, 668 .probe = iseries_probe,
689 .check_legacy_ioport = iseries_check_legacy_ioport, 669 .check_legacy_ioport = iseries_check_legacy_ioport,
670 .ioremap = iseries_ioremap,
671 .iounmap = iseries_iounmap,
690 /* XXX Implement enable_pmcs for iSeries */ 672 /* XXX Implement enable_pmcs for iSeries */
691}; 673};
692 674
@@ -697,7 +679,7 @@ void * __init iSeries_early_setup(void)
697 /* Identify CPU type. This is done again by the common code later 679 /* Identify CPU type. This is done again by the common code later
698 * on but calling this function multiple times is fine. 680 * on but calling this function multiple times is fine.
699 */ 681 */
700 identify_cpu(0); 682 identify_cpu(0, mfspr(SPRN_PVR));
701 683
702 powerpc_firmware_features |= FW_FEATURE_ISERIES; 684 powerpc_firmware_features |= FW_FEATURE_ISERIES;
703 powerpc_firmware_features |= FW_FEATURE_LPAR; 685 powerpc_firmware_features |= FW_FEATURE_LPAR;
diff --git a/arch/powerpc/platforms/iseries/viopath.c b/arch/powerpc/platforms/iseries/viopath.c
index 04e07e5da0c1..84e7ee2c086f 100644
--- a/arch/powerpc/platforms/iseries/viopath.c
+++ b/arch/powerpc/platforms/iseries/viopath.c
@@ -119,10 +119,9 @@ static int proc_viopath_show(struct seq_file *m, void *v)
119 struct device_node *node; 119 struct device_node *node;
120 const char *sysid; 120 const char *sysid;
121 121
122 buf = kmalloc(HW_PAGE_SIZE, GFP_KERNEL); 122 buf = kzalloc(HW_PAGE_SIZE, GFP_KERNEL);
123 if (!buf) 123 if (!buf)
124 return 0; 124 return 0;
125 memset(buf, 0, HW_PAGE_SIZE);
126 125
127 handle = dma_map_single(iSeries_vio_dev, buf, HW_PAGE_SIZE, 126 handle = dma_map_single(iSeries_vio_dev, buf, HW_PAGE_SIZE,
128 DMA_FROM_DEVICE); 127 DMA_FROM_DEVICE);
diff --git a/arch/powerpc/platforms/maple/maple.h b/arch/powerpc/platforms/maple/maple.h
index 0657c579b840..c6911ddc479f 100644
--- a/arch/powerpc/platforms/maple/maple.h
+++ b/arch/powerpc/platforms/maple/maple.h
@@ -8,5 +8,5 @@ extern void maple_get_rtc_time(struct rtc_time *tm);
8extern unsigned long maple_get_boot_time(void); 8extern unsigned long maple_get_boot_time(void);
9extern void maple_calibrate_decr(void); 9extern void maple_calibrate_decr(void);
10extern void maple_pci_init(void); 10extern void maple_pci_init(void);
11extern void maple_pcibios_fixup(void); 11extern void maple_pci_irq_fixup(struct pci_dev *dev);
12extern int maple_pci_get_legacy_ide_irq(struct pci_dev *dev, int channel); 12extern int maple_pci_get_legacy_ide_irq(struct pci_dev *dev, int channel);
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c
index 63b4d1bff359..3a32deda765d 100644
--- a/arch/powerpc/platforms/maple/pci.c
+++ b/arch/powerpc/platforms/maple/pci.c
@@ -502,38 +502,29 @@ static int __init add_bridge(struct device_node *dev)
502} 502}
503 503
504 504
505void __init maple_pcibios_fixup(void) 505void __devinit maple_pci_irq_fixup(struct pci_dev *dev)
506{ 506{
507 struct pci_dev *dev = NULL; 507 DBG(" -> maple_pci_irq_fixup\n");
508 508
509 DBG(" -> maple_pcibios_fixup\n"); 509 /* Fixup IRQ for PCIe host */
510 510 if (u4_pcie != NULL && dev->bus->number == 0 &&
511 for_each_pci_dev(dev) { 511 pci_bus_to_host(dev->bus) == u4_pcie) {
512 /* Fixup IRQ for PCIe host */ 512 printk(KERN_DEBUG "Fixup U4 PCIe IRQ\n");
513 if (u4_pcie != NULL && dev->bus->number == 0 && 513 dev->irq = irq_create_mapping(NULL, 1);
514 pci_bus_to_host(dev->bus) == u4_pcie) { 514 if (dev->irq != NO_IRQ)
515 printk(KERN_DEBUG "Fixup U4 PCIe IRQ\n"); 515 set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);
516 dev->irq = irq_create_mapping(NULL, 1); 516 }
517 if (dev->irq != NO_IRQ)
518 set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);
519 continue;
520 }
521
522 /* Hide AMD8111 IDE interrupt when in legacy mode so
523 * the driver calls pci_get_legacy_ide_irq()
524 */
525 if (dev->vendor == PCI_VENDOR_ID_AMD &&
526 dev->device == PCI_DEVICE_ID_AMD_8111_IDE &&
527 (dev->class & 5) != 5) {
528 dev->irq = NO_IRQ;
529 continue;
530 }
531 517
532 /* For all others, map the interrupt from the device-tree */ 518 /* Hide AMD8111 IDE interrupt when in legacy mode so
533 pci_read_irq_line(dev); 519 * the driver calls pci_get_legacy_ide_irq()
520 */
521 if (dev->vendor == PCI_VENDOR_ID_AMD &&
522 dev->device == PCI_DEVICE_ID_AMD_8111_IDE &&
523 (dev->class & 5) != 5) {
524 dev->irq = NO_IRQ;
534 } 525 }
535 526
536 DBG(" <- maple_pcibios_fixup\n"); 527 DBG(" <- maple_pci_irq_fixup\n");
537} 528}
538 529
539static void __init maple_fixup_phb_resources(void) 530static void __init maple_fixup_phb_resources(void)
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c
index fe6b9bff61b9..094989d50bab 100644
--- a/arch/powerpc/platforms/maple/setup.c
+++ b/arch/powerpc/platforms/maple/setup.c
@@ -312,7 +312,7 @@ define_machine(maple_md) {
312 .setup_arch = maple_setup_arch, 312 .setup_arch = maple_setup_arch,
313 .init_early = maple_init_early, 313 .init_early = maple_init_early,
314 .init_IRQ = maple_init_IRQ, 314 .init_IRQ = maple_init_IRQ,
315 .pcibios_fixup = maple_pcibios_fixup, 315 .pci_irq_fixup = maple_pci_irq_fixup,
316 .pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq, 316 .pci_get_legacy_ide_irq = maple_pci_get_legacy_ide_irq,
317 .restart = maple_restart, 317 .restart = maple_restart,
318 .power_off = maple_power_off, 318 .power_off = maple_power_off,
diff --git a/arch/powerpc/platforms/pasemi/pasemi.h b/arch/powerpc/platforms/pasemi/pasemi.h
index fd71d72736b2..51c2a2397ecf 100644
--- a/arch/powerpc/platforms/pasemi/pasemi.h
+++ b/arch/powerpc/platforms/pasemi/pasemi.h
@@ -3,6 +3,5 @@
3 3
4extern unsigned long pas_get_boot_time(void); 4extern unsigned long pas_get_boot_time(void);
5extern void pas_pci_init(void); 5extern void pas_pci_init(void);
6extern void pas_pcibios_fixup(void);
7 6
8#endif /* _PASEMI_PASEMI_H */ 7#endif /* _PASEMI_PASEMI_H */
diff --git a/arch/powerpc/platforms/pasemi/pci.c b/arch/powerpc/platforms/pasemi/pci.c
index 39020c1fa13d..faa618e04047 100644
--- a/arch/powerpc/platforms/pasemi/pci.c
+++ b/arch/powerpc/platforms/pasemi/pci.c
@@ -148,14 +148,6 @@ static int __init add_bridge(struct device_node *dev)
148} 148}
149 149
150 150
151void __init pas_pcibios_fixup(void)
152{
153 struct pci_dev *dev = NULL;
154
155 for_each_pci_dev(dev)
156 pci_read_irq_line(dev);
157}
158
159static void __init pas_fixup_phb_resources(void) 151static void __init pas_fixup_phb_resources(void)
160{ 152{
161 struct pci_controller *hose, *tmp; 153 struct pci_controller *hose, *tmp;
diff --git a/arch/powerpc/platforms/pasemi/setup.c b/arch/powerpc/platforms/pasemi/setup.c
index 106896c3b60a..89d6e295dbf7 100644
--- a/arch/powerpc/platforms/pasemi/setup.c
+++ b/arch/powerpc/platforms/pasemi/setup.c
@@ -26,6 +26,7 @@
26#include <linux/kernel.h> 26#include <linux/kernel.h>
27#include <linux/delay.h> 27#include <linux/delay.h>
28#include <linux/console.h> 28#include <linux/console.h>
29#include <linux/pci.h>
29 30
30#include <asm/prom.h> 31#include <asm/prom.h>
31#include <asm/system.h> 32#include <asm/system.h>
@@ -71,6 +72,9 @@ void __init pas_setup_arch(void)
71 /* Setup SMP callback */ 72 /* Setup SMP callback */
72 smp_ops = &pas_smp_ops; 73 smp_ops = &pas_smp_ops;
73#endif 74#endif
75 /* no iommu yet */
76 pci_dma_ops = &dma_direct_ops;
77
74 /* Lookup PCI hosts */ 78 /* Lookup PCI hosts */
75 pas_pci_init(); 79 pas_pci_init();
76 80
@@ -81,17 +85,6 @@ void __init pas_setup_arch(void)
81 printk(KERN_DEBUG "Using default idle loop\n"); 85 printk(KERN_DEBUG "Using default idle loop\n");
82} 86}
83 87
84static void iommu_dev_setup_null(struct pci_dev *dev) { }
85static void iommu_bus_setup_null(struct pci_bus *bus) { }
86
87static void __init pas_init_early(void)
88{
89 /* No iommu code yet */
90 ppc_md.iommu_dev_setup = iommu_dev_setup_null;
91 ppc_md.iommu_bus_setup = iommu_bus_setup_null;
92 pci_direct_iommu_init();
93}
94
95/* No legacy IO on our parts */ 88/* No legacy IO on our parts */
96static int pas_check_legacy_ioport(unsigned int baseport) 89static int pas_check_legacy_ioport(unsigned int baseport)
97{ 90{
@@ -173,10 +166,8 @@ define_machine(pas) {
173 .name = "PA Semi PA6T-1682M", 166 .name = "PA Semi PA6T-1682M",
174 .probe = pas_probe, 167 .probe = pas_probe,
175 .setup_arch = pas_setup_arch, 168 .setup_arch = pas_setup_arch,
176 .init_early = pas_init_early,
177 .init_IRQ = pas_init_IRQ, 169 .init_IRQ = pas_init_IRQ,
178 .get_irq = mpic_get_irq, 170 .get_irq = mpic_get_irq,
179 .pcibios_fixup = pas_pcibios_fixup,
180 .restart = pas_restart, 171 .restart = pas_restart,
181 .power_off = pas_power_off, 172 .power_off = pas_power_off,
182 .halt = pas_halt, 173 .halt = pas_halt,
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c
index e49621be6640..c29a6a064d22 100644
--- a/arch/powerpc/platforms/powermac/feature.c
+++ b/arch/powerpc/platforms/powermac/feature.c
@@ -486,10 +486,6 @@ static long heathrow_sound_enable(struct device_node *node, long param,
486 486
487static u32 save_fcr[6]; 487static u32 save_fcr[6];
488static u32 save_mbcr; 488static u32 save_mbcr;
489static u32 save_gpio_levels[2];
490static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT];
491static u8 save_gpio_normal[KEYLARGO_GPIO_CNT];
492static u32 save_unin_clock_ctl;
493static struct dbdma_regs save_dbdma[13]; 489static struct dbdma_regs save_dbdma[13];
494static struct dbdma_regs save_alt_dbdma[13]; 490static struct dbdma_regs save_alt_dbdma[13];
495 491
@@ -1548,6 +1544,10 @@ void g5_phy_disable_cpu1(void)
1548 1544
1549 1545
1550#ifdef CONFIG_PM 1546#ifdef CONFIG_PM
1547static u32 save_gpio_levels[2];
1548static u8 save_gpio_extint[KEYLARGO_GPIO_EXTINT_CNT];
1549static u8 save_gpio_normal[KEYLARGO_GPIO_CNT];
1550static u32 save_unin_clock_ctl;
1551 1551
1552static void keylargo_shutdown(struct macio_chip *macio, int sleep_mode) 1552static void keylargo_shutdown(struct macio_chip *macio, int sleep_mode)
1553{ 1553{
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c
index 257dc9068468..f42475b27c15 100644
--- a/arch/powerpc/platforms/powermac/pci.c
+++ b/arch/powerpc/platforms/powermac/pci.c
@@ -984,30 +984,23 @@ static int __init add_bridge(struct device_node *dev)
984 return 0; 984 return 0;
985} 985}
986 986
987void __init pmac_pcibios_fixup(void) 987void __devinit pmac_pci_irq_fixup(struct pci_dev *dev)
988{ 988{
989 struct pci_dev* dev = NULL;
990
991 for_each_pci_dev(dev) {
992 /* Read interrupt from the device-tree */
993 pci_read_irq_line(dev);
994
995#ifdef CONFIG_PPC32 989#ifdef CONFIG_PPC32
996 /* Fixup interrupt for the modem/ethernet combo controller. 990 /* Fixup interrupt for the modem/ethernet combo controller.
997 * on machines with a second ohare chip. 991 * on machines with a second ohare chip.
998 * The number in the device tree (27) is bogus (correct for 992 * The number in the device tree (27) is bogus (correct for
999 * the ethernet-only board but not the combo ethernet/modem 993 * the ethernet-only board but not the combo ethernet/modem
1000 * board). The real interrupt is 28 on the second controller 994 * board). The real interrupt is 28 on the second controller
1001 * -> 28+32 = 60. 995 * -> 28+32 = 60.
1002 */ 996 */
1003 if (has_second_ohare && 997 if (has_second_ohare &&
1004 dev->vendor == PCI_VENDOR_ID_DEC && 998 dev->vendor == PCI_VENDOR_ID_DEC &&
1005 dev->device == PCI_DEVICE_ID_DEC_TULIP_PLUS) { 999 dev->device == PCI_DEVICE_ID_DEC_TULIP_PLUS) {
1006 dev->irq = irq_create_mapping(NULL, 60); 1000 dev->irq = irq_create_mapping(NULL, 60);
1007 set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW); 1001 set_irq_type(dev->irq, IRQ_TYPE_LEVEL_LOW);
1008 }
1009#endif /* CONFIG_PPC32 */
1010 } 1002 }
1003#endif /* CONFIG_PPC32 */
1011} 1004}
1012 1005
1013#ifdef CONFIG_PPC64 1006#ifdef CONFIG_PPC64
diff --git a/arch/powerpc/platforms/powermac/pmac.h b/arch/powerpc/platforms/powermac/pmac.h
index 94e7b24b840b..6e090a7dea83 100644
--- a/arch/powerpc/platforms/powermac/pmac.h
+++ b/arch/powerpc/platforms/powermac/pmac.h
@@ -20,7 +20,7 @@ extern void pmac_get_rtc_time(struct rtc_time *);
20extern int pmac_set_rtc_time(struct rtc_time *); 20extern int pmac_set_rtc_time(struct rtc_time *);
21extern void pmac_read_rtc_time(void); 21extern void pmac_read_rtc_time(void);
22extern void pmac_calibrate_decr(void); 22extern void pmac_calibrate_decr(void);
23extern void pmac_pcibios_fixup(void); 23extern void pmac_pci_irq_fixup(struct pci_dev *);
24extern void pmac_pci_init(void); 24extern void pmac_pci_init(void);
25extern unsigned long pmac_ide_get_base(int index); 25extern unsigned long pmac_ide_get_base(int index);
26extern void pmac_ide_init_hwif_ports(hw_regs_t *hw, 26extern void pmac_ide_init_hwif_ports(hw_regs_t *hw,
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c
index 824a618396ab..d949e9df41ef 100644
--- a/arch/powerpc/platforms/powermac/setup.c
+++ b/arch/powerpc/platforms/powermac/setup.c
@@ -70,6 +70,7 @@
70#include <asm/pmac_feature.h> 70#include <asm/pmac_feature.h>
71#include <asm/time.h> 71#include <asm/time.h>
72#include <asm/of_device.h> 72#include <asm/of_device.h>
73#include <asm/of_platform.h>
73#include <asm/mmu_context.h> 74#include <asm/mmu_context.h>
74#include <asm/iommu.h> 75#include <asm/iommu.h>
75#include <asm/smu.h> 76#include <asm/smu.h>
@@ -361,7 +362,7 @@ char *bootdevice;
361void *boot_host; 362void *boot_host;
362int boot_target; 363int boot_target;
363int boot_part; 364int boot_part;
364extern dev_t boot_dev; 365static dev_t boot_dev;
365 366
366#ifdef CONFIG_SCSI 367#ifdef CONFIG_SCSI
367void __init note_scsi_host(struct device_node *node, void *host) 368void __init note_scsi_host(struct device_node *node, void *host)
@@ -676,8 +677,6 @@ static int __init pmac_probe(void)
676 677
677#ifdef CONFIG_PPC32 678#ifdef CONFIG_PPC32
678 /* isa_io_base gets set in pmac_pci_init */ 679 /* isa_io_base gets set in pmac_pci_init */
679 isa_mem_base = PMAC_ISA_MEM_BASE;
680 pci_dram_offset = PMAC_PCI_DRAM_OFFSET;
681 ISA_DMA_THRESHOLD = ~0L; 680 ISA_DMA_THRESHOLD = ~0L;
682 DMA_MODE_READ = 1; 681 DMA_MODE_READ = 1;
683 DMA_MODE_WRITE = 2; 682 DMA_MODE_WRITE = 2;
@@ -727,7 +726,7 @@ define_machine(powermac) {
727 .show_cpuinfo = pmac_show_cpuinfo, 726 .show_cpuinfo = pmac_show_cpuinfo,
728 .init_IRQ = pmac_pic_init, 727 .init_IRQ = pmac_pic_init,
729 .get_irq = NULL, /* changed later */ 728 .get_irq = NULL, /* changed later */
730 .pcibios_fixup = pmac_pcibios_fixup, 729 .pci_irq_fixup = pmac_pci_irq_fixup,
731 .restart = pmac_restart, 730 .restart = pmac_restart,
732 .power_off = pmac_power_off, 731 .power_off = pmac_power_off,
733 .halt = pmac_halt, 732 .halt = pmac_halt,
diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
new file mode 100644
index 000000000000..451bfcd5502e
--- /dev/null
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -0,0 +1,43 @@
1menu "PS3 Platform Options"
2 depends on PPC_PS3
3
4config PS3_HTAB_SIZE
5 depends on PPC_PS3
6 int "PS3 Platform pagetable size"
7 range 18 20
8 default 20
9 help
10 This option is only for experts who may have the desire to fine
11 tune the pagetable size on their system. The value here is
12 expressed as the log2 of the page table size. Valid values are
13 18, 19, and 20, corresponding to 256KB, 512KB and 1MB respectively.
14
15 If unsure, choose the default (20) with the confidence that your
16 system will have optimal runtime performance.
17
18config PS3_DYNAMIC_DMA
19 depends on PPC_PS3 && EXPERIMENTAL
20 bool "PS3 Platform dynamic DMA page table management"
21 default n
22 help
23 This option will enable kernel support to take advantage of the
24 per device dynamic DMA page table management provided by the Cell
25 processor's IO Controller. This support incurs some runtime
26 overhead and also slightly increases kernel memory usage. The
27 current implementation should be considered experimental.
28
29 This support is mainly for Linux kernel development. If unsure,
30 say N.
31
32config PS3_USE_LPAR_ADDR
33 depends on PPC_PS3 && EXPERIMENTAL
34 bool "PS3 use lpar address space"
35 default y
36 help
37 This option is solely for experimentation by experts. Disables
38 translation of lpar addresses. SPE support currently won't work
39 without this set to y.
40
41 If you have any doubt, choose the default y.
42
43endmenu
diff --git a/arch/powerpc/platforms/ps3/Makefile b/arch/powerpc/platforms/ps3/Makefile
new file mode 100644
index 000000000000..3757cfabc8ce
--- /dev/null
+++ b/arch/powerpc/platforms/ps3/Makefile
@@ -0,0 +1,4 @@
1obj-y += setup.o mm.o smp.o time.o hvcall.o htab.o repository.o
2obj-y += interrupt.o exports.o os-area.o
3
4obj-$(CONFIG_SPU_BASE) += spu.o
diff --git a/arch/powerpc/platforms/ps3/exports.c b/arch/powerpc/platforms/ps3/exports.c
new file mode 100644
index 000000000000..a7e8ffd24a65
--- /dev/null
+++ b/arch/powerpc/platforms/ps3/exports.c
@@ -0,0 +1,27 @@
1/*
2 * PS3 hvcall exports for modules.
3 *
4 * Copyright (C) 2006 Sony Computer Entertainment Inc.
5 * Copyright 2006 Sony Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/module.h>
22
23#define LV1_CALL(name, in, out, num) \
24 extern s64 _lv1_##name(LV1_##in##_IN_##out##_OUT_ARG_DECL); \
25 EXPORT_SYMBOL(_lv1_##name);
26
27#include <asm/lv1call.h>
diff --git a/arch/powerpc/platforms/ps3/htab.c b/arch/powerpc/platforms/ps3/htab.c
new file mode 100644
index 000000000000..8fe1769655a3
--- /dev/null
+++ b/arch/powerpc/platforms/ps3/htab.c
@@ -0,0 +1,277 @@
1/*
2 * PS3 pagetable management routines.
3 *
4 * Copyright (C) 2006 Sony Computer Entertainment Inc.
5 * Copyright 2006 Sony Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/kernel.h>
22
23#include <asm/machdep.h>
24#include <asm/lmb.h>
25#include <asm/udbg.h>
26#include <asm/ps3.h>
27#include <asm/lv1call.h>
28
29#include "platform.h"
30
31#if defined(DEBUG)
32#define DBG(fmt...) udbg_printf(fmt)
33#else
34#define DBG(fmt...) do{if(0)printk(fmt);}while(0)
35#endif
36
37static hpte_t *htab;
38static unsigned long htab_addr;
39static unsigned char *bolttab;
40static unsigned char *inusetab;
41
42static spinlock_t ps3_bolttab_lock = SPIN_LOCK_UNLOCKED;
43
44#define debug_dump_hpte(_a, _b, _c, _d, _e, _f, _g) \
45 _debug_dump_hpte(_a, _b, _c, _d, _e, _f, _g, __func__, __LINE__)
46static void _debug_dump_hpte(unsigned long pa, unsigned long va,
47 unsigned long group, unsigned long bitmap, hpte_t lhpte, int psize,
48 unsigned long slot, const char* func, int line)
49{
50 DBG("%s:%d: pa = %lxh\n", func, line, pa);
51 DBG("%s:%d: lpar = %lxh\n", func, line,
52 ps3_mm_phys_to_lpar(pa));
53 DBG("%s:%d: va = %lxh\n", func, line, va);
54 DBG("%s:%d: group = %lxh\n", func, line, group);
55 DBG("%s:%d: bitmap = %lxh\n", func, line, bitmap);
56 DBG("%s:%d: hpte.v = %lxh\n", func, line, lhpte.v);
57 DBG("%s:%d: hpte.r = %lxh\n", func, line, lhpte.r);
58 DBG("%s:%d: psize = %xh\n", func, line, psize);
59 DBG("%s:%d: slot = %lxh\n", func, line, slot);
60}
61
62static long ps3_hpte_insert(unsigned long hpte_group, unsigned long va,
63 unsigned long pa, unsigned long rflags, unsigned long vflags, int psize)
64{
65 unsigned long slot;
66 hpte_t lhpte;
67 int secondary = 0;
68 unsigned long result;
69 unsigned long bitmap;
70 unsigned long flags;
71 unsigned long p_pteg, s_pteg, b_index, b_mask, cb, ci;
72
73 vflags &= ~HPTE_V_SECONDARY; /* this bit is ignored */
74
75 lhpte.v = hpte_encode_v(va, psize) | vflags | HPTE_V_VALID;
76 lhpte.r = hpte_encode_r(ps3_mm_phys_to_lpar(pa), psize) | rflags;
77
78 p_pteg = hpte_group / HPTES_PER_GROUP;
79 s_pteg = ~p_pteg & htab_hash_mask;
80
81 spin_lock_irqsave(&ps3_bolttab_lock, flags);
82
83 BUG_ON(bolttab[p_pteg] == 0xff && bolttab[s_pteg] == 0xff);
84
85 bitmap = (inusetab[p_pteg] << 8) | inusetab[s_pteg];
86
87 if (bitmap == 0xffff) {
88 /*
89 * PTEG is full. Search for victim.
90 */
91 bitmap &= ~((bolttab[p_pteg] << 8) | bolttab[s_pteg]);
92 do {
93 ci = mftb() & 15;
94 cb = 0x8000UL >> ci;
95 } while ((cb & bitmap) == 0);
96 } else {
97 /*
98 * search free slot in hardware order
99 * [primary] 0, 2, 4, 6, 1, 3, 5, 7
100 * [secondary] 0, 2, 4, 6, 1, 3, 5, 7
101 */
102 for (ci = 0; ci < HPTES_PER_GROUP; ci += 2) {
103 cb = 0x8000UL >> ci;
104 if ((cb & bitmap) == 0)
105 goto found;
106 }
107 for (ci = 1; ci < HPTES_PER_GROUP; ci += 2) {
108 cb = 0x8000UL >> ci;
109 if ((cb & bitmap) == 0)
110 goto found;
111 }
112 for (ci = HPTES_PER_GROUP; ci < HPTES_PER_GROUP*2; ci += 2) {
113 cb = 0x8000UL >> ci;
114 if ((cb & bitmap) == 0)
115 goto found;
116 }
117 for (ci = HPTES_PER_GROUP+1; ci < HPTES_PER_GROUP*2; ci += 2) {
118 cb = 0x8000UL >> ci;
119 if ((cb & bitmap) == 0)
120 goto found;
121 }
122 }
123
124found:
125 if (ci < HPTES_PER_GROUP) {
126 slot = p_pteg * HPTES_PER_GROUP + ci;
127 } else {
128 slot = s_pteg * HPTES_PER_GROUP + (ci & 7);
129 /* lhpte.dw0.dw0.h = 1; */
130 vflags |= HPTE_V_SECONDARY;
131 lhpte.v |= HPTE_V_SECONDARY;
132 }
133
134 result = lv1_write_htab_entry(0, slot, lhpte.v, lhpte.r);
135
136 if (result) {
137 debug_dump_hpte(pa, va, hpte_group, bitmap, lhpte, psize, slot);
138 BUG();
139 }
140
141 /*
142 * If used slot is not in primary HPTE group,
143 * the slot should be in secondary HPTE group.
144 */
145
146 if ((hpte_group ^ slot) & ~(HPTES_PER_GROUP - 1)) {
147 secondary = 1;
148 b_index = s_pteg;
149 } else {
150 secondary = 0;
151 b_index = p_pteg;
152 }
153
154 b_mask = (lhpte.v & HPTE_V_BOLTED) ? 1 << 7 : 0 << 7;
155 bolttab[b_index] |= b_mask >> (slot & 7);
156 b_mask = 1 << 7;
157 inusetab[b_index] |= b_mask >> (slot & 7);
158 spin_unlock_irqrestore(&ps3_bolttab_lock, flags);
159
160 return (slot & 7) | (secondary << 3);
161}
162
163static long ps3_hpte_remove(unsigned long hpte_group)
164{
165 panic("ps3_hpte_remove() not implemented");
166 return 0;
167}
168
169static long ps3_hpte_updatepp(unsigned long slot, unsigned long newpp,
170 unsigned long va, int psize, int local)
171{
172 unsigned long flags;
173 unsigned long result;
174 unsigned long pteg, bit;
175 unsigned long hpte_v, want_v;
176
177 want_v = hpte_encode_v(va, psize);
178
179 spin_lock_irqsave(&ps3_bolttab_lock, flags);
180
181 hpte_v = htab[slot].v;
182 if (!HPTE_V_COMPARE(hpte_v, want_v) || !(hpte_v & HPTE_V_VALID)) {
183 spin_unlock_irqrestore(&ps3_bolttab_lock, flags);
184
185 /* ps3_hpte_insert() will be used to update PTE */
186 return -1;
187 }
188
189 result = lv1_write_htab_entry(0, slot, 0, 0);
190
191 if (result) {
192 DBG("%s: va=%lx slot=%lx psize=%d result = %ld (0x%lx)\n",
193 __func__, va, slot, psize, result, result);
194 BUG();
195 }
196
197 pteg = slot / HPTES_PER_GROUP;
198 bit = slot % HPTES_PER_GROUP;
199 inusetab[pteg] &= ~(0x80 >> bit);
200
201 spin_unlock_irqrestore(&ps3_bolttab_lock, flags);
202
203 /* ps3_hpte_insert() will be used to update PTE */
204 return -1;
205}
206
207static void ps3_hpte_updateboltedpp(unsigned long newpp, unsigned long ea,
208 int psize)
209{
210 panic("ps3_hpte_updateboltedpp() not implemented");
211}
212
213static void ps3_hpte_invalidate(unsigned long slot, unsigned long va,
214 int psize, int local)
215{
216 unsigned long flags;
217 unsigned long result;
218 unsigned long pteg, bit;
219
220 spin_lock_irqsave(&ps3_bolttab_lock, flags);
221 result = lv1_write_htab_entry(0, slot, 0, 0);
222
223 if (result) {
224 DBG("%s: va=%lx slot=%lx psize=%d result = %ld (0x%lx)\n",
225 __func__, va, slot, psize, result, result);
226 BUG();
227 }
228
229 pteg = slot / HPTES_PER_GROUP;
230 bit = slot % HPTES_PER_GROUP;
231 inusetab[pteg] &= ~(0x80 >> bit);
232 spin_unlock_irqrestore(&ps3_bolttab_lock, flags);
233}
234
235static void ps3_hpte_clear(void)
236{
237 lv1_unmap_htab(htab_addr);
238}
239
240void __init ps3_hpte_init(unsigned long htab_size)
241{
242 long bitmap_size;
243
244 DBG(" -> %s:%d\n", __func__, __LINE__);
245
246 ppc_md.hpte_invalidate = ps3_hpte_invalidate;
247 ppc_md.hpte_updatepp = ps3_hpte_updatepp;
248 ppc_md.hpte_updateboltedpp = ps3_hpte_updateboltedpp;
249 ppc_md.hpte_insert = ps3_hpte_insert;
250 ppc_md.hpte_remove = ps3_hpte_remove;
251 ppc_md.hpte_clear_all = ps3_hpte_clear;
252
253 ppc64_pft_size = __ilog2(htab_size);
254
255 bitmap_size = htab_size / sizeof(hpte_t) / 8;
256
257 bolttab = __va(lmb_alloc(bitmap_size, 1));
258 inusetab = __va(lmb_alloc(bitmap_size, 1));
259
260 memset(bolttab, 0, bitmap_size);
261 memset(inusetab, 0, bitmap_size);
262
263 DBG(" <- %s:%d\n", __func__, __LINE__);
264}
265
266void __init ps3_map_htab(void)
267{
268 long result;
269 unsigned long htab_size = (1UL << ppc64_pft_size);
270
271 result = lv1_map_htab(0, &htab_addr);
272
273 htab = (hpte_t *)__ioremap(htab_addr, htab_size, PAGE_READONLY_X);
274
275 DBG("%s:%d: lpar %016lxh, virt %016lxh\n", __func__, __LINE__,
276 htab_addr, (unsigned long)htab);
277}
diff --git a/arch/powerpc/platforms/ps3/hvcall.S b/arch/powerpc/platforms/ps3/hvcall.S
new file mode 100644
index 000000000000..54be6523a0e8
--- /dev/null
+++ b/arch/powerpc/platforms/ps3/hvcall.S
@@ -0,0 +1,804 @@
1/*
2 * PS3 hvcall interface.
3 *
4 * Copyright (C) 2006 Sony Computer Entertainment Inc.
5 * Copyright 2006 Sony Corp.
6 * Copyright 2003, 2004 (c) MontaVista Software, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include <asm/processor.h>
23#include <asm/ppc_asm.h>
24
25#define lv1call .long 0x44000022; extsw r3, r3
26
27#define LV1_N_IN_0_OUT(API_NAME, API_NUMBER) \
28_GLOBAL(_##API_NAME) \
29 \
30 mflr r0; \
31 std r0, 16(r1); \
32 \
33 li r11, API_NUMBER; \
34 lv1call; \
35 \
36 ld r0, 16(r1); \
37 mtlr r0; \
38 blr
39
40#define LV1_0_IN_0_OUT LV1_N_IN_0_OUT
41#define LV1_1_IN_0_OUT LV1_N_IN_0_OUT
42#define LV1_2_IN_0_OUT LV1_N_IN_0_OUT
43#define LV1_3_IN_0_OUT LV1_N_IN_0_OUT
44#define LV1_4_IN_0_OUT LV1_N_IN_0_OUT
45#define LV1_5_IN_0_OUT LV1_N_IN_0_OUT
46#define LV1_6_IN_0_OUT LV1_N_IN_0_OUT
47#define LV1_7_IN_0_OUT LV1_N_IN_0_OUT
48
49#define LV1_0_IN_1_OUT(API_NAME, API_NUMBER) \
50_GLOBAL(_##API_NAME) \
51 \
52 mflr r0; \
53 std r0, 16(r1); \
54 \
55 stdu r3, -8(r1); \
56 \
57 li r11, API_NUMBER; \
58 lv1call; \
59 \
60 addi r1, r1, 8; \
61 ld r11, -8(r1); \
62 std r4, 0(r11); \
63 \
64 ld r0, 16(r1); \
65 mtlr r0; \
66 blr
67
68#define LV1_0_IN_2_OUT(API_NAME, API_NUMBER) \
69_GLOBAL(_##API_NAME) \
70 \
71 mflr r0; \
72 std r0, 16(r1); \
73 \
74 std r3, -8(r1); \
75 stdu r4, -16(r1); \
76 \
77 li r11, API_NUMBER; \
78 lv1call; \
79 \
80 addi r1, r1, 16; \
81 ld r11, -8(r1); \
82 std r4, 0(r11); \
83 ld r11, -16(r1); \
84 std r5, 0(r11); \
85 \
86 ld r0, 16(r1); \
87 mtlr r0; \
88 blr
89
90#define LV1_0_IN_3_OUT(API_NAME, API_NUMBER) \
91_GLOBAL(_##API_NAME) \
92 \
93 mflr r0; \
94 std r0, 16(r1); \
95 \
96 std r3, -8(r1); \
97 std r4, -16(r1); \
98 stdu r5, -24(r1); \
99 \
100 li r11, API_NUMBER; \
101 lv1call; \
102 \
103 addi r1, r1, 24; \
104 ld r11, -8(r1); \
105 std r4, 0(r11); \
106 ld r11, -16(r1); \
107 std r5, 0(r11); \
108 ld r11, -24(r1); \
109 std r6, 0(r11); \
110 \
111 ld r0, 16(r1); \
112 mtlr r0; \
113 blr
114
115#define LV1_0_IN_7_OUT(API_NAME, API_NUMBER) \
116_GLOBAL(_##API_NAME) \
117 \
118 mflr r0; \
119 std r0, 16(r1); \
120 \
121 std r3, -8(r1); \
122 std r4, -16(r1); \
123 std r5, -24(r1); \
124 std r6, -32(r1); \
125 std r7, -40(r1); \
126 std r8, -48(r1); \
127 stdu r9, -56(r1); \
128 \
129 li r11, API_NUMBER; \
130 lv1call; \
131 \
132 addi r1, r1, 56; \
133 ld r11, -8(r1); \
134 std r4, 0(r11); \
135 ld r11, -16(r1); \
136 std r5, 0(r11); \
137 ld r11, -24(r1); \
138 std r6, 0(r11); \
139 ld r11, -32(r1); \
140 std r7, 0(r11); \
141 ld r11, -40(r1); \
142 std r8, 0(r11); \
143 ld r11, -48(r1); \
144 std r9, 0(r11); \
145 ld r11, -56(r1); \
146 std r10, 0(r11); \
147 \
148 ld r0, 16(r1); \
149 mtlr r0; \
150 blr
151
152#define LV1_1_IN_1_OUT(API_NAME, API_NUMBER) \
153_GLOBAL(_##API_NAME) \
154 \
155 mflr r0; \
156 std r0, 16(r1); \
157 \
158 stdu r4, -8(r1); \
159 \
160 li r11, API_NUMBER; \
161 lv1call; \
162 \
163 addi r1, r1, 8; \
164 ld r11, -8(r1); \
165 std r4, 0(r11); \
166 \
167 ld r0, 16(r1); \
168 mtlr r0; \
169 blr
170
171#define LV1_1_IN_2_OUT(API_NAME, API_NUMBER) \
172_GLOBAL(_##API_NAME) \
173 \
174 mflr r0; \
175 std r0, 16(r1); \
176 \
177 std r4, -8(r1); \
178 stdu r5, -16(r1); \
179 \
180 li r11, API_NUMBER; \
181 lv1call; \
182 \
183 addi r1, r1, 16; \
184 ld r11, -8(r1); \
185 std r4, 0(r11); \
186 ld r11, -16(r1); \
187 std r5, 0(r11); \
188 \
189 ld r0, 16(r1); \
190 mtlr r0; \
191 blr
192
193#define LV1_1_IN_3_OUT(API_NAME, API_NUMBER) \
194_GLOBAL(_##API_NAME) \
195 \
196 mflr r0; \
197 std r0, 16(r1); \
198 \
199 std r4, -8(r1); \
200 std r5, -16(r1); \
201 stdu r6, -24(r1); \
202 \
203 li r11, API_NUMBER; \
204 lv1call; \
205 \
206 addi r1, r1, 24; \
207 ld r11, -8(r1); \
208 std r4, 0(r11); \
209 ld r11, -16(r1); \
210 std r5, 0(r11); \
211 ld r11, -24(r1); \
212 std r6, 0(r11); \
213 \
214 ld r0, 16(r1); \
215 mtlr r0; \
216 blr
217
218#define LV1_1_IN_4_OUT(API_NAME, API_NUMBER) \
219_GLOBAL(_##API_NAME) \
220 \
221 mflr r0; \
222 std r0, 16(r1); \
223 \
224 std r4, -8(r1); \
225 std r5, -16(r1); \
226 std r6, -24(r1); \
227 stdu r7, -32(r1); \
228 \
229 li r11, API_NUMBER; \
230 lv1call; \
231 \
232 addi r1, r1, 32; \
233 ld r11, -8(r1); \
234 std r4, 0(r11); \
235 ld r11, -16(r1); \
236 std r5, 0(r11); \
237 ld r11, -24(r1); \
238 std r6, 0(r11); \
239 ld r11, -32(r1); \
240 std r7, 0(r11); \
241 \
242 ld r0, 16(r1); \
243 mtlr r0; \
244 blr
245
246#define LV1_1_IN_5_OUT(API_NAME, API_NUMBER) \
247_GLOBAL(_##API_NAME) \
248 \
249 mflr r0; \
250 std r0, 16(r1); \
251 \
252 std r4, -8(r1); \
253 std r5, -16(r1); \
254 std r6, -24(r1); \
255 std r7, -32(r1); \
256 stdu r8, -40(r1); \
257 \
258 li r11, API_NUMBER; \
259 lv1call; \
260 \
261 addi r1, r1, 40; \
262 ld r11, -8(r1); \
263 std r4, 0(r11); \
264 ld r11, -16(r1); \
265 std r5, 0(r11); \
266 ld r11, -24(r1); \
267 std r6, 0(r11); \
268 ld r11, -32(r1); \
269 std r7, 0(r11); \
270 ld r11, -40(r1); \
271 std r8, 0(r11); \
272 \
273 ld r0, 16(r1); \
274 mtlr r0; \
275 blr
276
277#define LV1_1_IN_6_OUT(API_NAME, API_NUMBER) \
278_GLOBAL(_##API_NAME) \
279 \
280 mflr r0; \
281 std r0, 16(r1); \
282 \
283 std r4, -8(r1); \
284 std r5, -16(r1); \
285 std r6, -24(r1); \
286 std r7, -32(r1); \
287 std r8, -40(r1); \
288 stdu r9, -48(r1); \
289 \
290 li r11, API_NUMBER; \
291 lv1call; \
292 \
293 addi r1, r1, 48; \
294 ld r11, -8(r1); \
295 std r4, 0(r11); \
296 ld r11, -16(r1); \
297 std r5, 0(r11); \
298 ld r11, -24(r1); \
299 std r6, 0(r11); \
300 ld r11, -32(r1); \
301 std r7, 0(r11); \
302 ld r11, -40(r1); \
303 std r8, 0(r11); \
304 ld r11, -48(r1); \
305 std r9, 0(r11); \
306 \
307 ld r0, 16(r1); \
308 mtlr r0; \
309 blr
310
311#define LV1_1_IN_7_OUT(API_NAME, API_NUMBER) \
312_GLOBAL(_##API_NAME) \
313 \
314 mflr r0; \
315 std r0, 16(r1); \
316 \
317 std r4, -8(r1); \
318 std r5, -16(r1); \
319 std r6, -24(r1); \
320 std r7, -32(r1); \
321 std r8, -40(r1); \
322 std r9, -48(r1); \
323 stdu r10, -56(r1); \
324 \
325 li r11, API_NUMBER; \
326 lv1call; \
327 \
328 addi r1, r1, 56; \
329 ld r11, -8(r1); \
330 std r4, 0(r11); \
331 ld r11, -16(r1); \
332 std r5, 0(r11); \
333 ld r11, -24(r1); \
334 std r6, 0(r11); \
335 ld r11, -32(r1); \
336 std r7, 0(r11); \
337 ld r11, -40(r1); \
338 std r8, 0(r11); \
339 ld r11, -48(r1); \
340 std r9, 0(r11); \
341 ld r11, -56(r1); \
342 std r10, 0(r11); \
343 \
344 ld r0, 16(r1); \
345 mtlr r0; \
346 blr
347
348#define LV1_2_IN_1_OUT(API_NAME, API_NUMBER) \
349_GLOBAL(_##API_NAME) \
350 \
351 mflr r0; \
352 std r0, 16(r1); \
353 \
354 stdu r5, -8(r1); \
355 \
356 li r11, API_NUMBER; \
357 lv1call; \
358 \
359 addi r1, r1, 8; \
360 ld r11, -8(r1); \
361 std r4, 0(r11); \
362 \
363 ld r0, 16(r1); \
364 mtlr r0; \
365 blr
366
367#define LV1_2_IN_2_OUT(API_NAME, API_NUMBER) \
368_GLOBAL(_##API_NAME) \
369 \
370 mflr r0; \
371 std r0, 16(r1); \
372 \
373 std r5, -8(r1); \
374 stdu r6, -16(r1); \
375 \
376 li r11, API_NUMBER; \
377 lv1call; \
378 \
379 addi r1, r1, 16; \
380 ld r11, -8(r1); \
381 std r4, 0(r11); \
382 ld r11, -16(r1); \
383 std r5, 0(r11); \
384 \
385 ld r0, 16(r1); \
386 mtlr r0; \
387 blr
388
389#define LV1_2_IN_3_OUT(API_NAME, API_NUMBER) \
390_GLOBAL(_##API_NAME) \
391 \
392 mflr r0; \
393 std r0, 16(r1); \
394 \
395 std r5, -8(r1); \
396 std r6, -16(r1); \
397 stdu r7, -24(r1); \
398 \
399 li r11, API_NUMBER; \
400 lv1call; \
401 \
402 addi r1, r1, 24; \
403 ld r11, -8(r1); \
404 std r4, 0(r11); \
405 ld r11, -16(r1); \
406 std r5, 0(r11); \
407 ld r11, -24(r1); \
408 std r6, 0(r11); \
409 \
410 ld r0, 16(r1); \
411 mtlr r0; \
412 blr
413
414#define LV1_2_IN_4_OUT(API_NAME, API_NUMBER) \
415_GLOBAL(_##API_NAME) \
416 \
417 mflr r0; \
418 std r0, 16(r1); \
419 \
420 std r5, -8(r1); \
421 std r6, -16(r1); \
422 std r7, -24(r1); \
423 stdu r8, -32(r1); \
424 \
425 li r11, API_NUMBER; \
426 lv1call; \
427 \
428 addi r1, r1, 32; \
429 ld r11, -8(r1); \
430 std r4, 0(r11); \
431 ld r11, -16(r1); \
432 std r5, 0(r11); \
433 ld r11, -24(r1); \
434 std r6, 0(r11); \
435 ld r11, -32(r1); \
436 std r7, 0(r11); \
437 \
438 ld r0, 16(r1); \
439 mtlr r0; \
440 blr
441
442#define LV1_2_IN_5_OUT(API_NAME, API_NUMBER) \
443_GLOBAL(_##API_NAME) \
444 \
445 mflr r0; \
446 std r0, 16(r1); \
447 \
448 std r5, -8(r1); \
449 std r6, -16(r1); \
450 std r7, -24(r1); \
451 std r8, -32(r1); \
452 stdu r9, -40(r1); \
453 \
454 li r11, API_NUMBER; \
455 lv1call; \
456 \
457 addi r1, r1, 40; \
458 ld r11, -8(r1); \
459 std r4, 0(r11); \
460 ld r11, -16(r1); \
461 std r5, 0(r11); \
462 ld r11, -24(r1); \
463 std r6, 0(r11); \
464 ld r11, -32(r1); \
465 std r7, 0(r11); \
466 ld r11, -40(r1); \
467 std r8, 0(r11); \
468 \
469 ld r0, 16(r1); \
470 mtlr r0; \
471 blr
472
473#define LV1_3_IN_1_OUT(API_NAME, API_NUMBER) \
474_GLOBAL(_##API_NAME) \
475 \
476 mflr r0; \
477 std r0, 16(r1); \
478 \
479 stdu r6, -8(r1); \
480 \
481 li r11, API_NUMBER; \
482 lv1call; \
483 \
484 addi r1, r1, 8; \
485 ld r11, -8(r1); \
486 std r4, 0(r11); \
487 \
488 ld r0, 16(r1); \
489 mtlr r0; \
490 blr
491
492#define LV1_3_IN_2_OUT(API_NAME, API_NUMBER) \
493_GLOBAL(_##API_NAME) \
494 \
495 mflr r0; \
496 std r0, 16(r1); \
497 \
498 std r6, -8(r1); \
499 stdu r7, -16(r1); \
500 \
501 li r11, API_NUMBER; \
502 lv1call; \
503 \
504 addi r1, r1, 16; \
505 ld r11, -8(r1); \
506 std r4, 0(r11); \
507 ld r11, -16(r1); \
508 std r5, 0(r11); \
509 \
510 ld r0, 16(r1); \
511 mtlr r0; \
512 blr
513
514#define LV1_3_IN_3_OUT(API_NAME, API_NUMBER) \
515_GLOBAL(_##API_NAME) \
516 \
517 mflr r0; \
518 std r0, 16(r1); \
519 \
520 std r6, -8(r1); \
521 std r7, -16(r1); \
522 stdu r8, -24(r1); \
523 \
524 li r11, API_NUMBER; \
525 lv1call; \
526 \
527 addi r1, r1, 24; \
528 ld r11, -8(r1); \
529 std r4, 0(r11); \
530 ld r11, -16(r1); \
531 std r5, 0(r11); \
532 ld r11, -24(r1); \
533 std r6, 0(r11); \
534 \
535 ld r0, 16(r1); \
536 mtlr r0; \
537 blr
538
539#define LV1_4_IN_1_OUT(API_NAME, API_NUMBER) \
540_GLOBAL(_##API_NAME) \
541 \
542 mflr r0; \
543 std r0, 16(r1); \
544 \
545 stdu r7, -8(r1); \
546 \
547 li r11, API_NUMBER; \
548 lv1call; \
549 \
550 addi r1, r1, 8; \
551 ld r11, -8(r1); \
552 std r4, 0(r11); \
553 \
554 ld r0, 16(r1); \
555 mtlr r0; \
556 blr
557
558#define LV1_4_IN_2_OUT(API_NAME, API_NUMBER) \
559_GLOBAL(_##API_NAME) \
560 \
561 mflr r0; \
562 std r0, 16(r1); \
563 \
564 std r7, -8(r1); \
565 stdu r8, -16(r1); \
566 \
567 li r11, API_NUMBER; \
568 lv1call; \
569 \
570 addi r1, r1, 16; \
571 ld r11, -8(r1); \
572 std r4, 0(r11); \
573 ld r11, -16(r1); \
574 std r5, 0(r11); \
575 \
576 ld r0, 16(r1); \
577 mtlr r0; \
578 blr
579
580#define LV1_4_IN_3_OUT(API_NAME, API_NUMBER) \
581_GLOBAL(_##API_NAME) \
582 \
583 mflr r0; \
584 std r0, 16(r1); \
585 \
586 std r7, -8(r1); \
587 std r8, -16(r1); \
588 stdu r9, -24(r1); \
589 \
590 li r11, API_NUMBER; \
591 lv1call; \
592 \
593 addi r1, r1, 24; \
594 ld r11, -8(r1); \
595 std r4, 0(r11); \
596 ld r11, -16(r1); \
597 std r5, 0(r11); \
598 ld r11, -24(r1); \
599 std r6, 0(r11); \
600 \
601 ld r0, 16(r1); \
602 mtlr r0; \
603 blr
604
605#define LV1_5_IN_1_OUT(API_NAME, API_NUMBER) \
606_GLOBAL(_##API_NAME) \
607 \
608 mflr r0; \
609 std r0, 16(r1); \
610 \
611 stdu r8, -8(r1); \
612 \
613 li r11, API_NUMBER; \
614 lv1call; \
615 \
616 addi r1, r1, 8; \
617 ld r11, -8(r1); \
618 std r4, 0(r11); \
619 \
620 ld r0, 16(r1); \
621 mtlr r0; \
622 blr
623
624#define LV1_5_IN_2_OUT(API_NAME, API_NUMBER) \
625_GLOBAL(_##API_NAME) \
626 \
627 mflr r0; \
628 std r0, 16(r1); \
629 \
630 std r8, -8(r1); \
631 stdu r9, -16(r1); \
632 \
633 li r11, API_NUMBER; \
634 lv1call; \
635 \
636 addi r1, r1, 16; \
637 ld r11, -8(r1); \
638 std r4, 0(r11); \
639 ld r11, -16(r1); \
640 std r5, 0(r11); \
641 \
642 ld r0, 16(r1); \
643 mtlr r0; \
644 blr
645
646#define LV1_5_IN_3_OUT(API_NAME, API_NUMBER) \
647_GLOBAL(_##API_NAME) \
648 \
649 mflr r0; \
650 std r0, 16(r1); \
651 \
652 std r8, -8(r1); \
653 std r9, -16(r1); \
654 stdu r10, -24(r1); \
655 \
656 li r11, API_NUMBER; \
657 lv1call; \
658 \
659 addi r1, r1, 24; \
660 ld r11, -8(r1); \
661 std r4, 0(r11); \
662 ld r11, -16(r1); \
663 std r5, 0(r11); \
664 ld r11, -24(r1); \
665 std r6, 0(r11); \
666 \
667 ld r0, 16(r1); \
668 mtlr r0; \
669 blr
670
671#define LV1_6_IN_1_OUT(API_NAME, API_NUMBER) \
672_GLOBAL(_##API_NAME) \
673 \
674 mflr r0; \
675 std r0, 16(r1); \
676 \
677 stdu r9, -8(r1); \
678 \
679 li r11, API_NUMBER; \
680 lv1call; \
681 \
682 addi r1, r1, 8; \
683 ld r11, -8(r1); \
684 std r4, 0(r11); \
685 \
686 ld r0, 16(r1); \
687 mtlr r0; \
688 blr
689
690#define LV1_6_IN_2_OUT(API_NAME, API_NUMBER) \
691_GLOBAL(_##API_NAME) \
692 \
693 mflr r0; \
694 std r0, 16(r1); \
695 \
696 std r9, -8(r1); \
697 stdu r10, -16(r1); \
698 \
699 li r11, API_NUMBER; \
700 lv1call; \
701 \
702 addi r1, r1, 16; \
703 ld r11, -8(r1); \
704 std r4, 0(r11); \
705 ld r11, -16(r1); \
706 std r5, 0(r11); \
707 \
708 ld r0, 16(r1); \
709 mtlr r0; \
710 blr
711
712#define LV1_6_IN_3_OUT(API_NAME, API_NUMBER) \
713_GLOBAL(_##API_NAME) \
714 \
715 mflr r0; \
716 std r0, 16(r1); \
717 \
718 std r9, -8(r1); \
719 stdu r10, -16(r1); \
720 \
721 li r11, API_NUMBER; \
722 lv1call; \
723 \
724 addi r1, r1, 16; \
725 ld r11, -8(r1); \
726 std r4, 0(r11); \
727 ld r11, -16(r1); \
728 std r5, 0(r11); \
729 ld r11, 48+8*8(r1); \
730 std r6, 0(r11); \
731 \
732 ld r0, 16(r1); \
733 mtlr r0; \
734 blr
735
736#define LV1_7_IN_1_OUT(API_NAME, API_NUMBER) \
737_GLOBAL(_##API_NAME) \
738 \
739 mflr r0; \
740 std r0, 16(r1); \
741 \
742 stdu r10, -8(r1); \
743 \
744 li r11, API_NUMBER; \
745 lv1call; \
746 \
747 addi r1, r1, 8; \
748 ld r11, -8(r1); \
749 std r4, 0(r11); \
750 \
751 ld r0, 16(r1); \
752 mtlr r0; \
753 blr
754
755#define LV1_7_IN_6_OUT(API_NAME, API_NUMBER) \
756_GLOBAL(_##API_NAME) \
757 \
758 mflr r0; \
759 std r0, 16(r1); \
760 \
761 std r10, 48+8*7(r1); \
762 \
763 li r11, API_NUMBER; \
764 lv1call; \
765 \
766 ld r11, 48+8*7(r1); \
767 std r4, 0(r11); \
768 ld r11, 48+8*8(r1); \
769 std r5, 0(r11); \
770 ld r11, 48+8*9(r1); \
771 std r6, 0(r11); \
772 ld r11, 48+8*10(r1); \
773 std r7, 0(r11); \
774 ld r11, 48+8*11(r1); \
775 std r8, 0(r11); \
776 ld r11, 48+8*12(r1); \
777 std r9, 0(r11); \
778 \
779 ld r0, 16(r1); \
780 mtlr r0; \
781 blr
782
783#define LV1_8_IN_1_OUT(API_NAME, API_NUMBER) \
784_GLOBAL(_##API_NAME) \
785 \
786 mflr r0; \
787 std r0, 16(r1); \
788 \
789 li r11, API_NUMBER; \
790 lv1call; \
791 \
792 ld r11, 48+8*8(r1); \
793 std r4, 0(r11); \
794 \
795 ld r0, 16(r1); \
796 mtlr r0; \
797 blr
798
799 .text
800
801/* the lv1 underscored call definitions expand here */
802
803#define LV1_CALL(name, in, out, num) LV1_##in##_IN_##out##_OUT(lv1_##name, num)
804#include <asm/lv1call.h>
diff --git a/arch/powerpc/platforms/ps3/interrupt.c b/arch/powerpc/platforms/ps3/interrupt.c
new file mode 100644
index 000000000000..056c1e4141ba
--- /dev/null
+++ b/arch/powerpc/platforms/ps3/interrupt.c
@@ -0,0 +1,575 @@
1/*
2 * PS3 interrupt routines.
3 *
4 * Copyright (C) 2006 Sony Computer Entertainment Inc.
5 * Copyright 2006 Sony Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/irq.h>
24
25#include <asm/machdep.h>
26#include <asm/udbg.h>
27#include <asm/ps3.h>
28#include <asm/lv1call.h>
29
30#include "platform.h"
31
32#if defined(DEBUG)
33#define DBG(fmt...) udbg_printf(fmt)
34#else
35#define DBG(fmt...) do{if(0)printk(fmt);}while(0)
36#endif
37
38/**
39 * ps3_alloc_io_irq - Assign a virq to a system bus device.
40 * interrupt_id: The device interrupt id read from the system repository.
41 * @virq: The assigned Linux virq.
42 *
43 * An io irq represents a non-virtualized device interrupt. interrupt_id
44 * coresponds to the interrupt number of the interrupt controller.
45 */
46
47int ps3_alloc_io_irq(unsigned int interrupt_id, unsigned int *virq)
48{
49 int result;
50 unsigned long outlet;
51
52 result = lv1_construct_io_irq_outlet(interrupt_id, &outlet);
53
54 if (result) {
55 pr_debug("%s:%d: lv1_construct_io_irq_outlet failed: %s\n",
56 __func__, __LINE__, ps3_result(result));
57 return result;
58 }
59
60 *virq = irq_create_mapping(NULL, outlet);
61
62 pr_debug("%s:%d: interrupt_id %u => outlet %lu, virq %u\n",
63 __func__, __LINE__, interrupt_id, outlet, *virq);
64
65 return 0;
66}
67
68int ps3_free_io_irq(unsigned int virq)
69{
70 int result;
71
72 result = lv1_destruct_io_irq_outlet(virq_to_hw(virq));
73
74 if (!result)
75 pr_debug("%s:%d: lv1_destruct_io_irq_outlet failed: %s\n",
76 __func__, __LINE__, ps3_result(result));
77
78 irq_dispose_mapping(virq);
79
80 return result;
81}
82
83/**
84 * ps3_alloc_event_irq - Allocate a virq for use with a system event.
85 * @virq: The assigned Linux virq.
86 *
87 * The virq can be used with lv1_connect_interrupt_event_receive_port() to
88 * arrange to receive events, or with ps3_send_event_locally() to signal
89 * events.
90 */
91
92int ps3_alloc_event_irq(unsigned int *virq)
93{
94 int result;
95 unsigned long outlet;
96
97 result = lv1_construct_event_receive_port(&outlet);
98
99 if (result) {
100 pr_debug("%s:%d: lv1_construct_event_receive_port failed: %s\n",
101 __func__, __LINE__, ps3_result(result));
102 *virq = NO_IRQ;
103 return result;
104 }
105
106 *virq = irq_create_mapping(NULL, outlet);
107
108 pr_debug("%s:%d: outlet %lu, virq %u\n", __func__, __LINE__, outlet,
109 *virq);
110
111 return 0;
112}
113
114int ps3_free_event_irq(unsigned int virq)
115{
116 int result;
117
118 pr_debug(" -> %s:%d\n", __func__, __LINE__);
119
120 result = lv1_destruct_event_receive_port(virq_to_hw(virq));
121
122 if (result)
123 pr_debug("%s:%d: lv1_destruct_event_receive_port failed: %s\n",
124 __func__, __LINE__, ps3_result(result));
125
126 irq_dispose_mapping(virq);
127
128 pr_debug(" <- %s:%d\n", __func__, __LINE__);
129 return result;
130}
131
132int ps3_send_event_locally(unsigned int virq)
133{
134 return lv1_send_event_locally(virq_to_hw(virq));
135}
136
137/**
138 * ps3_connect_event_irq - Assign a virq to a system bus device.
139 * @did: The HV device identifier read from the system repository.
140 * @interrupt_id: The device interrupt id read from the system repository.
141 * @virq: The assigned Linux virq.
142 *
143 * An event irq represents a virtual device interrupt. The interrupt_id
144 * coresponds to the software interrupt number.
145 */
146
147int ps3_connect_event_irq(const struct ps3_device_id *did,
148 unsigned int interrupt_id, unsigned int *virq)
149{
150 int result;
151
152 result = ps3_alloc_event_irq(virq);
153
154 if (result)
155 return result;
156
157 result = lv1_connect_interrupt_event_receive_port(did->bus_id,
158 did->dev_id, virq_to_hw(*virq), interrupt_id);
159
160 if (result) {
161 pr_debug("%s:%d: lv1_connect_interrupt_event_receive_port"
162 " failed: %s\n", __func__, __LINE__,
163 ps3_result(result));
164 ps3_free_event_irq(*virq);
165 *virq = NO_IRQ;
166 return result;
167 }
168
169 pr_debug("%s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__,
170 interrupt_id, *virq);
171
172 return 0;
173}
174
175int ps3_disconnect_event_irq(const struct ps3_device_id *did,
176 unsigned int interrupt_id, unsigned int virq)
177{
178 int result;
179
180 pr_debug(" -> %s:%d: interrupt_id %u, virq %u\n", __func__, __LINE__,
181 interrupt_id, virq);
182
183 result = lv1_disconnect_interrupt_event_receive_port(did->bus_id,
184 did->dev_id, virq_to_hw(virq), interrupt_id);
185
186 if (result)
187 pr_debug("%s:%d: lv1_disconnect_interrupt_event_receive_port"
188 " failed: %s\n", __func__, __LINE__,
189 ps3_result(result));
190
191 ps3_free_event_irq(virq);
192
193 pr_debug(" <- %s:%d\n", __func__, __LINE__);
194 return result;
195}
196
197/**
198 * ps3_alloc_vuart_irq - Configure the system virtual uart virq.
199 * @virt_addr_bmp: The caller supplied virtual uart interrupt bitmap.
200 * @virq: The assigned Linux virq.
201 *
202 * The system supports only a single virtual uart, so multiple calls without
203 * freeing the interrupt will return a wrong state error.
204 */
205
206int ps3_alloc_vuart_irq(void* virt_addr_bmp, unsigned int *virq)
207{
208 int result;
209 unsigned long outlet;
210 unsigned long lpar_addr;
211
212 BUG_ON(!is_kernel_addr((unsigned long)virt_addr_bmp));
213
214 lpar_addr = ps3_mm_phys_to_lpar(__pa(virt_addr_bmp));
215
216 result = lv1_configure_virtual_uart_irq(lpar_addr, &outlet);
217
218 if (result) {
219 pr_debug("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n",
220 __func__, __LINE__, ps3_result(result));
221 return result;
222 }
223
224 *virq = irq_create_mapping(NULL, outlet);
225
226 pr_debug("%s:%d: outlet %lu, virq %u\n", __func__, __LINE__,
227 outlet, *virq);
228
229 return 0;
230}
231
232int ps3_free_vuart_irq(unsigned int virq)
233{
234 int result;
235
236 result = lv1_deconfigure_virtual_uart_irq();
237
238 if (result) {
239 pr_debug("%s:%d: lv1_configure_virtual_uart_irq failed: %s\n",
240 __func__, __LINE__, ps3_result(result));
241 return result;
242 }
243
244 irq_dispose_mapping(virq);
245
246 return result;
247}
248
249/**
250 * ps3_alloc_spe_irq - Configure an spe virq.
251 * @spe_id: The spe_id returned from lv1_construct_logical_spe().
252 * @class: The spe interrupt class {0,1,2}.
253 * @virq: The assigned Linux virq.
254 *
255 */
256
257int ps3_alloc_spe_irq(unsigned long spe_id, unsigned int class,
258 unsigned int *virq)
259{
260 int result;
261 unsigned long outlet;
262
263 BUG_ON(class > 2);
264
265 result = lv1_get_spe_irq_outlet(spe_id, class, &outlet);
266
267 if (result) {
268 pr_debug("%s:%d: lv1_get_spe_irq_outlet failed: %s\n",
269 __func__, __LINE__, ps3_result(result));
270 return result;
271 }
272
273 *virq = irq_create_mapping(NULL, outlet);
274
275 pr_debug("%s:%d: spe_id %lu, class %u, outlet %lu, virq %u\n",
276 __func__, __LINE__, spe_id, class, outlet, *virq);
277
278 return 0;
279}
280
281int ps3_free_spe_irq(unsigned int virq)
282{
283 irq_dispose_mapping(virq);
284 return 0;
285}
286
287#define PS3_INVALID_OUTLET ((irq_hw_number_t)-1)
288#define PS3_PLUG_MAX 63
289
290/**
291 * struct bmp - a per cpu irq status and mask bitmap structure
292 * @status: 256 bit status bitmap indexed by plug
293 * @unused_1:
294 * @mask: 256 bit mask bitmap indexed by plug
295 * @unused_2:
296 * @lock:
297 * @ipi_debug_brk_mask:
298 *
299 * The HV mantains per SMT thread mappings of HV outlet to HV plug on
300 * behalf of the guest. These mappings are implemented as 256 bit guest
301 * supplied bitmaps indexed by plug number. The address of the bitmaps are
302 * registered with the HV through lv1_configure_irq_state_bitmap().
303 *
304 * The HV supports 256 plugs per thread, assigned as {0..255}, for a total
305 * of 512 plugs supported on a processor. To simplify the logic this
306 * implementation equates HV plug value to linux virq value, constrains each
307 * interrupt to have a system wide unique plug number, and limits the range
308 * of the plug values to map into the first dword of the bitmaps. This
309 * gives a usable range of plug values of {NUM_ISA_INTERRUPTS..63}. Note
310 * that there is no constraint on how many in this set an individual thread
311 * can aquire.
312 */
313
314struct bmp {
315 struct {
316 unsigned long status;
317 unsigned long unused_1[3];
318 unsigned long mask;
319 unsigned long unused_2[3];
320 } __attribute__ ((packed));
321 spinlock_t lock;
322 unsigned long ipi_debug_brk_mask;
323};
324
325/**
326 * struct private - a per cpu data structure
327 * @node: HV node id
328 * @cpu: HV thread id
329 * @bmp: an HV bmp structure
330 */
331
332struct private {
333 unsigned long node;
334 unsigned int cpu;
335 struct bmp bmp;
336};
337
338#if defined(DEBUG)
339static void _dump_64_bmp(const char *header, const unsigned long *p, unsigned cpu,
340 const char* func, int line)
341{
342 pr_debug("%s:%d: %s %u {%04lx_%04lx_%04lx_%04lx}\n",
343 func, line, header, cpu,
344 *p >> 48, (*p >> 32) & 0xffff, (*p >> 16) & 0xffff,
345 *p & 0xffff);
346}
347
348static void __attribute__ ((unused)) _dump_256_bmp(const char *header,
349 const unsigned long *p, unsigned cpu, const char* func, int line)
350{
351 pr_debug("%s:%d: %s %u {%016lx:%016lx:%016lx:%016lx}\n",
352 func, line, header, cpu, p[0], p[1], p[2], p[3]);
353}
354
355#define dump_bmp(_x) _dump_bmp(_x, __func__, __LINE__)
356static void _dump_bmp(struct private* pd, const char* func, int line)
357{
358 unsigned long flags;
359
360 spin_lock_irqsave(&pd->bmp.lock, flags);
361 _dump_64_bmp("stat", &pd->bmp.status, pd->cpu, func, line);
362 _dump_64_bmp("mask", &pd->bmp.mask, pd->cpu, func, line);
363 spin_unlock_irqrestore(&pd->bmp.lock, flags);
364}
365
366#define dump_mask(_x) _dump_mask(_x, __func__, __LINE__)
367static void __attribute__ ((unused)) _dump_mask(struct private* pd,
368 const char* func, int line)
369{
370 unsigned long flags;
371
372 spin_lock_irqsave(&pd->bmp.lock, flags);
373 _dump_64_bmp("mask", &pd->bmp.mask, pd->cpu, func, line);
374 spin_unlock_irqrestore(&pd->bmp.lock, flags);
375}
376#else
377static void dump_bmp(struct private* pd) {};
378#endif /* defined(DEBUG) */
379
380static void chip_mask(unsigned int virq)
381{
382 unsigned long flags;
383 struct private *pd = get_irq_chip_data(virq);
384
385 pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
386
387 BUG_ON(virq < NUM_ISA_INTERRUPTS);
388 BUG_ON(virq > PS3_PLUG_MAX);
389
390 spin_lock_irqsave(&pd->bmp.lock, flags);
391 pd->bmp.mask &= ~(0x8000000000000000UL >> virq);
392 spin_unlock_irqrestore(&pd->bmp.lock, flags);
393
394 lv1_did_update_interrupt_mask(pd->node, pd->cpu);
395}
396
397static void chip_unmask(unsigned int virq)
398{
399 unsigned long flags;
400 struct private *pd = get_irq_chip_data(virq);
401
402 pr_debug("%s:%d: cpu %u, virq %d\n", __func__, __LINE__, pd->cpu, virq);
403
404 BUG_ON(virq < NUM_ISA_INTERRUPTS);
405 BUG_ON(virq > PS3_PLUG_MAX);
406
407 spin_lock_irqsave(&pd->bmp.lock, flags);
408 pd->bmp.mask |= (0x8000000000000000UL >> virq);
409 spin_unlock_irqrestore(&pd->bmp.lock, flags);
410
411 lv1_did_update_interrupt_mask(pd->node, pd->cpu);
412}
413
414static void chip_eoi(unsigned int virq)
415{
416 lv1_end_of_interrupt(virq);
417}
418
419static struct irq_chip irq_chip = {
420 .typename = "ps3",
421 .mask = chip_mask,
422 .unmask = chip_unmask,
423 .eoi = chip_eoi,
424};
425
426static void host_unmap(struct irq_host *h, unsigned int virq)
427{
428 int result;
429
430 pr_debug("%s:%d: virq %d\n", __func__, __LINE__, virq);
431
432 lv1_disconnect_irq_plug(virq);
433
434 result = set_irq_chip_data(virq, NULL);
435 BUG_ON(result);
436}
437
438static DEFINE_PER_CPU(struct private, private);
439
440static int host_map(struct irq_host *h, unsigned int virq,
441 irq_hw_number_t hwirq)
442{
443 int result;
444 unsigned int cpu;
445
446 pr_debug(" -> %s:%d\n", __func__, __LINE__);
447 pr_debug("%s:%d: hwirq %lu => virq %u\n", __func__, __LINE__, hwirq,
448 virq);
449
450 /* bind this virq to a cpu */
451
452 preempt_disable();
453 cpu = smp_processor_id();
454 result = lv1_connect_irq_plug(virq, hwirq);
455 preempt_enable();
456
457 if (result) {
458 pr_info("%s:%d: lv1_connect_irq_plug failed:"
459 " %s\n", __func__, __LINE__, ps3_result(result));
460 return -EPERM;
461 }
462
463 result = set_irq_chip_data(virq, &per_cpu(private, cpu));
464 BUG_ON(result);
465
466 set_irq_chip_and_handler(virq, &irq_chip, handle_fasteoi_irq);
467
468 pr_debug(" <- %s:%d\n", __func__, __LINE__);
469 return result;
470}
471
472static struct irq_host_ops host_ops = {
473 .map = host_map,
474 .unmap = host_unmap,
475};
476
477void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq)
478{
479 struct private *pd = &per_cpu(private, cpu);
480
481 pd->bmp.ipi_debug_brk_mask = 0x8000000000000000UL >> virq;
482
483 pr_debug("%s:%d: cpu %u, virq %u, mask %lxh\n", __func__, __LINE__,
484 cpu, virq, pd->bmp.ipi_debug_brk_mask);
485}
486
487static int bmp_get_and_clear_status_bit(struct bmp *m)
488{
489 unsigned long flags;
490 unsigned int bit;
491 unsigned long x;
492
493 spin_lock_irqsave(&m->lock, flags);
494
495 /* check for ipi break first to stop this cpu ASAP */
496
497 if (m->status & m->ipi_debug_brk_mask) {
498 m->status &= ~m->ipi_debug_brk_mask;
499 spin_unlock_irqrestore(&m->lock, flags);
500 return __ilog2(m->ipi_debug_brk_mask);
501 }
502
503 x = (m->status & m->mask);
504
505 for (bit = NUM_ISA_INTERRUPTS, x <<= bit; x; bit++, x <<= 1)
506 if (x & 0x8000000000000000UL) {
507 m->status &= ~(0x8000000000000000UL >> bit);
508 spin_unlock_irqrestore(&m->lock, flags);
509 return bit;
510 }
511
512 spin_unlock_irqrestore(&m->lock, flags);
513
514 pr_debug("%s:%d: not found\n", __func__, __LINE__);
515 return -1;
516}
517
518unsigned int ps3_get_irq(void)
519{
520 int plug;
521
522 struct private *pd = &__get_cpu_var(private);
523
524 plug = bmp_get_and_clear_status_bit(&pd->bmp);
525
526 if (plug < 1) {
527 pr_debug("%s:%d: no plug found: cpu %u\n", __func__, __LINE__,
528 pd->cpu);
529 dump_bmp(&per_cpu(private, 0));
530 dump_bmp(&per_cpu(private, 1));
531 return NO_IRQ;
532 }
533
534#if defined(DEBUG)
535 if (plug < NUM_ISA_INTERRUPTS || plug > PS3_PLUG_MAX) {
536 dump_bmp(&per_cpu(private, 0));
537 dump_bmp(&per_cpu(private, 1));
538 BUG();
539 }
540#endif
541 return plug;
542}
543
544void __init ps3_init_IRQ(void)
545{
546 int result;
547 unsigned long node;
548 unsigned cpu;
549 struct irq_host *host;
550
551 lv1_get_logical_ppe_id(&node);
552
553 host = irq_alloc_host(IRQ_HOST_MAP_NOMAP, 0, &host_ops,
554 PS3_INVALID_OUTLET);
555 irq_set_default_host(host);
556 irq_set_virq_count(PS3_PLUG_MAX + 1);
557
558 for_each_possible_cpu(cpu) {
559 struct private *pd = &per_cpu(private, cpu);
560
561 pd->node = node;
562 pd->cpu = cpu;
563 spin_lock_init(&pd->bmp.lock);
564
565 result = lv1_configure_irq_state_bitmap(node, cpu,
566 ps3_mm_phys_to_lpar(__pa(&pd->bmp.status)));
567
568 if (result)
569 pr_debug("%s:%d: lv1_configure_irq_state_bitmap failed:"
570 " %s\n", __func__, __LINE__,
571 ps3_result(result));
572 }
573
574 ppc_md.get_irq = ps3_get_irq;
575}
diff --git a/arch/powerpc/platforms/ps3/mm.c b/arch/powerpc/platforms/ps3/mm.c
new file mode 100644
index 000000000000..49c0d010d491
--- /dev/null
+++ b/arch/powerpc/platforms/ps3/mm.c
@@ -0,0 +1,831 @@
1/*
2 * PS3 address space management.
3 *
4 * Copyright (C) 2006 Sony Computer Entertainment Inc.
5 * Copyright 2006 Sony Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/kernel.h>
22#include <linux/module.h>
23#include <linux/memory_hotplug.h>
24
25#include <asm/firmware.h>
26#include <asm/lmb.h>
27#include <asm/udbg.h>
28#include <asm/ps3.h>
29#include <asm/lv1call.h>
30
31#include "platform.h"
32
33#if defined(DEBUG)
34#define DBG(fmt...) udbg_printf(fmt)
35#else
36#define DBG(fmt...) do{if(0)printk(fmt);}while(0)
37#endif
38
39enum {
40#if defined(CONFIG_PS3_USE_LPAR_ADDR)
41 USE_LPAR_ADDR = 1,
42#else
43 USE_LPAR_ADDR = 0,
44#endif
45#if defined(CONFIG_PS3_DYNAMIC_DMA)
46 USE_DYNAMIC_DMA = 1,
47#else
48 USE_DYNAMIC_DMA = 0,
49#endif
50};
51
52enum {
53 PAGE_SHIFT_4K = 12U,
54 PAGE_SHIFT_64K = 16U,
55 PAGE_SHIFT_16M = 24U,
56};
57
58static unsigned long make_page_sizes(unsigned long a, unsigned long b)
59{
60 return (a << 56) | (b << 48);
61}
62
63enum {
64 ALLOCATE_MEMORY_TRY_ALT_UNIT = 0X04,
65 ALLOCATE_MEMORY_ADDR_ZERO = 0X08,
66};
67
68/* valid htab sizes are {18,19,20} = 256K, 512K, 1M */
69
70enum {
71 HTAB_SIZE_MAX = 20U, /* HV limit of 1MB */
72 HTAB_SIZE_MIN = 18U, /* CPU limit of 256KB */
73};
74
75/*============================================================================*/
76/* virtual address space routines */
77/*============================================================================*/
78
79/**
80 * struct mem_region - memory region structure
81 * @base: base address
82 * @size: size in bytes
83 * @offset: difference between base and rm.size
84 */
85
86struct mem_region {
87 unsigned long base;
88 unsigned long size;
89 unsigned long offset;
90};
91
92/**
93 * struct map - address space state variables holder
94 * @total: total memory available as reported by HV
95 * @vas_id - HV virtual address space id
96 * @htab_size: htab size in bytes
97 *
98 * The HV virtual address space (vas) allows for hotplug memory regions.
99 * Memory regions can be created and destroyed in the vas at runtime.
100 * @rm: real mode (bootmem) region
101 * @r1: hotplug memory region(s)
102 *
103 * ps3 addresses
104 * virt_addr: a cpu 'translated' effective address
105 * phys_addr: an address in what Linux thinks is the physical address space
106 * lpar_addr: an address in the HV virtual address space
107 * bus_addr: an io controller 'translated' address on a device bus
108 */
109
110struct map {
111 unsigned long total;
112 unsigned long vas_id;
113 unsigned long htab_size;
114 struct mem_region rm;
115 struct mem_region r1;
116};
117
118#define debug_dump_map(x) _debug_dump_map(x, __func__, __LINE__)
119static void _debug_dump_map(const struct map* m, const char* func, int line)
120{
121 DBG("%s:%d: map.total = %lxh\n", func, line, m->total);
122 DBG("%s:%d: map.rm.size = %lxh\n", func, line, m->rm.size);
123 DBG("%s:%d: map.vas_id = %lu\n", func, line, m->vas_id);
124 DBG("%s:%d: map.htab_size = %lxh\n", func, line, m->htab_size);
125 DBG("%s:%d: map.r1.base = %lxh\n", func, line, m->r1.base);
126 DBG("%s:%d: map.r1.offset = %lxh\n", func, line, m->r1.offset);
127 DBG("%s:%d: map.r1.size = %lxh\n", func, line, m->r1.size);
128}
129
130static struct map map;
131
132/**
133 * ps3_mm_phys_to_lpar - translate a linux physical address to lpar address
134 * @phys_addr: linux physical address
135 */
136
137unsigned long ps3_mm_phys_to_lpar(unsigned long phys_addr)
138{
139 BUG_ON(is_kernel_addr(phys_addr));
140 if (USE_LPAR_ADDR)
141 return phys_addr;
142 else
143 return (phys_addr < map.rm.size || phys_addr >= map.total)
144 ? phys_addr : phys_addr + map.r1.offset;
145}
146
147EXPORT_SYMBOL(ps3_mm_phys_to_lpar);
148
149/**
150 * ps3_mm_vas_create - create the virtual address space
151 */
152
153void __init ps3_mm_vas_create(unsigned long* htab_size)
154{
155 int result;
156 unsigned long start_address;
157 unsigned long size;
158 unsigned long access_right;
159 unsigned long max_page_size;
160 unsigned long flags;
161
162 result = lv1_query_logical_partition_address_region_info(0,
163 &start_address, &size, &access_right, &max_page_size,
164 &flags);
165
166 if (result) {
167 DBG("%s:%d: lv1_query_logical_partition_address_region_info "
168 "failed: %s\n", __func__, __LINE__,
169 ps3_result(result));
170 goto fail;
171 }
172
173 if (max_page_size < PAGE_SHIFT_16M) {
174 DBG("%s:%d: bad max_page_size %lxh\n", __func__, __LINE__,
175 max_page_size);
176 goto fail;
177 }
178
179 BUILD_BUG_ON(CONFIG_PS3_HTAB_SIZE > HTAB_SIZE_MAX);
180 BUILD_BUG_ON(CONFIG_PS3_HTAB_SIZE < HTAB_SIZE_MIN);
181
182 result = lv1_construct_virtual_address_space(CONFIG_PS3_HTAB_SIZE,
183 2, make_page_sizes(PAGE_SHIFT_16M, PAGE_SHIFT_64K),
184 &map.vas_id, &map.htab_size);
185
186 if (result) {
187 DBG("%s:%d: lv1_construct_virtual_address_space failed: %s\n",
188 __func__, __LINE__, ps3_result(result));
189 goto fail;
190 }
191
192 result = lv1_select_virtual_address_space(map.vas_id);
193
194 if (result) {
195 DBG("%s:%d: lv1_select_virtual_address_space failed: %s\n",
196 __func__, __LINE__, ps3_result(result));
197 goto fail;
198 }
199
200 *htab_size = map.htab_size;
201
202 debug_dump_map(&map);
203
204 return;
205
206fail:
207 panic("ps3_mm_vas_create failed");
208}
209
210/**
211 * ps3_mm_vas_destroy -
212 */
213
214void ps3_mm_vas_destroy(void)
215{
216 if (map.vas_id) {
217 lv1_select_virtual_address_space(0);
218 lv1_destruct_virtual_address_space(map.vas_id);
219 map.vas_id = 0;
220 }
221}
222
223/*============================================================================*/
224/* memory hotplug routines */
225/*============================================================================*/
226
227/**
228 * ps3_mm_region_create - create a memory region in the vas
229 * @r: pointer to a struct mem_region to accept initialized values
230 * @size: requested region size
231 *
232 * This implementation creates the region with the vas large page size.
233 * @size is rounded down to a multiple of the vas large page size.
234 */
235
236int ps3_mm_region_create(struct mem_region *r, unsigned long size)
237{
238 int result;
239 unsigned long muid;
240
241 r->size = _ALIGN_DOWN(size, 1 << PAGE_SHIFT_16M);
242
243 DBG("%s:%d requested %lxh\n", __func__, __LINE__, size);
244 DBG("%s:%d actual %lxh\n", __func__, __LINE__, r->size);
245 DBG("%s:%d difference %lxh (%luMB)\n", __func__, __LINE__,
246 (unsigned long)(size - r->size),
247 (size - r->size) / 1024 / 1024);
248
249 if (r->size == 0) {
250 DBG("%s:%d: size == 0\n", __func__, __LINE__);
251 result = -1;
252 goto zero_region;
253 }
254
255 result = lv1_allocate_memory(r->size, PAGE_SHIFT_16M, 0,
256 ALLOCATE_MEMORY_TRY_ALT_UNIT, &r->base, &muid);
257
258 if (result || r->base < map.rm.size) {
259 DBG("%s:%d: lv1_allocate_memory failed: %s\n",
260 __func__, __LINE__, ps3_result(result));
261 goto zero_region;
262 }
263
264 r->offset = r->base - map.rm.size;
265 return result;
266
267zero_region:
268 r->size = r->base = r->offset = 0;
269 return result;
270}
271
272/**
273 * ps3_mm_region_destroy - destroy a memory region
274 * @r: pointer to struct mem_region
275 */
276
277void ps3_mm_region_destroy(struct mem_region *r)
278{
279 if (r->base) {
280 lv1_release_memory(r->base);
281 r->size = r->base = r->offset = 0;
282 map.total = map.rm.size;
283 }
284}
285
286/**
287 * ps3_mm_add_memory - hot add memory
288 */
289
290static int __init ps3_mm_add_memory(void)
291{
292 int result;
293 unsigned long start_addr;
294 unsigned long start_pfn;
295 unsigned long nr_pages;
296
297 if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
298 return 0;
299
300 BUG_ON(!mem_init_done);
301
302 start_addr = USE_LPAR_ADDR ? map.r1.base : map.rm.size;
303 start_pfn = start_addr >> PAGE_SHIFT;
304 nr_pages = (map.r1.size + PAGE_SIZE - 1) >> PAGE_SHIFT;
305
306 DBG("%s:%d: start_addr %lxh, start_pfn %lxh, nr_pages %lxh\n",
307 __func__, __LINE__, start_addr, start_pfn, nr_pages);
308
309 result = add_memory(0, start_addr, map.r1.size);
310
311 if (result) {
312 DBG("%s:%d: add_memory failed: (%d)\n",
313 __func__, __LINE__, result);
314 return result;
315 }
316
317 result = online_pages(start_pfn, nr_pages);
318
319 if (result)
320 DBG("%s:%d: online_pages failed: (%d)\n",
321 __func__, __LINE__, result);
322
323 return result;
324}
325
326core_initcall(ps3_mm_add_memory);
327
328/*============================================================================*/
329/* dma routines */
330/*============================================================================*/
331
332/**
333 * dma_lpar_to_bus - Translate an lpar address to ioc mapped bus address.
334 * @r: pointer to dma region structure
335 * @lpar_addr: HV lpar address
336 */
337
338static unsigned long dma_lpar_to_bus(struct ps3_dma_region *r,
339 unsigned long lpar_addr)
340{
341 BUG_ON(lpar_addr >= map.r1.base + map.r1.size);
342 return r->bus_addr + (lpar_addr <= map.rm.size ? lpar_addr
343 : lpar_addr - map.r1.offset);
344}
345
346#define dma_dump_region(_a) _dma_dump_region(_a, __func__, __LINE__)
347static void _dma_dump_region(const struct ps3_dma_region *r, const char* func,
348 int line)
349{
350 DBG("%s:%d: dev %u:%u\n", func, line, r->did.bus_id,
351 r->did.dev_id);
352 DBG("%s:%d: page_size %u\n", func, line, r->page_size);
353 DBG("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr);
354 DBG("%s:%d: len %lxh\n", func, line, r->len);
355}
356
357/**
358 * dma_chunk - A chunk of dma pages mapped by the io controller.
359 * @region - The dma region that owns this chunk.
360 * @lpar_addr: Starting lpar address of the area to map.
361 * @bus_addr: Starting ioc bus address of the area to map.
362 * @len: Length in bytes of the area to map.
363 * @link: A struct list_head used with struct ps3_dma_region.chunk_list, the
364 * list of all chuncks owned by the region.
365 *
366 * This implementation uses a very simple dma page manager
367 * based on the dma_chunk structure. This scheme assumes
368 * that all drivers use very well behaved dma ops.
369 */
370
371struct dma_chunk {
372 struct ps3_dma_region *region;
373 unsigned long lpar_addr;
374 unsigned long bus_addr;
375 unsigned long len;
376 struct list_head link;
377 unsigned int usage_count;
378};
379
380#define dma_dump_chunk(_a) _dma_dump_chunk(_a, __func__, __LINE__)
381static void _dma_dump_chunk (const struct dma_chunk* c, const char* func,
382 int line)
383{
384 DBG("%s:%d: r.dev %u:%u\n", func, line,
385 c->region->did.bus_id, c->region->did.dev_id);
386 DBG("%s:%d: r.bus_addr %lxh\n", func, line, c->region->bus_addr);
387 DBG("%s:%d: r.page_size %u\n", func, line, c->region->page_size);
388 DBG("%s:%d: r.len %lxh\n", func, line, c->region->len);
389 DBG("%s:%d: c.lpar_addr %lxh\n", func, line, c->lpar_addr);
390 DBG("%s:%d: c.bus_addr %lxh\n", func, line, c->bus_addr);
391 DBG("%s:%d: c.len %lxh\n", func, line, c->len);
392}
393
394static struct dma_chunk * dma_find_chunk(struct ps3_dma_region *r,
395 unsigned long bus_addr, unsigned long len)
396{
397 struct dma_chunk *c;
398 unsigned long aligned_bus = _ALIGN_DOWN(bus_addr, 1 << r->page_size);
399 unsigned long aligned_len = _ALIGN_UP(len, 1 << r->page_size);
400
401 list_for_each_entry(c, &r->chunk_list.head, link) {
402 /* intersection */
403 if (aligned_bus >= c->bus_addr
404 && aligned_bus < c->bus_addr + c->len
405 && aligned_bus + aligned_len <= c->bus_addr + c->len) {
406 return c;
407 }
408 /* below */
409 if (aligned_bus + aligned_len <= c->bus_addr) {
410 continue;
411 }
412 /* above */
413 if (aligned_bus >= c->bus_addr + c->len) {
414 continue;
415 }
416
417 /* we don't handle the multi-chunk case for now */
418
419 dma_dump_chunk(c);
420 BUG();
421 }
422 return NULL;
423}
424
425static int dma_free_chunk(struct dma_chunk *c)
426{
427 int result = 0;
428
429 if (c->bus_addr) {
430 result = lv1_unmap_device_dma_region(c->region->did.bus_id,
431 c->region->did.dev_id, c->bus_addr, c->len);
432 BUG_ON(result);
433 }
434
435 kfree(c);
436 return result;
437}
438
439/**
440 * dma_map_pages - Maps dma pages into the io controller bus address space.
441 * @r: Pointer to a struct ps3_dma_region.
442 * @phys_addr: Starting physical address of the area to map.
443 * @len: Length in bytes of the area to map.
444 * c_out: A pointer to receive an allocated struct dma_chunk for this area.
445 *
446 * This is the lowest level dma mapping routine, and is the one that will
447 * make the HV call to add the pages into the io controller address space.
448 */
449
450static int dma_map_pages(struct ps3_dma_region *r, unsigned long phys_addr,
451 unsigned long len, struct dma_chunk **c_out)
452{
453 int result;
454 struct dma_chunk *c;
455
456 c = kzalloc(sizeof(struct dma_chunk), GFP_ATOMIC);
457
458 if (!c) {
459 result = -ENOMEM;
460 goto fail_alloc;
461 }
462
463 c->region = r;
464 c->lpar_addr = ps3_mm_phys_to_lpar(phys_addr);
465 c->bus_addr = dma_lpar_to_bus(r, c->lpar_addr);
466 c->len = len;
467
468 result = lv1_map_device_dma_region(c->region->did.bus_id,
469 c->region->did.dev_id, c->lpar_addr, c->bus_addr, c->len,
470 0xf800000000000000UL);
471
472 if (result) {
473 DBG("%s:%d: lv1_map_device_dma_region failed: %s\n",
474 __func__, __LINE__, ps3_result(result));
475 goto fail_map;
476 }
477
478 list_add(&c->link, &r->chunk_list.head);
479
480 *c_out = c;
481 return 0;
482
483fail_map:
484 kfree(c);
485fail_alloc:
486 *c_out = NULL;
487 DBG(" <- %s:%d\n", __func__, __LINE__);
488 return result;
489}
490
491/**
492 * dma_region_create - Create a device dma region.
493 * @r: Pointer to a struct ps3_dma_region.
494 *
495 * This is the lowest level dma region create routine, and is the one that
496 * will make the HV call to create the region.
497 */
498
499static int dma_region_create(struct ps3_dma_region* r)
500{
501 int result;
502
503 r->len = _ALIGN_UP(map.total, 1 << r->page_size);
504 INIT_LIST_HEAD(&r->chunk_list.head);
505 spin_lock_init(&r->chunk_list.lock);
506
507 result = lv1_allocate_device_dma_region(r->did.bus_id, r->did.dev_id,
508 r->len, r->page_size, r->region_type, &r->bus_addr);
509
510 dma_dump_region(r);
511
512 if (result) {
513 DBG("%s:%d: lv1_allocate_device_dma_region failed: %s\n",
514 __func__, __LINE__, ps3_result(result));
515 r->len = r->bus_addr = 0;
516 }
517
518 return result;
519}
520
521/**
522 * dma_region_free - Free a device dma region.
523 * @r: Pointer to a struct ps3_dma_region.
524 *
525 * This is the lowest level dma region free routine, and is the one that
526 * will make the HV call to free the region.
527 */
528
529static int dma_region_free(struct ps3_dma_region* r)
530{
531 int result;
532 struct dma_chunk *c;
533 struct dma_chunk *tmp;
534
535 list_for_each_entry_safe(c, tmp, &r->chunk_list.head, link) {
536 list_del(&c->link);
537 dma_free_chunk(c);
538 }
539
540 result = lv1_free_device_dma_region(r->did.bus_id, r->did.dev_id,
541 r->bus_addr);
542
543 if (result)
544 DBG("%s:%d: lv1_free_device_dma_region failed: %s\n",
545 __func__, __LINE__, ps3_result(result));
546
547 r->len = r->bus_addr = 0;
548
549 return result;
550}
551
552/**
553 * dma_map_area - Map an area of memory into a device dma region.
554 * @r: Pointer to a struct ps3_dma_region.
555 * @virt_addr: Starting virtual address of the area to map.
556 * @len: Length in bytes of the area to map.
557 * @bus_addr: A pointer to return the starting ioc bus address of the area to
558 * map.
559 *
560 * This is the common dma mapping routine.
561 */
562
563static int dma_map_area(struct ps3_dma_region *r, unsigned long virt_addr,
564 unsigned long len, unsigned long *bus_addr)
565{
566 int result;
567 unsigned long flags;
568 struct dma_chunk *c;
569 unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr)
570 : virt_addr;
571
572 *bus_addr = dma_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr));
573
574 if (!USE_DYNAMIC_DMA) {
575 unsigned long lpar_addr = ps3_mm_phys_to_lpar(phys_addr);
576 DBG(" -> %s:%d\n", __func__, __LINE__);
577 DBG("%s:%d virt_addr %lxh\n", __func__, __LINE__,
578 virt_addr);
579 DBG("%s:%d phys_addr %lxh\n", __func__, __LINE__,
580 phys_addr);
581 DBG("%s:%d lpar_addr %lxh\n", __func__, __LINE__,
582 lpar_addr);
583 DBG("%s:%d len %lxh\n", __func__, __LINE__, len);
584 DBG("%s:%d bus_addr %lxh (%lxh)\n", __func__, __LINE__,
585 *bus_addr, len);
586 }
587
588 spin_lock_irqsave(&r->chunk_list.lock, flags);
589 c = dma_find_chunk(r, *bus_addr, len);
590
591 if (c) {
592 c->usage_count++;
593 spin_unlock_irqrestore(&r->chunk_list.lock, flags);
594 return 0;
595 }
596
597 result = dma_map_pages(r, _ALIGN_DOWN(phys_addr, 1 << r->page_size),
598 _ALIGN_UP(len, 1 << r->page_size), &c);
599
600 if (result) {
601 *bus_addr = 0;
602 DBG("%s:%d: dma_map_pages failed (%d)\n",
603 __func__, __LINE__, result);
604 spin_unlock_irqrestore(&r->chunk_list.lock, flags);
605 return result;
606 }
607
608 c->usage_count = 1;
609
610 spin_unlock_irqrestore(&r->chunk_list.lock, flags);
611 return result;
612}
613
614/**
615 * dma_unmap_area - Unmap an area of memory from a device dma region.
616 * @r: Pointer to a struct ps3_dma_region.
617 * @bus_addr: The starting ioc bus address of the area to unmap.
618 * @len: Length in bytes of the area to unmap.
619 *
620 * This is the common dma unmap routine.
621 */
622
623int dma_unmap_area(struct ps3_dma_region *r, unsigned long bus_addr,
624 unsigned long len)
625{
626 unsigned long flags;
627 struct dma_chunk *c;
628
629 spin_lock_irqsave(&r->chunk_list.lock, flags);
630 c = dma_find_chunk(r, bus_addr, len);
631
632 if (!c) {
633 unsigned long aligned_bus = _ALIGN_DOWN(bus_addr,
634 1 << r->page_size);
635 unsigned long aligned_len = _ALIGN_UP(len, 1 << r->page_size);
636 DBG("%s:%d: not found: bus_addr %lxh\n",
637 __func__, __LINE__, bus_addr);
638 DBG("%s:%d: not found: len %lxh\n",
639 __func__, __LINE__, len);
640 DBG("%s:%d: not found: aligned_bus %lxh\n",
641 __func__, __LINE__, aligned_bus);
642 DBG("%s:%d: not found: aligned_len %lxh\n",
643 __func__, __LINE__, aligned_len);
644 BUG();
645 }
646
647 c->usage_count--;
648
649 if (!c->usage_count) {
650 list_del(&c->link);
651 dma_free_chunk(c);
652 }
653
654 spin_unlock_irqrestore(&r->chunk_list.lock, flags);
655 return 0;
656}
657
658/**
659 * dma_region_create_linear - Setup a linear dma maping for a device.
660 * @r: Pointer to a struct ps3_dma_region.
661 *
662 * This routine creates an HV dma region for the device and maps all available
663 * ram into the io controller bus address space.
664 */
665
666static int dma_region_create_linear(struct ps3_dma_region *r)
667{
668 int result;
669 unsigned long tmp;
670
671 /* force 16M dma pages for linear mapping */
672
673 if (r->page_size != PS3_DMA_16M) {
674 pr_info("%s:%d: forcing 16M pages for linear map\n",
675 __func__, __LINE__);
676 r->page_size = PS3_DMA_16M;
677 }
678
679 result = dma_region_create(r);
680 BUG_ON(result);
681
682 result = dma_map_area(r, map.rm.base, map.rm.size, &tmp);
683 BUG_ON(result);
684
685 if (USE_LPAR_ADDR)
686 result = dma_map_area(r, map.r1.base, map.r1.size,
687 &tmp);
688 else
689 result = dma_map_area(r, map.rm.size, map.r1.size,
690 &tmp);
691
692 BUG_ON(result);
693
694 return result;
695}
696
697/**
698 * dma_region_free_linear - Free a linear dma mapping for a device.
699 * @r: Pointer to a struct ps3_dma_region.
700 *
701 * This routine will unmap all mapped areas and free the HV dma region.
702 */
703
704static int dma_region_free_linear(struct ps3_dma_region *r)
705{
706 int result;
707
708 result = dma_unmap_area(r, dma_lpar_to_bus(r, 0), map.rm.size);
709 BUG_ON(result);
710
711 result = dma_unmap_area(r, dma_lpar_to_bus(r, map.r1.base),
712 map.r1.size);
713 BUG_ON(result);
714
715 result = dma_region_free(r);
716 BUG_ON(result);
717
718 return result;
719}
720
721/**
722 * dma_map_area_linear - Map an area of memory into a device dma region.
723 * @r: Pointer to a struct ps3_dma_region.
724 * @virt_addr: Starting virtual address of the area to map.
725 * @len: Length in bytes of the area to map.
726 * @bus_addr: A pointer to return the starting ioc bus address of the area to
727 * map.
728 *
729 * This routine just returns the coresponding bus address. Actual mapping
730 * occurs in dma_region_create_linear().
731 */
732
733static int dma_map_area_linear(struct ps3_dma_region *r,
734 unsigned long virt_addr, unsigned long len, unsigned long *bus_addr)
735{
736 unsigned long phys_addr = is_kernel_addr(virt_addr) ? __pa(virt_addr)
737 : virt_addr;
738 *bus_addr = dma_lpar_to_bus(r, ps3_mm_phys_to_lpar(phys_addr));
739 return 0;
740}
741
742/**
743 * dma_unmap_area_linear - Unmap an area of memory from a device dma region.
744 * @r: Pointer to a struct ps3_dma_region.
745 * @bus_addr: The starting ioc bus address of the area to unmap.
746 * @len: Length in bytes of the area to unmap.
747 *
748 * This routine does nothing. Unmapping occurs in dma_region_free_linear().
749 */
750
751static int dma_unmap_area_linear(struct ps3_dma_region *r,
752 unsigned long bus_addr, unsigned long len)
753{
754 return 0;
755}
756
757int ps3_dma_region_create(struct ps3_dma_region *r)
758{
759 return (USE_DYNAMIC_DMA)
760 ? dma_region_create(r)
761 : dma_region_create_linear(r);
762}
763
764int ps3_dma_region_free(struct ps3_dma_region *r)
765{
766 return (USE_DYNAMIC_DMA)
767 ? dma_region_free(r)
768 : dma_region_free_linear(r);
769}
770
771int ps3_dma_map(struct ps3_dma_region *r, unsigned long virt_addr,
772 unsigned long len, unsigned long *bus_addr)
773{
774 return (USE_DYNAMIC_DMA)
775 ? dma_map_area(r, virt_addr, len, bus_addr)
776 : dma_map_area_linear(r, virt_addr, len, bus_addr);
777}
778
779int ps3_dma_unmap(struct ps3_dma_region *r, unsigned long bus_addr,
780 unsigned long len)
781{
782 return (USE_DYNAMIC_DMA) ? dma_unmap_area(r, bus_addr, len)
783 : dma_unmap_area_linear(r, bus_addr, len);
784}
785
786/*============================================================================*/
787/* system startup routines */
788/*============================================================================*/
789
790/**
791 * ps3_mm_init - initialize the address space state variables
792 */
793
794void __init ps3_mm_init(void)
795{
796 int result;
797
798 DBG(" -> %s:%d\n", __func__, __LINE__);
799
800 result = ps3_repository_read_mm_info(&map.rm.base, &map.rm.size,
801 &map.total);
802
803 if (result)
804 panic("ps3_repository_read_mm_info() failed");
805
806 map.rm.offset = map.rm.base;
807 map.vas_id = map.htab_size = 0;
808
809 /* this implementation assumes map.rm.base is zero */
810
811 BUG_ON(map.rm.base);
812 BUG_ON(!map.rm.size);
813
814 lmb_add(map.rm.base, map.rm.size);
815 lmb_analyze();
816
817 /* arrange to do this in ps3_mm_add_memory */
818 ps3_mm_region_create(&map.r1, map.total - map.rm.size);
819
820 DBG(" <- %s:%d\n", __func__, __LINE__);
821}
822
823/**
824 * ps3_mm_shutdown - final cleanup of address space
825 */
826
827void ps3_mm_shutdown(void)
828{
829 ps3_mm_region_destroy(&map.r1);
830 map.total = map.rm.size;
831}
diff --git a/arch/powerpc/platforms/ps3/os-area.c b/arch/powerpc/platforms/ps3/os-area.c
new file mode 100644
index 000000000000..58358305dc10
--- /dev/null
+++ b/arch/powerpc/platforms/ps3/os-area.c
@@ -0,0 +1,259 @@
1/*
2 * PS3 'Other OS' area data.
3 *
4 * Copyright (C) 2006 Sony Computer Entertainment Inc.
5 * Copyright 2006 Sony Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/kernel.h>
22#include <linux/io.h>
23
24#include <asm/lmb.h>
25#include <asm/ps3.h>
26
27#include "platform.h"
28
29enum {
30 OS_AREA_SEGMENT_SIZE = 0X200,
31};
32
33enum {
34 HEADER_LDR_FORMAT_RAW = 0,
35 HEADER_LDR_FORMAT_GZIP = 1,
36};
37
38/**
39 * struct os_area_header - os area header segment.
40 * @magic_num: Always 'cell_ext_os_area'.
41 * @hdr_version: Header format version number.
42 * @os_area_offset: Starting segment number of os image area.
43 * @ldr_area_offset: Starting segment number of bootloader image area.
44 * @ldr_format: HEADER_LDR_FORMAT flag.
45 * @ldr_size: Size of bootloader image in bytes.
46 *
47 * Note that the docs refer to area offsets. These are offsets in units of
48 * segments from the start of the os area (top of the header). These are
49 * better thought of as segment numbers. The os area of the os area is
50 * reserved for the os image.
51 */
52
53struct os_area_header {
54 s8 magic_num[16];
55 u32 hdr_version;
56 u32 os_area_offset;
57 u32 ldr_area_offset;
58 u32 _reserved_1;
59 u32 ldr_format;
60 u32 ldr_size;
61 u32 _reserved_2[6];
62} __attribute__ ((packed));
63
64enum {
65 PARAM_BOOT_FLAG_GAME_OS = 0,
66 PARAM_BOOT_FLAG_OTHER_OS = 1,
67};
68
69enum {
70 PARAM_AV_MULTI_OUT_NTSC = 0,
71 PARAM_AV_MULTI_OUT_PAL_RGB = 1,
72 PARAM_AV_MULTI_OUT_PAL_YCBCR = 2,
73 PARAM_AV_MULTI_OUT_SECAM = 3,
74};
75
76enum {
77 PARAM_CTRL_BUTTON_O_IS_YES = 0,
78 PARAM_CTRL_BUTTON_X_IS_YES = 1,
79};
80
81/**
82 * struct os_area_params - os area params segment.
83 * @boot_flag: User preference of operating system, PARAM_BOOT_FLAG flag.
84 * @num_params: Number of params in this (params) segment.
85 * @rtc_diff: Difference in seconds between 1970 and the ps3 rtc value.
86 * @av_multi_out: User preference of AV output, PARAM_AV_MULTI_OUT flag.
87 * @ctrl_button: User preference of controller button config, PARAM_CTRL_BUTTON
88 * flag.
89 * @static_ip_addr: User preference of static IP address.
90 * @network_mask: User preference of static network mask.
91 * @default_gateway: User preference of static default gateway.
92 * @dns_primary: User preference of static primary dns server.
93 * @dns_secondary: User preference of static secondary dns server.
94 *
95 * User preference of zero for static_ip_addr means use dhcp.
96 */
97
98struct os_area_params {
99 u32 boot_flag;
100 u32 _reserved_1[3];
101 u32 num_params;
102 u32 _reserved_2[3];
103 /* param 0 */
104 s64 rtc_diff;
105 u8 av_multi_out;
106 u8 ctrl_button;
107 u8 _reserved_3[6];
108 /* param 1 */
109 u8 static_ip_addr[4];
110 u8 network_mask[4];
111 u8 default_gateway[4];
112 u8 _reserved_4[4];
113 /* param 2 */
114 u8 dns_primary[4];
115 u8 dns_secondary[4];
116 u8 _reserved_5[8];
117} __attribute__ ((packed));
118
119/**
120 * struct saved_params - Static working copies of data from the 'Other OS' area.
121 *
122 * For the convinience of the guest, the HV makes a copy of the 'Other OS' area
123 * in flash to a high address in the boot memory region and then puts that RAM
124 * address and the byte count into the repository for retreval by the guest.
125 * We copy the data we want into a static variable and allow the memory setup
126 * by the HV to be claimed by the lmb manager.
127 */
128
129struct saved_params {
130 /* param 0 */
131 s64 rtc_diff;
132 unsigned int av_multi_out;
133 unsigned int ctrl_button;
134 /* param 1 */
135 u8 static_ip_addr[4];
136 u8 network_mask[4];
137 u8 default_gateway[4];
138 /* param 2 */
139 u8 dns_primary[4];
140 u8 dns_secondary[4];
141} static saved_params;
142
143#define dump_header(_a) _dump_header(_a, __func__, __LINE__)
144static void _dump_header(const struct os_area_header __iomem *h, const char* func,
145 int line)
146{
147 pr_debug("%s:%d: h.magic_num: '%s'\n", func, line,
148 h->magic_num);
149 pr_debug("%s:%d: h.hdr_version: %u\n", func, line,
150 h->hdr_version);
151 pr_debug("%s:%d: h.os_area_offset: %u\n", func, line,
152 h->os_area_offset);
153 pr_debug("%s:%d: h.ldr_area_offset: %u\n", func, line,
154 h->ldr_area_offset);
155 pr_debug("%s:%d: h.ldr_format: %u\n", func, line,
156 h->ldr_format);
157 pr_debug("%s:%d: h.ldr_size: %xh\n", func, line,
158 h->ldr_size);
159}
160
161#define dump_params(_a) _dump_params(_a, __func__, __LINE__)
162static void _dump_params(const struct os_area_params __iomem *p, const char* func,
163 int line)
164{
165 pr_debug("%s:%d: p.boot_flag: %u\n", func, line, p->boot_flag);
166 pr_debug("%s:%d: p.num_params: %u\n", func, line, p->num_params);
167 pr_debug("%s:%d: p.rtc_diff %ld\n", func, line, p->rtc_diff);
168 pr_debug("%s:%d: p.av_multi_out %u\n", func, line, p->av_multi_out);
169 pr_debug("%s:%d: p.ctrl_button: %u\n", func, line, p->ctrl_button);
170 pr_debug("%s:%d: p.static_ip_addr: %u.%u.%u.%u\n", func, line,
171 p->static_ip_addr[0], p->static_ip_addr[1],
172 p->static_ip_addr[2], p->static_ip_addr[3]);
173 pr_debug("%s:%d: p.network_mask: %u.%u.%u.%u\n", func, line,
174 p->network_mask[0], p->network_mask[1],
175 p->network_mask[2], p->network_mask[3]);
176 pr_debug("%s:%d: p.default_gateway: %u.%u.%u.%u\n", func, line,
177 p->default_gateway[0], p->default_gateway[1],
178 p->default_gateway[2], p->default_gateway[3]);
179 pr_debug("%s:%d: p.dns_primary: %u.%u.%u.%u\n", func, line,
180 p->dns_primary[0], p->dns_primary[1],
181 p->dns_primary[2], p->dns_primary[3]);
182 pr_debug("%s:%d: p.dns_secondary: %u.%u.%u.%u\n", func, line,
183 p->dns_secondary[0], p->dns_secondary[1],
184 p->dns_secondary[2], p->dns_secondary[3]);
185}
186
187static int __init verify_header(const struct os_area_header *header)
188{
189 if (memcmp(header->magic_num, "cell_ext_os_area", 16)) {
190 pr_debug("%s:%d magic_num failed\n", __func__, __LINE__);
191 return -1;
192 }
193
194 if (header->hdr_version < 1) {
195 pr_debug("%s:%d hdr_version failed\n", __func__, __LINE__);
196 return -1;
197 }
198
199 if (header->os_area_offset > header->ldr_area_offset) {
200 pr_debug("%s:%d offsets failed\n", __func__, __LINE__);
201 return -1;
202 }
203
204 return 0;
205}
206
207int __init ps3_os_area_init(void)
208{
209 int result;
210 u64 lpar_addr;
211 unsigned int size;
212 struct os_area_header *header;
213 struct os_area_params *params;
214
215 result = ps3_repository_read_boot_dat_info(&lpar_addr, &size);
216
217 if (result) {
218 pr_debug("%s:%d ps3_repository_read_boot_dat_info failed\n",
219 __func__, __LINE__);
220 return result;
221 }
222
223 header = (struct os_area_header *)__va(lpar_addr);
224 params = (struct os_area_params *)__va(lpar_addr + OS_AREA_SEGMENT_SIZE);
225
226 result = verify_header(header);
227
228 if (result) {
229 pr_debug("%s:%d verify_header failed\n", __func__, __LINE__);
230 dump_header(header);
231 return -EIO;
232 }
233
234 dump_header(header);
235 dump_params(params);
236
237 saved_params.rtc_diff = params->rtc_diff;
238 saved_params.av_multi_out = params->av_multi_out;
239 saved_params.ctrl_button = params->ctrl_button;
240 memcpy(saved_params.static_ip_addr, params->static_ip_addr, 4);
241 memcpy(saved_params.network_mask, params->network_mask, 4);
242 memcpy(saved_params.default_gateway, params->default_gateway, 4);
243 memcpy(saved_params.dns_secondary, params->dns_secondary, 4);
244
245 return result;
246}
247
248/**
249 * ps3_os_area_rtc_diff - Returns the ps3 rtc diff value.
250 *
251 * The ps3 rtc maintains a value that approximates seconds since
252 * 2000-01-01 00:00:00 UTC. Returns the exact number of seconds from 1970 to
253 * 2000 when saved_params.rtc_diff has not been properly set up.
254 */
255
256u64 ps3_os_area_rtc_diff(void)
257{
258 return saved_params.rtc_diff ? saved_params.rtc_diff : 946684800UL;
259}
diff --git a/arch/powerpc/platforms/ps3/platform.h b/arch/powerpc/platforms/ps3/platform.h
new file mode 100644
index 000000000000..23b111bea9d0
--- /dev/null
+++ b/arch/powerpc/platforms/ps3/platform.h
@@ -0,0 +1,68 @@
1/*
2 * PS3 platform declarations.
3 *
4 * Copyright (C) 2006 Sony Computer Entertainment Inc.
5 * Copyright 2006 Sony Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#if !defined(_PS3_PLATFORM_H)
22#define _PS3_PLATFORM_H
23
24#include <linux/rtc.h>
25
26/* htab */
27
28void __init ps3_hpte_init(unsigned long htab_size);
29void __init ps3_map_htab(void);
30
31/* mm */
32
33void __init ps3_mm_init(void);
34void __init ps3_mm_vas_create(unsigned long* htab_size);
35void ps3_mm_vas_destroy(void);
36void ps3_mm_shutdown(void);
37
38/* irq */
39
40void ps3_init_IRQ(void);
41void __init ps3_register_ipi_debug_brk(unsigned int cpu, unsigned int virq);
42
43/* smp */
44
45void smp_init_ps3(void);
46void ps3_smp_cleanup_cpu(int cpu);
47
48/* time */
49
50void __init ps3_calibrate_decr(void);
51unsigned long __init ps3_get_boot_time(void);
52void ps3_get_rtc_time(struct rtc_time *time);
53int ps3_set_rtc_time(struct rtc_time *time);
54
55/* os area */
56
57int __init ps3_os_area_init(void);
58u64 ps3_os_area_rtc_diff(void);
59
60/* spu */
61
62#if defined(CONFIG_SPU_BASE)
63void ps3_spu_set_platform (void);
64#else
65static inline void ps3_spu_set_platform (void) {}
66#endif
67
68#endif
diff --git a/arch/powerpc/platforms/ps3/repository.c b/arch/powerpc/platforms/ps3/repository.c
new file mode 100644
index 000000000000..273a0d621bdd
--- /dev/null
+++ b/arch/powerpc/platforms/ps3/repository.c
@@ -0,0 +1,840 @@
1/*
2 * PS3 repository routines.
3 *
4 * Copyright (C) 2006 Sony Computer Entertainment Inc.
5 * Copyright 2006 Sony Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <asm/ps3.h>
22#include <asm/lv1call.h>
23
24enum ps3_vendor_id {
25 PS3_VENDOR_ID_NONE = 0,
26 PS3_VENDOR_ID_SONY = 0x8000000000000000UL,
27};
28
29enum ps3_lpar_id {
30 PS3_LPAR_ID_CURRENT = 0,
31 PS3_LPAR_ID_PME = 1,
32};
33
34#define dump_field(_a, _b) _dump_field(_a, _b, __func__, __LINE__)
35static void _dump_field(const char *hdr, u64 n, const char* func, int line)
36{
37#if defined(DEBUG)
38 char s[16];
39 const char *const in = (const char *)&n;
40 unsigned int i;
41
42 for (i = 0; i < 8; i++)
43 s[i] = (in[i] <= 126 && in[i] >= 32) ? in[i] : '.';
44 s[i] = 0;
45
46 pr_debug("%s:%d: %s%016lx : %s\n", func, line, hdr, n, s);
47#endif
48}
49
50#define dump_node_name(_a, _b, _c, _d, _e) \
51 _dump_node_name(_a, _b, _c, _d, _e, __func__, __LINE__)
52static void _dump_node_name (unsigned int lpar_id, u64 n1, u64 n2, u64 n3,
53 u64 n4, const char* func, int line)
54{
55 pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id);
56 _dump_field("n1: ", n1, func, line);
57 _dump_field("n2: ", n2, func, line);
58 _dump_field("n3: ", n3, func, line);
59 _dump_field("n4: ", n4, func, line);
60}
61
62#define dump_node(_a, _b, _c, _d, _e, _f, _g) \
63 _dump_node(_a, _b, _c, _d, _e, _f, _g, __func__, __LINE__)
64static void _dump_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
65 u64 v1, u64 v2, const char* func, int line)
66{
67 pr_debug("%s:%d: lpar: %u\n", func, line, lpar_id);
68 _dump_field("n1: ", n1, func, line);
69 _dump_field("n2: ", n2, func, line);
70 _dump_field("n3: ", n3, func, line);
71 _dump_field("n4: ", n4, func, line);
72 pr_debug("%s:%d: v1: %016lx\n", func, line, v1);
73 pr_debug("%s:%d: v2: %016lx\n", func, line, v2);
74}
75
76/**
77 * make_first_field - Make the first field of a repository node name.
78 * @text: Text portion of the field.
79 * @index: Numeric index portion of the field. Use zero for 'don't care'.
80 *
81 * This routine sets the vendor id to zero (non-vendor specific).
82 * Returns field value.
83 */
84
85static u64 make_first_field(const char *text, u64 index)
86{
87 u64 n;
88
89 strncpy((char *)&n, text, 8);
90 return PS3_VENDOR_ID_NONE + (n >> 32) + index;
91}
92
93/**
94 * make_field - Make subsequent fields of a repository node name.
95 * @text: Text portion of the field. Use "" for 'don't care'.
96 * @index: Numeric index portion of the field. Use zero for 'don't care'.
97 *
98 * Returns field value.
99 */
100
101static u64 make_field(const char *text, u64 index)
102{
103 u64 n;
104
105 strncpy((char *)&n, text, 8);
106 return n + index;
107}
108
109/**
110 * read_node - Read a repository node from raw fields.
111 * @n1: First field of node name.
112 * @n2: Second field of node name. Use zero for 'don't care'.
113 * @n3: Third field of node name. Use zero for 'don't care'.
114 * @n4: Fourth field of node name. Use zero for 'don't care'.
115 * @v1: First repository value (high word).
116 * @v2: Second repository value (low word). Optional parameter, use zero
117 * for 'don't care'.
118 */
119
120static int read_node(unsigned int lpar_id, u64 n1, u64 n2, u64 n3, u64 n4,
121 u64 *_v1, u64 *_v2)
122{
123 int result;
124 u64 v1;
125 u64 v2;
126
127 if (lpar_id == PS3_LPAR_ID_CURRENT) {
128 u64 id;
129 lv1_get_logical_partition_id(&id);
130 lpar_id = id;
131 }
132
133 result = lv1_get_repository_node_value(lpar_id, n1, n2, n3, n4, &v1,
134 &v2);
135
136 if (result) {
137 pr_debug("%s:%d: lv1_get_repository_node_value failed: %s\n",
138 __func__, __LINE__, ps3_result(result));
139 dump_node_name(lpar_id, n1, n2, n3, n4);
140 return result;
141 }
142
143 dump_node(lpar_id, n1, n2, n3, n4, v1, v2);
144
145 if (_v1)
146 *_v1 = v1;
147 if (_v2)
148 *_v2 = v2;
149
150 if (v1 && !_v1)
151 pr_debug("%s:%d: warning: discarding non-zero v1: %016lx\n",
152 __func__, __LINE__, v1);
153 if (v2 && !_v2)
154 pr_debug("%s:%d: warning: discarding non-zero v2: %016lx\n",
155 __func__, __LINE__, v2);
156
157 return result;
158}
159
160int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str,
161 u64 *value)
162{
163 return read_node(PS3_LPAR_ID_PME,
164 make_first_field("bus", bus_index),
165 make_field(bus_str, 0),
166 0, 0,
167 value, 0);
168}
169
170int ps3_repository_read_bus_id(unsigned int bus_index, unsigned int *bus_id)
171{
172 int result;
173 u64 v1;
174 u64 v2; /* unused */
175
176 result = read_node(PS3_LPAR_ID_PME,
177 make_first_field("bus", bus_index),
178 make_field("id", 0),
179 0, 0,
180 &v1, &v2);
181 *bus_id = v1;
182 return result;
183}
184
185int ps3_repository_read_bus_type(unsigned int bus_index,
186 enum ps3_bus_type *bus_type)
187{
188 int result;
189 u64 v1;
190
191 result = read_node(PS3_LPAR_ID_PME,
192 make_first_field("bus", bus_index),
193 make_field("type", 0),
194 0, 0,
195 &v1, 0);
196 *bus_type = v1;
197 return result;
198}
199
200int ps3_repository_read_bus_num_dev(unsigned int bus_index,
201 unsigned int *num_dev)
202{
203 int result;
204 u64 v1;
205
206 result = read_node(PS3_LPAR_ID_PME,
207 make_first_field("bus", bus_index),
208 make_field("num_dev", 0),
209 0, 0,
210 &v1, 0);
211 *num_dev = v1;
212 return result;
213}
214
215int ps3_repository_read_dev_str(unsigned int bus_index,
216 unsigned int dev_index, const char *dev_str, u64 *value)
217{
218 return read_node(PS3_LPAR_ID_PME,
219 make_first_field("bus", bus_index),
220 make_field("dev", dev_index),
221 make_field(dev_str, 0),
222 0,
223 value, 0);
224}
225
226int ps3_repository_read_dev_id(unsigned int bus_index, unsigned int dev_index,
227 unsigned int *dev_id)
228{
229 int result;
230 u64 v1;
231
232 result = read_node(PS3_LPAR_ID_PME,
233 make_first_field("bus", bus_index),
234 make_field("dev", dev_index),
235 make_field("id", 0),
236 0,
237 &v1, 0);
238 *dev_id = v1;
239 return result;
240}
241
242int ps3_repository_read_dev_type(unsigned int bus_index,
243 unsigned int dev_index, enum ps3_dev_type *dev_type)
244{
245 int result;
246 u64 v1;
247
248 result = read_node(PS3_LPAR_ID_PME,
249 make_first_field("bus", bus_index),
250 make_field("dev", dev_index),
251 make_field("type", 0),
252 0,
253 &v1, 0);
254 *dev_type = v1;
255 return result;
256}
257
258int ps3_repository_read_dev_intr(unsigned int bus_index,
259 unsigned int dev_index, unsigned int intr_index,
260 unsigned int *intr_type, unsigned int* interrupt_id)
261{
262 int result;
263 u64 v1;
264 u64 v2;
265
266 result = read_node(PS3_LPAR_ID_PME,
267 make_first_field("bus", bus_index),
268 make_field("dev", dev_index),
269 make_field("intr", intr_index),
270 0,
271 &v1, &v2);
272 *intr_type = v1;
273 *interrupt_id = v2;
274 return result;
275}
276
277int ps3_repository_read_dev_reg_type(unsigned int bus_index,
278 unsigned int dev_index, unsigned int reg_index, unsigned int *reg_type)
279{
280 int result;
281 u64 v1;
282
283 result = read_node(PS3_LPAR_ID_PME,
284 make_first_field("bus", bus_index),
285 make_field("dev", dev_index),
286 make_field("reg", reg_index),
287 make_field("type", 0),
288 &v1, 0);
289 *reg_type = v1;
290 return result;
291}
292
293int ps3_repository_read_dev_reg_addr(unsigned int bus_index,
294 unsigned int dev_index, unsigned int reg_index, u64 *bus_addr, u64 *len)
295{
296 return read_node(PS3_LPAR_ID_PME,
297 make_first_field("bus", bus_index),
298 make_field("dev", dev_index),
299 make_field("reg", reg_index),
300 make_field("data", 0),
301 bus_addr, len);
302}
303
304int ps3_repository_read_dev_reg(unsigned int bus_index,
305 unsigned int dev_index, unsigned int reg_index, unsigned int *reg_type,
306 u64 *bus_addr, u64 *len)
307{
308 int result = ps3_repository_read_dev_reg_type(bus_index, dev_index,
309 reg_index, reg_type);
310 return result ? result
311 : ps3_repository_read_dev_reg_addr(bus_index, dev_index,
312 reg_index, bus_addr, len);
313}
314
315#if defined(DEBUG)
316int ps3_repository_dump_resource_info(unsigned int bus_index,
317 unsigned int dev_index)
318{
319 int result = 0;
320 unsigned int res_index;
321
322 pr_debug(" -> %s:%d: (%u:%u)\n", __func__, __LINE__,
323 bus_index, dev_index);
324
325 for (res_index = 0; res_index < 10; res_index++) {
326 enum ps3_interrupt_type intr_type;
327 unsigned int interrupt_id;
328
329 result = ps3_repository_read_dev_intr(bus_index, dev_index,
330 res_index, &intr_type, &interrupt_id);
331
332 if (result) {
333 if (result != LV1_NO_ENTRY)
334 pr_debug("%s:%d ps3_repository_read_dev_intr"
335 " (%u:%u) failed\n", __func__, __LINE__,
336 bus_index, dev_index);
337 break;
338 }
339
340 pr_debug("%s:%d (%u:%u) intr_type %u, interrupt_id %u\n",
341 __func__, __LINE__, bus_index, dev_index, intr_type,
342 interrupt_id);
343 }
344
345 for (res_index = 0; res_index < 10; res_index++) {
346 enum ps3_region_type reg_type;
347 u64 bus_addr;
348 u64 len;
349
350 result = ps3_repository_read_dev_reg(bus_index, dev_index,
351 res_index, &reg_type, &bus_addr, &len);
352
353 if (result) {
354 if (result != LV1_NO_ENTRY)
355 pr_debug("%s:%d ps3_repository_read_dev_reg"
356 " (%u:%u) failed\n", __func__, __LINE__,
357 bus_index, dev_index);
358 break;
359 }
360
361 pr_debug("%s:%d (%u:%u) reg_type %u, bus_addr %lxh, len %lxh\n",
362 __func__, __LINE__, bus_index, dev_index, reg_type,
363 bus_addr, len);
364 }
365
366 pr_debug(" <- %s:%d\n", __func__, __LINE__);
367 return result;
368}
369
370static int dump_device_info(unsigned int bus_index, unsigned int num_dev)
371{
372 int result = 0;
373 unsigned int dev_index;
374
375 pr_debug(" -> %s:%d: bus_%u\n", __func__, __LINE__, bus_index);
376
377 for (dev_index = 0; dev_index < num_dev; dev_index++) {
378 enum ps3_dev_type dev_type;
379 unsigned int dev_id;
380
381 result = ps3_repository_read_dev_type(bus_index, dev_index,
382 &dev_type);
383
384 if (result) {
385 pr_debug("%s:%d ps3_repository_read_dev_type"
386 " (%u:%u) failed\n", __func__, __LINE__,
387 bus_index, dev_index);
388 break;
389 }
390
391 result = ps3_repository_read_dev_id(bus_index, dev_index,
392 &dev_id);
393
394 if (result) {
395 pr_debug("%s:%d ps3_repository_read_dev_id"
396 " (%u:%u) failed\n", __func__, __LINE__,
397 bus_index, dev_index);
398 continue;
399 }
400
401 pr_debug("%s:%d (%u:%u): dev_type %u, dev_id %u\n", __func__,
402 __LINE__, bus_index, dev_index, dev_type, dev_id);
403
404 ps3_repository_dump_resource_info(bus_index, dev_index);
405 }
406
407 pr_debug(" <- %s:%d\n", __func__, __LINE__);
408 return result;
409}
410
411int ps3_repository_dump_bus_info(void)
412{
413 int result = 0;
414 unsigned int bus_index;
415
416 pr_debug(" -> %s:%d\n", __func__, __LINE__);
417
418 for (bus_index = 0; bus_index < 10; bus_index++) {
419 enum ps3_bus_type bus_type;
420 unsigned int bus_id;
421 unsigned int num_dev;
422
423 result = ps3_repository_read_bus_type(bus_index, &bus_type);
424
425 if (result) {
426 pr_debug("%s:%d read_bus_type(%u) failed\n",
427 __func__, __LINE__, bus_index);
428 break;
429 }
430
431 result = ps3_repository_read_bus_id(bus_index, &bus_id);
432
433 if (result) {
434 pr_debug("%s:%d read_bus_id(%u) failed\n",
435 __func__, __LINE__, bus_index);
436 continue;
437 }
438
439 if (bus_index != bus_id)
440 pr_debug("%s:%d bus_index != bus_id\n",
441 __func__, __LINE__);
442
443 result = ps3_repository_read_bus_num_dev(bus_index, &num_dev);
444
445 if (result) {
446 pr_debug("%s:%d read_bus_num_dev(%u) failed\n",
447 __func__, __LINE__, bus_index);
448 continue;
449 }
450
451 pr_debug("%s:%d bus_%u: bus_type %u, bus_id %u, num_dev %u\n",
452 __func__, __LINE__, bus_index, bus_type, bus_id,
453 num_dev);
454
455 dump_device_info(bus_index, num_dev);
456 }
457
458 pr_debug(" <- %s:%d\n", __func__, __LINE__);
459 return result;
460}
461#endif /* defined(DEBUG) */
462
463static int find_device(unsigned int bus_index, unsigned int num_dev,
464 unsigned int start_dev_index, enum ps3_dev_type dev_type,
465 struct ps3_repository_device *dev)
466{
467 int result = 0;
468 unsigned int dev_index;
469
470 pr_debug("%s:%d: find dev_type %u\n", __func__, __LINE__, dev_type);
471
472 dev->dev_index = UINT_MAX;
473
474 for (dev_index = start_dev_index; dev_index < num_dev; dev_index++) {
475 enum ps3_dev_type x;
476
477 result = ps3_repository_read_dev_type(bus_index, dev_index,
478 &x);
479
480 if (result) {
481 pr_debug("%s:%d read_dev_type failed\n",
482 __func__, __LINE__);
483 return result;
484 }
485
486 if (x == dev_type)
487 break;
488 }
489
490 BUG_ON(dev_index == num_dev);
491
492 pr_debug("%s:%d: found dev_type %u at dev_index %u\n",
493 __func__, __LINE__, dev_type, dev_index);
494
495 result = ps3_repository_read_dev_id(bus_index, dev_index,
496 &dev->did.dev_id);
497
498 if (result) {
499 pr_debug("%s:%d read_dev_id failed\n",
500 __func__, __LINE__);
501 return result;
502 }
503
504 dev->dev_index = dev_index;
505
506 pr_debug("%s:%d found: dev_id %u\n", __func__, __LINE__,
507 dev->did.dev_id);
508
509 return result;
510}
511
512int ps3_repository_find_device (enum ps3_bus_type bus_type,
513 enum ps3_dev_type dev_type,
514 const struct ps3_repository_device *start_dev,
515 struct ps3_repository_device *dev)
516{
517 int result = 0;
518 unsigned int bus_index;
519 unsigned int num_dev;
520
521 pr_debug("%s:%d: find bus_type %u, dev_type %u\n", __func__, __LINE__,
522 bus_type, dev_type);
523
524 dev->bus_index = UINT_MAX;
525
526 for (bus_index = start_dev ? start_dev->bus_index : 0; bus_index < 10;
527 bus_index++) {
528 enum ps3_bus_type x;
529
530 result = ps3_repository_read_bus_type(bus_index, &x);
531
532 if (result) {
533 pr_debug("%s:%d read_bus_type failed\n",
534 __func__, __LINE__);
535 return result;
536 }
537 if (x == bus_type)
538 break;
539 }
540
541 BUG_ON(bus_index == 10);
542
543 pr_debug("%s:%d: found bus_type %u at bus_index %u\n",
544 __func__, __LINE__, bus_type, bus_index);
545
546 result = ps3_repository_read_bus_num_dev(bus_index, &num_dev);
547
548 if (result) {
549 pr_debug("%s:%d read_bus_num_dev failed\n",
550 __func__, __LINE__);
551 return result;
552 }
553
554 result = find_device(bus_index, num_dev, start_dev
555 ? start_dev->dev_index + 1 : 0, dev_type, dev);
556
557 if (result) {
558 pr_debug("%s:%d get_did failed\n", __func__, __LINE__);
559 return result;
560 }
561
562 result = ps3_repository_read_bus_id(bus_index, &dev->did.bus_id);
563
564 if (result) {
565 pr_debug("%s:%d read_bus_id failed\n",
566 __func__, __LINE__);
567 return result;
568 }
569
570 dev->bus_index = bus_index;
571
572 pr_debug("%s:%d found: bus_id %u, dev_id %u\n",
573 __func__, __LINE__, dev->did.bus_id, dev->did.dev_id);
574
575 return result;
576}
577
578int ps3_repository_find_interrupt(const struct ps3_repository_device *dev,
579 enum ps3_interrupt_type intr_type, unsigned int *interrupt_id)
580{
581 int result = 0;
582 unsigned int res_index;
583
584 pr_debug("%s:%d: find intr_type %u\n", __func__, __LINE__, intr_type);
585
586 *interrupt_id = UINT_MAX;
587
588 for (res_index = 0; res_index < 10; res_index++) {
589 enum ps3_interrupt_type t;
590 unsigned int id;
591
592 result = ps3_repository_read_dev_intr(dev->bus_index,
593 dev->dev_index, res_index, &t, &id);
594
595 if (result) {
596 pr_debug("%s:%d read_dev_intr failed\n",
597 __func__, __LINE__);
598 return result;
599 }
600
601 if (t == intr_type) {
602 *interrupt_id = id;
603 break;
604 }
605 }
606
607 BUG_ON(res_index == 10);
608
609 pr_debug("%s:%d: found intr_type %u at res_index %u\n",
610 __func__, __LINE__, intr_type, res_index);
611
612 return result;
613}
614
615int ps3_repository_find_region(const struct ps3_repository_device *dev,
616 enum ps3_region_type reg_type, u64 *bus_addr, u64 *len)
617{
618 int result = 0;
619 unsigned int res_index;
620
621 pr_debug("%s:%d: find reg_type %u\n", __func__, __LINE__, reg_type);
622
623 *bus_addr = *len = 0;
624
625 for (res_index = 0; res_index < 10; res_index++) {
626 enum ps3_region_type t;
627 u64 a;
628 u64 l;
629
630 result = ps3_repository_read_dev_reg(dev->bus_index,
631 dev->dev_index, res_index, &t, &a, &l);
632
633 if (result) {
634 pr_debug("%s:%d read_dev_reg failed\n",
635 __func__, __LINE__);
636 return result;
637 }
638
639 if (t == reg_type) {
640 *bus_addr = a;
641 *len = l;
642 break;
643 }
644 }
645
646 BUG_ON(res_index == 10);
647
648 pr_debug("%s:%d: found reg_type %u at res_index %u\n",
649 __func__, __LINE__, reg_type, res_index);
650
651 return result;
652}
653
654int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size)
655{
656 return read_node(PS3_LPAR_ID_CURRENT,
657 make_first_field("bi", 0),
658 make_field("pu", 0),
659 ppe_id,
660 make_field("rm_size", 0),
661 rm_size, 0);
662}
663
664int ps3_repository_read_region_total(u64 *region_total)
665{
666 return read_node(PS3_LPAR_ID_CURRENT,
667 make_first_field("bi", 0),
668 make_field("rgntotal", 0),
669 0, 0,
670 region_total, 0);
671}
672
673/**
674 * ps3_repository_read_mm_info - Read mm info for single pu system.
675 * @rm_base: Real mode memory base address.
676 * @rm_size: Real mode memory size.
677 * @region_total: Maximum memory region size.
678 */
679
680int ps3_repository_read_mm_info(u64 *rm_base, u64 *rm_size, u64 *region_total)
681{
682 int result;
683 u64 ppe_id;
684
685 lv1_get_logical_ppe_id(&ppe_id);
686 *rm_base = 0;
687 result = ps3_repository_read_rm_size(ppe_id, rm_size);
688 return result ? result
689 : ps3_repository_read_region_total(region_total);
690}
691
692/**
693 * ps3_repository_read_num_spu_reserved - Number of physical spus reserved.
694 * @num_spu: Number of physical spus.
695 */
696
697int ps3_repository_read_num_spu_reserved(unsigned int *num_spu_reserved)
698{
699 int result;
700 u64 v1;
701
702 result = read_node(PS3_LPAR_ID_CURRENT,
703 make_first_field("bi", 0),
704 make_field("spun", 0),
705 0, 0,
706 &v1, 0);
707 *num_spu_reserved = v1;
708 return result;
709}
710
711/**
712 * ps3_repository_read_num_spu_resource_id - Number of spu resource reservations.
713 * @num_resource_id: Number of spu resource ids.
714 */
715
716int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id)
717{
718 int result;
719 u64 v1;
720
721 result = read_node(PS3_LPAR_ID_CURRENT,
722 make_first_field("bi", 0),
723 make_field("spursvn", 0),
724 0, 0,
725 &v1, 0);
726 *num_resource_id = v1;
727 return result;
728}
729
730/**
731 * ps3_repository_read_spu_resource_id - spu resource reservation id value.
732 * @res_index: Resource reservation index.
733 * @resource_type: Resource reservation type.
734 * @resource_id: Resource reservation id.
735 */
736
737int ps3_repository_read_spu_resource_id(unsigned int res_index,
738 enum ps3_spu_resource_type* resource_type, unsigned int *resource_id)
739{
740 int result;
741 u64 v1;
742 u64 v2;
743
744 result = read_node(PS3_LPAR_ID_CURRENT,
745 make_first_field("bi", 0),
746 make_field("spursv", 0),
747 res_index,
748 0,
749 &v1, &v2);
750 *resource_type = v1;
751 *resource_id = v2;
752 return result;
753}
754
755int ps3_repository_read_boot_dat_address(u64 *address)
756{
757 return read_node(PS3_LPAR_ID_CURRENT,
758 make_first_field("bi", 0),
759 make_field("boot_dat", 0),
760 make_field("address", 0),
761 0,
762 address, 0);
763}
764
765int ps3_repository_read_boot_dat_size(unsigned int *size)
766{
767 int result;
768 u64 v1;
769
770 result = read_node(PS3_LPAR_ID_CURRENT,
771 make_first_field("bi", 0),
772 make_field("boot_dat", 0),
773 make_field("size", 0),
774 0,
775 &v1, 0);
776 *size = v1;
777 return result;
778}
779
780/**
781 * ps3_repository_read_boot_dat_info - Get address and size of cell_ext_os_area.
782 * address: lpar address of cell_ext_os_area
783 * @size: size of cell_ext_os_area
784 */
785
786int ps3_repository_read_boot_dat_info(u64 *lpar_addr, unsigned int *size)
787{
788 int result;
789
790 *size = 0;
791 result = ps3_repository_read_boot_dat_address(lpar_addr);
792 return result ? result
793 : ps3_repository_read_boot_dat_size(size);
794}
795
796int ps3_repository_read_num_be(unsigned int *num_be)
797{
798 int result;
799 u64 v1;
800
801 result = read_node(PS3_LPAR_ID_PME,
802 make_first_field("ben", 0),
803 0,
804 0,
805 0,
806 &v1, 0);
807 *num_be = v1;
808 return result;
809}
810
811int ps3_repository_read_be_node_id(unsigned int be_index, u64 *node_id)
812{
813 return read_node(PS3_LPAR_ID_PME,
814 make_first_field("be", be_index),
815 0,
816 0,
817 0,
818 node_id, 0);
819}
820
821int ps3_repository_read_tb_freq(u64 node_id, u64 *tb_freq)
822{
823 return read_node(PS3_LPAR_ID_PME,
824 make_first_field("be", 0),
825 node_id,
826 make_field("clock", 0),
827 0,
828 tb_freq, 0);
829}
830
831int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq)
832{
833 int result;
834 u64 node_id;
835
836 *tb_freq = 0;
837 result = ps3_repository_read_be_node_id(0, &node_id);
838 return result ? result
839 : ps3_repository_read_tb_freq(node_id, tb_freq);
840}
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
new file mode 100644
index 000000000000..d8b5cadbe80e
--- /dev/null
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -0,0 +1,173 @@
1/*
2 * PS3 platform setup routines.
3 *
4 * Copyright (C) 2006 Sony Computer Entertainment Inc.
5 * Copyright 2006 Sony Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/kernel.h>
22#include <linux/delay.h>
23#include <linux/fs.h>
24#include <linux/root_dev.h>
25#include <linux/console.h>
26#include <linux/kexec.h>
27
28#include <asm/machdep.h>
29#include <asm/firmware.h>
30#include <asm/time.h>
31#include <asm/iommu.h>
32#include <asm/udbg.h>
33#include <asm/prom.h>
34#include <asm/lv1call.h>
35
36#include "platform.h"
37
38#if defined(DEBUG)
39#define DBG(fmt...) udbg_printf(fmt)
40#else
41#define DBG(fmt...) do{if(0)printk(fmt);}while(0)
42#endif
43
44static void ps3_show_cpuinfo(struct seq_file *m)
45{
46 seq_printf(m, "machine\t\t: %s\n", ppc_md.name);
47}
48
49static void ps3_power_save(void)
50{
51 /*
52 * lv1_pause() puts the PPE thread into inactive state until an
53 * irq on an unmasked plug exists. MSR[EE] has no effect.
54 * flags: 0 = wake on DEC interrupt, 1 = ignore DEC interrupt.
55 */
56
57 lv1_pause(0);
58}
59
60static void ps3_panic(char *str)
61{
62 DBG("%s:%d %s\n", __func__, __LINE__, str);
63
64#ifdef CONFIG_SMP
65 smp_send_stop();
66#endif
67 printk("\n");
68 printk(" System does not reboot automatically.\n");
69 printk(" Please press POWER button.\n");
70 printk("\n");
71
72 for (;;) ;
73}
74
75static void __init ps3_setup_arch(void)
76{
77 DBG(" -> %s:%d\n", __func__, __LINE__);
78
79 ps3_spu_set_platform();
80 ps3_map_htab();
81
82#ifdef CONFIG_SMP
83 smp_init_ps3();
84#endif
85
86#ifdef CONFIG_DUMMY_CONSOLE
87 conswitchp = &dummy_con;
88#endif
89
90 ppc_md.power_save = ps3_power_save;
91
92 DBG(" <- %s:%d\n", __func__, __LINE__);
93}
94
95static void __init ps3_progress(char *s, unsigned short hex)
96{
97 printk("*** %04x : %s\n", hex, s ? s : "");
98}
99
100static int __init ps3_probe(void)
101{
102 unsigned long htab_size;
103 unsigned long dt_root;
104
105 DBG(" -> %s:%d\n", __func__, __LINE__);
106
107 dt_root = of_get_flat_dt_root();
108 if (!of_flat_dt_is_compatible(dt_root, "PS3"))
109 return 0;
110
111 powerpc_firmware_features |= FW_FEATURE_PS3_POSSIBLE;
112
113 ps3_os_area_init();
114 ps3_mm_init();
115 ps3_mm_vas_create(&htab_size);
116 ps3_hpte_init(htab_size);
117
118 DBG(" <- %s:%d\n", __func__, __LINE__);
119 return 1;
120}
121
122#if defined(CONFIG_KEXEC)
123static void ps3_kexec_cpu_down(int crash_shutdown, int secondary)
124{
125 DBG(" -> %s:%d\n", __func__, __LINE__);
126
127 if (secondary) {
128 int cpu;
129 for_each_online_cpu(cpu)
130 if (cpu)
131 ps3_smp_cleanup_cpu(cpu);
132 } else
133 ps3_smp_cleanup_cpu(0);
134
135 DBG(" <- %s:%d\n", __func__, __LINE__);
136}
137
138static void ps3_machine_kexec(struct kimage *image)
139{
140 unsigned long ppe_id;
141
142 DBG(" -> %s:%d\n", __func__, __LINE__);
143
144 lv1_get_logical_ppe_id(&ppe_id);
145 lv1_configure_irq_state_bitmap(ppe_id, 0, 0);
146 ps3_mm_shutdown();
147 ps3_mm_vas_destroy();
148
149 default_machine_kexec(image);
150
151 DBG(" <- %s:%d\n", __func__, __LINE__);
152}
153#endif
154
155define_machine(ps3) {
156 .name = "PS3",
157 .probe = ps3_probe,
158 .setup_arch = ps3_setup_arch,
159 .show_cpuinfo = ps3_show_cpuinfo,
160 .init_IRQ = ps3_init_IRQ,
161 .panic = ps3_panic,
162 .get_boot_time = ps3_get_boot_time,
163 .set_rtc_time = ps3_set_rtc_time,
164 .get_rtc_time = ps3_get_rtc_time,
165 .calibrate_decr = ps3_calibrate_decr,
166 .progress = ps3_progress,
167#if defined(CONFIG_KEXEC)
168 .kexec_cpu_down = ps3_kexec_cpu_down,
169 .machine_kexec = ps3_machine_kexec,
170 .machine_kexec_prepare = default_machine_kexec_prepare,
171 .machine_crash_shutdown = default_machine_crash_shutdown,
172#endif
173};
diff --git a/arch/powerpc/platforms/ps3/smp.c b/arch/powerpc/platforms/ps3/smp.c
new file mode 100644
index 000000000000..11d2080607ed
--- /dev/null
+++ b/arch/powerpc/platforms/ps3/smp.c
@@ -0,0 +1,158 @@
1/*
2 * PS3 SMP routines.
3 *
4 * Copyright (C) 2006 Sony Computer Entertainment Inc.
5 * Copyright 2006 Sony Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/kernel.h>
22#include <linux/smp.h>
23
24#include <asm/machdep.h>
25#include <asm/udbg.h>
26#include <asm/ps3.h>
27
28#include "platform.h"
29
30#if defined(DEBUG)
31#define DBG(fmt...) udbg_printf(fmt)
32#else
33#define DBG(fmt...) do{if(0)printk(fmt);}while(0)
34#endif
35
36static irqreturn_t ipi_function_handler(int irq, void *msg)
37{
38 smp_message_recv((int)(long)msg);
39 return IRQ_HANDLED;
40}
41
42/**
43 * virqs - a per cpu array of virqs for ipi use
44 */
45
46#define MSG_COUNT 4
47static DEFINE_PER_CPU(unsigned int, virqs[MSG_COUNT]);
48
49static const char *names[MSG_COUNT] = {
50 "ipi call",
51 "ipi reschedule",
52 "ipi migrate",
53 "ipi debug brk"
54};
55
56static void do_message_pass(int target, int msg)
57{
58 int result;
59 unsigned int virq;
60
61 if (msg >= MSG_COUNT) {
62 DBG("%s:%d: bad msg: %d\n", __func__, __LINE__, msg);
63 return;
64 }
65
66 virq = per_cpu(virqs, target)[msg];
67 result = ps3_send_event_locally(virq);
68
69 if (result)
70 DBG("%s:%d: ps3_send_event_locally(%d, %d) failed"
71 " (%d)\n", __func__, __LINE__, target, msg, result);
72}
73
74static void ps3_smp_message_pass(int target, int msg)
75{
76 int cpu;
77
78 if (target < NR_CPUS)
79 do_message_pass(target, msg);
80 else if (target == MSG_ALL_BUT_SELF) {
81 for_each_online_cpu(cpu)
82 if (cpu != smp_processor_id())
83 do_message_pass(cpu, msg);
84 } else {
85 for_each_online_cpu(cpu)
86 do_message_pass(cpu, msg);
87 }
88}
89
90static int ps3_smp_probe(void)
91{
92 return 2;
93}
94
95static void __init ps3_smp_setup_cpu(int cpu)
96{
97 int result;
98 unsigned int *virqs = per_cpu(virqs, cpu);
99 int i;
100
101 DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);
102
103 /*
104 * Check assumptions on virqs[] indexing. If this
105 * check fails, then a different mapping of PPC_MSG_
106 * to index needs to be setup.
107 */
108
109 BUILD_BUG_ON(PPC_MSG_CALL_FUNCTION != 0);
110 BUILD_BUG_ON(PPC_MSG_RESCHEDULE != 1);
111 BUILD_BUG_ON(PPC_MSG_DEBUGGER_BREAK != 3);
112
113 for (i = 0; i < MSG_COUNT; i++) {
114 result = ps3_alloc_event_irq(&virqs[i]);
115
116 if (result)
117 continue;
118
119 DBG("%s:%d: (%d, %d) => virq %u\n",
120 __func__, __LINE__, cpu, i, virqs[i]);
121
122
123 request_irq(virqs[i], ipi_function_handler, IRQF_DISABLED,
124 names[i], (void*)(long)i);
125 }
126
127 ps3_register_ipi_debug_brk(cpu, virqs[PPC_MSG_DEBUGGER_BREAK]);
128
129 DBG(" <- %s:%d: (%d)\n", __func__, __LINE__, cpu);
130}
131
132void ps3_smp_cleanup_cpu(int cpu)
133{
134 unsigned int *virqs = per_cpu(virqs, cpu);
135 int i;
136
137 DBG(" -> %s:%d: (%d)\n", __func__, __LINE__, cpu);
138 for (i = 0; i < MSG_COUNT; i++) {
139 ps3_free_event_irq(virqs[i]);
140 free_irq(virqs[i], (void*)(long)i);
141 virqs[i] = NO_IRQ;
142 }
143 DBG(" <- %s:%d: (%d)\n", __func__, __LINE__, cpu);
144}
145
146static struct smp_ops_t ps3_smp_ops = {
147 .probe = ps3_smp_probe,
148 .message_pass = ps3_smp_message_pass,
149 .kick_cpu = smp_generic_kick_cpu,
150 .setup_cpu = ps3_smp_setup_cpu,
151};
152
153void smp_init_ps3(void)
154{
155 DBG(" -> %s\n", __func__);
156 smp_ops = &ps3_smp_ops;
157 DBG(" <- %s\n", __func__);
158}
diff --git a/arch/powerpc/platforms/ps3/spu.c b/arch/powerpc/platforms/ps3/spu.c
new file mode 100644
index 000000000000..644532c3b7c4
--- /dev/null
+++ b/arch/powerpc/platforms/ps3/spu.c
@@ -0,0 +1,613 @@
1/*
2 * PS3 Platform spu routines.
3 *
4 * Copyright (C) 2006 Sony Computer Entertainment Inc.
5 * Copyright 2006 Sony Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/mmzone.h>
24#include <linux/io.h>
25#include <linux/mm.h>
26
27#include <asm/spu.h>
28#include <asm/spu_priv1.h>
29#include <asm/ps3.h>
30#include <asm/lv1call.h>
31
32/* spu_management_ops */
33
34/**
35 * enum spe_type - Type of spe to create.
36 * @spe_type_logical: Standard logical spe.
37 *
38 * For use with lv1_construct_logical_spe(). The current HV does not support
39 * any types other than those listed.
40 */
41
42enum spe_type {
43 SPE_TYPE_LOGICAL = 0,
44};
45
46/**
47 * struct spe_shadow - logical spe shadow register area.
48 *
49 * Read-only shadow of spe registers.
50 */
51
52struct spe_shadow {
53 u8 padding_0000[0x0140];
54 u64 int_status_class0_RW; /* 0x0140 */
55 u64 int_status_class1_RW; /* 0x0148 */
56 u64 int_status_class2_RW; /* 0x0150 */
57 u8 padding_0158[0x0610-0x0158];
58 u64 mfc_dsisr_RW; /* 0x0610 */
59 u8 padding_0618[0x0620-0x0618];
60 u64 mfc_dar_RW; /* 0x0620 */
61 u8 padding_0628[0x0800-0x0628];
62 u64 mfc_dsipr_R; /* 0x0800 */
63 u8 padding_0808[0x0810-0x0808];
64 u64 mfc_lscrr_R; /* 0x0810 */
65 u8 padding_0818[0x0c00-0x0818];
66 u64 mfc_cer_R; /* 0x0c00 */
67 u8 padding_0c08[0x0f00-0x0c08];
68 u64 spe_execution_status; /* 0x0f00 */
69 u8 padding_0f08[0x1000-0x0f08];
70} __attribute__ ((packed));
71
72
73/**
74 * enum spe_ex_state - Logical spe execution state.
75 * @spe_ex_state_unexecutable: Uninitialized.
76 * @spe_ex_state_executable: Enabled, not ready.
77 * @spe_ex_state_executed: Ready for use.
78 *
79 * The execution state (status) of the logical spe as reported in
80 * struct spe_shadow:spe_execution_status.
81 */
82
83enum spe_ex_state {
84 SPE_EX_STATE_UNEXECUTABLE = 0,
85 SPE_EX_STATE_EXECUTABLE = 2,
86 SPE_EX_STATE_EXECUTED = 3,
87};
88
89/**
90 * struct priv1_cache - Cached values of priv1 registers.
91 * @masks[]: Array of cached spe interrupt masks, indexed by class.
92 * @sr1: Cached mfc_sr1 register.
93 * @tclass_id: Cached mfc_tclass_id register.
94 */
95
96struct priv1_cache {
97 u64 masks[3];
98 u64 sr1;
99 u64 tclass_id;
100};
101
102/**
103 * struct spu_pdata - Platform state variables.
104 * @spe_id: HV spe id returned by lv1_construct_logical_spe().
105 * @resource_id: HV spe resource id returned by
106 * ps3_repository_read_spe_resource_id().
107 * @priv2_addr: lpar address of spe priv2 area returned by
108 * lv1_construct_logical_spe().
109 * @shadow_addr: lpar address of spe register shadow area returned by
110 * lv1_construct_logical_spe().
111 * @shadow: Virtual (ioremap) address of spe register shadow area.
112 * @cache: Cached values of priv1 registers.
113 */
114
115struct spu_pdata {
116 u64 spe_id;
117 u64 resource_id;
118 u64 priv2_addr;
119 u64 shadow_addr;
120 struct spe_shadow __iomem *shadow;
121 struct priv1_cache cache;
122};
123
124static struct spu_pdata *spu_pdata(struct spu *spu)
125{
126 return spu->pdata;
127}
128
129#define dump_areas(_a, _b, _c, _d, _e) \
130 _dump_areas(_a, _b, _c, _d, _e, __func__, __LINE__)
131static void _dump_areas(unsigned int spe_id, unsigned long priv2,
132 unsigned long problem, unsigned long ls, unsigned long shadow,
133 const char* func, int line)
134{
135 pr_debug("%s:%d: spe_id: %xh (%u)\n", func, line, spe_id, spe_id);
136 pr_debug("%s:%d: priv2: %lxh\n", func, line, priv2);
137 pr_debug("%s:%d: problem: %lxh\n", func, line, problem);
138 pr_debug("%s:%d: ls: %lxh\n", func, line, ls);
139 pr_debug("%s:%d: shadow: %lxh\n", func, line, shadow);
140}
141
142static unsigned long get_vas_id(void)
143{
144 unsigned long id;
145
146 lv1_get_logical_ppe_id(&id);
147 lv1_get_virtual_address_space_id_of_ppe(id, &id);
148
149 return id;
150}
151
152static int __init construct_spu(struct spu *spu)
153{
154 int result;
155 unsigned long unused;
156
157 result = lv1_construct_logical_spe(PAGE_SHIFT, PAGE_SHIFT, PAGE_SHIFT,
158 PAGE_SHIFT, PAGE_SHIFT, get_vas_id(), SPE_TYPE_LOGICAL,
159 &spu_pdata(spu)->priv2_addr, &spu->problem_phys,
160 &spu->local_store_phys, &unused,
161 &spu_pdata(spu)->shadow_addr,
162 &spu_pdata(spu)->spe_id);
163
164 if (result) {
165 pr_debug("%s:%d: lv1_construct_logical_spe failed: %s\n",
166 __func__, __LINE__, ps3_result(result));
167 return result;
168 }
169
170 return result;
171}
172
173static int __init add_spu_pages(unsigned long start_addr, unsigned long size)
174{
175 int result;
176 unsigned long start_pfn;
177 unsigned long nr_pages;
178 struct pglist_data *pgdata;
179 struct zone *zone;
180
181 BUG_ON(!mem_init_done);
182
183 start_pfn = start_addr >> PAGE_SHIFT;
184 nr_pages = (size + PAGE_SIZE - 1) >> PAGE_SHIFT;
185
186 pgdata = NODE_DATA(0);
187 zone = pgdata->node_zones;
188
189 result = __add_pages(zone, start_pfn, nr_pages);
190
191 if (result)
192 pr_debug("%s:%d: __add_pages failed: (%d)\n",
193 __func__, __LINE__, result);
194
195 return result;
196}
197
198static void spu_unmap(struct spu *spu)
199{
200 iounmap(spu->priv2);
201 iounmap(spu->problem);
202 iounmap((__force u8 __iomem *)spu->local_store);
203 iounmap(spu_pdata(spu)->shadow);
204}
205
206static int __init setup_areas(struct spu *spu)
207{
208 struct table {char* name; unsigned long addr; unsigned long size;};
209 int result;
210
211 /* setup pages */
212
213 result = add_spu_pages(spu->local_store_phys, LS_SIZE);
214 if (result)
215 goto fail_add;
216
217 result = add_spu_pages(spu->problem_phys, sizeof(struct spu_problem));
218 if (result)
219 goto fail_add;
220
221 /* ioremap */
222
223 spu_pdata(spu)->shadow = __ioremap(
224 spu_pdata(spu)->shadow_addr, sizeof(struct spe_shadow),
225 PAGE_READONLY | _PAGE_NO_CACHE | _PAGE_GUARDED);
226 if (!spu_pdata(spu)->shadow) {
227 pr_debug("%s:%d: ioremap shadow failed\n", __func__, __LINE__);
228 goto fail_ioremap;
229 }
230
231 spu->local_store = ioremap(spu->local_store_phys, LS_SIZE);
232 if (!spu->local_store) {
233 pr_debug("%s:%d: ioremap local_store failed\n",
234 __func__, __LINE__);
235 goto fail_ioremap;
236 }
237
238 spu->problem = ioremap(spu->problem_phys,
239 sizeof(struct spu_problem));
240 if (!spu->problem) {
241 pr_debug("%s:%d: ioremap problem failed\n", __func__, __LINE__);
242 goto fail_ioremap;
243 }
244
245 spu->priv2 = ioremap(spu_pdata(spu)->priv2_addr,
246 sizeof(struct spu_priv2));
247 if (!spu->priv2) {
248 pr_debug("%s:%d: ioremap priv2 failed\n", __func__, __LINE__);
249 goto fail_ioremap;
250 }
251
252 dump_areas(spu_pdata(spu)->spe_id, spu_pdata(spu)->priv2_addr,
253 spu->problem_phys, spu->local_store_phys,
254 spu_pdata(spu)->shadow_addr);
255 dump_areas(spu_pdata(spu)->spe_id, (unsigned long)spu->priv2,
256 (unsigned long)spu->problem, (unsigned long)spu->local_store,
257 (unsigned long)spu_pdata(spu)->shadow);
258
259 return 0;
260
261fail_ioremap:
262 spu_unmap(spu);
263fail_add:
264 return result;
265}
266
267static int __init setup_interrupts(struct spu *spu)
268{
269 int result;
270
271 result = ps3_alloc_spe_irq(spu_pdata(spu)->spe_id, 0,
272 &spu->irqs[0]);
273
274 if (result)
275 goto fail_alloc_0;
276
277 result = ps3_alloc_spe_irq(spu_pdata(spu)->spe_id, 1,
278 &spu->irqs[1]);
279
280 if (result)
281 goto fail_alloc_1;
282
283 result = ps3_alloc_spe_irq(spu_pdata(spu)->spe_id, 2,
284 &spu->irqs[2]);
285
286 if (result)
287 goto fail_alloc_2;
288
289 return result;
290
291fail_alloc_2:
292 ps3_free_spe_irq(spu->irqs[1]);
293fail_alloc_1:
294 ps3_free_spe_irq(spu->irqs[0]);
295fail_alloc_0:
296 spu->irqs[0] = spu->irqs[1] = spu->irqs[2] = NO_IRQ;
297 return result;
298}
299
300static int __init enable_spu(struct spu *spu)
301{
302 int result;
303
304 result = lv1_enable_logical_spe(spu_pdata(spu)->spe_id,
305 spu_pdata(spu)->resource_id);
306
307 if (result) {
308 pr_debug("%s:%d: lv1_enable_logical_spe failed: %s\n",
309 __func__, __LINE__, ps3_result(result));
310 goto fail_enable;
311 }
312
313 result = setup_areas(spu);
314
315 if (result)
316 goto fail_areas;
317
318 result = setup_interrupts(spu);
319
320 if (result)
321 goto fail_interrupts;
322
323 return 0;
324
325fail_interrupts:
326 spu_unmap(spu);
327fail_areas:
328 lv1_disable_logical_spe(spu_pdata(spu)->spe_id, 0);
329fail_enable:
330 return result;
331}
332
333static int ps3_destroy_spu(struct spu *spu)
334{
335 int result;
336
337 pr_debug("%s:%d spu_%d\n", __func__, __LINE__, spu->number);
338
339 result = lv1_disable_logical_spe(spu_pdata(spu)->spe_id, 0);
340 BUG_ON(result);
341
342 ps3_free_spe_irq(spu->irqs[2]);
343 ps3_free_spe_irq(spu->irqs[1]);
344 ps3_free_spe_irq(spu->irqs[0]);
345
346 spu->irqs[0] = spu->irqs[1] = spu->irqs[2] = NO_IRQ;
347
348 spu_unmap(spu);
349
350 result = lv1_destruct_logical_spe(spu_pdata(spu)->spe_id);
351 BUG_ON(result);
352
353 kfree(spu->pdata);
354 spu->pdata = NULL;
355
356 return 0;
357}
358
359static int __init ps3_create_spu(struct spu *spu, void *data)
360{
361 int result;
362
363 pr_debug("%s:%d spu_%d\n", __func__, __LINE__, spu->number);
364
365 spu->pdata = kzalloc(sizeof(struct spu_pdata),
366 GFP_KERNEL);
367
368 if (!spu->pdata) {
369 result = -ENOMEM;
370 goto fail_malloc;
371 }
372
373 spu_pdata(spu)->resource_id = (unsigned long)data;
374
375 /* Init cached reg values to HV defaults. */
376
377 spu_pdata(spu)->cache.sr1 = 0x33;
378
379 result = construct_spu(spu);
380
381 if (result)
382 goto fail_construct;
383
384 /* For now, just go ahead and enable it. */
385
386 result = enable_spu(spu);
387
388 if (result)
389 goto fail_enable;
390
391 /* Make sure the spu is in SPE_EX_STATE_EXECUTED. */
392
393 /* need something better here!!! */
394 while (in_be64(&spu_pdata(spu)->shadow->spe_execution_status)
395 != SPE_EX_STATE_EXECUTED)
396 (void)0;
397
398 return result;
399
400fail_enable:
401fail_construct:
402 ps3_destroy_spu(spu);
403fail_malloc:
404 return result;
405}
406
407static int __init ps3_enumerate_spus(int (*fn)(void *data))
408{
409 int result;
410 unsigned int num_resource_id;
411 unsigned int i;
412
413 result = ps3_repository_read_num_spu_resource_id(&num_resource_id);
414
415 pr_debug("%s:%d: num_resource_id %u\n", __func__, __LINE__,
416 num_resource_id);
417
418 /*
419 * For now, just create logical spus equal to the number
420 * of physical spus reserved for the partition.
421 */
422
423 for (i = 0; i < num_resource_id; i++) {
424 enum ps3_spu_resource_type resource_type;
425 unsigned int resource_id;
426
427 result = ps3_repository_read_spu_resource_id(i,
428 &resource_type, &resource_id);
429
430 if (result)
431 break;
432
433 if (resource_type == PS3_SPU_RESOURCE_TYPE_EXCLUSIVE) {
434 result = fn((void*)(unsigned long)resource_id);
435
436 if (result)
437 break;
438 }
439 }
440
441 if (result)
442 printk(KERN_WARNING "%s:%d: Error initializing spus\n",
443 __func__, __LINE__);
444
445 return result;
446}
447
448const struct spu_management_ops spu_management_ps3_ops = {
449 .enumerate_spus = ps3_enumerate_spus,
450 .create_spu = ps3_create_spu,
451 .destroy_spu = ps3_destroy_spu,
452};
453
454/* spu_priv1_ops */
455
456static void int_mask_and(struct spu *spu, int class, u64 mask)
457{
458 u64 old_mask;
459
460 /* are these serialized by caller??? */
461 old_mask = spu_int_mask_get(spu, class);
462 spu_int_mask_set(spu, class, old_mask & mask);
463}
464
465static void int_mask_or(struct spu *spu, int class, u64 mask)
466{
467 u64 old_mask;
468
469 old_mask = spu_int_mask_get(spu, class);
470 spu_int_mask_set(spu, class, old_mask | mask);
471}
472
473static void int_mask_set(struct spu *spu, int class, u64 mask)
474{
475 spu_pdata(spu)->cache.masks[class] = mask;
476 lv1_set_spe_interrupt_mask(spu_pdata(spu)->spe_id, class,
477 spu_pdata(spu)->cache.masks[class]);
478}
479
480static u64 int_mask_get(struct spu *spu, int class)
481{
482 return spu_pdata(spu)->cache.masks[class];
483}
484
485static void int_stat_clear(struct spu *spu, int class, u64 stat)
486{
487 /* Note that MFC_DSISR will be cleared when class1[MF] is set. */
488
489 lv1_clear_spe_interrupt_status(spu_pdata(spu)->spe_id, class,
490 stat, 0);
491}
492
493static u64 int_stat_get(struct spu *spu, int class)
494{
495 u64 stat;
496
497 lv1_get_spe_interrupt_status(spu_pdata(spu)->spe_id, class, &stat);
498 return stat;
499}
500
501static void cpu_affinity_set(struct spu *spu, int cpu)
502{
503 /* No support. */
504}
505
506static u64 mfc_dar_get(struct spu *spu)
507{
508 return in_be64(&spu_pdata(spu)->shadow->mfc_dar_RW);
509}
510
511static void mfc_dsisr_set(struct spu *spu, u64 dsisr)
512{
513 /* Nothing to do, cleared in int_stat_clear(). */
514}
515
516static u64 mfc_dsisr_get(struct spu *spu)
517{
518 return in_be64(&spu_pdata(spu)->shadow->mfc_dsisr_RW);
519}
520
521static void mfc_sdr_setup(struct spu *spu)
522{
523 /* Nothing to do. */
524}
525
526static void mfc_sr1_set(struct spu *spu, u64 sr1)
527{
528 /* Check bits allowed by HV. */
529
530 static const u64 allowed = ~(MFC_STATE1_LOCAL_STORAGE_DECODE_MASK
531 | MFC_STATE1_PROBLEM_STATE_MASK);
532
533 BUG_ON((sr1 & allowed) != (spu_pdata(spu)->cache.sr1 & allowed));
534
535 spu_pdata(spu)->cache.sr1 = sr1;
536 lv1_set_spe_privilege_state_area_1_register(
537 spu_pdata(spu)->spe_id,
538 offsetof(struct spu_priv1, mfc_sr1_RW),
539 spu_pdata(spu)->cache.sr1);
540}
541
542static u64 mfc_sr1_get(struct spu *spu)
543{
544 return spu_pdata(spu)->cache.sr1;
545}
546
547static void mfc_tclass_id_set(struct spu *spu, u64 tclass_id)
548{
549 spu_pdata(spu)->cache.tclass_id = tclass_id;
550 lv1_set_spe_privilege_state_area_1_register(
551 spu_pdata(spu)->spe_id,
552 offsetof(struct spu_priv1, mfc_tclass_id_RW),
553 spu_pdata(spu)->cache.tclass_id);
554}
555
556static u64 mfc_tclass_id_get(struct spu *spu)
557{
558 return spu_pdata(spu)->cache.tclass_id;
559}
560
561static void tlb_invalidate(struct spu *spu)
562{
563 /* Nothing to do. */
564}
565
566static void resource_allocation_groupID_set(struct spu *spu, u64 id)
567{
568 /* No support. */
569}
570
571static u64 resource_allocation_groupID_get(struct spu *spu)
572{
573 return 0; /* No support. */
574}
575
576static void resource_allocation_enable_set(struct spu *spu, u64 enable)
577{
578 /* No support. */
579}
580
581static u64 resource_allocation_enable_get(struct spu *spu)
582{
583 return 0; /* No support. */
584}
585
586const struct spu_priv1_ops spu_priv1_ps3_ops = {
587 .int_mask_and = int_mask_and,
588 .int_mask_or = int_mask_or,
589 .int_mask_set = int_mask_set,
590 .int_mask_get = int_mask_get,
591 .int_stat_clear = int_stat_clear,
592 .int_stat_get = int_stat_get,
593 .cpu_affinity_set = cpu_affinity_set,
594 .mfc_dar_get = mfc_dar_get,
595 .mfc_dsisr_set = mfc_dsisr_set,
596 .mfc_dsisr_get = mfc_dsisr_get,
597 .mfc_sdr_setup = mfc_sdr_setup,
598 .mfc_sr1_set = mfc_sr1_set,
599 .mfc_sr1_get = mfc_sr1_get,
600 .mfc_tclass_id_set = mfc_tclass_id_set,
601 .mfc_tclass_id_get = mfc_tclass_id_get,
602 .tlb_invalidate = tlb_invalidate,
603 .resource_allocation_groupID_set = resource_allocation_groupID_set,
604 .resource_allocation_groupID_get = resource_allocation_groupID_get,
605 .resource_allocation_enable_set = resource_allocation_enable_set,
606 .resource_allocation_enable_get = resource_allocation_enable_get,
607};
608
609void ps3_spu_set_platform(void)
610{
611 spu_priv1_ops = &spu_priv1_ps3_ops;
612 spu_management_ops = &spu_management_ps3_ops;
613}
diff --git a/arch/powerpc/platforms/ps3/time.c b/arch/powerpc/platforms/ps3/time.c
new file mode 100644
index 000000000000..1bae8b19b363
--- /dev/null
+++ b/arch/powerpc/platforms/ps3/time.c
@@ -0,0 +1,104 @@
1/*
2 * PS3 time and rtc routines.
3 *
4 * Copyright (C) 2006 Sony Computer Entertainment Inc.
5 * Copyright 2006 Sony Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/kernel.h>
22
23#include <asm/rtc.h>
24#include <asm/lv1call.h>
25#include <asm/ps3.h>
26
27#include "platform.h"
28
29#define dump_tm(_a) _dump_tm(_a, __func__, __LINE__)
30static void _dump_tm(const struct rtc_time *tm, const char* func, int line)
31{
32 pr_debug("%s:%d tm_sec %d\n", func, line, tm->tm_sec);
33 pr_debug("%s:%d tm_min %d\n", func, line, tm->tm_min);
34 pr_debug("%s:%d tm_hour %d\n", func, line, tm->tm_hour);
35 pr_debug("%s:%d tm_mday %d\n", func, line, tm->tm_mday);
36 pr_debug("%s:%d tm_mon %d\n", func, line, tm->tm_mon);
37 pr_debug("%s:%d tm_year %d\n", func, line, tm->tm_year);
38 pr_debug("%s:%d tm_wday %d\n", func, line, tm->tm_wday);
39}
40
41#define dump_time(_a) _dump_time(_a, __func__, __LINE__)
42static void __attribute__ ((unused)) _dump_time(int time, const char* func,
43 int line)
44{
45 struct rtc_time tm;
46
47 to_tm(time, &tm);
48
49 pr_debug("%s:%d time %d\n", func, line, time);
50 _dump_tm(&tm, func, line);
51}
52
53/**
54 * rtc_shift - Difference in seconds between 1970 and the ps3 rtc value.
55 */
56
57static s64 rtc_shift;
58
59void __init ps3_calibrate_decr(void)
60{
61 int result;
62 u64 tmp;
63
64 result = ps3_repository_read_be_tb_freq(0, &tmp);
65 BUG_ON(result);
66
67 ppc_tb_freq = tmp;
68 ppc_proc_freq = ppc_tb_freq * 40;
69
70 rtc_shift = ps3_os_area_rtc_diff();
71}
72
73static u64 read_rtc(void)
74{
75 int result;
76 u64 rtc_val;
77 u64 tb_val;
78
79 result = lv1_get_rtc(&rtc_val, &tb_val);
80 BUG_ON(result);
81
82 return rtc_val;
83}
84
85int ps3_set_rtc_time(struct rtc_time *tm)
86{
87 u64 now = mktime(tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday,
88 tm->tm_hour, tm->tm_min, tm->tm_sec);
89
90 rtc_shift = now - read_rtc();
91 return 0;
92}
93
94void ps3_get_rtc_time(struct rtc_time *tm)
95{
96 to_tm(read_rtc() + rtc_shift, tm);
97 tm->tm_year -= 1900;
98 tm->tm_mon -= 1;
99}
100
101unsigned long __init ps3_get_boot_time(void)
102{
103 return read_rtc() + rtc_shift;
104}
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c
index 556c279a789d..3c95392f4f41 100644
--- a/arch/powerpc/platforms/pseries/iommu.c
+++ b/arch/powerpc/platforms/pseries/iommu.c
@@ -309,7 +309,7 @@ static void iommu_table_setparms_lpar(struct pci_controller *phb,
309 tbl->it_size = size >> IOMMU_PAGE_SHIFT; 309 tbl->it_size = size >> IOMMU_PAGE_SHIFT;
310} 310}
311 311
312static void iommu_bus_setup_pSeries(struct pci_bus *bus) 312static void pci_dma_bus_setup_pSeries(struct pci_bus *bus)
313{ 313{
314 struct device_node *dn; 314 struct device_node *dn;
315 struct iommu_table *tbl; 315 struct iommu_table *tbl;
@@ -318,10 +318,9 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus)
318 struct pci_dn *pci; 318 struct pci_dn *pci;
319 int children; 319 int children;
320 320
321 DBG("iommu_bus_setup_pSeries, bus %p, bus->self %p\n", bus, bus->self);
322
323 dn = pci_bus_to_OF_node(bus); 321 dn = pci_bus_to_OF_node(bus);
324 pci = PCI_DN(dn); 322
323 DBG("pci_dma_bus_setup_pSeries: setting up bus %s\n", dn->full_name);
325 324
326 if (bus->self) { 325 if (bus->self) {
327 /* This is not a root bus, any setup will be done for the 326 /* This is not a root bus, any setup will be done for the
@@ -329,6 +328,7 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus)
329 */ 328 */
330 return; 329 return;
331 } 330 }
331 pci = PCI_DN(dn);
332 332
333 /* Check if the ISA bus on the system is under 333 /* Check if the ISA bus on the system is under
334 * this PHB. 334 * this PHB.
@@ -390,17 +390,17 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus)
390} 390}
391 391
392 392
393static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) 393static void pci_dma_bus_setup_pSeriesLP(struct pci_bus *bus)
394{ 394{
395 struct iommu_table *tbl; 395 struct iommu_table *tbl;
396 struct device_node *dn, *pdn; 396 struct device_node *dn, *pdn;
397 struct pci_dn *ppci; 397 struct pci_dn *ppci;
398 const void *dma_window = NULL; 398 const void *dma_window = NULL;
399 399
400 DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self);
401
402 dn = pci_bus_to_OF_node(bus); 400 dn = pci_bus_to_OF_node(bus);
403 401
402 DBG("pci_dma_bus_setup_pSeriesLP: setting up bus %s\n", dn->full_name);
403
404 /* Find nearest ibm,dma-window, walking up the device tree */ 404 /* Find nearest ibm,dma-window, walking up the device tree */
405 for (pdn = dn; pdn != NULL; pdn = pdn->parent) { 405 for (pdn = dn; pdn != NULL; pdn = pdn->parent) {
406 dma_window = get_property(pdn, "ibm,dma-window", NULL); 406 dma_window = get_property(pdn, "ibm,dma-window", NULL);
@@ -409,11 +409,15 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
409 } 409 }
410 410
411 if (dma_window == NULL) { 411 if (dma_window == NULL) {
412 DBG("iommu_bus_setup_pSeriesLP: bus %s seems to have no ibm,dma-window property\n", dn->full_name); 412 DBG(" no ibm,dma-window property !\n");
413 return; 413 return;
414 } 414 }
415 415
416 ppci = PCI_DN(pdn); 416 ppci = PCI_DN(pdn);
417
418 DBG(" parent is %s, iommu_table: 0x%p\n",
419 pdn->full_name, ppci->iommu_table);
420
417 if (!ppci->iommu_table) { 421 if (!ppci->iommu_table) {
418 /* Bussubno hasn't been copied yet. 422 /* Bussubno hasn't been copied yet.
419 * Do it now because iommu_table_setparms_lpar needs it. 423 * Do it now because iommu_table_setparms_lpar needs it.
@@ -427,6 +431,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
427 iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window); 431 iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window);
428 432
429 ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node); 433 ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node);
434 DBG(" created table: %p\n", ppci->iommu_table);
430 } 435 }
431 436
432 if (pdn != dn) 437 if (pdn != dn)
@@ -434,27 +439,27 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus)
434} 439}
435 440
436 441
437static void iommu_dev_setup_pSeries(struct pci_dev *dev) 442static void pci_dma_dev_setup_pSeries(struct pci_dev *dev)
438{ 443{
439 struct device_node *dn, *mydn; 444 struct device_node *dn;
440 struct iommu_table *tbl; 445 struct iommu_table *tbl;
441 446
442 DBG("iommu_dev_setup_pSeries, dev %p (%s)\n", dev, pci_name(dev)); 447 DBG("pci_dma_dev_setup_pSeries: %s\n", pci_name(dev));
443 448
444 mydn = dn = pci_device_to_OF_node(dev); 449 dn = dev->dev.archdata.of_node;
445 450
446 /* If we're the direct child of a root bus, then we need to allocate 451 /* If we're the direct child of a root bus, then we need to allocate
447 * an iommu table ourselves. The bus setup code should have setup 452 * an iommu table ourselves. The bus setup code should have setup
448 * the window sizes already. 453 * the window sizes already.
449 */ 454 */
450 if (!dev->bus->self) { 455 if (!dev->bus->self) {
456 struct pci_controller *phb = PCI_DN(dn)->phb;
457
451 DBG(" --> first child, no bridge. Allocating iommu table.\n"); 458 DBG(" --> first child, no bridge. Allocating iommu table.\n");
452 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, 459 tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL,
453 PCI_DN(dn)->phb->node); 460 phb->node);
454 iommu_table_setparms(PCI_DN(dn)->phb, dn, tbl); 461 iommu_table_setparms(phb, dn, tbl);
455 PCI_DN(dn)->iommu_table = iommu_init_table(tbl, 462 dev->dev.archdata.dma_data = iommu_init_table(tbl, phb->node);
456 PCI_DN(dn)->phb->node);
457
458 return; 463 return;
459 } 464 }
460 465
@@ -465,11 +470,11 @@ static void iommu_dev_setup_pSeries(struct pci_dev *dev)
465 while (dn && PCI_DN(dn) && PCI_DN(dn)->iommu_table == NULL) 470 while (dn && PCI_DN(dn) && PCI_DN(dn)->iommu_table == NULL)
466 dn = dn->parent; 471 dn = dn->parent;
467 472
468 if (dn && PCI_DN(dn)) { 473 if (dn && PCI_DN(dn))
469 PCI_DN(mydn)->iommu_table = PCI_DN(dn)->iommu_table; 474 dev->dev.archdata.dma_data = PCI_DN(dn)->iommu_table;
470 } else { 475 else
471 DBG("iommu_dev_setup_pSeries, dev %p (%s) has no iommu table\n", dev, pci_name(dev)); 476 printk(KERN_WARNING "iommu: Device %s has no iommu table\n",
472 } 477 pci_name(dev));
473} 478}
474 479
475static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node) 480static int iommu_reconfig_notifier(struct notifier_block *nb, unsigned long action, void *node)
@@ -495,13 +500,15 @@ static struct notifier_block iommu_reconfig_nb = {
495 .notifier_call = iommu_reconfig_notifier, 500 .notifier_call = iommu_reconfig_notifier,
496}; 501};
497 502
498static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) 503static void pci_dma_dev_setup_pSeriesLP(struct pci_dev *dev)
499{ 504{
500 struct device_node *pdn, *dn; 505 struct device_node *pdn, *dn;
501 struct iommu_table *tbl; 506 struct iommu_table *tbl;
502 const void *dma_window = NULL; 507 const void *dma_window = NULL;
503 struct pci_dn *pci; 508 struct pci_dn *pci;
504 509
510 DBG("pci_dma_dev_setup_pSeriesLP: %s\n", pci_name(dev));
511
505 /* dev setup for LPAR is a little tricky, since the device tree might 512 /* dev setup for LPAR is a little tricky, since the device tree might
506 * contain the dma-window properties per-device and not neccesarily 513 * contain the dma-window properties per-device and not neccesarily
507 * for the bus. So we need to search upwards in the tree until we 514 * for the bus. So we need to search upwards in the tree until we
@@ -509,9 +516,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
509 * already allocated. 516 * already allocated.
510 */ 517 */
511 dn = pci_device_to_OF_node(dev); 518 dn = pci_device_to_OF_node(dev);
512 519 DBG(" node is %s\n", dn->full_name);
513 DBG("iommu_dev_setup_pSeriesLP, dev %p (%s) %s\n",
514 dev, pci_name(dev), dn->full_name);
515 520
516 for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table; 521 for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table;
517 pdn = pdn->parent) { 522 pdn = pdn->parent) {
@@ -520,16 +525,17 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
520 break; 525 break;
521 } 526 }
522 527
528 DBG(" parent is %s\n", pdn->full_name);
529
523 /* Check for parent == NULL so we don't try to setup the empty EADS 530 /* Check for parent == NULL so we don't try to setup the empty EADS
524 * slots on POWER4 machines. 531 * slots on POWER4 machines.
525 */ 532 */
526 if (dma_window == NULL || pdn->parent == NULL) { 533 if (dma_window == NULL || pdn->parent == NULL) {
527 DBG("No dma window for device, linking to parent\n"); 534 DBG(" no dma window for device, linking to parent\n");
528 PCI_DN(dn)->iommu_table = PCI_DN(pdn)->iommu_table; 535 dev->dev.archdata.dma_data = PCI_DN(pdn)->iommu_table;
529 return; 536 return;
530 } else {
531 DBG("Found DMA window, allocating table\n");
532 } 537 }
538 DBG(" found DMA window, table: %p\n", pci->iommu_table);
533 539
534 pci = PCI_DN(pdn); 540 pci = PCI_DN(pdn);
535 if (!pci->iommu_table) { 541 if (!pci->iommu_table) {
@@ -542,24 +548,20 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev)
542 iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window); 548 iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window);
543 549
544 pci->iommu_table = iommu_init_table(tbl, pci->phb->node); 550 pci->iommu_table = iommu_init_table(tbl, pci->phb->node);
551 DBG(" created table: %p\n", pci->iommu_table);
545 } 552 }
546 553
547 if (pdn != dn) 554 dev->dev.archdata.dma_data = pci->iommu_table;
548 PCI_DN(dn)->iommu_table = pci->iommu_table;
549} 555}
550 556
551static void iommu_bus_setup_null(struct pci_bus *b) { }
552static void iommu_dev_setup_null(struct pci_dev *d) { }
553
554/* These are called very early. */ 557/* These are called very early. */
555void iommu_init_early_pSeries(void) 558void iommu_init_early_pSeries(void)
556{ 559{
557 if (of_chosen && get_property(of_chosen, "linux,iommu-off", NULL)) { 560 if (of_chosen && get_property(of_chosen, "linux,iommu-off", NULL)) {
558 /* Direct I/O, IOMMU off */ 561 /* Direct I/O, IOMMU off */
559 ppc_md.iommu_dev_setup = iommu_dev_setup_null; 562 ppc_md.pci_dma_dev_setup = NULL;
560 ppc_md.iommu_bus_setup = iommu_bus_setup_null; 563 ppc_md.pci_dma_bus_setup = NULL;
561 pci_direct_iommu_init(); 564 pci_dma_ops = &dma_direct_ops;
562
563 return; 565 return;
564 } 566 }
565 567
@@ -572,19 +574,19 @@ void iommu_init_early_pSeries(void)
572 ppc_md.tce_free = tce_free_pSeriesLP; 574 ppc_md.tce_free = tce_free_pSeriesLP;
573 } 575 }
574 ppc_md.tce_get = tce_get_pSeriesLP; 576 ppc_md.tce_get = tce_get_pSeriesLP;
575 ppc_md.iommu_bus_setup = iommu_bus_setup_pSeriesLP; 577 ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_pSeriesLP;
576 ppc_md.iommu_dev_setup = iommu_dev_setup_pSeriesLP; 578 ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_pSeriesLP;
577 } else { 579 } else {
578 ppc_md.tce_build = tce_build_pSeries; 580 ppc_md.tce_build = tce_build_pSeries;
579 ppc_md.tce_free = tce_free_pSeries; 581 ppc_md.tce_free = tce_free_pSeries;
580 ppc_md.tce_get = tce_get_pseries; 582 ppc_md.tce_get = tce_get_pseries;
581 ppc_md.iommu_bus_setup = iommu_bus_setup_pSeries; 583 ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_pSeries;
582 ppc_md.iommu_dev_setup = iommu_dev_setup_pSeries; 584 ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_pSeries;
583 } 585 }
584 586
585 587
586 pSeries_reconfig_notifier_register(&iommu_reconfig_nb); 588 pSeries_reconfig_notifier_register(&iommu_reconfig_nb);
587 589
588 pci_iommu_init(); 590 pci_dma_ops = &dma_iommu_ops;
589} 591}
590 592
diff --git a/arch/powerpc/platforms/pseries/lpar.c b/arch/powerpc/platforms/pseries/lpar.c
index 1820a0b0a8c6..721436db3ef0 100644
--- a/arch/powerpc/platforms/pseries/lpar.c
+++ b/arch/powerpc/platforms/pseries/lpar.c
@@ -282,7 +282,7 @@ void vpa_init(int cpu)
282 } 282 }
283} 283}
284 284
285long pSeries_lpar_hpte_insert(unsigned long hpte_group, 285static long pSeries_lpar_hpte_insert(unsigned long hpte_group,
286 unsigned long va, unsigned long pa, 286 unsigned long va, unsigned long pa,
287 unsigned long rflags, unsigned long vflags, 287 unsigned long rflags, unsigned long vflags,
288 int psize) 288 int psize)
@@ -506,7 +506,7 @@ static void pSeries_lpar_hpte_invalidate(unsigned long slot, unsigned long va,
506 * Take a spinlock around flushes to avoid bouncing the hypervisor tlbie 506 * Take a spinlock around flushes to avoid bouncing the hypervisor tlbie
507 * lock. 507 * lock.
508 */ 508 */
509void pSeries_lpar_flush_hash_range(unsigned long number, int local) 509static void pSeries_lpar_flush_hash_range(unsigned long number, int local)
510{ 510{
511 int i; 511 int i;
512 unsigned long flags = 0; 512 unsigned long flags = 0;
diff --git a/arch/powerpc/platforms/pseries/pci.c b/arch/powerpc/platforms/pseries/pci.c
index 410a6bcc4ca0..715db5c89908 100644
--- a/arch/powerpc/platforms/pseries/pci.c
+++ b/arch/powerpc/platforms/pseries/pci.c
@@ -29,8 +29,6 @@
29#include <asm/prom.h> 29#include <asm/prom.h>
30#include <asm/ppc-pci.h> 30#include <asm/ppc-pci.h>
31 31
32static int __devinitdata s7a_workaround = -1;
33
34#if 0 32#if 0
35void pcibios_name_device(struct pci_dev *dev) 33void pcibios_name_device(struct pci_dev *dev)
36{ 34{
@@ -57,39 +55,6 @@ void pcibios_name_device(struct pci_dev *dev)
57DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device); 55DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pcibios_name_device);
58#endif 56#endif
59 57
60static void __devinit check_s7a(void)
61{
62 struct device_node *root;
63 const char *model;
64
65 s7a_workaround = 0;
66 root = of_find_node_by_path("/");
67 if (root) {
68 model = get_property(root, "model", NULL);
69 if (model && !strcmp(model, "IBM,7013-S7A"))
70 s7a_workaround = 1;
71 of_node_put(root);
72 }
73}
74
75void __devinit pSeries_irq_bus_setup(struct pci_bus *bus)
76{
77 struct pci_dev *dev;
78
79 if (s7a_workaround < 0)
80 check_s7a();
81 list_for_each_entry(dev, &bus->devices, bus_list) {
82 pci_read_irq_line(dev);
83 if (s7a_workaround) {
84 if (dev->irq > 16) {
85 dev->irq -= 3;
86 pci_write_config_byte(dev, PCI_INTERRUPT_LINE,
87 dev->irq);
88 }
89 }
90 }
91}
92
93static void __init pSeries_request_regions(void) 58static void __init pSeries_request_regions(void)
94{ 59{
95 if (!isa_io_base) 60 if (!isa_io_base)
diff --git a/arch/powerpc/platforms/pseries/pci_dlpar.c b/arch/powerpc/platforms/pseries/pci_dlpar.c
index 6bfacc217085..ac56b868913a 100644
--- a/arch/powerpc/platforms/pseries/pci_dlpar.c
+++ b/arch/powerpc/platforms/pseries/pci_dlpar.c
@@ -93,8 +93,8 @@ pcibios_fixup_new_pci_devices(struct pci_bus *bus, int fix_bus)
93 if (list_empty(&dev->global_list)) { 93 if (list_empty(&dev->global_list)) {
94 int i; 94 int i;
95 95
96 /* Need to setup IOMMU tables */ 96 /* Fill device archdata and setup iommu table */
97 ppc_md.iommu_dev_setup(dev); 97 pcibios_setup_new_device(dev);
98 98
99 if(fix_bus) 99 if(fix_bus)
100 pcibios_fixup_device_resources(dev, bus); 100 pcibios_fixup_device_resources(dev, bus);
@@ -195,7 +195,7 @@ struct pci_controller * __devinit init_phb_dynamic(struct device_node *dn)
195 phb = pcibios_alloc_controller(dn); 195 phb = pcibios_alloc_controller(dn);
196 if (!phb) 196 if (!phb)
197 return NULL; 197 return NULL;
198 setup_phb(dn, phb); 198 rtas_setup_phb(phb);
199 pci_process_bridge_OF_ranges(phb, dn, 0); 199 pci_process_bridge_OF_ranges(phb, dn, 0);
200 200
201 pci_setup_phb_io_dynamic(phb, primary); 201 pci_setup_phb_io_dynamic(phb, primary);
diff --git a/arch/powerpc/platforms/pseries/reconfig.c b/arch/powerpc/platforms/pseries/reconfig.c
index 1773103354be..4ad33e41b008 100644
--- a/arch/powerpc/platforms/pseries/reconfig.c
+++ b/arch/powerpc/platforms/pseries/reconfig.c
@@ -268,11 +268,10 @@ static char * parse_next_property(char *buf, char *end, char **name, int *length
268static struct property *new_property(const char *name, const int length, 268static struct property *new_property(const char *name, const int length,
269 const unsigned char *value, struct property *last) 269 const unsigned char *value, struct property *last)
270{ 270{
271 struct property *new = kmalloc(sizeof(*new), GFP_KERNEL); 271 struct property *new = kzalloc(sizeof(*new), GFP_KERNEL);
272 272
273 if (!new) 273 if (!new)
274 return NULL; 274 return NULL;
275 memset(new, 0, sizeof(*new));
276 275
277 if (!(new->name = kmalloc(strlen(name) + 1, GFP_KERNEL))) 276 if (!(new->name = kmalloc(strlen(name) + 1, GFP_KERNEL)))
278 goto cleanup; 277 goto cleanup;
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 89a8119f988d..0dc2548ca9bc 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -347,6 +347,7 @@ static int __init pSeries_init_panel(void)
347} 347}
348arch_initcall(pSeries_init_panel); 348arch_initcall(pSeries_init_panel);
349 349
350#ifdef CONFIG_HOTPLUG_CPU
350static void pSeries_mach_cpu_die(void) 351static void pSeries_mach_cpu_die(void)
351{ 352{
352 local_irq_disable(); 353 local_irq_disable();
@@ -357,6 +358,9 @@ static void pSeries_mach_cpu_die(void)
357 BUG(); 358 BUG();
358 for(;;); 359 for(;;);
359} 360}
361#else
362#define pSeries_mach_cpu_die NULL
363#endif
360 364
361static int pseries_set_dabr(unsigned long dabr) 365static int pseries_set_dabr(unsigned long dabr)
362{ 366{
@@ -553,7 +557,6 @@ define_machine(pseries) {
553 .log_error = pSeries_log_error, 557 .log_error = pSeries_log_error,
554 .pcibios_fixup = pSeries_final_fixup, 558 .pcibios_fixup = pSeries_final_fixup,
555 .pci_probe_mode = pSeries_pci_probe_mode, 559 .pci_probe_mode = pSeries_pci_probe_mode,
556 .irq_bus_setup = pSeries_irq_bus_setup,
557 .restart = rtas_restart, 560 .restart = rtas_restart,
558 .power_off = rtas_power_off, 561 .power_off = rtas_power_off,
559 .halt = rtas_halt, 562 .halt = rtas_halt,
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c
index d071abe78ab1..b5b2b1103de8 100644
--- a/arch/powerpc/platforms/pseries/xics.c
+++ b/arch/powerpc/platforms/pseries/xics.c
@@ -656,13 +656,38 @@ static void __init xics_setup_8259_cascade(void)
656 set_irq_chained_handler(cascade, pseries_8259_cascade); 656 set_irq_chained_handler(cascade, pseries_8259_cascade);
657} 657}
658 658
659static struct device_node *cpuid_to_of_node(int cpu)
660{
661 struct device_node *np;
662 u32 hcpuid = get_hard_smp_processor_id(cpu);
663
664 for_each_node_by_type(np, "cpu") {
665 int i, len;
666 const u32 *intserv;
667
668 intserv = get_property(np, "ibm,ppc-interrupt-server#s", &len);
669
670 if (!intserv)
671 intserv = get_property(np, "reg", &len);
672
673 i = len / sizeof(u32);
674
675 while (i--)
676 if (intserv[i] == hcpuid)
677 return np;
678 }
679
680 return NULL;
681}
682
659void __init xics_init_IRQ(void) 683void __init xics_init_IRQ(void)
660{ 684{
661 int i; 685 int i, j;
662 struct device_node *np; 686 struct device_node *np;
663 u32 ilen, indx = 0; 687 u32 ilen, indx = 0;
664 const u32 *ireg; 688 const u32 *ireg, *isize;
665 int found = 0; 689 int found = 0;
690 u32 hcpuid;
666 691
667 ppc64_boot_msg(0x20, "XICS Init"); 692 ppc64_boot_msg(0x20, "XICS Init");
668 693
@@ -683,26 +708,31 @@ void __init xics_init_IRQ(void)
683 xics_init_host(); 708 xics_init_host();
684 709
685 /* Find the server numbers for the boot cpu. */ 710 /* Find the server numbers for the boot cpu. */
686 for (np = of_find_node_by_type(NULL, "cpu"); 711 np = cpuid_to_of_node(boot_cpuid);
687 np; 712 BUG_ON(!np);
688 np = of_find_node_by_type(np, "cpu")) { 713 ireg = get_property(np, "ibm,ppc-interrupt-gserver#s", &ilen);
689 ireg = get_property(np, "reg", &ilen); 714 if (!ireg)
690 if (ireg && ireg[0] == get_hard_smp_processor_id(boot_cpuid)) { 715 goto skip_gserver_check;
691 ireg = get_property(np, 716 i = ilen / sizeof(int);
692 "ibm,ppc-interrupt-gserver#s", &ilen); 717 hcpuid = get_hard_smp_processor_id(boot_cpuid);
693 i = ilen / sizeof(int); 718
694 if (ireg && i > 0) { 719 /* Global interrupt distribution server is specified in the last
695 default_server = ireg[0]; 720 * entry of "ibm,ppc-interrupt-gserver#s" property. Get the last
696 /* take last element */ 721 * entry fom this property for current boot cpu id and use it as
697 default_distrib_server = ireg[i-1]; 722 * default distribution server
698 } 723 */
699 ireg = get_property(np, 724 for (j = 0; j < i; j += 2) {
725 if (ireg[j] == hcpuid) {
726 default_server = hcpuid;
727 default_distrib_server = ireg[j+1];
728
729 isize = get_property(np,
700 "ibm,interrupt-server#-size", NULL); 730 "ibm,interrupt-server#-size", NULL);
701 if (ireg) 731 if (isize)
702 interrupt_server_size = *ireg; 732 interrupt_server_size = *isize;
703 break;
704 } 733 }
705 } 734 }
735skip_gserver_check:
706 of_node_put(np); 736 of_node_put(np);
707 737
708 if (firmware_has_feature(FW_FEATURE_LPAR)) 738 if (firmware_has_feature(FW_FEATURE_LPAR))
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 91f052d8cce0..6cc34597a620 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -5,14 +5,13 @@ endif
5obj-$(CONFIG_MPIC) += mpic.o 5obj-$(CONFIG_MPIC) += mpic.o
6obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o 6obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o
7obj-$(CONFIG_PPC_MPC106) += grackle.o 7obj-$(CONFIG_PPC_MPC106) += grackle.o
8obj-$(CONFIG_BOOKE) += dcr.o 8obj-$(CONFIG_PPC_DCR) += dcr.o dcr-low.o
9obj-$(CONFIG_40x) += dcr.o
10obj-$(CONFIG_U3_DART) += dart_iommu.o 9obj-$(CONFIG_U3_DART) += dart_iommu.o
11obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o 10obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o
12obj-$(CONFIG_FSL_SOC) += fsl_soc.o 11obj-$(CONFIG_FSL_SOC) += fsl_soc.o
13obj-$(CONFIG_PPC_TODC) += todc.o
14obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o 12obj-$(CONFIG_TSI108_BRIDGE) += tsi108_pci.o tsi108_dev.o
15obj-$(CONFIG_QUICC_ENGINE) += qe_lib/ 13obj-$(CONFIG_QUICC_ENGINE) += qe_lib/
14obj-$(CONFIG_MTD) += rom.o
16 15
17ifeq ($(CONFIG_PPC_MERGE),y) 16ifeq ($(CONFIG_PPC_MERGE),y)
18obj-$(CONFIG_PPC_I8259) += i8259.o 17obj-$(CONFIG_PPC_I8259) += i8259.o
diff --git a/arch/powerpc/sysdev/dart_iommu.c b/arch/powerpc/sysdev/dart_iommu.c
index 572b7846cc77..1488535b0e13 100644
--- a/arch/powerpc/sysdev/dart_iommu.c
+++ b/arch/powerpc/sysdev/dart_iommu.c
@@ -48,9 +48,6 @@
48 48
49#include "dart.h" 49#include "dart.h"
50 50
51extern int iommu_is_off;
52extern int iommu_force_on;
53
54/* Physical base address and size of the DART table */ 51/* Physical base address and size of the DART table */
55unsigned long dart_tablebase; /* exported to htab_initialize */ 52unsigned long dart_tablebase; /* exported to htab_initialize */
56static unsigned long dart_tablesize; 53static unsigned long dart_tablesize;
@@ -289,24 +286,15 @@ static void iommu_table_dart_setup(void)
289 set_bit(iommu_table_dart.it_size - 1, iommu_table_dart.it_map); 286 set_bit(iommu_table_dart.it_size - 1, iommu_table_dart.it_map);
290} 287}
291 288
292static void iommu_dev_setup_dart(struct pci_dev *dev) 289static void pci_dma_dev_setup_dart(struct pci_dev *dev)
293{ 290{
294 struct device_node *dn;
295
296 /* We only have one iommu table on the mac for now, which makes 291 /* We only have one iommu table on the mac for now, which makes
297 * things simple. Setup all PCI devices to point to this table 292 * things simple. Setup all PCI devices to point to this table
298 *
299 * We must use pci_device_to_OF_node() to make sure that
300 * we get the real "final" pointer to the device in the
301 * pci_dev sysdata and not the temporary PHB one
302 */ 293 */
303 dn = pci_device_to_OF_node(dev); 294 dev->dev.archdata.dma_data = &iommu_table_dart;
304
305 if (dn)
306 PCI_DN(dn)->iommu_table = &iommu_table_dart;
307} 295}
308 296
309static void iommu_bus_setup_dart(struct pci_bus *bus) 297static void pci_dma_bus_setup_dart(struct pci_bus *bus)
310{ 298{
311 struct device_node *dn; 299 struct device_node *dn;
312 300
@@ -321,9 +309,6 @@ static void iommu_bus_setup_dart(struct pci_bus *bus)
321 PCI_DN(dn)->iommu_table = &iommu_table_dart; 309 PCI_DN(dn)->iommu_table = &iommu_table_dart;
322} 310}
323 311
324static void iommu_dev_setup_null(struct pci_dev *dev) { }
325static void iommu_bus_setup_null(struct pci_bus *bus) { }
326
327void iommu_init_early_dart(void) 312void iommu_init_early_dart(void)
328{ 313{
329 struct device_node *dn; 314 struct device_node *dn;
@@ -344,22 +329,21 @@ void iommu_init_early_dart(void)
344 329
345 /* Initialize the DART HW */ 330 /* Initialize the DART HW */
346 if (dart_init(dn) == 0) { 331 if (dart_init(dn) == 0) {
347 ppc_md.iommu_dev_setup = iommu_dev_setup_dart; 332 ppc_md.pci_dma_dev_setup = pci_dma_dev_setup_dart;
348 ppc_md.iommu_bus_setup = iommu_bus_setup_dart; 333 ppc_md.pci_dma_bus_setup = pci_dma_bus_setup_dart;
349 334
350 /* Setup pci_dma ops */ 335 /* Setup pci_dma ops */
351 pci_iommu_init(); 336 pci_dma_ops = &dma_iommu_ops;
352
353 return; 337 return;
354 } 338 }
355 339
356 bail: 340 bail:
357 /* If init failed, use direct iommu and null setup functions */ 341 /* If init failed, use direct iommu and null setup functions */
358 ppc_md.iommu_dev_setup = iommu_dev_setup_null; 342 ppc_md.pci_dma_dev_setup = NULL;
359 ppc_md.iommu_bus_setup = iommu_bus_setup_null; 343 ppc_md.pci_dma_bus_setup = NULL;
360 344
361 /* Setup pci_dma ops */ 345 /* Setup pci_dma ops */
362 pci_direct_iommu_init(); 346 pci_dma_ops = &dma_direct_ops;
363} 347}
364 348
365 349
diff --git a/arch/powerpc/sysdev/dcr-low.S b/arch/powerpc/sysdev/dcr-low.S
new file mode 100644
index 000000000000..2078f39e2f17
--- /dev/null
+++ b/arch/powerpc/sysdev/dcr-low.S
@@ -0,0 +1,39 @@
1/*
2 * "Indirect" DCR access
3 *
4 * Copyright (c) 2004 Eugene Surovegin <ebs@ebshome.net>
5 *
6 * This program is free software; you can redistribute it and/or modify it
7 * under the terms of the GNU General Public License as published by the
8 * Free Software Foundation; either version 2 of the License, or (at your
9 * option) any later version.
10 */
11
12#include <asm/ppc_asm.h>
13#include <asm/processor.h>
14
15#define DCR_ACCESS_PROLOG(table) \
16 rlwinm r3,r3,4,18,27; \
17 lis r5,table@h; \
18 ori r5,r5,table@l; \
19 add r3,r3,r5; \
20 mtctr r3; \
21 bctr
22
23_GLOBAL(__mfdcr)
24 DCR_ACCESS_PROLOG(__mfdcr_table)
25
26_GLOBAL(__mtdcr)
27 DCR_ACCESS_PROLOG(__mtdcr_table)
28
29__mfdcr_table:
30 mfdcr r3,0; blr
31__mtdcr_table:
32 mtdcr 0,r4; blr
33
34dcr = 1
35 .rept 1023
36 mfdcr r3,dcr; blr
37 mtdcr dcr,r4; blr
38 dcr = dcr + 1
39 .endr
diff --git a/arch/powerpc/sysdev/dcr.c b/arch/powerpc/sysdev/dcr.c
new file mode 100644
index 000000000000..dffeeaeca1d9
--- /dev/null
+++ b/arch/powerpc/sysdev/dcr.c
@@ -0,0 +1,137 @@
1/*
2 * (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp.
3 * <benh@kernel.crashing.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#undef DEBUG
21
22#include <linux/kernel.h>
23#include <asm/prom.h>
24#include <asm/dcr.h>
25
26unsigned int dcr_resource_start(struct device_node *np, unsigned int index)
27{
28 unsigned int ds;
29 const u32 *dr = get_property(np, "dcr-reg", &ds);
30
31 if (dr == NULL || ds & 1 || index >= (ds / 8))
32 return 0;
33
34 return dr[index * 2];
35}
36
37unsigned int dcr_resource_len(struct device_node *np, unsigned int index)
38{
39 unsigned int ds;
40 const u32 *dr = get_property(np, "dcr-reg", &ds);
41
42 if (dr == NULL || ds & 1 || index >= (ds / 8))
43 return 0;
44
45 return dr[index * 2 + 1];
46}
47
48#ifndef CONFIG_PPC_DCR_NATIVE
49
50static struct device_node * find_dcr_parent(struct device_node * node)
51{
52 struct device_node *par, *tmp;
53 const u32 *p;
54
55 for (par = of_node_get(node); par;) {
56 if (get_property(par, "dcr-controller", NULL))
57 break;
58 p = get_property(par, "dcr-parent", NULL);
59 tmp = par;
60 if (p == NULL)
61 par = of_get_parent(par);
62 else
63 par = of_find_node_by_phandle(*p);
64 of_node_put(tmp);
65 }
66 return par;
67}
68
69u64 of_translate_dcr_address(struct device_node *dev,
70 unsigned int dcr_n,
71 unsigned int *out_stride)
72{
73 struct device_node *dp;
74 const u32 *p;
75 unsigned int stride;
76 u64 ret;
77
78 dp = find_dcr_parent(dev);
79 if (dp == NULL)
80 return OF_BAD_ADDR;
81
82 /* Stride is not properly defined yet, default to 0x10 for Axon */
83 p = get_property(dp, "dcr-mmio-stride", NULL);
84 stride = (p == NULL) ? 0x10 : *p;
85
86 /* XXX FIXME: Which property name is to use of the 2 following ? */
87 p = get_property(dp, "dcr-mmio-range", NULL);
88 if (p == NULL)
89 p = get_property(dp, "dcr-mmio-space", NULL);
90 if (p == NULL)
91 return OF_BAD_ADDR;
92
93 /* Maybe could do some better range checking here */
94 ret = of_translate_address(dp, p);
95 if (ret != OF_BAD_ADDR)
96 ret += (u64)(stride) * (u64)dcr_n;
97 if (out_stride)
98 *out_stride = stride;
99 return ret;
100}
101
102dcr_host_t dcr_map(struct device_node *dev, unsigned int dcr_n,
103 unsigned int dcr_c)
104{
105 dcr_host_t ret = { .token = NULL, .stride = 0 };
106 u64 addr;
107
108 pr_debug("dcr_map(%s, 0x%x, 0x%x)\n",
109 dev->full_name, dcr_n, dcr_c);
110
111 addr = of_translate_dcr_address(dev, dcr_n, &ret.stride);
112 pr_debug("translates to addr: 0x%lx, stride: 0x%x\n",
113 addr, ret.stride);
114 if (addr == OF_BAD_ADDR)
115 return ret;
116 pr_debug("mapping 0x%x bytes\n", dcr_c * ret.stride);
117 ret.token = ioremap(addr, dcr_c * ret.stride);
118 if (ret.token == NULL)
119 return ret;
120 pr_debug("mapped at 0x%p -> base is 0x%p\n",
121 ret.token, ret.token - dcr_n * ret.stride);
122 ret.token -= dcr_n * ret.stride;
123 return ret;
124}
125
126void dcr_unmap(dcr_host_t host, unsigned int dcr_n, unsigned int dcr_c)
127{
128 dcr_host_t h = host;
129
130 if (h.token == NULL)
131 return;
132 h.token -= dcr_n * h.stride;
133 iounmap(h.token);
134 h.token = NULL;
135}
136
137#endif /* !defined(CONFIG_PPC_DCR_NATIVE) */
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index dbe92ae20333..ad31e56e892b 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -22,6 +22,7 @@
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/device.h> 23#include <linux/device.h>
24#include <linux/platform_device.h> 24#include <linux/platform_device.h>
25#include <linux/phy.h>
25#include <linux/fsl_devices.h> 26#include <linux/fsl_devices.h>
26#include <linux/fs_enet_pd.h> 27#include <linux/fs_enet_pd.h>
27#include <linux/fs_uart_pd.h> 28#include <linux/fs_uart_pd.h>
@@ -146,7 +147,7 @@ static int __init gfar_mdio_of_init(void)
146 } 147 }
147 148
148 for (k = 0; k < 32; k++) 149 for (k = 0; k < 32; k++)
149 mdio_data.irq[k] = -1; 150 mdio_data.irq[k] = PHY_POLL;
150 151
151 while ((child = of_get_next_child(np, child)) != NULL) { 152 while ((child = of_get_next_child(np, child)) != NULL) {
152 int irq = irq_of_parse_and_map(child, 0); 153 int irq = irq_of_parse_and_map(child, 0);
@@ -177,6 +178,7 @@ static const char *gfar_tx_intr = "tx";
177static const char *gfar_rx_intr = "rx"; 178static const char *gfar_rx_intr = "rx";
178static const char *gfar_err_intr = "error"; 179static const char *gfar_err_intr = "error";
179 180
181
180static int __init gfar_of_init(void) 182static int __init gfar_of_init(void)
181{ 183{
182 struct device_node *np; 184 struct device_node *np;
@@ -204,8 +206,7 @@ static int __init gfar_of_init(void)
204 if (ret) 206 if (ret)
205 goto err; 207 goto err;
206 208
207 r[1].start = r[1].end = irq_of_parse_and_map(np, 0); 209 of_irq_to_resource(np, 0, &r[1]);
208 r[1].flags = IORESOURCE_IRQ;
209 210
210 model = get_property(np, "model", NULL); 211 model = get_property(np, "model", NULL);
211 212
@@ -214,12 +215,10 @@ static int __init gfar_of_init(void)
214 r[1].name = gfar_tx_intr; 215 r[1].name = gfar_tx_intr;
215 216
216 r[2].name = gfar_rx_intr; 217 r[2].name = gfar_rx_intr;
217 r[2].start = r[2].end = irq_of_parse_and_map(np, 1); 218 of_irq_to_resource(np, 1, &r[2]);
218 r[2].flags = IORESOURCE_IRQ;
219 219
220 r[3].name = gfar_err_intr; 220 r[3].name = gfar_err_intr;
221 r[3].start = r[3].end = irq_of_parse_and_map(np, 2); 221 of_irq_to_resource(np, 2, &r[3]);
222 r[3].flags = IORESOURCE_IRQ;
223 222
224 n_res += 2; 223 n_res += 2;
225 } 224 }
@@ -323,8 +322,7 @@ static int __init fsl_i2c_of_init(void)
323 if (ret) 322 if (ret)
324 goto err; 323 goto err;
325 324
326 r[1].start = r[1].end = irq_of_parse_and_map(np, 0); 325 of_irq_to_resource(np, 0, &r[1]);
327 r[1].flags = IORESOURCE_IRQ;
328 326
329 i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2); 327 i2c_dev = platform_device_register_simple("fsl-i2c", i, r, 2);
330 if (IS_ERR(i2c_dev)) { 328 if (IS_ERR(i2c_dev)) {
@@ -459,8 +457,7 @@ static int __init fsl_usb_of_init(void)
459 if (ret) 457 if (ret)
460 goto err; 458 goto err;
461 459
462 r[1].start = r[1].end = irq_of_parse_and_map(np, 0); 460 of_irq_to_resource(np, 0, &r[1]);
463 r[1].flags = IORESOURCE_IRQ;
464 461
465 usb_dev_mph = 462 usb_dev_mph =
466 platform_device_register_simple("fsl-ehci", i, r, 2); 463 platform_device_register_simple("fsl-ehci", i, r, 2);
@@ -507,8 +504,7 @@ static int __init fsl_usb_of_init(void)
507 if (ret) 504 if (ret)
508 goto unreg_mph; 505 goto unreg_mph;
509 506
510 r[1].start = r[1].end = irq_of_parse_and_map(np, 0); 507 of_irq_to_resource(np, 0, &r[1]);
511 r[1].flags = IORESOURCE_IRQ;
512 508
513 usb_dev_dr = 509 usb_dev_dr =
514 platform_device_register_simple("fsl-ehci", i, r, 2); 510 platform_device_register_simple("fsl-ehci", i, r, 2);
@@ -591,8 +587,7 @@ static int __init fs_enet_of_init(void)
591 r[2].name = fcc_regs_c; 587 r[2].name = fcc_regs_c;
592 fs_enet_data.fcc_regs_c = r[2].start; 588 fs_enet_data.fcc_regs_c = r[2].start;
593 589
594 r[3].start = r[3].end = irq_of_parse_and_map(np, 0); 590 of_irq_to_resource(np, 0, &r[3]);
595 r[3].flags = IORESOURCE_IRQ;
596 591
597 fs_enet_dev = 592 fs_enet_dev =
598 platform_device_register_simple("fsl-cpm-fcc", i, &r[0], 4); 593 platform_device_register_simple("fsl-cpm-fcc", i, &r[0], 4);
@@ -754,8 +749,7 @@ static int __init cpm_uart_of_init(void)
754 goto err; 749 goto err;
755 r[1].name = scc_pram; 750 r[1].name = scc_pram;
756 751
757 r[2].start = r[2].end = irq_of_parse_and_map(np, 0); 752 of_irq_to_resource(np, 0, &r[2]);
758 r[2].flags = IORESOURCE_IRQ;
759 753
760 cpm_uart_dev = 754 cpm_uart_dev =
761 platform_device_register_simple("fsl-cpm-scc:uart", i, &r[0], 3); 755 platform_device_register_simple("fsl-cpm-scc:uart", i, &r[0], 3);
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index ba4833f57d47..411480d5c626 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -147,33 +147,51 @@ static u32 mpic_infos[][MPIC_IDX_END] = {
147 */ 147 */
148 148
149 149
150static inline u32 _mpic_read(unsigned int be, volatile u32 __iomem *base, 150static inline u32 _mpic_read(enum mpic_reg_type type,
151 unsigned int reg) 151 struct mpic_reg_bank *rb,
152 unsigned int reg)
152{ 153{
153 if (be) 154 switch(type) {
154 return in_be32(base + (reg >> 2)); 155#ifdef CONFIG_PPC_DCR
155 else 156 case mpic_access_dcr:
156 return in_le32(base + (reg >> 2)); 157 return dcr_read(rb->dhost,
158 rb->dbase + reg + rb->doff);
159#endif
160 case mpic_access_mmio_be:
161 return in_be32(rb->base + (reg >> 2));
162 case mpic_access_mmio_le:
163 default:
164 return in_le32(rb->base + (reg >> 2));
165 }
157} 166}
158 167
159static inline void _mpic_write(unsigned int be, volatile u32 __iomem *base, 168static inline void _mpic_write(enum mpic_reg_type type,
160 unsigned int reg, u32 value) 169 struct mpic_reg_bank *rb,
170 unsigned int reg, u32 value)
161{ 171{
162 if (be) 172 switch(type) {
163 out_be32(base + (reg >> 2), value); 173#ifdef CONFIG_PPC_DCR
164 else 174 case mpic_access_dcr:
165 out_le32(base + (reg >> 2), value); 175 return dcr_write(rb->dhost,
176 rb->dbase + reg + rb->doff, value);
177#endif
178 case mpic_access_mmio_be:
179 return out_be32(rb->base + (reg >> 2), value);
180 case mpic_access_mmio_le:
181 default:
182 return out_le32(rb->base + (reg >> 2), value);
183 }
166} 184}
167 185
168static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi) 186static inline u32 _mpic_ipi_read(struct mpic *mpic, unsigned int ipi)
169{ 187{
170 unsigned int be = (mpic->flags & MPIC_BIG_ENDIAN) != 0; 188 enum mpic_reg_type type = mpic->reg_type;
171 unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) + 189 unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) +
172 (ipi * MPIC_INFO(GREG_IPI_STRIDE)); 190 (ipi * MPIC_INFO(GREG_IPI_STRIDE));
173 191
174 if (mpic->flags & MPIC_BROKEN_IPI) 192 if ((mpic->flags & MPIC_BROKEN_IPI) && type == mpic_access_mmio_le)
175 be = !be; 193 type = mpic_access_mmio_be;
176 return _mpic_read(be, mpic->gregs, offset); 194 return _mpic_read(type, &mpic->gregs, offset);
177} 195}
178 196
179static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 value) 197static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 value)
@@ -181,7 +199,7 @@ static inline void _mpic_ipi_write(struct mpic *mpic, unsigned int ipi, u32 valu
181 unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) + 199 unsigned int offset = MPIC_INFO(GREG_IPI_VECTOR_PRI_0) +
182 (ipi * MPIC_INFO(GREG_IPI_STRIDE)); 200 (ipi * MPIC_INFO(GREG_IPI_STRIDE));
183 201
184 _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->gregs, offset, value); 202 _mpic_write(mpic->reg_type, &mpic->gregs, offset, value);
185} 203}
186 204
187static inline u32 _mpic_cpu_read(struct mpic *mpic, unsigned int reg) 205static inline u32 _mpic_cpu_read(struct mpic *mpic, unsigned int reg)
@@ -190,8 +208,7 @@ static inline u32 _mpic_cpu_read(struct mpic *mpic, unsigned int reg)
190 208
191 if (mpic->flags & MPIC_PRIMARY) 209 if (mpic->flags & MPIC_PRIMARY)
192 cpu = hard_smp_processor_id(); 210 cpu = hard_smp_processor_id();
193 return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, 211 return _mpic_read(mpic->reg_type, &mpic->cpuregs[cpu], reg);
194 mpic->cpuregs[cpu], reg);
195} 212}
196 213
197static inline void _mpic_cpu_write(struct mpic *mpic, unsigned int reg, u32 value) 214static inline void _mpic_cpu_write(struct mpic *mpic, unsigned int reg, u32 value)
@@ -201,7 +218,7 @@ static inline void _mpic_cpu_write(struct mpic *mpic, unsigned int reg, u32 valu
201 if (mpic->flags & MPIC_PRIMARY) 218 if (mpic->flags & MPIC_PRIMARY)
202 cpu = hard_smp_processor_id(); 219 cpu = hard_smp_processor_id();
203 220
204 _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->cpuregs[cpu], reg, value); 221 _mpic_write(mpic->reg_type, &mpic->cpuregs[cpu], reg, value);
205} 222}
206 223
207static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigned int reg) 224static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigned int reg)
@@ -209,7 +226,7 @@ static inline u32 _mpic_irq_read(struct mpic *mpic, unsigned int src_no, unsigne
209 unsigned int isu = src_no >> mpic->isu_shift; 226 unsigned int isu = src_no >> mpic->isu_shift;
210 unsigned int idx = src_no & mpic->isu_mask; 227 unsigned int idx = src_no & mpic->isu_mask;
211 228
212 return _mpic_read(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu], 229 return _mpic_read(mpic->reg_type, &mpic->isus[isu],
213 reg + (idx * MPIC_INFO(IRQ_STRIDE))); 230 reg + (idx * MPIC_INFO(IRQ_STRIDE)));
214} 231}
215 232
@@ -219,12 +236,12 @@ static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
219 unsigned int isu = src_no >> mpic->isu_shift; 236 unsigned int isu = src_no >> mpic->isu_shift;
220 unsigned int idx = src_no & mpic->isu_mask; 237 unsigned int idx = src_no & mpic->isu_mask;
221 238
222 _mpic_write(mpic->flags & MPIC_BIG_ENDIAN, mpic->isus[isu], 239 _mpic_write(mpic->reg_type, &mpic->isus[isu],
223 reg + (idx * MPIC_INFO(IRQ_STRIDE)), value); 240 reg + (idx * MPIC_INFO(IRQ_STRIDE)), value);
224} 241}
225 242
226#define mpic_read(b,r) _mpic_read(mpic->flags & MPIC_BIG_ENDIAN,(b),(r)) 243#define mpic_read(b,r) _mpic_read(mpic->reg_type,&(b),(r))
227#define mpic_write(b,r,v) _mpic_write(mpic->flags & MPIC_BIG_ENDIAN,(b),(r),(v)) 244#define mpic_write(b,r,v) _mpic_write(mpic->reg_type,&(b),(r),(v))
228#define mpic_ipi_read(i) _mpic_ipi_read(mpic,(i)) 245#define mpic_ipi_read(i) _mpic_ipi_read(mpic,(i))
229#define mpic_ipi_write(i,v) _mpic_ipi_write(mpic,(i),(v)) 246#define mpic_ipi_write(i,v) _mpic_ipi_write(mpic,(i),(v))
230#define mpic_cpu_read(i) _mpic_cpu_read(mpic,(i)) 247#define mpic_cpu_read(i) _mpic_cpu_read(mpic,(i))
@@ -238,6 +255,38 @@ static inline void _mpic_irq_write(struct mpic *mpic, unsigned int src_no,
238 */ 255 */
239 256
240 257
258static void _mpic_map_mmio(struct mpic *mpic, unsigned long phys_addr,
259 struct mpic_reg_bank *rb, unsigned int offset,
260 unsigned int size)
261{
262 rb->base = ioremap(phys_addr + offset, size);
263 BUG_ON(rb->base == NULL);
264}
265
266#ifdef CONFIG_PPC_DCR
267static void _mpic_map_dcr(struct mpic *mpic, struct mpic_reg_bank *rb,
268 unsigned int offset, unsigned int size)
269{
270 rb->dbase = mpic->dcr_base;
271 rb->doff = offset;
272 rb->dhost = dcr_map(mpic->of_node, rb->dbase + rb->doff, size);
273 BUG_ON(!DCR_MAP_OK(rb->dhost));
274}
275
276static inline void mpic_map(struct mpic *mpic, unsigned long phys_addr,
277 struct mpic_reg_bank *rb, unsigned int offset,
278 unsigned int size)
279{
280 if (mpic->flags & MPIC_USES_DCR)
281 _mpic_map_dcr(mpic, rb, offset, size);
282 else
283 _mpic_map_mmio(mpic, phys_addr, rb, offset, size);
284}
285#else /* CONFIG_PPC_DCR */
286#define mpic_map(m,p,b,o,s) _mpic_map_mmio(m,p,b,o,s)
287#endif /* !CONFIG_PPC_DCR */
288
289
241 290
242/* Check if we have one of those nice broken MPICs with a flipped endian on 291/* Check if we have one of those nice broken MPICs with a flipped endian on
243 * reads from IPI registers 292 * reads from IPI registers
@@ -845,7 +894,7 @@ static struct irq_host_ops mpic_host_ops = {
845 */ 894 */
846 895
847struct mpic * __init mpic_alloc(struct device_node *node, 896struct mpic * __init mpic_alloc(struct device_node *node,
848 unsigned long phys_addr, 897 phys_addr_t phys_addr,
849 unsigned int flags, 898 unsigned int flags,
850 unsigned int isu_size, 899 unsigned int isu_size,
851 unsigned int irq_count, 900 unsigned int irq_count,
@@ -855,6 +904,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
855 u32 reg; 904 u32 reg;
856 const char *vers; 905 const char *vers;
857 int i; 906 int i;
907 u64 paddr = phys_addr;
858 908
859 mpic = alloc_bootmem(sizeof(struct mpic)); 909 mpic = alloc_bootmem(sizeof(struct mpic));
860 if (mpic == NULL) 910 if (mpic == NULL)
@@ -883,6 +933,7 @@ struct mpic * __init mpic_alloc(struct device_node *node,
883 if (flags & MPIC_PRIMARY) 933 if (flags & MPIC_PRIMARY)
884 mpic->hc_ht_irq.set_affinity = mpic_set_affinity; 934 mpic->hc_ht_irq.set_affinity = mpic_set_affinity;
885#endif /* CONFIG_MPIC_BROKEN_U3 */ 935#endif /* CONFIG_MPIC_BROKEN_U3 */
936
886#ifdef CONFIG_SMP 937#ifdef CONFIG_SMP
887 mpic->hc_ipi = mpic_ipi_chip; 938 mpic->hc_ipi = mpic_ipi_chip;
888 mpic->hc_ipi.typename = name; 939 mpic->hc_ipi.typename = name;
@@ -893,15 +944,52 @@ struct mpic * __init mpic_alloc(struct device_node *node,
893 mpic->irq_count = irq_count; 944 mpic->irq_count = irq_count;
894 mpic->num_sources = 0; /* so far */ 945 mpic->num_sources = 0; /* so far */
895 946
947 /* Check for "big-endian" in device-tree */
948 if (node && get_property(node, "big-endian", NULL) != NULL)
949 mpic->flags |= MPIC_BIG_ENDIAN;
950
951
896#ifdef CONFIG_MPIC_WEIRD 952#ifdef CONFIG_MPIC_WEIRD
897 mpic->hw_set = mpic_infos[MPIC_GET_REGSET(flags)]; 953 mpic->hw_set = mpic_infos[MPIC_GET_REGSET(flags)];
898#endif 954#endif
899 955
956 /* default register type */
957 mpic->reg_type = (flags & MPIC_BIG_ENDIAN) ?
958 mpic_access_mmio_be : mpic_access_mmio_le;
959
960 /* If no physical address is passed in, a device-node is mandatory */
961 BUG_ON(paddr == 0 && node == NULL);
962
963 /* If no physical address passed in, check if it's dcr based */
964 if (paddr == 0 && get_property(node, "dcr-reg", NULL) != NULL)
965 mpic->flags |= MPIC_USES_DCR;
966
967#ifdef CONFIG_PPC_DCR
968 if (mpic->flags & MPIC_USES_DCR) {
969 const u32 *dbasep;
970 dbasep = get_property(node, "dcr-reg", NULL);
971 BUG_ON(dbasep == NULL);
972 mpic->dcr_base = *dbasep;
973 mpic->reg_type = mpic_access_dcr;
974 }
975#else
976 BUG_ON (mpic->flags & MPIC_USES_DCR);
977#endif /* CONFIG_PPC_DCR */
978
979 /* If the MPIC is not DCR based, and no physical address was passed
980 * in, try to obtain one
981 */
982 if (paddr == 0 && !(mpic->flags & MPIC_USES_DCR)) {
983 const u32 *reg;
984 reg = get_property(node, "reg", NULL);
985 BUG_ON(reg == NULL);
986 paddr = of_translate_address(node, reg);
987 BUG_ON(paddr == OF_BAD_ADDR);
988 }
989
900 /* Map the global registers */ 990 /* Map the global registers */
901 mpic->gregs = ioremap(phys_addr + MPIC_INFO(GREG_BASE), 0x1000); 991 mpic_map(mpic, paddr, &mpic->gregs, MPIC_INFO(GREG_BASE), 0x1000);
902 mpic->tmregs = mpic->gregs + 992 mpic_map(mpic, paddr, &mpic->tmregs, MPIC_INFO(TIMER_BASE), 0x1000);
903 ((MPIC_INFO(TIMER_BASE) - MPIC_INFO(GREG_BASE)) >> 2);
904 BUG_ON(mpic->gregs == NULL);
905 993
906 /* Reset */ 994 /* Reset */
907 if (flags & MPIC_WANTS_RESET) { 995 if (flags & MPIC_WANTS_RESET) {
@@ -926,17 +1014,16 @@ struct mpic * __init mpic_alloc(struct device_node *node,
926 1014
927 /* Map the per-CPU registers */ 1015 /* Map the per-CPU registers */
928 for (i = 0; i < mpic->num_cpus; i++) { 1016 for (i = 0; i < mpic->num_cpus; i++) {
929 mpic->cpuregs[i] = ioremap(phys_addr + MPIC_INFO(CPU_BASE) + 1017 mpic_map(mpic, paddr, &mpic->cpuregs[i],
930 i * MPIC_INFO(CPU_STRIDE), 0x1000); 1018 MPIC_INFO(CPU_BASE) + i * MPIC_INFO(CPU_STRIDE),
931 BUG_ON(mpic->cpuregs[i] == NULL); 1019 0x1000);
932 } 1020 }
933 1021
934 /* Initialize main ISU if none provided */ 1022 /* Initialize main ISU if none provided */
935 if (mpic->isu_size == 0) { 1023 if (mpic->isu_size == 0) {
936 mpic->isu_size = mpic->num_sources; 1024 mpic->isu_size = mpic->num_sources;
937 mpic->isus[0] = ioremap(phys_addr + MPIC_INFO(IRQ_BASE), 1025 mpic_map(mpic, paddr, &mpic->isus[0],
938 MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); 1026 MPIC_INFO(IRQ_BASE), MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
939 BUG_ON(mpic->isus[0] == NULL);
940 } 1027 }
941 mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1); 1028 mpic->isu_shift = 1 + __ilog2(mpic->isu_size - 1);
942 mpic->isu_mask = (1 << mpic->isu_shift) - 1; 1029 mpic->isu_mask = (1 << mpic->isu_shift) - 1;
@@ -956,10 +1043,11 @@ struct mpic * __init mpic_alloc(struct device_node *node,
956 vers = "<unknown>"; 1043 vers = "<unknown>";
957 break; 1044 break;
958 } 1045 }
959 printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %lx, max %d CPUs\n", 1046 printk(KERN_INFO "mpic: Setting up MPIC \"%s\" version %s at %llx,"
960 name, vers, phys_addr, mpic->num_cpus); 1047 " max %d CPUs\n",
961 printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n", mpic->isu_size, 1048 name, vers, (unsigned long long)paddr, mpic->num_cpus);
962 mpic->isu_shift, mpic->isu_mask); 1049 printk(KERN_INFO "mpic: ISU size: %d, shift: %d, mask: %x\n",
1050 mpic->isu_size, mpic->isu_shift, mpic->isu_mask);
963 1051
964 mpic->next = mpics; 1052 mpic->next = mpics;
965 mpics = mpic; 1053 mpics = mpic;
@@ -973,14 +1061,14 @@ struct mpic * __init mpic_alloc(struct device_node *node,
973} 1061}
974 1062
975void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, 1063void __init mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
976 unsigned long phys_addr) 1064 phys_addr_t paddr)
977{ 1065{
978 unsigned int isu_first = isu_num * mpic->isu_size; 1066 unsigned int isu_first = isu_num * mpic->isu_size;
979 1067
980 BUG_ON(isu_num >= MPIC_MAX_ISU); 1068 BUG_ON(isu_num >= MPIC_MAX_ISU);
981 1069
982 mpic->isus[isu_num] = ioremap(phys_addr, 1070 mpic_map(mpic, paddr, &mpic->isus[isu_num], 0,
983 MPIC_INFO(IRQ_STRIDE) * mpic->isu_size); 1071 MPIC_INFO(IRQ_STRIDE) * mpic->isu_size);
984 if ((isu_first + mpic->isu_size) > mpic->num_sources) 1072 if ((isu_first + mpic->isu_size) > mpic->num_sources)
985 mpic->num_sources = isu_first + mpic->isu_size; 1073 mpic->num_sources = isu_first + mpic->isu_size;
986} 1074}
diff --git a/arch/powerpc/sysdev/qe_lib/qe.c b/arch/powerpc/sysdev/qe_lib/qe.c
index e4223226a7a8..e3d71e083f35 100644
--- a/arch/powerpc/sysdev/qe_lib/qe.c
+++ b/arch/powerpc/sysdev/qe_lib/qe.c
@@ -174,8 +174,7 @@ void qe_setbrg(u32 brg, u32 rate)
174 u32 divisor, tempval; 174 u32 divisor, tempval;
175 int div16 = 0; 175 int div16 = 0;
176 176
177 bp = &qe_immr->brg.brgc1; 177 bp = &qe_immr->brg.brgc[brg];
178 bp += brg;
179 178
180 divisor = (get_brg_clk() / rate); 179 divisor = (get_brg_clk() / rate);
181 if (divisor > QE_BRGC_DIVISOR_MAX + 1) { 180 if (divisor > QE_BRGC_DIVISOR_MAX + 1) {
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_fast.c b/arch/powerpc/sysdev/qe_lib/ucc_fast.c
index 75fa3104a43a..e657559bea93 100644
--- a/arch/powerpc/sysdev/qe_lib/ucc_fast.c
+++ b/arch/powerpc/sysdev/qe_lib/ucc_fast.c
@@ -216,14 +216,12 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
216 return -EINVAL; 216 return -EINVAL;
217 } 217 }
218 218
219 uccf = (struct ucc_fast_private *) 219 uccf = kzalloc(sizeof(struct ucc_fast_private), GFP_KERNEL);
220 kmalloc(sizeof(struct ucc_fast_private), GFP_KERNEL);
221 if (!uccf) { 220 if (!uccf) {
222 uccf_err 221 uccf_err
223 ("ucc_fast_init: No memory for UCC slow data structure!"); 222 ("ucc_fast_init: No memory for UCC slow data structure!");
224 return -ENOMEM; 223 return -ENOMEM;
225 } 224 }
226 memset(uccf, 0, sizeof(struct ucc_fast_private));
227 225
228 /* Fill fast UCC structure */ 226 /* Fill fast UCC structure */
229 uccf->uf_info = uf_info; 227 uccf->uf_info = uf_info;
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_slow.c b/arch/powerpc/sysdev/qe_lib/ucc_slow.c
index a49da6b73ecf..47b56203f47e 100644
--- a/arch/powerpc/sysdev/qe_lib/ucc_slow.c
+++ b/arch/powerpc/sysdev/qe_lib/ucc_slow.c
@@ -168,14 +168,12 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
168 return -EINVAL; 168 return -EINVAL;
169 } 169 }
170 170
171 uccs = (struct ucc_slow_private *) 171 uccs = kzalloc(sizeof(struct ucc_slow_private), GFP_KERNEL);
172 kmalloc(sizeof(struct ucc_slow_private), GFP_KERNEL);
173 if (!uccs) { 172 if (!uccs) {
174 uccs_err 173 uccs_err
175 ("ucc_slow_init: No memory for UCC slow data structure!"); 174 ("ucc_slow_init: No memory for UCC slow data structure!");
176 return -ENOMEM; 175 return -ENOMEM;
177 } 176 }
178 memset(uccs, 0, sizeof(struct ucc_slow_private));
179 177
180 /* Fill slow UCC structure */ 178 /* Fill slow UCC structure */
181 uccs->us_info = us_info; 179 uccs->us_info = us_info;
diff --git a/arch/powerpc/sysdev/rom.c b/arch/powerpc/sysdev/rom.c
new file mode 100644
index 000000000000..bf5b3f10e6c6
--- /dev/null
+++ b/arch/powerpc/sysdev/rom.c
@@ -0,0 +1,31 @@
1/*
2 * ROM device registration
3 *
4 * (C) 2006 MontaVista Software, Inc. This file is licensed under
5 * the terms of the GNU General Public License version 2. This program
6 * is licensed "as is" without any warranty of any kind, whether express
7 * or implied.
8 */
9
10#include <linux/kernel.h>
11#include <asm/of_device.h>
12
13static int __init powerpc_flash_init(void)
14{
15 struct device_node *node = NULL;
16
17 /*
18 * Register all the devices which type is "rom"
19 */
20 while ((node = of_find_node_by_type(node, "rom")) != NULL) {
21 if (node->name == NULL) {
22 printk(KERN_WARNING "powerpc_flash_init: found 'rom' "
23 "device, but with no name, skipping...\n");
24 continue;
25 }
26 of_platform_device_create(node, node->name, NULL);
27 }
28 return 0;
29}
30
31arch_initcall(powerpc_flash_init);
diff --git a/arch/powerpc/sysdev/todc.c b/arch/powerpc/sysdev/todc.c
deleted file mode 100644
index 0a65980efb50..000000000000
--- a/arch/powerpc/sysdev/todc.c
+++ /dev/null
@@ -1,392 +0,0 @@
1/*
2 * Time of Day Clock support for the M48T35, M48T37, M48T59, and MC146818
3 * Real Time Clocks/Timekeepers.
4 *
5 * Author: Mark A. Greer <mgreer@mvista.com>
6 *
7 * 2001-2004 (c) MontaVista, Software, Inc. This file is licensed under
8 * the terms of the GNU General Public License version 2. This program
9 * is licensed "as is" without any warranty of any kind, whether express
10 * or implied.
11 */
12#include <linux/errno.h>
13#include <linux/init.h>
14#include <linux/kernel.h>
15#include <linux/time.h>
16#include <linux/timex.h>
17#include <linux/bcd.h>
18#include <linux/mc146818rtc.h>
19
20#include <asm/machdep.h>
21#include <asm/io.h>
22#include <asm/time.h>
23#include <asm/todc.h>
24
25/*
26 * Depending on the hardware on your board and your board design, the
27 * RTC/NVRAM may be accessed either directly (like normal memory) or via
28 * address/data registers. If your board uses the direct method, set
29 * 'nvram_data' to the base address of your nvram and leave 'nvram_as0' and
30 * 'nvram_as1' NULL. If your board uses address/data regs to access nvram,
31 * set 'nvram_as0' to the address of the lower byte, set 'nvram_as1' to the
32 * address of the upper byte (leave NULL if using mc146818), and set
33 * 'nvram_data' to the address of the 8-bit data register.
34 *
35 * Note: Even though the documentation for the various RTC chips say that it
36 * take up to a second before it starts updating once the 'R' bit is
37 * cleared, they always seem to update even though we bang on it many
38 * times a second. This is true, except for the Dallas Semi 1746/1747
39 * (possibly others). Those chips seem to have a real problem whenever
40 * we set the 'R' bit before reading them, they basically stop counting.
41 * --MAG
42 */
43
44/*
45 * 'todc_info' should be initialized in your *_setup.c file to
46 * point to a fully initialized 'todc_info_t' structure.
47 * This structure holds all the register offsets for your particular
48 * TODC/RTC chip.
49 * TODC_ALLOC()/TODC_INIT() will allocate and initialize this table for you.
50 */
51
52#ifdef RTC_FREQ_SELECT
53#undef RTC_FREQ_SELECT
54#define RTC_FREQ_SELECT control_b /* Register A */
55#endif
56
57#ifdef RTC_CONTROL
58#undef RTC_CONTROL
59#define RTC_CONTROL control_a /* Register B */
60#endif
61
62#ifdef RTC_INTR_FLAGS
63#undef RTC_INTR_FLAGS
64#define RTC_INTR_FLAGS watchdog /* Register C */
65#endif
66
67#ifdef RTC_VALID
68#undef RTC_VALID
69#define RTC_VALID interrupts /* Register D */
70#endif
71
72/* Access routines when RTC accessed directly (like normal memory) */
73u_char
74todc_direct_read_val(int addr)
75{
76 return readb((void __iomem *)(todc_info->nvram_data + addr));
77}
78
79void
80todc_direct_write_val(int addr, unsigned char val)
81{
82 writeb(val, (void __iomem *)(todc_info->nvram_data + addr));
83 return;
84}
85
86/* Access routines for accessing m48txx type chips via addr/data regs */
87u_char
88todc_m48txx_read_val(int addr)
89{
90 outb(addr, todc_info->nvram_as0);
91 outb(addr>>todc_info->as0_bits, todc_info->nvram_as1);
92 return inb(todc_info->nvram_data);
93}
94
95void
96todc_m48txx_write_val(int addr, unsigned char val)
97{
98 outb(addr, todc_info->nvram_as0);
99 outb(addr>>todc_info->as0_bits, todc_info->nvram_as1);
100 outb(val, todc_info->nvram_data);
101 return;
102}
103
104/* Access routines for accessing mc146818 type chips via addr/data regs */
105u_char
106todc_mc146818_read_val(int addr)
107{
108 outb_p(addr, todc_info->nvram_as0);
109 return inb_p(todc_info->nvram_data);
110}
111
112void
113todc_mc146818_write_val(int addr, unsigned char val)
114{
115 outb_p(addr, todc_info->nvram_as0);
116 outb_p(val, todc_info->nvram_data);
117}
118
119
120/*
121 * Routines to make RTC chips with NVRAM buried behind an addr/data pair
122 * have the NVRAM and clock regs appear at the same level.
123 * The NVRAM will appear to start at addr 0 and the clock regs will appear
124 * to start immediately after the NVRAM (actually, start at offset
125 * todc_info->nvram_size).
126 */
127static inline u_char
128todc_read_val(int addr)
129{
130 u_char val;
131
132 if (todc_info->sw_flags & TODC_FLAG_2_LEVEL_NVRAM) {
133 if (addr < todc_info->nvram_size) { /* NVRAM */
134 ppc_md.rtc_write_val(todc_info->nvram_addr_reg, addr);
135 val = ppc_md.rtc_read_val(todc_info->nvram_data_reg);
136 } else { /* Clock Reg */
137 addr -= todc_info->nvram_size;
138 val = ppc_md.rtc_read_val(addr);
139 }
140 } else
141 val = ppc_md.rtc_read_val(addr);
142
143 return val;
144}
145
146static inline void
147todc_write_val(int addr, u_char val)
148{
149 if (todc_info->sw_flags & TODC_FLAG_2_LEVEL_NVRAM) {
150 if (addr < todc_info->nvram_size) { /* NVRAM */
151 ppc_md.rtc_write_val(todc_info->nvram_addr_reg, addr);
152 ppc_md.rtc_write_val(todc_info->nvram_data_reg, val);
153 } else { /* Clock Reg */
154 addr -= todc_info->nvram_size;
155 ppc_md.rtc_write_val(addr, val);
156 }
157 } else
158 ppc_md.rtc_write_val(addr, val);
159}
160
161/*
162 * TODC routines
163 *
164 * There is some ugly stuff in that there are assumptions for the mc146818.
165 *
166 * Assumptions:
167 * - todc_info->control_a has the offset as mc146818 Register B reg
168 * - todc_info->control_b has the offset as mc146818 Register A reg
169 * - m48txx control reg's write enable or 'W' bit is same as
170 * mc146818 Register B 'SET' bit (i.e., 0x80)
171 *
172 * These assumptions were made to make the code simpler.
173 */
174long __init
175todc_time_init(void)
176{
177 u_char cntl_b;
178
179 if (!ppc_md.rtc_read_val)
180 ppc_md.rtc_read_val = ppc_md.nvram_read_val;
181 if (!ppc_md.rtc_write_val)
182 ppc_md.rtc_write_val = ppc_md.nvram_write_val;
183
184 cntl_b = todc_read_val(todc_info->control_b);
185
186 if (todc_info->rtc_type == TODC_TYPE_MC146818) {
187 if ((cntl_b & 0x70) != 0x20) {
188 printk(KERN_INFO "TODC real-time-clock was stopped."
189 " Now starting...");
190 cntl_b &= ~0x70;
191 cntl_b |= 0x20;
192 }
193
194 todc_write_val(todc_info->control_b, cntl_b);
195 } else if (todc_info->rtc_type == TODC_TYPE_DS17285) {
196 u_char mode;
197
198 mode = todc_read_val(TODC_TYPE_DS17285_CNTL_A);
199 /* Make sure countdown clear is not set */
200 mode &= ~0x40;
201 /* Enable oscillator, extended register set */
202 mode |= 0x30;
203 todc_write_val(TODC_TYPE_DS17285_CNTL_A, mode);
204
205 } else if (todc_info->rtc_type == TODC_TYPE_DS1501) {
206 u_char month;
207
208 todc_info->enable_read = TODC_DS1501_CNTL_B_TE;
209 todc_info->enable_write = TODC_DS1501_CNTL_B_TE;
210
211 month = todc_read_val(todc_info->month);
212
213 if ((month & 0x80) == 0x80) {
214 printk(KERN_INFO "TODC %s %s\n",
215 "real-time-clock was stopped.",
216 "Now starting...");
217 month &= ~0x80;
218 todc_write_val(todc_info->month, month);
219 }
220
221 cntl_b &= ~TODC_DS1501_CNTL_B_TE;
222 todc_write_val(todc_info->control_b, cntl_b);
223 } else { /* must be a m48txx type */
224 u_char cntl_a;
225
226 todc_info->enable_read = TODC_MK48TXX_CNTL_A_R;
227 todc_info->enable_write = TODC_MK48TXX_CNTL_A_W;
228
229 cntl_a = todc_read_val(todc_info->control_a);
230
231 /* Check & clear STOP bit in control B register */
232 if (cntl_b & TODC_MK48TXX_DAY_CB) {
233 printk(KERN_INFO "TODC %s %s\n",
234 "real-time-clock was stopped.",
235 "Now starting...");
236
237 cntl_a |= todc_info->enable_write;
238 cntl_b &= ~TODC_MK48TXX_DAY_CB;/* Start Oscil */
239
240 todc_write_val(todc_info->control_a, cntl_a);
241 todc_write_val(todc_info->control_b, cntl_b);
242 }
243
244 /* Make sure READ & WRITE bits are cleared. */
245 cntl_a &= ~(todc_info->enable_write | todc_info->enable_read);
246 todc_write_val(todc_info->control_a, cntl_a);
247 }
248
249 return 0;
250}
251
252/*
253 * There is some ugly stuff in that there are assumptions that for a mc146818,
254 * the todc_info->control_a has the offset of the mc146818 Register B reg and
255 * that the register'ss 'SET' bit is the same as the m48txx's write enable
256 * bit in the control register of the m48txx (i.e., 0x80).
257 *
258 * It was done to make the code look simpler.
259 */
260void
261todc_get_rtc_time(struct rtc_time *tm)
262{
263 uint year = 0, mon = 0, mday = 0, hour = 0, min = 0, sec = 0;
264 uint limit, i;
265 u_char save_control, uip = 0;
266 extern void GregorianDay(struct rtc_time *);
267
268 spin_lock(&rtc_lock);
269 save_control = todc_read_val(todc_info->control_a);
270
271 if (todc_info->rtc_type != TODC_TYPE_MC146818) {
272 limit = 1;
273
274 switch (todc_info->rtc_type) {
275 case TODC_TYPE_DS1553:
276 case TODC_TYPE_DS1557:
277 case TODC_TYPE_DS1743:
278 case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */
279 case TODC_TYPE_DS1747:
280 case TODC_TYPE_DS17285:
281 break;
282 default:
283 todc_write_val(todc_info->control_a,
284 (save_control | todc_info->enable_read));
285 }
286 } else
287 limit = 100000000;
288
289 for (i=0; i<limit; i++) {
290 if (todc_info->rtc_type == TODC_TYPE_MC146818)
291 uip = todc_read_val(todc_info->RTC_FREQ_SELECT);
292
293 sec = todc_read_val(todc_info->seconds) & 0x7f;
294 min = todc_read_val(todc_info->minutes) & 0x7f;
295 hour = todc_read_val(todc_info->hours) & 0x3f;
296 mday = todc_read_val(todc_info->day_of_month) & 0x3f;
297 mon = todc_read_val(todc_info->month) & 0x1f;
298 year = todc_read_val(todc_info->year) & 0xff;
299
300 if (todc_info->rtc_type == TODC_TYPE_MC146818) {
301 uip |= todc_read_val(todc_info->RTC_FREQ_SELECT);
302 if ((uip & RTC_UIP) == 0)
303 break;
304 }
305 }
306
307 if (todc_info->rtc_type != TODC_TYPE_MC146818) {
308 switch (todc_info->rtc_type) {
309 case TODC_TYPE_DS1553:
310 case TODC_TYPE_DS1557:
311 case TODC_TYPE_DS1743:
312 case TODC_TYPE_DS1746: /* XXXX BAD HACK -> FIX */
313 case TODC_TYPE_DS1747:
314 case TODC_TYPE_DS17285:
315 break;
316 default:
317 save_control &= ~(todc_info->enable_read);
318 todc_write_val(todc_info->control_a, save_control);
319 }
320 }
321 spin_unlock(&rtc_lock);
322
323 if ((todc_info->rtc_type != TODC_TYPE_MC146818)
324 || ((save_control & RTC_DM_BINARY) == 0)
325 || RTC_ALWAYS_BCD) {
326 BCD_TO_BIN(sec);
327 BCD_TO_BIN(min);
328 BCD_TO_BIN(hour);
329 BCD_TO_BIN(mday);
330 BCD_TO_BIN(mon);
331 BCD_TO_BIN(year);
332 }
333
334 if ((year + 1900) < 1970) {
335 year += 100;
336 }
337
338 tm->tm_sec = sec;
339 tm->tm_min = min;
340 tm->tm_hour = hour;
341 tm->tm_mday = mday;
342 tm->tm_mon = mon;
343 tm->tm_year = year;
344
345 GregorianDay(tm);
346}
347
348int
349todc_set_rtc_time(struct rtc_time *tm)
350{
351 u_char save_control, save_freq_select = 0;
352
353 spin_lock(&rtc_lock);
354 save_control = todc_read_val(todc_info->control_a);
355
356 /* Assuming MK48T59_RTC_CA_WRITE & RTC_SET are equal */
357 todc_write_val(todc_info->control_a,
358 (save_control | todc_info->enable_write));
359 save_control &= ~(todc_info->enable_write); /* in case it was set */
360
361 if (todc_info->rtc_type == TODC_TYPE_MC146818) {
362 save_freq_select = todc_read_val(todc_info->RTC_FREQ_SELECT);
363 todc_write_val(todc_info->RTC_FREQ_SELECT,
364 save_freq_select | RTC_DIV_RESET2);
365 }
366
367 if ((todc_info->rtc_type != TODC_TYPE_MC146818)
368 || ((save_control & RTC_DM_BINARY) == 0)
369 || RTC_ALWAYS_BCD) {
370 BIN_TO_BCD(tm->tm_sec);
371 BIN_TO_BCD(tm->tm_min);
372 BIN_TO_BCD(tm->tm_hour);
373 BIN_TO_BCD(tm->tm_mon);
374 BIN_TO_BCD(tm->tm_mday);
375 BIN_TO_BCD(tm->tm_year);
376 }
377
378 todc_write_val(todc_info->seconds, tm->tm_sec);
379 todc_write_val(todc_info->minutes, tm->tm_min);
380 todc_write_val(todc_info->hours, tm->tm_hour);
381 todc_write_val(todc_info->month, tm->tm_mon);
382 todc_write_val(todc_info->day_of_month, tm->tm_mday);
383 todc_write_val(todc_info->year, tm->tm_year);
384
385 todc_write_val(todc_info->control_a, save_control);
386
387 if (todc_info->rtc_type == TODC_TYPE_MC146818)
388 todc_write_val(todc_info->RTC_FREQ_SELECT, save_freq_select);
389
390 spin_unlock(&rtc_lock);
391 return 0;
392}
diff --git a/arch/powerpc/sysdev/tsi108_pci.c b/arch/powerpc/sysdev/tsi108_pci.c
index 322f86e93de5..ae249c6bbbcf 100644
--- a/arch/powerpc/sysdev/tsi108_pci.c
+++ b/arch/powerpc/sysdev/tsi108_pci.c
@@ -3,6 +3,8 @@
3 * 3 *
4 * 2004-2005 (c) Tundra Semiconductor Corp. 4 * 2004-2005 (c) Tundra Semiconductor Corp.
5 * Author: Alex Bounine (alexandreb@tundra.com) 5 * Author: Alex Bounine (alexandreb@tundra.com)
6 * Author: Roy Zang (tie-fei.zang@freescale.com)
7 * Add pci interrupt router host
6 * 8 *
7 * This program is free software; you can redistribute it and/or modify it 9 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free 10 * under the terms of the GNU General Public License as published by the Free
@@ -48,6 +50,8 @@
48 50
49u32 tsi108_pci_cfg_base; 51u32 tsi108_pci_cfg_base;
50u32 tsi108_csr_vir_base; 52u32 tsi108_csr_vir_base;
53static struct device_node *pci_irq_node;
54static struct irq_host *pci_irq_host;
51 55
52extern u32 get_vir_csrbase(void); 56extern u32 get_vir_csrbase(void);
53extern u32 tsi108_read_reg(u32 reg_offset); 57extern u32 tsi108_read_reg(u32 reg_offset);
@@ -378,6 +382,38 @@ static struct irq_chip tsi108_pci_irq = {
378 .unmask = tsi108_pci_irq_enable, 382 .unmask = tsi108_pci_irq_enable,
379}; 383};
380 384
385static int pci_irq_host_xlate(struct irq_host *h, struct device_node *ct,
386 u32 *intspec, unsigned int intsize,
387 irq_hw_number_t *out_hwirq, unsigned int *out_flags)
388{
389 *out_hwirq = intspec[0];
390 *out_flags = IRQ_TYPE_LEVEL_HIGH;
391 return 0;
392}
393
394static int pci_irq_host_map(struct irq_host *h, unsigned int virq,
395 irq_hw_number_t hw)
396{ unsigned int irq;
397 DBG("%s(%d, 0x%lx)\n", __FUNCTION__, virq, hw);
398 if ((virq >= 1) && (virq <= 4)){
399 irq = virq + IRQ_PCI_INTAD_BASE - 1;
400 get_irq_desc(irq)->status |= IRQ_LEVEL;
401 set_irq_chip(irq, &tsi108_pci_irq);
402 }
403 return 0;
404}
405
406static int pci_irq_host_match(struct irq_host *h, struct device_node *node)
407{
408 return pci_irq_node == node;
409}
410
411static struct irq_host_ops pci_irq_host_ops = {
412 .match = pci_irq_host_match,
413 .map = pci_irq_host_map,
414 .xlate = pci_irq_host_xlate,
415};
416
381/* 417/*
382 * Exported functions 418 * Exported functions
383 */ 419 */
@@ -391,15 +427,15 @@ static struct irq_chip tsi108_pci_irq = {
391 * to the MPIC. 427 * to the MPIC.
392 */ 428 */
393 429
394void __init tsi108_pci_int_init(void) 430void __init tsi108_pci_int_init(struct device_node *node)
395{ 431{
396 u_int i;
397
398 DBG("Tsi108_pci_int_init: initializing PCI interrupts\n"); 432 DBG("Tsi108_pci_int_init: initializing PCI interrupts\n");
399 433
400 for (i = 0; i < NUM_PCI_IRQS; i++) { 434 pci_irq_node = of_node_get(node);
401 irq_desc[i + IRQ_PCI_INTAD_BASE].chip = &tsi108_pci_irq; 435 pci_irq_host = irq_alloc_host(IRQ_HOST_MAP_LEGACY, 0, &pci_irq_host_ops, 0);
402 irq_desc[i + IRQ_PCI_INTAD_BASE].status |= IRQ_LEVEL; 436 if (pci_irq_host == NULL) {
437 printk(KERN_ERR "pci_irq_host: failed to allocate irq host !\n");
438 return;
403 } 439 }
404 440
405 init_pci_source(); 441 init_pci_source();
diff --git a/arch/powerpc/xmon/Makefile b/arch/powerpc/xmon/Makefile
index 109d874ecfbe..51d97588e762 100644
--- a/arch/powerpc/xmon/Makefile
+++ b/arch/powerpc/xmon/Makefile
@@ -3,5 +3,10 @@
3ifdef CONFIG_PPC64 3ifdef CONFIG_PPC64
4EXTRA_CFLAGS += -mno-minimal-toc 4EXTRA_CFLAGS += -mno-minimal-toc
5endif 5endif
6obj-y += xmon.o ppc-dis.o ppc-opc.o setjmp.o start.o \ 6
7 nonstdio.o 7obj-y += xmon.o setjmp.o start.o nonstdio.o
8
9ifdef CONFIG_XMON_DISASSEMBLY
10obj-y += ppc-dis.o ppc-opc.o
11obj-$(CONFIG_SPU_BASE) += spu-dis.o spu-opc.o
12endif
diff --git a/arch/powerpc/xmon/dis-asm.h b/arch/powerpc/xmon/dis-asm.h
new file mode 100644
index 000000000000..be3533b93f30
--- /dev/null
+++ b/arch/powerpc/xmon/dis-asm.h
@@ -0,0 +1,31 @@
1#ifndef _POWERPC_XMON_DIS_ASM_H
2#define _POWERPC_XMON_DIS_ASM_H
3/*
4 * Copyright (C) 2006 Michael Ellerman, IBM Corporation.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version
9 * 2 of the License, or (at your option) any later version.
10 */
11
12extern void print_address (unsigned long memaddr);
13
14#ifdef CONFIG_XMON_DISASSEMBLY
15extern int print_insn_powerpc(unsigned long insn, unsigned long memaddr);
16extern int print_insn_spu(unsigned long insn, unsigned long memaddr);
17#else
18static inline int print_insn_powerpc(unsigned long insn, unsigned long memaddr)
19{
20 printf("%.8x", insn);
21 return 0;
22}
23
24static inline int print_insn_spu(unsigned long insn, unsigned long memaddr)
25{
26 printf("%.8x", insn);
27 return 0;
28}
29#endif
30
31#endif /* _POWERPC_XMON_DIS_ASM_H */
diff --git a/arch/powerpc/xmon/ppc-dis.c b/arch/powerpc/xmon/ppc-dis.c
index ac0a9d2427e0..89098f320ad5 100644
--- a/arch/powerpc/xmon/ppc-dis.c
+++ b/arch/powerpc/xmon/ppc-dis.c
@@ -1,5 +1,6 @@
1/* ppc-dis.c -- Disassemble PowerPC instructions 1/* ppc-dis.c -- Disassemble PowerPC instructions
2 Copyright 1994 Free Software Foundation, Inc. 2 Copyright 1994, 1995, 2000, 2001, 2002, 2003, 2004, 2005, 2006
3 Free Software Foundation, Inc.
3 Written by Ian Lance Taylor, Cygnus Support 4 Written by Ian Lance Taylor, Cygnus Support
4 5
5This file is part of GDB, GAS, and the GNU binutils. 6This file is part of GDB, GAS, and the GNU binutils.
@@ -16,27 +17,36 @@ the GNU General Public License for more details.
16 17
17You should have received a copy of the GNU General Public License 18You should have received a copy of the GNU General Public License
18along with this file; see the file COPYING. If not, write to the Free 19along with this file; see the file COPYING. If not, write to the Free
19Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 20Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
20 21
22#include <asm/cputable.h>
21#include "nonstdio.h" 23#include "nonstdio.h"
22#include "ansidecl.h" 24#include "ansidecl.h"
23#include "ppc.h" 25#include "ppc.h"
24 26#include "dis-asm.h"
25extern void print_address (unsigned long memaddr);
26 27
27/* Print a PowerPC or POWER instruction. */ 28/* Print a PowerPC or POWER instruction. */
28 29
29int 30int
30print_insn_powerpc (unsigned long insn, unsigned long memaddr, int dialect) 31print_insn_powerpc (unsigned long insn, unsigned long memaddr)
31{ 32{
32 const struct powerpc_opcode *opcode; 33 const struct powerpc_opcode *opcode;
33 const struct powerpc_opcode *opcode_end; 34 const struct powerpc_opcode *opcode_end;
34 unsigned long op; 35 unsigned long op;
36 int dialect;
35 37
36 if (dialect == 0) 38 dialect = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_COMMON
37 dialect = PPC_OPCODE_PPC | PPC_OPCODE_CLASSIC | PPC_OPCODE_COMMON
38 | PPC_OPCODE_64 | PPC_OPCODE_POWER4 | PPC_OPCODE_ALTIVEC; 39 | PPC_OPCODE_64 | PPC_OPCODE_POWER4 | PPC_OPCODE_ALTIVEC;
39 40
41 if (cpu_has_feature(CPU_FTRS_POWER5))
42 dialect |= PPC_OPCODE_POWER5;
43
44 if (cpu_has_feature(CPU_FTRS_CELL))
45 dialect |= PPC_OPCODE_CELL | PPC_OPCODE_ALTIVEC;
46
47 if (cpu_has_feature(CPU_FTRS_POWER6))
48 dialect |= PPC_OPCODE_POWER5 | PPC_OPCODE_POWER6 | PPC_OPCODE_ALTIVEC;
49
40 /* Get the major opcode of the instruction. */ 50 /* Get the major opcode of the instruction. */
41 op = PPC_OP (insn); 51 op = PPC_OP (insn);
42 52
@@ -121,7 +131,8 @@ print_insn_powerpc (unsigned long insn, unsigned long memaddr, int dialect)
121 } 131 }
122 132
123 /* Print the operand as directed by the flags. */ 133 /* Print the operand as directed by the flags. */
124 if ((operand->flags & PPC_OPERAND_GPR) != 0) 134 if ((operand->flags & PPC_OPERAND_GPR) != 0
135 || ((operand->flags & PPC_OPERAND_GPR_0) != 0 && value != 0))
125 printf("r%ld", value); 136 printf("r%ld", value);
126 else if ((operand->flags & PPC_OPERAND_FPR) != 0) 137 else if ((operand->flags & PPC_OPERAND_FPR) != 0)
127 printf("f%ld", value); 138 printf("f%ld", value);
@@ -137,7 +148,7 @@ print_insn_powerpc (unsigned long insn, unsigned long memaddr, int dialect)
137 else 148 else
138 { 149 {
139 if (operand->bits == 3) 150 if (operand->bits == 3)
140 printf("cr%d", value); 151 printf("cr%ld", value);
141 else 152 else
142 { 153 {
143 static const char *cbnames[4] = { "lt", "gt", "eq", "so" }; 154 static const char *cbnames[4] = { "lt", "gt", "eq", "so" };
diff --git a/arch/powerpc/xmon/ppc-opc.c b/arch/powerpc/xmon/ppc-opc.c
index 5ee8fc32f824..5d841f4b3530 100644
--- a/arch/powerpc/xmon/ppc-opc.c
+++ b/arch/powerpc/xmon/ppc-opc.c
@@ -1,6 +1,6 @@
1/* ppc-opc.c -- PowerPC opcode list 1/* ppc-opc.c -- PowerPC opcode list
2 Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003 2 Copyright 1994, 1995, 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004,
3 Free Software Foundation, Inc. 3 2005 Free Software Foundation, Inc.
4 Written by Ian Lance Taylor, Cygnus Support 4 Written by Ian Lance Taylor, Cygnus Support
5 5
6 This file is part of GDB, GAS, and the GNU binutils. 6 This file is part of GDB, GAS, and the GNU binutils.
@@ -17,8 +17,8 @@
17 17
18 You should have received a copy of the GNU General Public License 18 You should have received a copy of the GNU General Public License
19 along with this file; see the file COPYING. If not, write to the Free 19 along with this file; see the file COPYING. If not, write to the Free
20 Software Foundation, 59 Temple Place - Suite 330, Boston, MA 20 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
21 02111-1307, USA. */ 21 02110-1301, USA. */
22 22
23#include <linux/stddef.h> 23#include <linux/stddef.h>
24#include "nonstdio.h" 24#include "nonstdio.h"
@@ -86,6 +86,8 @@ static unsigned long insert_sh6 (unsigned long, long, int, const char **);
86static long extract_sh6 (unsigned long, int, int *); 86static long extract_sh6 (unsigned long, int, int *);
87static unsigned long insert_spr (unsigned long, long, int, const char **); 87static unsigned long insert_spr (unsigned long, long, int, const char **);
88static long extract_spr (unsigned long, int, int *); 88static long extract_spr (unsigned long, int, int *);
89static unsigned long insert_sprg (unsigned long, long, int, const char **);
90static long extract_sprg (unsigned long, int, int *);
89static unsigned long insert_tbr (unsigned long, long, int, const char **); 91static unsigned long insert_tbr (unsigned long, long, int, const char **);
90static long extract_tbr (unsigned long, int, int *); 92static long extract_tbr (unsigned long, int, int *);
91static unsigned long insert_ev2 (unsigned long, long, int, const char **); 93static unsigned long insert_ev2 (unsigned long, long, int, const char **);
@@ -196,8 +198,11 @@ const struct powerpc_operand powerpc_operands[] =
196#define BOE BO + 1 198#define BOE BO + 1
197 { 5, 21, insert_boe, extract_boe, 0 }, 199 { 5, 21, insert_boe, extract_boe, 0 },
198 200
201#define BH BOE + 1
202 { 2, 11, NULL, NULL, PPC_OPERAND_OPTIONAL },
203
199 /* The BT field in an X or XL form instruction. */ 204 /* The BT field in an X or XL form instruction. */
200#define BT BOE + 1 205#define BT BH + 1
201 { 5, 21, NULL, NULL, PPC_OPERAND_CR }, 206 { 5, 21, NULL, NULL, PPC_OPERAND_CR },
202 207
203 /* The condition register number portion of the BI field in a B form 208 /* The condition register number portion of the BI field in a B form
@@ -301,10 +306,14 @@ const struct powerpc_operand powerpc_operands[] =
301#define L FXM4 + 1 306#define L FXM4 + 1
302 { 1, 21, NULL, NULL, PPC_OPERAND_OPTIONAL }, 307 { 1, 21, NULL, NULL, PPC_OPERAND_OPTIONAL },
303 308
304 /* The LEV field in a POWER SC form instruction. */ 309 /* The LEV field in a POWER SVC form instruction. */
305#define LEV L + 1 310#define SVC_LEV L + 1
306 { 7, 5, NULL, NULL, 0 }, 311 { 7, 5, NULL, NULL, 0 },
307 312
313 /* The LEV field in an SC form instruction. */
314#define LEV SVC_LEV + 1
315 { 7, 5, NULL, NULL, PPC_OPERAND_OPTIONAL },
316
308 /* The LI field in an I form instruction. The lower two bits are 317 /* The LI field in an I form instruction. The lower two bits are
309 forced to zero. */ 318 forced to zero. */
310#define LI LEV + 1 319#define LI LEV + 1
@@ -346,7 +355,7 @@ const struct powerpc_operand powerpc_operands[] =
346 355
347 /* The MO field in an mbar instruction. */ 356 /* The MO field in an mbar instruction. */
348#define MO MB6 + 1 357#define MO MB6 + 1
349 { 5, 21, NULL, NULL, 0 }, 358 { 5, 21, NULL, NULL, PPC_OPERAND_OPTIONAL },
350 359
351 /* The NB field in an X form instruction. The value 32 is stored as 360 /* The NB field in an X form instruction. The value 32 is stored as
352 0. */ 361 0. */
@@ -364,30 +373,38 @@ const struct powerpc_operand powerpc_operands[] =
364#define RA_MASK (0x1f << 16) 373#define RA_MASK (0x1f << 16)
365 { 5, 16, NULL, NULL, PPC_OPERAND_GPR }, 374 { 5, 16, NULL, NULL, PPC_OPERAND_GPR },
366 375
376 /* As above, but 0 in the RA field means zero, not r0. */
377#define RA0 RA + 1
378 { 5, 16, NULL, NULL, PPC_OPERAND_GPR_0 },
379
367 /* The RA field in the DQ form lq instruction, which has special 380 /* The RA field in the DQ form lq instruction, which has special
368 value restrictions. */ 381 value restrictions. */
369#define RAQ RA + 1 382#define RAQ RA0 + 1
370 { 5, 16, insert_raq, NULL, PPC_OPERAND_GPR }, 383 { 5, 16, insert_raq, NULL, PPC_OPERAND_GPR_0 },
371 384
372 /* The RA field in a D or X form instruction which is an updating 385 /* The RA field in a D or X form instruction which is an updating
373 load, which means that the RA field may not be zero and may not 386 load, which means that the RA field may not be zero and may not
374 equal the RT field. */ 387 equal the RT field. */
375#define RAL RAQ + 1 388#define RAL RAQ + 1
376 { 5, 16, insert_ral, NULL, PPC_OPERAND_GPR }, 389 { 5, 16, insert_ral, NULL, PPC_OPERAND_GPR_0 },
377 390
378 /* The RA field in an lmw instruction, which has special value 391 /* The RA field in an lmw instruction, which has special value
379 restrictions. */ 392 restrictions. */
380#define RAM RAL + 1 393#define RAM RAL + 1
381 { 5, 16, insert_ram, NULL, PPC_OPERAND_GPR }, 394 { 5, 16, insert_ram, NULL, PPC_OPERAND_GPR_0 },
382 395
383 /* The RA field in a D or X form instruction which is an updating 396 /* The RA field in a D or X form instruction which is an updating
384 store or an updating floating point load, which means that the RA 397 store or an updating floating point load, which means that the RA
385 field may not be zero. */ 398 field may not be zero. */
386#define RAS RAM + 1 399#define RAS RAM + 1
387 { 5, 16, insert_ras, NULL, PPC_OPERAND_GPR }, 400 { 5, 16, insert_ras, NULL, PPC_OPERAND_GPR_0 },
401
402 /* The RA field of the tlbwe instruction, which is optional. */
403#define RAOPT RAS + 1
404 { 5, 16, NULL, NULL, PPC_OPERAND_GPR | PPC_OPERAND_OPTIONAL },
388 405
389 /* The RB field in an X, XO, M, or MDS form instruction. */ 406 /* The RB field in an X, XO, M, or MDS form instruction. */
390#define RB RAS + 1 407#define RB RAOPT + 1
391#define RB_MASK (0x1f << 11) 408#define RB_MASK (0x1f << 11)
392 { 5, 11, NULL, NULL, PPC_OPERAND_GPR }, 409 { 5, 11, NULL, NULL, PPC_OPERAND_GPR },
393 410
@@ -408,15 +425,20 @@ const struct powerpc_operand powerpc_operands[] =
408 /* The RS field of the DS form stq instruction, which has special 425 /* The RS field of the DS form stq instruction, which has special
409 value restrictions. */ 426 value restrictions. */
410#define RSQ RS + 1 427#define RSQ RS + 1
411 { 5, 21, insert_rsq, NULL, PPC_OPERAND_GPR }, 428 { 5, 21, insert_rsq, NULL, PPC_OPERAND_GPR_0 },
412 429
413 /* The RT field of the DQ form lq instruction, which has special 430 /* The RT field of the DQ form lq instruction, which has special
414 value restrictions. */ 431 value restrictions. */
415#define RTQ RSQ + 1 432#define RTQ RSQ + 1
416 { 5, 21, insert_rtq, NULL, PPC_OPERAND_GPR }, 433 { 5, 21, insert_rtq, NULL, PPC_OPERAND_GPR_0 },
434
435 /* The RS field of the tlbwe instruction, which is optional. */
436#define RSO RTQ + 1
437#define RTO RSO
438 { 5, 21, NULL, NULL, PPC_OPERAND_GPR | PPC_OPERAND_OPTIONAL },
417 439
418 /* The SH field in an X or M form instruction. */ 440 /* The SH field in an X or M form instruction. */
419#define SH RTQ + 1 441#define SH RSO + 1
420#define SH_MASK (0x1f << 11) 442#define SH_MASK (0x1f << 11)
421 { 5, 11, NULL, NULL, 0 }, 443 { 5, 11, NULL, NULL, 0 },
422 444
@@ -425,8 +447,12 @@ const struct powerpc_operand powerpc_operands[] =
425#define SH6_MASK ((0x1f << 11) | (1 << 1)) 447#define SH6_MASK ((0x1f << 11) | (1 << 1))
426 { 6, 1, insert_sh6, extract_sh6, 0 }, 448 { 6, 1, insert_sh6, extract_sh6, 0 },
427 449
450 /* The SH field of the tlbwe instruction, which is optional. */
451#define SHO SH6 + 1
452 { 5, 11,NULL, NULL, PPC_OPERAND_OPTIONAL },
453
428 /* The SI field in a D form instruction. */ 454 /* The SI field in a D form instruction. */
429#define SI SH6 + 1 455#define SI SHO + 1
430 { 16, 0, NULL, NULL, PPC_OPERAND_SIGNED }, 456 { 16, 0, NULL, NULL, PPC_OPERAND_SIGNED },
431 457
432 /* The SI field in a D form instruction when we accept a wide range 458 /* The SI field in a D form instruction when we accept a wide range
@@ -448,8 +474,7 @@ const struct powerpc_operand powerpc_operands[] =
448 474
449 /* The SPRG register number in an XFX form m[ft]sprg instruction. */ 475 /* The SPRG register number in an XFX form m[ft]sprg instruction. */
450#define SPRG SPRBAT + 1 476#define SPRG SPRBAT + 1
451#define SPRG_MASK (0x3 << 16) 477 { 5, 16, insert_sprg, extract_sprg, 0 },
452 { 2, 16, NULL, NULL, 0 },
453 478
454 /* The SR field in an X form instruction. */ 479 /* The SR field in an X form instruction. */
455#define SR SPRG + 1 480#define SR SPRG + 1
@@ -536,10 +561,45 @@ const struct powerpc_operand powerpc_operands[] =
536#define WS_MASK (0x7 << 11) 561#define WS_MASK (0x7 << 11)
537 { 3, 11, NULL, NULL, 0 }, 562 { 3, 11, NULL, NULL, 0 },
538 563
539 /* The L field in an mtmsrd instruction */ 564 /* The L field in an mtmsrd or A form instruction. */
540#define MTMSRD_L WS + 1 565#define MTMSRD_L WS + 1
566#define A_L MTMSRD_L
541 { 1, 16, NULL, NULL, PPC_OPERAND_OPTIONAL }, 567 { 1, 16, NULL, NULL, PPC_OPERAND_OPTIONAL },
542 568
569 /* The DCM field in a Z form instruction. */
570#define DCM MTMSRD_L + 1
571 { 6, 16, NULL, NULL, 0 },
572
573 /* Likewise, the DGM field in a Z form instruction. */
574#define DGM DCM + 1
575 { 6, 16, NULL, NULL, 0 },
576
577#define TE DGM + 1
578 { 5, 11, NULL, NULL, 0 },
579
580#define RMC TE + 1
581 { 2, 21, NULL, NULL, 0 },
582
583#define R RMC + 1
584 { 1, 15, NULL, NULL, 0 },
585
586#define SP R + 1
587 { 2, 11, NULL, NULL, 0 },
588
589#define S SP + 1
590 { 1, 11, NULL, NULL, 0 },
591
592 /* SH field starting at bit position 16. */
593#define SH16 S + 1
594 { 6, 10, NULL, NULL, 0 },
595
596 /* The L field in an X form with the RT field fixed instruction. */
597#define XRT_L SH16 + 1
598 { 2, 21, NULL, NULL, PPC_OPERAND_OPTIONAL },
599
600 /* The EH field in larx instruction. */
601#define EH XRT_L + 1
602 { 1, 0, NULL, NULL, PPC_OPERAND_OPTIONAL },
543}; 603};
544 604
545/* The functions used to insert and extract complicated operands. */ 605/* The functions used to insert and extract complicated operands. */
@@ -550,7 +610,6 @@ const struct powerpc_operand powerpc_operands[] =
550 and the extraction function just checks that the fields are the 610 and the extraction function just checks that the fields are the
551 same. */ 611 same. */
552 612
553/*ARGSUSED*/
554static unsigned long 613static unsigned long
555insert_bat (unsigned long insn, 614insert_bat (unsigned long insn,
556 long value ATTRIBUTE_UNUSED, 615 long value ATTRIBUTE_UNUSED,
@@ -576,7 +635,6 @@ extract_bat (unsigned long insn,
576 and the extraction function just checks that the fields are the 635 and the extraction function just checks that the fields are the
577 same. */ 636 same. */
578 637
579/*ARGSUSED*/
580static unsigned long 638static unsigned long
581insert_bba (unsigned long insn, 639insert_bba (unsigned long insn,
582 long value ATTRIBUTE_UNUSED, 640 long value ATTRIBUTE_UNUSED,
@@ -599,7 +657,6 @@ extract_bba (unsigned long insn,
599/* The BD field in a B form instruction. The lower two bits are 657/* The BD field in a B form instruction. The lower two bits are
600 forced to zero. */ 658 forced to zero. */
601 659
602/*ARGSUSED*/
603static unsigned long 660static unsigned long
604insert_bd (unsigned long insn, 661insert_bd (unsigned long insn,
605 long value, 662 long value,
@@ -609,7 +666,6 @@ insert_bd (unsigned long insn,
609 return insn | (value & 0xfffc); 666 return insn | (value & 0xfffc);
610} 667}
611 668
612/*ARGSUSED*/
613static long 669static long
614extract_bd (unsigned long insn, 670extract_bd (unsigned long insn,
615 int dialect ATTRIBUTE_UNUSED, 671 int dialect ATTRIBUTE_UNUSED,
@@ -631,7 +687,6 @@ extract_bd (unsigned long insn,
631 in BO field, the "a" bit is 00010 for branch on CR(BI) and 01000 687 in BO field, the "a" bit is 00010 for branch on CR(BI) and 01000
632 for branch on CTR. We only handle the taken/not-taken hint here. */ 688 for branch on CTR. We only handle the taken/not-taken hint here. */
633 689
634/*ARGSUSED*/
635static unsigned long 690static unsigned long
636insert_bdm (unsigned long insn, 691insert_bdm (unsigned long insn,
637 long value, 692 long value,
@@ -677,7 +732,6 @@ extract_bdm (unsigned long insn,
677 This is like BDM, above, except that the branch is expected to be 732 This is like BDM, above, except that the branch is expected to be
678 taken. */ 733 taken. */
679 734
680/*ARGSUSED*/
681static unsigned long 735static unsigned long
682insert_bdp (unsigned long insn, 736insert_bdp (unsigned long insn,
683 long value, 737 long value,
@@ -831,7 +885,6 @@ extract_boe (unsigned long insn,
831/* The DQ field in a DQ form instruction. This is like D, but the 885/* The DQ field in a DQ form instruction. This is like D, but the
832 lower four bits are forced to zero. */ 886 lower four bits are forced to zero. */
833 887
834/*ARGSUSED*/
835static unsigned long 888static unsigned long
836insert_dq (unsigned long insn, 889insert_dq (unsigned long insn,
837 long value, 890 long value,
@@ -843,7 +896,6 @@ insert_dq (unsigned long insn,
843 return insn | (value & 0xfff0); 896 return insn | (value & 0xfff0);
844} 897}
845 898
846/*ARGSUSED*/
847static long 899static long
848extract_dq (unsigned long insn, 900extract_dq (unsigned long insn,
849 int dialect ATTRIBUTE_UNUSED, 901 int dialect ATTRIBUTE_UNUSED,
@@ -918,7 +970,6 @@ extract_ev8 (unsigned long insn,
918/* The DS field in a DS form instruction. This is like D, but the 970/* The DS field in a DS form instruction. This is like D, but the
919 lower two bits are forced to zero. */ 971 lower two bits are forced to zero. */
920 972
921/*ARGSUSED*/
922static unsigned long 973static unsigned long
923insert_ds (unsigned long insn, 974insert_ds (unsigned long insn,
924 long value, 975 long value,
@@ -930,7 +981,6 @@ insert_ds (unsigned long insn,
930 return insn | (value & 0xfffc); 981 return insn | (value & 0xfffc);
931} 982}
932 983
933/*ARGSUSED*/
934static long 984static long
935extract_ds (unsigned long insn, 985extract_ds (unsigned long insn,
936 int dialect ATTRIBUTE_UNUSED, 986 int dialect ATTRIBUTE_UNUSED,
@@ -941,7 +991,6 @@ extract_ds (unsigned long insn,
941 991
942/* The DE field in a DE form instruction. */ 992/* The DE field in a DE form instruction. */
943 993
944/*ARGSUSED*/
945static unsigned long 994static unsigned long
946insert_de (unsigned long insn, 995insert_de (unsigned long insn,
947 long value, 996 long value,
@@ -953,7 +1002,6 @@ insert_de (unsigned long insn,
953 return insn | ((value << 4) & 0xfff0); 1002 return insn | ((value << 4) & 0xfff0);
954} 1003}
955 1004
956/*ARGSUSED*/
957static long 1005static long
958extract_de (unsigned long insn, 1006extract_de (unsigned long insn,
959 int dialect ATTRIBUTE_UNUSED, 1007 int dialect ATTRIBUTE_UNUSED,
@@ -964,7 +1012,6 @@ extract_de (unsigned long insn,
964 1012
965/* The DES field in a DES form instruction. */ 1013/* The DES field in a DES form instruction. */
966 1014
967/*ARGSUSED*/
968static unsigned long 1015static unsigned long
969insert_des (unsigned long insn, 1016insert_des (unsigned long insn,
970 long value, 1017 long value,
@@ -978,7 +1025,6 @@ insert_des (unsigned long insn,
978 return insn | ((value << 2) & 0xfff0); 1025 return insn | ((value << 2) & 0xfff0);
979} 1026}
980 1027
981/*ARGSUSED*/
982static long 1028static long
983extract_des (unsigned long insn, 1029extract_des (unsigned long insn,
984 int dialect ATTRIBUTE_UNUSED, 1030 int dialect ATTRIBUTE_UNUSED,
@@ -995,17 +1041,33 @@ insert_fxm (unsigned long insn,
995 int dialect, 1041 int dialect,
996 const char **errmsg) 1042 const char **errmsg)
997{ 1043{
1044 /* If we're handling the mfocrf and mtocrf insns ensure that exactly
1045 one bit of the mask field is set. */
1046 if ((insn & (1 << 20)) != 0)
1047 {
1048 if (value == 0 || (value & -value) != value)
1049 {
1050 *errmsg = _("invalid mask field");
1051 value = 0;
1052 }
1053 }
1054
998 /* If the optional field on mfcr is missing that means we want to use 1055 /* If the optional field on mfcr is missing that means we want to use
999 the old form of the instruction that moves the whole cr. In that 1056 the old form of the instruction that moves the whole cr. In that
1000 case we'll have VALUE zero. There doesn't seem to be a way to 1057 case we'll have VALUE zero. There doesn't seem to be a way to
1001 distinguish this from the case where someone writes mfcr %r3,0. */ 1058 distinguish this from the case where someone writes mfcr %r3,0. */
1002 if (value == 0) 1059 else if (value == 0)
1003 ; 1060 ;
1004 1061
1005 /* If only one bit of the FXM field is set, we can use the new form 1062 /* If only one bit of the FXM field is set, we can use the new form
1006 of the instruction, which is faster. Unlike the Power4 branch hint 1063 of the instruction, which is faster. Unlike the Power4 branch hint
1007 encoding, this is not backward compatible. */ 1064 encoding, this is not backward compatible. Do not generate the
1008 else if ((dialect & PPC_OPCODE_POWER4) != 0 && (value & -value) == value) 1065 new form unless -mpower4 has been given, or -many and the two
1066 operand form of mfcr was used. */
1067 else if ((value & -value) == value
1068 && ((dialect & PPC_OPCODE_POWER4) != 0
1069 || ((dialect & PPC_OPCODE_ANY) != 0
1070 && (insn & (0x3ff << 1)) == 19 << 1)))
1009 insn |= 1 << 20; 1071 insn |= 1 << 20;
1010 1072
1011 /* Any other value on mfcr is an error. */ 1073 /* Any other value on mfcr is an error. */
@@ -1020,7 +1082,7 @@ insert_fxm (unsigned long insn,
1020 1082
1021static long 1083static long
1022extract_fxm (unsigned long insn, 1084extract_fxm (unsigned long insn,
1023 int dialect, 1085 int dialect ATTRIBUTE_UNUSED,
1024 int *invalid) 1086 int *invalid)
1025{ 1087{
1026 long mask = (insn >> 12) & 0xff; 1088 long mask = (insn >> 12) & 0xff;
@@ -1028,14 +1090,9 @@ extract_fxm (unsigned long insn,
1028 /* Is this a Power4 insn? */ 1090 /* Is this a Power4 insn? */
1029 if ((insn & (1 << 20)) != 0) 1091 if ((insn & (1 << 20)) != 0)
1030 { 1092 {
1031 if ((dialect & PPC_OPCODE_POWER4) == 0) 1093 /* Exactly one bit of MASK should be set. */
1094 if (mask == 0 || (mask & -mask) != mask)
1032 *invalid = 1; 1095 *invalid = 1;
1033 else
1034 {
1035 /* Exactly one bit of MASK should be set. */
1036 if (mask == 0 || (mask & -mask) != mask)
1037 *invalid = 1;
1038 }
1039 } 1096 }
1040 1097
1041 /* Check that non-power4 form of mfcr has a zero MASK. */ 1098 /* Check that non-power4 form of mfcr has a zero MASK. */
@@ -1051,7 +1108,6 @@ extract_fxm (unsigned long insn,
1051/* The LI field in an I form instruction. The lower two bits are 1108/* The LI field in an I form instruction. The lower two bits are
1052 forced to zero. */ 1109 forced to zero. */
1053 1110
1054/*ARGSUSED*/
1055static unsigned long 1111static unsigned long
1056insert_li (unsigned long insn, 1112insert_li (unsigned long insn,
1057 long value, 1113 long value,
@@ -1063,7 +1119,6 @@ insert_li (unsigned long insn,
1063 return insn | (value & 0x3fffffc); 1119 return insn | (value & 0x3fffffc);
1064} 1120}
1065 1121
1066/*ARGSUSED*/
1067static long 1122static long
1068extract_li (unsigned long insn, 1123extract_li (unsigned long insn,
1069 int dialect ATTRIBUTE_UNUSED, 1124 int dialect ATTRIBUTE_UNUSED,
@@ -1163,7 +1218,6 @@ extract_mbe (unsigned long insn,
1163/* The MB or ME field in an MD or MDS form instruction. The high bit 1218/* The MB or ME field in an MD or MDS form instruction. The high bit
1164 is wrapped to the low end. */ 1219 is wrapped to the low end. */
1165 1220
1166/*ARGSUSED*/
1167static unsigned long 1221static unsigned long
1168insert_mb6 (unsigned long insn, 1222insert_mb6 (unsigned long insn,
1169 long value, 1223 long value,
@@ -1173,7 +1227,6 @@ insert_mb6 (unsigned long insn,
1173 return insn | ((value & 0x1f) << 6) | (value & 0x20); 1227 return insn | ((value & 0x1f) << 6) | (value & 0x20);
1174} 1228}
1175 1229
1176/*ARGSUSED*/
1177static long 1230static long
1178extract_mb6 (unsigned long insn, 1231extract_mb6 (unsigned long insn,
1179 int dialect ATTRIBUTE_UNUSED, 1232 int dialect ATTRIBUTE_UNUSED,
@@ -1198,7 +1251,6 @@ insert_nb (unsigned long insn,
1198 return insn | ((value & 0x1f) << 11); 1251 return insn | ((value & 0x1f) << 11);
1199} 1252}
1200 1253
1201/*ARGSUSED*/
1202static long 1254static long
1203extract_nb (unsigned long insn, 1255extract_nb (unsigned long insn,
1204 int dialect ATTRIBUTE_UNUSED, 1256 int dialect ATTRIBUTE_UNUSED,
@@ -1217,7 +1269,6 @@ extract_nb (unsigned long insn,
1217 invalid, since we never want to recognize an instruction which uses 1269 invalid, since we never want to recognize an instruction which uses
1218 a field of this type. */ 1270 a field of this type. */
1219 1271
1220/*ARGSUSED*/
1221static unsigned long 1272static unsigned long
1222insert_nsi (unsigned long insn, 1273insert_nsi (unsigned long insn,
1223 long value, 1274 long value,
@@ -1269,7 +1320,6 @@ insert_ram (unsigned long insn,
1269/* The RA field in the DQ form lq instruction, which has special 1320/* The RA field in the DQ form lq instruction, which has special
1270 value restrictions. */ 1321 value restrictions. */
1271 1322
1272/*ARGSUSED*/
1273static unsigned long 1323static unsigned long
1274insert_raq (unsigned long insn, 1324insert_raq (unsigned long insn,
1275 long value, 1325 long value,
@@ -1304,7 +1354,6 @@ insert_ras (unsigned long insn,
1304 function just copies the BT field into the BA field, and the 1354 function just copies the BT field into the BA field, and the
1305 extraction function just checks that the fields are the same. */ 1355 extraction function just checks that the fields are the same. */
1306 1356
1307/*ARGSUSED*/
1308static unsigned long 1357static unsigned long
1309insert_rbs (unsigned long insn, 1358insert_rbs (unsigned long insn,
1310 long value ATTRIBUTE_UNUSED, 1359 long value ATTRIBUTE_UNUSED,
@@ -1327,7 +1376,6 @@ extract_rbs (unsigned long insn,
1327/* The RT field of the DQ form lq instruction, which has special 1376/* The RT field of the DQ form lq instruction, which has special
1328 value restrictions. */ 1377 value restrictions. */
1329 1378
1330/*ARGSUSED*/
1331static unsigned long 1379static unsigned long
1332insert_rtq (unsigned long insn, 1380insert_rtq (unsigned long insn,
1333 long value, 1381 long value,
@@ -1342,7 +1390,6 @@ insert_rtq (unsigned long insn,
1342/* The RS field of the DS form stq instruction, which has special 1390/* The RS field of the DS form stq instruction, which has special
1343 value restrictions. */ 1391 value restrictions. */
1344 1392
1345/*ARGSUSED*/
1346static unsigned long 1393static unsigned long
1347insert_rsq (unsigned long insn, 1394insert_rsq (unsigned long insn,
1348 long value ATTRIBUTE_UNUSED, 1395 long value ATTRIBUTE_UNUSED,
@@ -1356,7 +1403,6 @@ insert_rsq (unsigned long insn,
1356 1403
1357/* The SH field in an MD form instruction. This is split. */ 1404/* The SH field in an MD form instruction. This is split. */
1358 1405
1359/*ARGSUSED*/
1360static unsigned long 1406static unsigned long
1361insert_sh6 (unsigned long insn, 1407insert_sh6 (unsigned long insn,
1362 long value, 1408 long value,
@@ -1366,7 +1412,6 @@ insert_sh6 (unsigned long insn,
1366 return insn | ((value & 0x1f) << 11) | ((value & 0x20) >> 4); 1412 return insn | ((value & 0x1f) << 11) | ((value & 0x20) >> 4);
1367} 1413}
1368 1414
1369/*ARGSUSED*/
1370static long 1415static long
1371extract_sh6 (unsigned long insn, 1416extract_sh6 (unsigned long insn,
1372 int dialect ATTRIBUTE_UNUSED, 1417 int dialect ATTRIBUTE_UNUSED,
@@ -1395,6 +1440,47 @@ extract_spr (unsigned long insn,
1395 return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0); 1440 return ((insn >> 16) & 0x1f) | ((insn >> 6) & 0x3e0);
1396} 1441}
1397 1442
1443/* Some dialects have 8 SPRG registers instead of the standard 4. */
1444
1445static unsigned long
1446insert_sprg (unsigned long insn,
1447 long value,
1448 int dialect,
1449 const char **errmsg)
1450{
1451 /* This check uses PPC_OPCODE_403 because PPC405 is later defined
1452 as a synonym. If ever a 405 specific dialect is added this
1453 check should use that instead. */
1454 if (value > 7
1455 || (value > 3
1456 && (dialect & (PPC_OPCODE_BOOKE | PPC_OPCODE_403)) == 0))
1457 *errmsg = _("invalid sprg number");
1458
1459 /* If this is mfsprg4..7 then use spr 260..263 which can be read in
1460 user mode. Anything else must use spr 272..279. */
1461 if (value <= 3 || (insn & 0x100) != 0)
1462 value |= 0x10;
1463
1464 return insn | ((value & 0x17) << 16);
1465}
1466
1467static long
1468extract_sprg (unsigned long insn,
1469 int dialect,
1470 int *invalid)
1471{
1472 unsigned long val = (insn >> 16) & 0x1f;
1473
1474 /* mfsprg can use 260..263 and 272..279. mtsprg only uses spr 272..279
1475 If not BOOKE or 405, then both use only 272..275. */
1476 if (val <= 3
1477 || (val < 0x10 && (insn & 0x100) != 0)
1478 || (val - 0x10 > 3
1479 && (dialect & (PPC_OPCODE_BOOKE | PPC_OPCODE_403)) == 0))
1480 *invalid = 1;
1481 return val & 7;
1482}
1483
1398/* The TBR field in an XFX instruction. This is just like SPR, but it 1484/* The TBR field in an XFX instruction. This is just like SPR, but it
1399 is optional. When TBR is omitted, it must be inserted as 268 (the 1485 is optional. When TBR is omitted, it must be inserted as 268 (the
1400 magic number of the TB register). These functions treat 0 1486 magic number of the TB register). These functions treat 0
@@ -1460,6 +1546,9 @@ extract_tbr (unsigned long insn,
1460/* An A_MASK with the FRA and FRC fields fixed. */ 1546/* An A_MASK with the FRA and FRC fields fixed. */
1461#define AFRAFRC_MASK (A_MASK | FRA_MASK | FRC_MASK) 1547#define AFRAFRC_MASK (A_MASK | FRA_MASK | FRC_MASK)
1462 1548
1549/* An AFRAFRC_MASK, but with L bit clear. */
1550#define AFRALFRC_MASK (AFRAFRC_MASK & ~((unsigned long) 1 << 16))
1551
1463/* A B form instruction. */ 1552/* A B form instruction. */
1464#define B(op, aa, lk) (OP (op) | ((((unsigned long)(aa)) & 1) << 1) | ((lk) & 1)) 1553#define B(op, aa, lk) (OP (op) | ((((unsigned long)(aa)) & 1) << 1) | ((lk) & 1))
1465#define B_MASK B (0x3f, 1, 1) 1554#define B_MASK B (0x3f, 1, 1)
@@ -1494,11 +1583,11 @@ extract_tbr (unsigned long insn,
1494 1583
1495/* An Context form instruction. */ 1584/* An Context form instruction. */
1496#define CTX(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x7)) 1585#define CTX(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x7))
1497#define CTX_MASK CTX(0x3f, 0x7) 1586#define CTX_MASK CTX(0x3f, 0x7)
1498 1587
1499/* An User Context form instruction. */ 1588/* An User Context form instruction. */
1500#define UCTX(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x1f)) 1589#define UCTX(op, xop) (OP (op) | (((unsigned long)(xop)) & 0x1f))
1501#define UCTX_MASK UCTX(0x3f, 0x1f) 1590#define UCTX_MASK UCTX(0x3f, 0x1f)
1502 1591
1503/* The main opcode mask with the RA field clear. */ 1592/* The main opcode mask with the RA field clear. */
1504#define DRA_MASK (OP_MASK | RA_MASK) 1593#define DRA_MASK (OP_MASK | RA_MASK)
@@ -1570,12 +1659,21 @@ extract_tbr (unsigned long insn,
1570/* An X form instruction. */ 1659/* An X form instruction. */
1571#define X(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x3ff) << 1)) 1660#define X(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x3ff) << 1))
1572 1661
1662/* A Z form instruction. */
1663#define Z(op, xop) (OP (op) | ((((unsigned long)(xop)) & 0x1ff) << 1))
1664
1573/* An X form instruction with the RC bit specified. */ 1665/* An X form instruction with the RC bit specified. */
1574#define XRC(op, xop, rc) (X ((op), (xop)) | ((rc) & 1)) 1666#define XRC(op, xop, rc) (X ((op), (xop)) | ((rc) & 1))
1575 1667
1668/* A Z form instruction with the RC bit specified. */
1669#define ZRC(op, xop, rc) (Z ((op), (xop)) | ((rc) & 1))
1670
1576/* The mask for an X form instruction. */ 1671/* The mask for an X form instruction. */
1577#define X_MASK XRC (0x3f, 0x3ff, 1) 1672#define X_MASK XRC (0x3f, 0x3ff, 1)
1578 1673
1674/* The mask for a Z form instruction. */
1675#define Z_MASK ZRC (0x3f, 0x1ff, 1)
1676
1579/* An X_MASK with the RA field fixed. */ 1677/* An X_MASK with the RA field fixed. */
1580#define XRA_MASK (X_MASK | RA_MASK) 1678#define XRA_MASK (X_MASK | RA_MASK)
1581 1679
@@ -1585,6 +1683,9 @@ extract_tbr (unsigned long insn,
1585/* An X_MASK with the RT field fixed. */ 1683/* An X_MASK with the RT field fixed. */
1586#define XRT_MASK (X_MASK | RT_MASK) 1684#define XRT_MASK (X_MASK | RT_MASK)
1587 1685
1686/* An XRT_MASK mask with the L bits clear. */
1687#define XLRT_MASK (XRT_MASK & ~((unsigned long) 0x3 << 21))
1688
1588/* An X_MASK with the RA and RB fields fixed. */ 1689/* An X_MASK with the RA and RB fields fixed. */
1589#define XRARB_MASK (X_MASK | RA_MASK | RB_MASK) 1690#define XRARB_MASK (X_MASK | RA_MASK | RB_MASK)
1590 1691
@@ -1597,8 +1698,8 @@ extract_tbr (unsigned long insn,
1597/* An XRTRA_MASK, but with L bit clear. */ 1698/* An XRTRA_MASK, but with L bit clear. */
1598#define XRTLRA_MASK (XRTRA_MASK & ~((unsigned long) 1 << 21)) 1699#define XRTLRA_MASK (XRTRA_MASK & ~((unsigned long) 1 << 21))
1599 1700
1600/* An X form comparison instruction. */ 1701/* An X form instruction with the L bit specified. */
1601#define XCMPL(op, xop, l) (X ((op), (xop)) | ((((unsigned long)(l)) & 1) << 21)) 1702#define XOPL(op, xop, l) (X ((op), (xop)) | ((((unsigned long)(l)) & 1) << 21))
1602 1703
1603/* The mask for an X form comparison instruction. */ 1704/* The mask for an X form comparison instruction. */
1604#define XCMP_MASK (X_MASK | (((unsigned long)1) << 22)) 1705#define XCMP_MASK (X_MASK | (((unsigned long)1) << 22))
@@ -1621,6 +1722,9 @@ extract_tbr (unsigned long insn,
1621/* An X form sync instruction with everything filled in except the LS field. */ 1722/* An X form sync instruction with everything filled in except the LS field. */
1622#define XSYNC_MASK (0xff9fffff) 1723#define XSYNC_MASK (0xff9fffff)
1623 1724
1725/* An X_MASK, but with the EH bit clear. */
1726#define XEH_MASK (X_MASK & ~((unsigned long )1))
1727
1624/* An X form AltiVec dss instruction. */ 1728/* An X form AltiVec dss instruction. */
1625#define XDSS(op, xop, a) (X ((op), (xop)) | ((((unsigned long)(a)) & 1) << 25)) 1729#define XDSS(op, xop, a) (X ((op), (xop)) | ((((unsigned long)(a)) & 1) << 25))
1626#define XDSS_MASK XDSS(0x3f, 0x3ff, 1) 1730#define XDSS_MASK XDSS(0x3f, 0x3ff, 1)
@@ -1663,6 +1767,9 @@ extract_tbr (unsigned long insn,
1663#define XLYBB_MASK (XLYLK_MASK | BB_MASK) 1767#define XLYBB_MASK (XLYLK_MASK | BB_MASK)
1664#define XLBOCBBB_MASK (XLOCB_MASK | BB_MASK) 1768#define XLBOCBBB_MASK (XLOCB_MASK | BB_MASK)
1665 1769
1770/* A mask for branch instructions using the BH field. */
1771#define XLBH_MASK (XL_MASK | (0x1c << 11))
1772
1666/* An XL_MASK with the BO and BB fields fixed. */ 1773/* An XL_MASK with the BO and BB fields fixed. */
1667#define XLBOBB_MASK (XL_MASK | BO_MASK | BB_MASK) 1774#define XLBOBB_MASK (XL_MASK | BO_MASK | BB_MASK)
1668 1775
@@ -1682,11 +1789,12 @@ extract_tbr (unsigned long insn,
1682#define XS_MASK XS (0x3f, 0x1ff, 1) 1789#define XS_MASK XS (0x3f, 0x1ff, 1)
1683 1790
1684/* A mask for the FXM version of an XFX form instruction. */ 1791/* A mask for the FXM version of an XFX form instruction. */
1685#define XFXFXM_MASK (X_MASK | (1 << 11)) 1792#define XFXFXM_MASK (X_MASK | (1 << 11) | (1 << 20))
1686 1793
1687/* An XFX form instruction with the FXM field filled in. */ 1794/* An XFX form instruction with the FXM field filled in. */
1688#define XFXM(op, xop, fxm) \ 1795#define XFXM(op, xop, fxm, p4) \
1689 (X ((op), (xop)) | ((((unsigned long)(fxm)) & 0xff) << 12)) 1796 (X ((op), (xop)) | ((((unsigned long)(fxm)) & 0xff) << 12) \
1797 | ((unsigned long)(p4) << 20))
1690 1798
1691/* An XFX form instruction with the SPR field filled in. */ 1799/* An XFX form instruction with the SPR field filled in. */
1692#define XSPR(op, xop, spr) \ 1800#define XSPR(op, xop, spr) \
@@ -1699,7 +1807,7 @@ extract_tbr (unsigned long insn,
1699 1807
1700/* An XFX form instruction with the SPR field filled in except for the 1808/* An XFX form instruction with the SPR field filled in except for the
1701 SPRG field. */ 1809 SPRG field. */
1702#define XSPRG_MASK (XSPR_MASK &~ SPRG_MASK) 1810#define XSPRG_MASK (XSPR_MASK & ~(0x17 << 16))
1703 1811
1704/* An X form instruction with everything filled in except the E field. */ 1812/* An X form instruction with everything filled in except the E field. */
1705#define XE_MASK (0xffff7fff) 1813#define XE_MASK (0xffff7fff)
@@ -1769,6 +1877,9 @@ extract_tbr (unsigned long insn,
1769#define PPCCOM PPC_OPCODE_PPC | PPC_OPCODE_COMMON 1877#define PPCCOM PPC_OPCODE_PPC | PPC_OPCODE_COMMON
1770#define NOPOWER4 PPC_OPCODE_NOPOWER4 | PPCCOM 1878#define NOPOWER4 PPC_OPCODE_NOPOWER4 | PPCCOM
1771#define POWER4 PPC_OPCODE_POWER4 1879#define POWER4 PPC_OPCODE_POWER4
1880#define POWER5 PPC_OPCODE_POWER5
1881#define POWER6 PPC_OPCODE_POWER6
1882#define CELL PPC_OPCODE_CELL
1772#define PPC32 PPC_OPCODE_32 | PPC_OPCODE_PPC 1883#define PPC32 PPC_OPCODE_32 | PPC_OPCODE_PPC
1773#define PPC64 PPC_OPCODE_64 | PPC_OPCODE_PPC 1884#define PPC64 PPC_OPCODE_64 | PPC_OPCODE_PPC
1774#define PPC403 PPC_OPCODE_403 1885#define PPC403 PPC_OPCODE_403
@@ -1776,7 +1887,7 @@ extract_tbr (unsigned long insn,
1776#define PPC440 PPC_OPCODE_440 1887#define PPC440 PPC_OPCODE_440
1777#define PPC750 PPC 1888#define PPC750 PPC
1778#define PPC860 PPC 1889#define PPC860 PPC
1779#define PPCVEC PPC_OPCODE_ALTIVEC | PPC_OPCODE_PPC 1890#define PPCVEC PPC_OPCODE_ALTIVEC
1780#define POWER PPC_OPCODE_POWER 1891#define POWER PPC_OPCODE_POWER
1781#define POWER2 PPC_OPCODE_POWER | PPC_OPCODE_POWER2 1892#define POWER2 PPC_OPCODE_POWER | PPC_OPCODE_POWER2
1782#define PPCPWR2 PPC_OPCODE_PPC | PPC_OPCODE_POWER | PPC_OPCODE_POWER2 1893#define PPCPWR2 PPC_OPCODE_PPC | PPC_OPCODE_POWER | PPC_OPCODE_POWER2
@@ -1790,6 +1901,7 @@ extract_tbr (unsigned long insn,
1790#define BOOKE PPC_OPCODE_BOOKE 1901#define BOOKE PPC_OPCODE_BOOKE
1791#define BOOKE64 PPC_OPCODE_BOOKE64 1902#define BOOKE64 PPC_OPCODE_BOOKE64
1792#define CLASSIC PPC_OPCODE_CLASSIC 1903#define CLASSIC PPC_OPCODE_CLASSIC
1904#define PPCE300 PPC_OPCODE_E300
1793#define PPCSPE PPC_OPCODE_SPE 1905#define PPCSPE PPC_OPCODE_SPE
1794#define PPCISEL PPC_OPCODE_ISEL 1906#define PPCISEL PPC_OPCODE_ISEL
1795#define PPCEFS PPC_OPCODE_EFS 1907#define PPCEFS PPC_OPCODE_EFS
@@ -1952,6 +2064,41 @@ const struct powerpc_opcode powerpc_opcodes[] = {
1952{ "nmaclhwso.", XO(4,494,1,1), XO_MASK, PPC405|PPC440, { RT, RA, RB } }, 2064{ "nmaclhwso.", XO(4,494,1,1), XO_MASK, PPC405|PPC440, { RT, RA, RB } },
1953{ "mfvscr", VX(4, 1540), VX_MASK, PPCVEC, { VD } }, 2065{ "mfvscr", VX(4, 1540), VX_MASK, PPCVEC, { VD } },
1954{ "mtvscr", VX(4, 1604), VX_MASK, PPCVEC, { VB } }, 2066{ "mtvscr", VX(4, 1604), VX_MASK, PPCVEC, { VB } },
2067
2068 /* Double-precision opcodes. */
2069 /* Some of these conflict with AltiVec, so move them before, since
2070 PPCVEC includes the PPC_OPCODE_PPC set. */
2071{ "efscfd", VX(4, 719), VX_MASK, PPCEFS, { RS, RB } },
2072{ "efdabs", VX(4, 740), VX_MASK, PPCEFS, { RS, RA } },
2073{ "efdnabs", VX(4, 741), VX_MASK, PPCEFS, { RS, RA } },
2074{ "efdneg", VX(4, 742), VX_MASK, PPCEFS, { RS, RA } },
2075{ "efdadd", VX(4, 736), VX_MASK, PPCEFS, { RS, RA, RB } },
2076{ "efdsub", VX(4, 737), VX_MASK, PPCEFS, { RS, RA, RB } },
2077{ "efdmul", VX(4, 744), VX_MASK, PPCEFS, { RS, RA, RB } },
2078{ "efddiv", VX(4, 745), VX_MASK, PPCEFS, { RS, RA, RB } },
2079{ "efdcmpgt", VX(4, 748), VX_MASK, PPCEFS, { CRFD, RA, RB } },
2080{ "efdcmplt", VX(4, 749), VX_MASK, PPCEFS, { CRFD, RA, RB } },
2081{ "efdcmpeq", VX(4, 750), VX_MASK, PPCEFS, { CRFD, RA, RB } },
2082{ "efdtstgt", VX(4, 764), VX_MASK, PPCEFS, { CRFD, RA, RB } },
2083{ "efdtstlt", VX(4, 765), VX_MASK, PPCEFS, { CRFD, RA, RB } },
2084{ "efdtsteq", VX(4, 766), VX_MASK, PPCEFS, { CRFD, RA, RB } },
2085{ "efdcfsi", VX(4, 753), VX_MASK, PPCEFS, { RS, RB } },
2086{ "efdcfsid", VX(4, 739), VX_MASK, PPCEFS, { RS, RB } },
2087{ "efdcfui", VX(4, 752), VX_MASK, PPCEFS, { RS, RB } },
2088{ "efdcfuid", VX(4, 738), VX_MASK, PPCEFS, { RS, RB } },
2089{ "efdcfsf", VX(4, 755), VX_MASK, PPCEFS, { RS, RB } },
2090{ "efdcfuf", VX(4, 754), VX_MASK, PPCEFS, { RS, RB } },
2091{ "efdctsi", VX(4, 757), VX_MASK, PPCEFS, { RS, RB } },
2092{ "efdctsidz",VX(4, 747), VX_MASK, PPCEFS, { RS, RB } },
2093{ "efdctsiz", VX(4, 762), VX_MASK, PPCEFS, { RS, RB } },
2094{ "efdctui", VX(4, 756), VX_MASK, PPCEFS, { RS, RB } },
2095{ "efdctuidz",VX(4, 746), VX_MASK, PPCEFS, { RS, RB } },
2096{ "efdctuiz", VX(4, 760), VX_MASK, PPCEFS, { RS, RB } },
2097{ "efdctsf", VX(4, 759), VX_MASK, PPCEFS, { RS, RB } },
2098{ "efdctuf", VX(4, 758), VX_MASK, PPCEFS, { RS, RB } },
2099{ "efdcfs", VX(4, 751), VX_MASK, PPCEFS, { RS, RB } },
2100 /* End of double-precision opcodes. */
2101
1955{ "vaddcuw", VX(4, 384), VX_MASK, PPCVEC, { VD, VA, VB } }, 2102{ "vaddcuw", VX(4, 384), VX_MASK, PPCVEC, { VD, VA, VB } },
1956{ "vaddfp", VX(4, 10), VX_MASK, PPCVEC, { VD, VA, VB } }, 2103{ "vaddfp", VX(4, 10), VX_MASK, PPCVEC, { VD, VA, VB } },
1957{ "vaddsbs", VX(4, 768), VX_MASK, PPCVEC, { VD, VA, VB } }, 2104{ "vaddsbs", VX(4, 768), VX_MASK, PPCVEC, { VD, VA, VB } },
@@ -2389,16 +2536,16 @@ const struct powerpc_opcode powerpc_opcodes[] = {
2389 2536
2390{ "li", OP(14), DRA_MASK, PPCCOM, { RT, SI } }, 2537{ "li", OP(14), DRA_MASK, PPCCOM, { RT, SI } },
2391{ "lil", OP(14), DRA_MASK, PWRCOM, { RT, SI } }, 2538{ "lil", OP(14), DRA_MASK, PWRCOM, { RT, SI } },
2392{ "addi", OP(14), OP_MASK, PPCCOM, { RT, RA, SI } }, 2539{ "addi", OP(14), OP_MASK, PPCCOM, { RT, RA0, SI } },
2393{ "cal", OP(14), OP_MASK, PWRCOM, { RT, D, RA } }, 2540{ "cal", OP(14), OP_MASK, PWRCOM, { RT, D, RA0 } },
2394{ "subi", OP(14), OP_MASK, PPCCOM, { RT, RA, NSI } }, 2541{ "subi", OP(14), OP_MASK, PPCCOM, { RT, RA0, NSI } },
2395{ "la", OP(14), OP_MASK, PPCCOM, { RT, D, RA } }, 2542{ "la", OP(14), OP_MASK, PPCCOM, { RT, D, RA0 } },
2396 2543
2397{ "lis", OP(15), DRA_MASK, PPCCOM, { RT, SISIGNOPT } }, 2544{ "lis", OP(15), DRA_MASK, PPCCOM, { RT, SISIGNOPT } },
2398{ "liu", OP(15), DRA_MASK, PWRCOM, { RT, SISIGNOPT } }, 2545{ "liu", OP(15), DRA_MASK, PWRCOM, { RT, SISIGNOPT } },
2399{ "addis", OP(15), OP_MASK, PPCCOM, { RT,RA,SISIGNOPT } }, 2546{ "addis", OP(15), OP_MASK, PPCCOM, { RT,RA0,SISIGNOPT } },
2400{ "cau", OP(15), OP_MASK, PWRCOM, { RT,RA,SISIGNOPT } }, 2547{ "cau", OP(15), OP_MASK, PWRCOM, { RT,RA0,SISIGNOPT } },
2401{ "subis", OP(15), OP_MASK, PPCCOM, { RT, RA, NSI } }, 2548{ "subis", OP(15), OP_MASK, PPCCOM, { RT, RA0, NSI } },
2402 2549
2403{ "bdnz-", BBO(16,BODNZ,0,0), BBOATBI_MASK, PPCCOM, { BDM } }, 2550{ "bdnz-", BBO(16,BODNZ,0,0), BBOATBI_MASK, PPCCOM, { BDM } },
2404{ "bdnz+", BBO(16,BODNZ,0,0), BBOATBI_MASK, PPCCOM, { BDP } }, 2551{ "bdnz+", BBO(16,BODNZ,0,0), BBOATBI_MASK, PPCCOM, { BDP } },
@@ -2665,9 +2812,9 @@ const struct powerpc_opcode powerpc_opcodes[] = {
2665{ "bcla+", B(16,1,1), B_MASK, PPCCOM, { BOE, BI, BDPA } }, 2812{ "bcla+", B(16,1,1), B_MASK, PPCCOM, { BOE, BI, BDPA } },
2666{ "bcla", B(16,1,1), B_MASK, COM, { BO, BI, BDA } }, 2813{ "bcla", B(16,1,1), B_MASK, COM, { BO, BI, BDA } },
2667 2814
2668{ "sc", SC(17,1,0), 0xffffffff, PPC, { 0 } }, 2815{ "sc", SC(17,1,0), SC_MASK, PPC, { LEV } },
2669{ "svc", SC(17,0,0), SC_MASK, POWER, { LEV, FL1, FL2 } }, 2816{ "svc", SC(17,0,0), SC_MASK, POWER, { SVC_LEV, FL1, FL2 } },
2670{ "svcl", SC(17,0,1), SC_MASK, POWER, { LEV, FL1, FL2 } }, 2817{ "svcl", SC(17,0,1), SC_MASK, POWER, { SVC_LEV, FL1, FL2 } },
2671{ "svca", SC(17,1,0), SC_MASK, PWRCOM, { SV } }, 2818{ "svca", SC(17,1,0), SC_MASK, PWRCOM, { SV } },
2672{ "svcla", SC(17,1,1), SC_MASK, POWER, { SV } }, 2819{ "svcla", SC(17,1,1), SC_MASK, POWER, { SV } },
2673 2820
@@ -2890,12 +3037,12 @@ const struct powerpc_opcode powerpc_opcodes[] = {
2890{ "bdzflrl", XLO(19,BODZF,16,1), XLBOBB_MASK, PPCCOM, { BI } }, 3037{ "bdzflrl", XLO(19,BODZF,16,1), XLBOBB_MASK, PPCCOM, { BI } },
2891{ "bdzflrl-",XLO(19,BODZF,16,1), XLBOBB_MASK, NOPOWER4, { BI } }, 3038{ "bdzflrl-",XLO(19,BODZF,16,1), XLBOBB_MASK, NOPOWER4, { BI } },
2892{ "bdzflrl+",XLO(19,BODZFP,16,1), XLBOBB_MASK, NOPOWER4, { BI } }, 3039{ "bdzflrl+",XLO(19,BODZFP,16,1), XLBOBB_MASK, NOPOWER4, { BI } },
2893{ "bclr", XLLK(19,16,0), XLYBB_MASK, PPCCOM, { BO, BI } },
2894{ "bclrl", XLLK(19,16,1), XLYBB_MASK, PPCCOM, { BO, BI } },
2895{ "bclr+", XLYLK(19,16,1,0), XLYBB_MASK, PPCCOM, { BOE, BI } }, 3040{ "bclr+", XLYLK(19,16,1,0), XLYBB_MASK, PPCCOM, { BOE, BI } },
2896{ "bclrl+", XLYLK(19,16,1,1), XLYBB_MASK, PPCCOM, { BOE, BI } }, 3041{ "bclrl+", XLYLK(19,16,1,1), XLYBB_MASK, PPCCOM, { BOE, BI } },
2897{ "bclr-", XLYLK(19,16,0,0), XLYBB_MASK, PPCCOM, { BOE, BI } }, 3042{ "bclr-", XLYLK(19,16,0,0), XLYBB_MASK, PPCCOM, { BOE, BI } },
2898{ "bclrl-", XLYLK(19,16,0,1), XLYBB_MASK, PPCCOM, { BOE, BI } }, 3043{ "bclrl-", XLYLK(19,16,0,1), XLYBB_MASK, PPCCOM, { BOE, BI } },
3044{ "bclr", XLLK(19,16,0), XLBH_MASK, PPCCOM, { BO, BI, BH } },
3045{ "bclrl", XLLK(19,16,1), XLBH_MASK, PPCCOM, { BO, BI, BH } },
2899{ "bcr", XLLK(19,16,0), XLBB_MASK, PWRCOM, { BO, BI } }, 3046{ "bcr", XLLK(19,16,0), XLBB_MASK, PWRCOM, { BO, BI } },
2900{ "bcrl", XLLK(19,16,1), XLBB_MASK, PWRCOM, { BO, BI } }, 3047{ "bcrl", XLLK(19,16,1), XLBB_MASK, PWRCOM, { BO, BI } },
2901{ "bclre", XLLK(19,17,0), XLBB_MASK, BOOKE64, { BO, BI } }, 3048{ "bclre", XLLK(19,17,0), XLBB_MASK, BOOKE64, { BO, BI } },
@@ -2924,14 +3071,23 @@ const struct powerpc_opcode powerpc_opcodes[] = {
2924 3071
2925{ "crand", XL(19,257), XL_MASK, COM, { BT, BA, BB } }, 3072{ "crand", XL(19,257), XL_MASK, COM, { BT, BA, BB } },
2926 3073
3074{ "hrfid", XL(19,274), 0xffffffff, POWER5 | CELL, { 0 } },
3075
2927{ "crset", XL(19,289), XL_MASK, PPCCOM, { BT, BAT, BBA } }, 3076{ "crset", XL(19,289), XL_MASK, PPCCOM, { BT, BAT, BBA } },
2928{ "creqv", XL(19,289), XL_MASK, COM, { BT, BA, BB } }, 3077{ "creqv", XL(19,289), XL_MASK, COM, { BT, BA, BB } },
2929 3078
3079{ "doze", XL(19,402), 0xffffffff, POWER6, { 0 } },
3080
2930{ "crorc", XL(19,417), XL_MASK, COM, { BT, BA, BB } }, 3081{ "crorc", XL(19,417), XL_MASK, COM, { BT, BA, BB } },
2931 3082
3083{ "nap", XL(19,434), 0xffffffff, POWER6, { 0 } },
3084
2932{ "crmove", XL(19,449), XL_MASK, PPCCOM, { BT, BA, BBA } }, 3085{ "crmove", XL(19,449), XL_MASK, PPCCOM, { BT, BA, BBA } },
2933{ "cror", XL(19,449), XL_MASK, COM, { BT, BA, BB } }, 3086{ "cror", XL(19,449), XL_MASK, COM, { BT, BA, BB } },
2934 3087
3088{ "sleep", XL(19,466), 0xffffffff, POWER6, { 0 } },
3089{ "rvwinkle", XL(19,498), 0xffffffff, POWER6, { 0 } },
3090
2935{ "bctr", XLO(19,BOU,528,0), XLBOBIBB_MASK, COM, { 0 } }, 3091{ "bctr", XLO(19,BOU,528,0), XLBOBIBB_MASK, COM, { 0 } },
2936{ "bctrl", XLO(19,BOU,528,1), XLBOBIBB_MASK, COM, { 0 } }, 3092{ "bctrl", XLO(19,BOU,528,1), XLBOBIBB_MASK, COM, { 0 } },
2937{ "bltctr", XLOCB(19,BOT,CBLT,528,0), XLBOCBBB_MASK, PPCCOM, { CR } }, 3093{ "bltctr", XLOCB(19,BOT,CBLT,528,0), XLBOCBBB_MASK, PPCCOM, { CR } },
@@ -3074,12 +3230,12 @@ const struct powerpc_opcode powerpc_opcodes[] = {
3074{ "bfctrl-", XLO(19,BOFM4,528,1), XLBOBB_MASK, POWER4, { BI } }, 3230{ "bfctrl-", XLO(19,BOFM4,528,1), XLBOBB_MASK, POWER4, { BI } },
3075{ "bfctrl+", XLO(19,BOFP,528,1), XLBOBB_MASK, NOPOWER4, { BI } }, 3231{ "bfctrl+", XLO(19,BOFP,528,1), XLBOBB_MASK, NOPOWER4, { BI } },
3076{ "bfctrl+", XLO(19,BOFP4,528,1), XLBOBB_MASK, POWER4, { BI } }, 3232{ "bfctrl+", XLO(19,BOFP4,528,1), XLBOBB_MASK, POWER4, { BI } },
3077{ "bcctr", XLLK(19,528,0), XLYBB_MASK, PPCCOM, { BO, BI } },
3078{ "bcctr-", XLYLK(19,528,0,0), XLYBB_MASK, PPCCOM, { BOE, BI } }, 3233{ "bcctr-", XLYLK(19,528,0,0), XLYBB_MASK, PPCCOM, { BOE, BI } },
3079{ "bcctr+", XLYLK(19,528,1,0), XLYBB_MASK, PPCCOM, { BOE, BI } }, 3234{ "bcctr+", XLYLK(19,528,1,0), XLYBB_MASK, PPCCOM, { BOE, BI } },
3080{ "bcctrl", XLLK(19,528,1), XLYBB_MASK, PPCCOM, { BO, BI } },
3081{ "bcctrl-", XLYLK(19,528,0,1), XLYBB_MASK, PPCCOM, { BOE, BI } }, 3235{ "bcctrl-", XLYLK(19,528,0,1), XLYBB_MASK, PPCCOM, { BOE, BI } },
3082{ "bcctrl+", XLYLK(19,528,1,1), XLYBB_MASK, PPCCOM, { BOE, BI } }, 3236{ "bcctrl+", XLYLK(19,528,1,1), XLYBB_MASK, PPCCOM, { BOE, BI } },
3237{ "bcctr", XLLK(19,528,0), XLBH_MASK, PPCCOM, { BO, BI, BH } },
3238{ "bcctrl", XLLK(19,528,1), XLBH_MASK, PPCCOM, { BO, BI, BH } },
3083{ "bcc", XLLK(19,528,0), XLBB_MASK, PWRCOM, { BO, BI } }, 3239{ "bcc", XLLK(19,528,0), XLBB_MASK, PWRCOM, { BO, BI } },
3084{ "bccl", XLLK(19,528,1), XLBB_MASK, PWRCOM, { BO, BI } }, 3240{ "bccl", XLLK(19,528,1), XLBB_MASK, PWRCOM, { BO, BI } },
3085{ "bcctre", XLLK(19,529,0), XLYBB_MASK, BOOKE64, { BO, BI } }, 3241{ "bcctre", XLLK(19,529,0), XLYBB_MASK, BOOKE64, { BO, BI } },
@@ -3158,8 +3314,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
3158{ "rldcr", MDS(30,9,0), MDS_MASK, PPC64, { RA, RS, RB, ME6 } }, 3314{ "rldcr", MDS(30,9,0), MDS_MASK, PPC64, { RA, RS, RB, ME6 } },
3159{ "rldcr.", MDS(30,9,1), MDS_MASK, PPC64, { RA, RS, RB, ME6 } }, 3315{ "rldcr.", MDS(30,9,1), MDS_MASK, PPC64, { RA, RS, RB, ME6 } },
3160 3316
3161{ "cmpw", XCMPL(31,0,0), XCMPL_MASK, PPCCOM, { OBF, RA, RB } }, 3317{ "cmpw", XOPL(31,0,0), XCMPL_MASK, PPCCOM, { OBF, RA, RB } },
3162{ "cmpd", XCMPL(31,0,1), XCMPL_MASK, PPC64, { OBF, RA, RB } }, 3318{ "cmpd", XOPL(31,0,1), XCMPL_MASK, PPC64, { OBF, RA, RB } },
3163{ "cmp", X(31,0), XCMP_MASK, PPC, { BF, L, RA, RB } }, 3319{ "cmp", X(31,0), XCMP_MASK, PPC, { BF, L, RA, RB } },
3164{ "cmp", X(31,0), XCMPL_MASK, PWRCOM, { BF, RA, RB } }, 3320{ "cmp", X(31,0), XCMPL_MASK, PWRCOM, { BF, RA, RB } },
3165 3321
@@ -3228,17 +3384,18 @@ const struct powerpc_opcode powerpc_opcodes[] = {
3228{ "iseleq", X(31,79), X_MASK, PPCISEL, { RT, RA, RB } }, 3384{ "iseleq", X(31,79), X_MASK, PPCISEL, { RT, RA, RB } },
3229{ "isel", XISEL(31,15), XISEL_MASK, PPCISEL, { RT, RA, RB, CRB } }, 3385{ "isel", XISEL(31,15), XISEL_MASK, PPCISEL, { RT, RA, RB, CRB } },
3230 3386
3231{ "mfcr", X(31,19), XRARB_MASK, NOPOWER4, { RT } }, 3387{ "mfocrf", XFXM(31,19,0,1), XFXFXM_MASK, COM, { RT, FXM } },
3388{ "mfcr", X(31,19), XRARB_MASK, NOPOWER4 | COM, { RT } },
3232{ "mfcr", X(31,19), XFXFXM_MASK, POWER4, { RT, FXM4 } }, 3389{ "mfcr", X(31,19), XFXFXM_MASK, POWER4, { RT, FXM4 } },
3233 3390
3234{ "lwarx", X(31,20), X_MASK, PPC, { RT, RA, RB } }, 3391{ "lwarx", X(31,20), XEH_MASK, PPC, { RT, RA0, RB, EH } },
3235 3392
3236{ "ldx", X(31,21), X_MASK, PPC64, { RT, RA, RB } }, 3393{ "ldx", X(31,21), X_MASK, PPC64, { RT, RA0, RB } },
3237 3394
3238{ "icbt", X(31,22), X_MASK, BOOKE, { CT, RA, RB } }, 3395{ "icbt", X(31,22), X_MASK, BOOKE|PPCE300, { CT, RA, RB } },
3239{ "icbt", X(31,262), XRT_MASK, PPC403, { RA, RB } }, 3396{ "icbt", X(31,262), XRT_MASK, PPC403, { RA, RB } },
3240 3397
3241{ "lwzx", X(31,23), X_MASK, PPCCOM, { RT, RA, RB } }, 3398{ "lwzx", X(31,23), X_MASK, PPCCOM, { RT, RA0, RB } },
3242{ "lx", X(31,23), X_MASK, PWRCOM, { RT, RA, RB } }, 3399{ "lx", X(31,23), X_MASK, PWRCOM, { RT, RA, RB } },
3243 3400
3244{ "slw", XRC(31,24,0), X_MASK, PPCCOM, { RA, RS, RB } }, 3401{ "slw", XRC(31,24,0), X_MASK, PPCCOM, { RA, RS, RB } },
@@ -3262,10 +3419,10 @@ const struct powerpc_opcode powerpc_opcodes[] = {
3262 3419
3263{ "icbte", X(31,30), X_MASK, BOOKE64, { CT, RA, RB } }, 3420{ "icbte", X(31,30), X_MASK, BOOKE64, { CT, RA, RB } },
3264 3421
3265{ "lwzxe", X(31,31), X_MASK, BOOKE64, { RT, RA, RB } }, 3422{ "lwzxe", X(31,31), X_MASK, BOOKE64, { RT, RA0, RB } },
3266 3423
3267{ "cmplw", XCMPL(31,32,0), XCMPL_MASK, PPCCOM, { OBF, RA, RB } }, 3424{ "cmplw", XOPL(31,32,0), XCMPL_MASK, PPCCOM, { OBF, RA, RB } },
3268{ "cmpld", XCMPL(31,32,1), XCMPL_MASK, PPC64, { OBF, RA, RB } }, 3425{ "cmpld", XOPL(31,32,1), XCMPL_MASK, PPC64, { OBF, RA, RB } },
3269{ "cmpl", X(31,32), XCMP_MASK, PPC, { BF, L, RA, RB } }, 3426{ "cmpl", X(31,32), XCMP_MASK, PPC, { BF, L, RA, RB } },
3270{ "cmpl", X(31,32), XCMPL_MASK, PWRCOM, { BF, RA, RB } }, 3427{ "cmpl", X(31,32), XCMPL_MASK, PWRCOM, { BF, RA, RB } },
3271 3428
@@ -3324,15 +3481,16 @@ const struct powerpc_opcode powerpc_opcodes[] = {
3324 3481
3325{ "mfmsr", X(31,83), XRARB_MASK, COM, { RT } }, 3482{ "mfmsr", X(31,83), XRARB_MASK, COM, { RT } },
3326 3483
3327{ "ldarx", X(31,84), X_MASK, PPC64, { RT, RA, RB } }, 3484{ "ldarx", X(31,84), XEH_MASK, PPC64, { RT, RA0, RB, EH } },
3328 3485
3329{ "dcbf", X(31,86), XRT_MASK, PPC, { RA, RB } }, 3486{ "dcbfl", XOPL(31,86,1), XRT_MASK, POWER5, { RA, RB } },
3487{ "dcbf", X(31,86), XLRT_MASK, PPC, { RA, RB, XRT_L } },
3330 3488
3331{ "lbzx", X(31,87), X_MASK, COM, { RT, RA, RB } }, 3489{ "lbzx", X(31,87), X_MASK, COM, { RT, RA0, RB } },
3332 3490
3333{ "dcbfe", X(31,94), XRT_MASK, BOOKE64, { RA, RB } }, 3491{ "dcbfe", X(31,94), XRT_MASK, BOOKE64, { RA, RB } },
3334 3492
3335{ "lbzxe", X(31,95), X_MASK, BOOKE64, { RT, RA, RB } }, 3493{ "lbzxe", X(31,95), X_MASK, BOOKE64, { RT, RA0, RB } },
3336 3494
3337{ "neg", XO(31,104,0,0), XORB_MASK, COM, { RT, RA } }, 3495{ "neg", XO(31,104,0,0), XORB_MASK, COM, { RT, RA } },
3338{ "neg.", XO(31,104,0,1), XORB_MASK, COM, { RT, RA } }, 3496{ "neg.", XO(31,104,0,1), XORB_MASK, COM, { RT, RA } },
@@ -3350,12 +3508,14 @@ const struct powerpc_opcode powerpc_opcodes[] = {
3350 3508
3351{ "lbzux", X(31,119), X_MASK, COM, { RT, RAL, RB } }, 3509{ "lbzux", X(31,119), X_MASK, COM, { RT, RAL, RB } },
3352 3510
3511{ "popcntb", X(31,122), XRB_MASK, POWER5, { RA, RS } },
3512
3353{ "not", XRC(31,124,0), X_MASK, COM, { RA, RS, RBS } }, 3513{ "not", XRC(31,124,0), X_MASK, COM, { RA, RS, RBS } },
3354{ "nor", XRC(31,124,0), X_MASK, COM, { RA, RS, RB } }, 3514{ "nor", XRC(31,124,0), X_MASK, COM, { RA, RS, RB } },
3355{ "not.", XRC(31,124,1), X_MASK, COM, { RA, RS, RBS } }, 3515{ "not.", XRC(31,124,1), X_MASK, COM, { RA, RS, RBS } },
3356{ "nor.", XRC(31,124,1), X_MASK, COM, { RA, RS, RB } }, 3516{ "nor.", XRC(31,124,1), X_MASK, COM, { RA, RS, RB } },
3357 3517
3358{ "lwarxe", X(31,126), X_MASK, BOOKE64, { RT, RA, RB } }, 3518{ "lwarxe", X(31,126), X_MASK, BOOKE64, { RT, RA0, RB } },
3359 3519
3360{ "lbzuxe", X(31,127), X_MASK, BOOKE64, { RT, RAL, RB } }, 3520{ "lbzuxe", X(31,127), X_MASK, BOOKE64, { RT, RAL, RB } },
3361 3521
@@ -3383,21 +3543,22 @@ const struct powerpc_opcode powerpc_opcodes[] = {
3383 3543
3384{ "dcbtstlse",X(31,142),X_MASK, PPCCHLK64, { CT, RA, RB }}, 3544{ "dcbtstlse",X(31,142),X_MASK, PPCCHLK64, { CT, RA, RB }},
3385 3545
3386{ "mtcr", XFXM(31,144,0xff), XRARB_MASK, COM, { RS }}, 3546{ "mtocrf", XFXM(31,144,0,1), XFXFXM_MASK, COM, { FXM, RS } },
3547{ "mtcr", XFXM(31,144,0xff,0), XRARB_MASK, COM, { RS }},
3387{ "mtcrf", X(31,144), XFXFXM_MASK, COM, { FXM, RS } }, 3548{ "mtcrf", X(31,144), XFXFXM_MASK, COM, { FXM, RS } },
3388 3549
3389{ "mtmsr", X(31,146), XRARB_MASK, COM, { RS } }, 3550{ "mtmsr", X(31,146), XRARB_MASK, COM, { RS } },
3390 3551
3391{ "stdx", X(31,149), X_MASK, PPC64, { RS, RA, RB } }, 3552{ "stdx", X(31,149), X_MASK, PPC64, { RS, RA0, RB } },
3392 3553
3393{ "stwcx.", XRC(31,150,1), X_MASK, PPC, { RS, RA, RB } }, 3554{ "stwcx.", XRC(31,150,1), X_MASK, PPC, { RS, RA0, RB } },
3394 3555
3395{ "stwx", X(31,151), X_MASK, PPCCOM, { RS, RA, RB } }, 3556{ "stwx", X(31,151), X_MASK, PPCCOM, { RS, RA0, RB } },
3396{ "stx", X(31,151), X_MASK, PWRCOM, { RS, RA, RB } }, 3557{ "stx", X(31,151), X_MASK, PWRCOM, { RS, RA, RB } },
3397 3558
3398{ "stwcxe.", XRC(31,158,1), X_MASK, BOOKE64, { RS, RA, RB } }, 3559{ "stwcxe.", XRC(31,158,1), X_MASK, BOOKE64, { RS, RA0, RB } },
3399 3560
3400{ "stwxe", X(31,159), X_MASK, BOOKE64, { RS, RA, RB } }, 3561{ "stwxe", X(31,159), X_MASK, BOOKE64, { RS, RA0, RB } },
3401 3562
3402{ "slq", XRC(31,152,0), X_MASK, M601, { RA, RS, RB } }, 3563{ "slq", XRC(31,152,0), X_MASK, M601, { RA, RS, RB } },
3403{ "slq.", XRC(31,152,1), X_MASK, M601, { RA, RS, RB } }, 3564{ "slq.", XRC(31,152,1), X_MASK, M601, { RA, RS, RB } },
@@ -3405,6 +3566,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
3405{ "sle", XRC(31,153,0), X_MASK, M601, { RA, RS, RB } }, 3566{ "sle", XRC(31,153,0), X_MASK, M601, { RA, RS, RB } },
3406{ "sle.", XRC(31,153,1), X_MASK, M601, { RA, RS, RB } }, 3567{ "sle.", XRC(31,153,1), X_MASK, M601, { RA, RS, RB } },
3407 3568
3569{ "prtyw", X(31,154), XRB_MASK, POWER6, { RA, RS } },
3570
3408{ "wrteei", X(31,163), XE_MASK, PPC403 | BOOKE, { E } }, 3571{ "wrteei", X(31,163), XE_MASK, PPC403 | BOOKE, { E } },
3409 3572
3410{ "dcbtls", X(31,166), X_MASK, PPCCHLK, { CT, RA, RB }}, 3573{ "dcbtls", X(31,166), X_MASK, PPCCHLK, { CT, RA, RB }},
@@ -3415,11 +3578,13 @@ const struct powerpc_opcode powerpc_opcodes[] = {
3415{ "stdux", X(31,181), X_MASK, PPC64, { RS, RAS, RB } }, 3578{ "stdux", X(31,181), X_MASK, PPC64, { RS, RAS, RB } },
3416 3579
3417{ "stwux", X(31,183), X_MASK, PPCCOM, { RS, RAS, RB } }, 3580{ "stwux", X(31,183), X_MASK, PPCCOM, { RS, RAS, RB } },
3418{ "stux", X(31,183), X_MASK, PWRCOM, { RS, RA, RB } }, 3581{ "stux", X(31,183), X_MASK, PWRCOM, { RS, RA0, RB } },
3419 3582
3420{ "sliq", XRC(31,184,0), X_MASK, M601, { RA, RS, SH } }, 3583{ "sliq", XRC(31,184,0), X_MASK, M601, { RA, RS, SH } },
3421{ "sliq.", XRC(31,184,1), X_MASK, M601, { RA, RS, SH } }, 3584{ "sliq.", XRC(31,184,1), X_MASK, M601, { RA, RS, SH } },
3422 3585
3586{ "prtyd", X(31,186), XRB_MASK, POWER6, { RA, RS } },
3587
3423{ "stwuxe", X(31,191), X_MASK, BOOKE64, { RS, RAS, RB } }, 3588{ "stwuxe", X(31,191), X_MASK, BOOKE64, { RS, RAS, RB } },
3424 3589
3425{ "subfze", XO(31,200,0,0), XORB_MASK, PPCCOM, { RT, RA } }, 3590{ "subfze", XO(31,200,0,0), XORB_MASK, PPCCOM, { RT, RA } },
@@ -3442,9 +3607,9 @@ const struct powerpc_opcode powerpc_opcodes[] = {
3442 3607
3443{ "mtsr", X(31,210), XRB_MASK|(1<<20), COM32, { SR, RS } }, 3608{ "mtsr", X(31,210), XRB_MASK|(1<<20), COM32, { SR, RS } },
3444 3609
3445{ "stdcx.", XRC(31,214,1), X_MASK, PPC64, { RS, RA, RB } }, 3610{ "stdcx.", XRC(31,214,1), X_MASK, PPC64, { RS, RA0, RB } },
3446 3611
3447{ "stbx", X(31,215), X_MASK, COM, { RS, RA, RB } }, 3612{ "stbx", X(31,215), X_MASK, COM, { RS, RA0, RB } },
3448 3613
3449{ "sllq", XRC(31,216,0), X_MASK, M601, { RA, RS, RB } }, 3614{ "sllq", XRC(31,216,0), X_MASK, M601, { RA, RS, RB } },
3450{ "sllq.", XRC(31,216,1), X_MASK, M601, { RA, RS, RB } }, 3615{ "sllq.", XRC(31,216,1), X_MASK, M601, { RA, RS, RB } },
@@ -3452,7 +3617,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
3452{ "sleq", XRC(31,217,0), X_MASK, M601, { RA, RS, RB } }, 3617{ "sleq", XRC(31,217,0), X_MASK, M601, { RA, RS, RB } },
3453{ "sleq.", XRC(31,217,1), X_MASK, M601, { RA, RS, RB } }, 3618{ "sleq.", XRC(31,217,1), X_MASK, M601, { RA, RS, RB } },
3454 3619
3455{ "stbxe", X(31,223), X_MASK, BOOKE64, { RS, RA, RB } }, 3620{ "stbxe", X(31,223), X_MASK, BOOKE64, { RS, RA0, RB } },
3456 3621
3457{ "icblc", X(31,230), X_MASK, PPCCHLK, { CT, RA, RB }}, 3622{ "icblc", X(31,230), X_MASK, PPCCHLK, { CT, RA, RB }},
3458 3623
@@ -3492,7 +3657,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
3492{ "mtsrin", X(31,242), XRA_MASK, PPC32, { RS, RB } }, 3657{ "mtsrin", X(31,242), XRA_MASK, PPC32, { RS, RB } },
3493{ "mtsri", X(31,242), XRA_MASK, POWER32, { RS, RB } }, 3658{ "mtsri", X(31,242), XRA_MASK, POWER32, { RS, RB } },
3494 3659
3495{ "dcbtst", X(31,246), XRT_MASK, PPC, { CT, RA, RB } }, 3660{ "dcbtst", X(31,246), X_MASK, PPC, { CT, RA, RB } },
3496 3661
3497{ "stbux", X(31,247), X_MASK, COM, { RS, RAS, RB } }, 3662{ "stbux", X(31,247), X_MASK, COM, { RS, RAS, RB } },
3498 3663
@@ -3519,26 +3684,26 @@ const struct powerpc_opcode powerpc_opcodes[] = {
3519{ "addo.", XO(31,266,1,1), XO_MASK, PPCCOM, { RT, RA, RB } }, 3684{ "addo.", XO(31,266,1,1), XO_MASK, PPCCOM, { RT, RA, RB } },
3520{ "caxo.", XO(31,266,1,1), XO_MASK, PWRCOM, { RT, RA, RB } }, 3685{ "caxo.", XO(31,266,1,1), XO_MASK, PWRCOM, { RT, RA, RB } },
3521 3686
3522{ "tlbiel", X(31,274), XRTRA_MASK, POWER4, { RB } }, 3687{ "tlbiel", X(31,274), XRTLRA_MASK, POWER4, { RB, L } },
3523 3688
3524{ "mfapidi", X(31,275), X_MASK, BOOKE, { RT, RA } }, 3689{ "mfapidi", X(31,275), X_MASK, BOOKE, { RT, RA } },
3525 3690
3526{ "lscbx", XRC(31,277,0), X_MASK, M601, { RT, RA, RB } }, 3691{ "lscbx", XRC(31,277,0), X_MASK, M601, { RT, RA, RB } },
3527{ "lscbx.", XRC(31,277,1), X_MASK, M601, { RT, RA, RB } }, 3692{ "lscbx.", XRC(31,277,1), X_MASK, M601, { RT, RA, RB } },
3528 3693
3529{ "dcbt", X(31,278), XRT_MASK, PPC, { CT, RA, RB } }, 3694{ "dcbt", X(31,278), X_MASK, PPC, { CT, RA, RB } },
3530 3695
3531{ "lhzx", X(31,279), X_MASK, COM, { RT, RA, RB } }, 3696{ "lhzx", X(31,279), X_MASK, COM, { RT, RA0, RB } },
3532 3697
3533{ "eqv", XRC(31,284,0), X_MASK, COM, { RA, RS, RB } }, 3698{ "eqv", XRC(31,284,0), X_MASK, COM, { RA, RS, RB } },
3534{ "eqv.", XRC(31,284,1), X_MASK, COM, { RA, RS, RB } }, 3699{ "eqv.", XRC(31,284,1), X_MASK, COM, { RA, RS, RB } },
3535 3700
3536{ "dcbte", X(31,286), X_MASK, BOOKE64, { CT, RA, RB } }, 3701{ "dcbte", X(31,286), X_MASK, BOOKE64, { CT, RA, RB } },
3537 3702
3538{ "lhzxe", X(31,287), X_MASK, BOOKE64, { RT, RA, RB } }, 3703{ "lhzxe", X(31,287), X_MASK, BOOKE64, { RT, RA0, RB } },
3539 3704
3540{ "tlbie", X(31,306), XRTLRA_MASK, PPC, { RB, L } }, 3705{ "tlbie", X(31,306), XRTLRA_MASK, PPC, { RB, L } },
3541{ "tlbi", X(31,306), XRT_MASK, POWER, { RA, RB } }, 3706{ "tlbi", X(31,306), XRT_MASK, POWER, { RA0, RB } },
3542 3707
3543{ "eciwx", X(31,310), X_MASK, PPC, { RT, RA, RB } }, 3708{ "eciwx", X(31,310), X_MASK, PPC, { RT, RA, RB } },
3544 3709
@@ -3607,6 +3772,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
3607{ "mfsdr1", XSPR(31,339,25), XSPR_MASK, COM, { RT } }, 3772{ "mfsdr1", XSPR(31,339,25), XSPR_MASK, COM, { RT } },
3608{ "mfsrr0", XSPR(31,339,26), XSPR_MASK, COM, { RT } }, 3773{ "mfsrr0", XSPR(31,339,26), XSPR_MASK, COM, { RT } },
3609{ "mfsrr1", XSPR(31,339,27), XSPR_MASK, COM, { RT } }, 3774{ "mfsrr1", XSPR(31,339,27), XSPR_MASK, COM, { RT } },
3775{ "mfcfar", XSPR(31,339,28), XSPR_MASK, POWER6, { RT } },
3610{ "mfpid", XSPR(31,339,48), XSPR_MASK, BOOKE, { RT } }, 3776{ "mfpid", XSPR(31,339,48), XSPR_MASK, BOOKE, { RT } },
3611{ "mfpid", XSPR(31,339,945), XSPR_MASK, PPC403, { RT } }, 3777{ "mfpid", XSPR(31,339,945), XSPR_MASK, PPC403, { RT } },
3612{ "mfcsrr0", XSPR(31,339,58), XSPR_MASK, BOOKE, { RT } }, 3778{ "mfcsrr0", XSPR(31,339,58), XSPR_MASK, BOOKE, { RT } },
@@ -3634,21 +3800,21 @@ const struct powerpc_opcode powerpc_opcodes[] = {
3634{ "mfbar", XSPR(31,339,159), XSPR_MASK, PPC860, { RT } }, 3800{ "mfbar", XSPR(31,339,159), XSPR_MASK, PPC860, { RT } },
3635{ "mfvrsave", XSPR(31,339,256), XSPR_MASK, PPCVEC, { RT } }, 3801{ "mfvrsave", XSPR(31,339,256), XSPR_MASK, PPCVEC, { RT } },
3636{ "mfusprg0", XSPR(31,339,256), XSPR_MASK, BOOKE, { RT } }, 3802{ "mfusprg0", XSPR(31,339,256), XSPR_MASK, BOOKE, { RT } },
3637{ "mfsprg4", XSPR(31,339,260), XSPR_MASK, PPC405, { RT } },
3638{ "mfsprg5", XSPR(31,339,261), XSPR_MASK, PPC405, { RT } },
3639{ "mfsprg6", XSPR(31,339,262), XSPR_MASK, PPC405, { RT } },
3640{ "mfsprg7", XSPR(31,339,263), XSPR_MASK, PPC405, { RT } },
3641{ "mftb", X(31,371), X_MASK, CLASSIC, { RT, TBR } }, 3803{ "mftb", X(31,371), X_MASK, CLASSIC, { RT, TBR } },
3642{ "mftb", XSPR(31,339,268), XSPR_MASK, BOOKE, { RT } }, 3804{ "mftb", XSPR(31,339,268), XSPR_MASK, BOOKE, { RT } },
3643{ "mftbl", XSPR(31,371,268), XSPR_MASK, CLASSIC, { RT } }, 3805{ "mftbl", XSPR(31,371,268), XSPR_MASK, CLASSIC, { RT } },
3644{ "mftbl", XSPR(31,339,268), XSPR_MASK, BOOKE, { RT } }, 3806{ "mftbl", XSPR(31,339,268), XSPR_MASK, BOOKE, { RT } },
3645{ "mftbu", XSPR(31,371,269), XSPR_MASK, CLASSIC, { RT } }, 3807{ "mftbu", XSPR(31,371,269), XSPR_MASK, CLASSIC, { RT } },
3646{ "mftbu", XSPR(31,339,269), XSPR_MASK, BOOKE, { RT } }, 3808{ "mftbu", XSPR(31,339,269), XSPR_MASK, BOOKE, { RT } },
3647{ "mfsprg", XSPR(31,339,272), XSPRG_MASK, PPC, { RT, SPRG } }, 3809{ "mfsprg", XSPR(31,339,256), XSPRG_MASK, PPC, { RT, SPRG } },
3648{ "mfsprg0", XSPR(31,339,272), XSPR_MASK, PPC, { RT } }, 3810{ "mfsprg0", XSPR(31,339,272), XSPR_MASK, PPC, { RT } },
3649{ "mfsprg1", XSPR(31,339,273), XSPR_MASK, PPC, { RT } }, 3811{ "mfsprg1", XSPR(31,339,273), XSPR_MASK, PPC, { RT } },
3650{ "mfsprg2", XSPR(31,339,274), XSPR_MASK, PPC, { RT } }, 3812{ "mfsprg2", XSPR(31,339,274), XSPR_MASK, PPC, { RT } },
3651{ "mfsprg3", XSPR(31,339,275), XSPR_MASK, PPC, { RT } }, 3813{ "mfsprg3", XSPR(31,339,275), XSPR_MASK, PPC, { RT } },
3814{ "mfsprg4", XSPR(31,339,260), XSPR_MASK, PPC405 | BOOKE, { RT } },
3815{ "mfsprg5", XSPR(31,339,261), XSPR_MASK, PPC405 | BOOKE, { RT } },
3816{ "mfsprg6", XSPR(31,339,262), XSPR_MASK, PPC405 | BOOKE, { RT } },
3817{ "mfsprg7", XSPR(31,339,263), XSPR_MASK, PPC405 | BOOKE, { RT } },
3652{ "mfasr", XSPR(31,339,280), XSPR_MASK, PPC64, { RT } }, 3818{ "mfasr", XSPR(31,339,280), XSPR_MASK, PPC64, { RT } },
3653{ "mfear", XSPR(31,339,282), XSPR_MASK, PPC, { RT } }, 3819{ "mfear", XSPR(31,339,282), XSPR_MASK, PPC, { RT } },
3654{ "mfpir", XSPR(31,339,286), XSPR_MASK, BOOKE, { RT } }, 3820{ "mfpir", XSPR(31,339,286), XSPR_MASK, BOOKE, { RT } },
@@ -3699,6 +3865,10 @@ const struct powerpc_opcode powerpc_opcodes[] = {
3699{ "mfspefscr", XSPR(31,339,512), XSPR_MASK, PPCSPE, { RT } }, 3865{ "mfspefscr", XSPR(31,339,512), XSPR_MASK, PPCSPE, { RT } },
3700{ "mfbbear", XSPR(31,339,513), XSPR_MASK, PPCBRLK, { RT } }, 3866{ "mfbbear", XSPR(31,339,513), XSPR_MASK, PPCBRLK, { RT } },
3701{ "mfbbtar", XSPR(31,339,514), XSPR_MASK, PPCBRLK, { RT } }, 3867{ "mfbbtar", XSPR(31,339,514), XSPR_MASK, PPCBRLK, { RT } },
3868{ "mfivor32", XSPR(31,339,528), XSPR_MASK, PPCSPE, { RT } },
3869{ "mfivor33", XSPR(31,339,529), XSPR_MASK, PPCSPE, { RT } },
3870{ "mfivor34", XSPR(31,339,530), XSPR_MASK, PPCSPE, { RT } },
3871{ "mfivor35", XSPR(31,339,531), XSPR_MASK, PPCPMR, { RT } },
3702{ "mfibatu", XSPR(31,339,528), XSPRBAT_MASK, PPC, { RT, SPRBAT } }, 3872{ "mfibatu", XSPR(31,339,528), XSPRBAT_MASK, PPC, { RT, SPRBAT } },
3703{ "mfibatl", XSPR(31,339,529), XSPRBAT_MASK, PPC, { RT, SPRBAT } }, 3873{ "mfibatl", XSPR(31,339,529), XSPRBAT_MASK, PPC, { RT, SPRBAT } },
3704{ "mfdbatu", XSPR(31,339,536), XSPRBAT_MASK, PPC, { RT, SPRBAT } }, 3874{ "mfdbatu", XSPR(31,339,536), XSPRBAT_MASK, PPC, { RT, SPRBAT } },
@@ -3708,10 +3878,11 @@ const struct powerpc_opcode powerpc_opcodes[] = {
3708{ "mfic_dat", XSPR(31,339,562), XSPR_MASK, PPC860, { RT } }, 3878{ "mfic_dat", XSPR(31,339,562), XSPR_MASK, PPC860, { RT } },
3709{ "mfdc_cst", XSPR(31,339,568), XSPR_MASK, PPC860, { RT } }, 3879{ "mfdc_cst", XSPR(31,339,568), XSPR_MASK, PPC860, { RT } },
3710{ "mfdc_adr", XSPR(31,339,569), XSPR_MASK, PPC860, { RT } }, 3880{ "mfdc_adr", XSPR(31,339,569), XSPR_MASK, PPC860, { RT } },
3711{ "mfdc_dat", XSPR(31,339,570), XSPR_MASK, PPC860, { RT } },
3712{ "mfmcsrr0", XSPR(31,339,570), XSPR_MASK, PPCRFMCI, { RT } }, 3881{ "mfmcsrr0", XSPR(31,339,570), XSPR_MASK, PPCRFMCI, { RT } },
3882{ "mfdc_dat", XSPR(31,339,570), XSPR_MASK, PPC860, { RT } },
3713{ "mfmcsrr1", XSPR(31,339,571), XSPR_MASK, PPCRFMCI, { RT } }, 3883{ "mfmcsrr1", XSPR(31,339,571), XSPR_MASK, PPCRFMCI, { RT } },
3714{ "mfmcsr", XSPR(31,339,572), XSPR_MASK, PPCRFMCI, { RT } }, 3884{ "mfmcsr", XSPR(31,339,572), XSPR_MASK, PPCRFMCI, { RT } },
3885{ "mfmcar", XSPR(31,339,573), XSPR_MASK, PPCRFMCI, { RT } },
3715{ "mfdpdr", XSPR(31,339,630), XSPR_MASK, PPC860, { RT } }, 3886{ "mfdpdr", XSPR(31,339,630), XSPR_MASK, PPC860, { RT } },
3716{ "mfdpir", XSPR(31,339,631), XSPR_MASK, PPC860, { RT } }, 3887{ "mfdpir", XSPR(31,339,631), XSPR_MASK, PPC860, { RT } },
3717{ "mfimmr", XSPR(31,339,638), XSPR_MASK, PPC860, { RT } }, 3888{ "mfimmr", XSPR(31,339,638), XSPR_MASK, PPC860, { RT } },
@@ -3775,14 +3946,14 @@ const struct powerpc_opcode powerpc_opcodes[] = {
3775{ "mfpbu2", XSPR(31,339,1023), XSPR_MASK, PPC403, { RT } }, 3946{ "mfpbu2", XSPR(31,339,1023), XSPR_MASK, PPC403, { RT } },
3776{ "mfspr", X(31,339), X_MASK, COM, { RT, SPR } }, 3947{ "mfspr", X(31,339), X_MASK, COM, { RT, SPR } },
3777 3948
3778{ "lwax", X(31,341), X_MASK, PPC64, { RT, RA, RB } }, 3949{ "lwax", X(31,341), X_MASK, PPC64, { RT, RA0, RB } },
3779 3950
3780{ "dst", XDSS(31,342,0), XDSS_MASK, PPCVEC, { RA, RB, STRM } }, 3951{ "dst", XDSS(31,342,0), XDSS_MASK, PPCVEC, { RA, RB, STRM } },
3781{ "dstt", XDSS(31,342,1), XDSS_MASK, PPCVEC, { RA, RB, STRM } }, 3952{ "dstt", XDSS(31,342,1), XDSS_MASK, PPCVEC, { RA, RB, STRM } },
3782 3953
3783{ "lhax", X(31,343), X_MASK, COM, { RT, RA, RB } }, 3954{ "lhax", X(31,343), X_MASK, COM, { RT, RA0, RB } },
3784 3955
3785{ "lhaxe", X(31,351), X_MASK, BOOKE64, { RT, RA, RB } }, 3956{ "lhaxe", X(31,351), X_MASK, BOOKE64, { RT, RA0, RB } },
3786 3957
3787{ "dstst", XDSS(31,374,0), XDSS_MASK, PPCVEC, { RA, RB, STRM } }, 3958{ "dstst", XDSS(31,374,0), XDSS_MASK, PPCVEC, { RA, RB, STRM } },
3788{ "dststt", XDSS(31,374,1), XDSS_MASK, PPCVEC, { RA, RB, STRM } }, 3959{ "dststt", XDSS(31,374,1), XDSS_MASK, PPCVEC, { RA, RB, STRM } },
@@ -3821,14 +3992,20 @@ const struct powerpc_opcode powerpc_opcodes[] = {
3821 3992
3822{ "slbmte", X(31,402), XRA_MASK, PPC64, { RS, RB } }, 3993{ "slbmte", X(31,402), XRA_MASK, PPC64, { RS, RB } },
3823 3994
3824{ "sthx", X(31,407), X_MASK, COM, { RS, RA, RB } }, 3995{ "sthx", X(31,407), X_MASK, COM, { RS, RA0, RB } },
3996
3997{ "cmpb", X(31,508), X_MASK, POWER6, { RA, RS, RB } },
3825 3998
3826{ "lfqx", X(31,791), X_MASK, POWER2, { FRT, RA, RB } }, 3999{ "lfqx", X(31,791), X_MASK, POWER2, { FRT, RA, RB } },
3827 4000
4001{ "lfdpx", X(31,791), X_MASK, POWER6, { FRT, RA, RB } },
4002
3828{ "lfqux", X(31,823), X_MASK, POWER2, { FRT, RA, RB } }, 4003{ "lfqux", X(31,823), X_MASK, POWER2, { FRT, RA, RB } },
3829 4004
3830{ "stfqx", X(31,919), X_MASK, POWER2, { FRS, RA, RB } }, 4005{ "stfqx", X(31,919), X_MASK, POWER2, { FRS, RA, RB } },
3831 4006
4007{ "stfdpx", X(31,919), X_MASK, POWER6, { FRS, RA, RB } },
4008
3832{ "stfqux", X(31,951), X_MASK, POWER2, { FRS, RA, RB } }, 4009{ "stfqux", X(31,951), X_MASK, POWER2, { FRS, RA, RB } },
3833 4010
3834{ "orc", XRC(31,412,0), X_MASK, COM, { RA, RS, RB } }, 4011{ "orc", XRC(31,412,0), X_MASK, COM, { RA, RS, RB } },
@@ -3837,7 +4014,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
3837{ "sradi", XS(31,413,0), XS_MASK, PPC64, { RA, RS, SH6 } }, 4014{ "sradi", XS(31,413,0), XS_MASK, PPC64, { RA, RS, SH6 } },
3838{ "sradi.", XS(31,413,1), XS_MASK, PPC64, { RA, RS, SH6 } }, 4015{ "sradi.", XS(31,413,1), XS_MASK, PPC64, { RA, RS, SH6 } },
3839 4016
3840{ "sthxe", X(31,415), X_MASK, BOOKE64, { RS, RA, RB } }, 4017{ "sthxe", X(31,415), X_MASK, BOOKE64, { RS, RA0, RB } },
3841 4018
3842{ "slbie", X(31,434), XRTRA_MASK, PPC64, { RB } }, 4019{ "slbie", X(31,434), XRTRA_MASK, PPC64, { RB } },
3843 4020
@@ -3918,6 +4095,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
3918{ "mtsdr1", XSPR(31,467,25), XSPR_MASK, COM, { RS } }, 4095{ "mtsdr1", XSPR(31,467,25), XSPR_MASK, COM, { RS } },
3919{ "mtsrr0", XSPR(31,467,26), XSPR_MASK, COM, { RS } }, 4096{ "mtsrr0", XSPR(31,467,26), XSPR_MASK, COM, { RS } },
3920{ "mtsrr1", XSPR(31,467,27), XSPR_MASK, COM, { RS } }, 4097{ "mtsrr1", XSPR(31,467,27), XSPR_MASK, COM, { RS } },
4098{ "mtcfar", XSPR(31,467,28), XSPR_MASK, POWER6, { RS } },
3921{ "mtpid", XSPR(31,467,48), XSPR_MASK, BOOKE, { RS } }, 4099{ "mtpid", XSPR(31,467,48), XSPR_MASK, BOOKE, { RS } },
3922{ "mtpid", XSPR(31,467,945), XSPR_MASK, PPC403, { RS } }, 4100{ "mtpid", XSPR(31,467,945), XSPR_MASK, PPC403, { RS } },
3923{ "mtdecar", XSPR(31,467,54), XSPR_MASK, BOOKE, { RS } }, 4101{ "mtdecar", XSPR(31,467,54), XSPR_MASK, BOOKE, { RS } },
@@ -3946,7 +4124,7 @@ const struct powerpc_opcode powerpc_opcodes[] = {
3946{ "mtbar", XSPR(31,467,159), XSPR_MASK, PPC860, { RS } }, 4124{ "mtbar", XSPR(31,467,159), XSPR_MASK, PPC860, { RS } },
3947{ "mtvrsave", XSPR(31,467,256), XSPR_MASK, PPCVEC, { RS } }, 4125{ "mtvrsave", XSPR(31,467,256), XSPR_MASK, PPCVEC, { RS } },
3948{ "mtusprg0", XSPR(31,467,256), XSPR_MASK, BOOKE, { RS } }, 4126{ "mtusprg0", XSPR(31,467,256), XSPR_MASK, BOOKE, { RS } },
3949{ "mtsprg", XSPR(31,467,272), XSPRG_MASK,PPC, { SPRG, RS } }, 4127{ "mtsprg", XSPR(31,467,256), XSPRG_MASK,PPC, { SPRG, RS } },
3950{ "mtsprg0", XSPR(31,467,272), XSPR_MASK, PPC, { RS } }, 4128{ "mtsprg0", XSPR(31,467,272), XSPR_MASK, PPC, { RS } },
3951{ "mtsprg1", XSPR(31,467,273), XSPR_MASK, PPC, { RS } }, 4129{ "mtsprg1", XSPR(31,467,273), XSPR_MASK, PPC, { RS } },
3952{ "mtsprg2", XSPR(31,467,274), XSPR_MASK, PPC, { RS } }, 4130{ "mtsprg2", XSPR(31,467,274), XSPR_MASK, PPC, { RS } },
@@ -4005,6 +4183,10 @@ const struct powerpc_opcode powerpc_opcodes[] = {
4005{ "mtspefscr", XSPR(31,467,512), XSPR_MASK, PPCSPE, { RS } }, 4183{ "mtspefscr", XSPR(31,467,512), XSPR_MASK, PPCSPE, { RS } },
4006{ "mtbbear", XSPR(31,467,513), XSPR_MASK, PPCBRLK, { RS } }, 4184{ "mtbbear", XSPR(31,467,513), XSPR_MASK, PPCBRLK, { RS } },
4007{ "mtbbtar", XSPR(31,467,514), XSPR_MASK, PPCBRLK, { RS } }, 4185{ "mtbbtar", XSPR(31,467,514), XSPR_MASK, PPCBRLK, { RS } },
4186{ "mtivor32", XSPR(31,467,528), XSPR_MASK, PPCSPE, { RS } },
4187{ "mtivor33", XSPR(31,467,529), XSPR_MASK, PPCSPE, { RS } },
4188{ "mtivor34", XSPR(31,467,530), XSPR_MASK, PPCSPE, { RS } },
4189{ "mtivor35", XSPR(31,467,531), XSPR_MASK, PPCPMR, { RS } },
4008{ "mtibatu", XSPR(31,467,528), XSPRBAT_MASK, PPC, { SPRBAT, RS } }, 4190{ "mtibatu", XSPR(31,467,528), XSPRBAT_MASK, PPC, { SPRBAT, RS } },
4009{ "mtibatl", XSPR(31,467,529), XSPRBAT_MASK, PPC, { SPRBAT, RS } }, 4191{ "mtibatl", XSPR(31,467,529), XSPRBAT_MASK, PPC, { SPRBAT, RS } },
4010{ "mtdbatu", XSPR(31,467,536), XSPRBAT_MASK, PPC, { SPRBAT, RS } }, 4192{ "mtdbatu", XSPR(31,467,536), XSPRBAT_MASK, PPC, { SPRBAT, RS } },
@@ -4101,13 +4283,15 @@ const struct powerpc_opcode powerpc_opcodes[] = {
4101 4283
4102{ "clcs", X(31,531), XRB_MASK, M601, { RT, RA } }, 4284{ "clcs", X(31,531), XRB_MASK, M601, { RT, RA } },
4103 4285
4104{ "lswx", X(31,533), X_MASK, PPCCOM, { RT, RA, RB } }, 4286{ "ldbrx", X(31,532), X_MASK, CELL, { RT, RA0, RB } },
4287
4288{ "lswx", X(31,533), X_MASK, PPCCOM, { RT, RA0, RB } },
4105{ "lsx", X(31,533), X_MASK, PWRCOM, { RT, RA, RB } }, 4289{ "lsx", X(31,533), X_MASK, PWRCOM, { RT, RA, RB } },
4106 4290
4107{ "lwbrx", X(31,534), X_MASK, PPCCOM, { RT, RA, RB } }, 4291{ "lwbrx", X(31,534), X_MASK, PPCCOM, { RT, RA0, RB } },
4108{ "lbrx", X(31,534), X_MASK, PWRCOM, { RT, RA, RB } }, 4292{ "lbrx", X(31,534), X_MASK, PWRCOM, { RT, RA, RB } },
4109 4293
4110{ "lfsx", X(31,535), X_MASK, COM, { FRT, RA, RB } }, 4294{ "lfsx", X(31,535), X_MASK, COM, { FRT, RA0, RB } },
4111 4295
4112{ "srw", XRC(31,536,0), X_MASK, PPCCOM, { RA, RS, RB } }, 4296{ "srw", XRC(31,536,0), X_MASK, PPCCOM, { RA, RS, RB } },
4113{ "sr", XRC(31,536,0), X_MASK, PWRCOM, { RA, RS, RB } }, 4297{ "sr", XRC(31,536,0), X_MASK, PWRCOM, { RA, RS, RB } },
@@ -4123,11 +4307,12 @@ const struct powerpc_opcode powerpc_opcodes[] = {
4123{ "maskir", XRC(31,541,0), X_MASK, M601, { RA, RS, RB } }, 4307{ "maskir", XRC(31,541,0), X_MASK, M601, { RA, RS, RB } },
4124{ "maskir.", XRC(31,541,1), X_MASK, M601, { RA, RS, RB } }, 4308{ "maskir.", XRC(31,541,1), X_MASK, M601, { RA, RS, RB } },
4125 4309
4126{ "lwbrxe", X(31,542), X_MASK, BOOKE64, { RT, RA, RB } }, 4310{ "lwbrxe", X(31,542), X_MASK, BOOKE64, { RT, RA0, RB } },
4127 4311
4128{ "lfsxe", X(31,543), X_MASK, BOOKE64, { FRT, RA, RB } }, 4312{ "lfsxe", X(31,543), X_MASK, BOOKE64, { FRT, RA0, RB } },
4129 4313
4130{ "bbelr", X(31,550), X_MASK, PPCBRLK, { 0 }}, 4314{ "bbelr", X(31,550), X_MASK, PPCBRLK, { 0 }},
4315
4131{ "tlbsync", X(31,566), 0xffffffff, PPC, { 0 } }, 4316{ "tlbsync", X(31,566), 0xffffffff, PPC, { 0 } },
4132 4317
4133{ "lfsux", X(31,567), X_MASK, COM, { FRT, RAS, RB } }, 4318{ "lfsux", X(31,567), X_MASK, COM, { FRT, RAS, RB } },
@@ -4136,8 +4321,8 @@ const struct powerpc_opcode powerpc_opcodes[] = {
4136 4321
4137{ "mfsr", X(31,595), XRB_MASK|(1<<20), COM32, { RT, SR } }, 4322{ "mfsr", X(31,595), XRB_MASK|(1<<20), COM32, { RT, SR } },
4138 4323
4139{ "lswi", X(31,597), X_MASK, PPCCOM, { RT, RA, NB } }, 4324{ "lswi", X(31,597), X_MASK, PPCCOM, { RT, RA0, NB } },
4140{ "lsi", X(31,597), X_MASK, PWRCOM, { RT, RA, NB } }, 4325{ "lsi", X(31,597), X_MASK, PWRCOM, { RT, RA0, NB } },
4141 4326
4142{ "lwsync", XSYNC(31,598,1), 0xffffffff, PPC, { 0 } }, 4327{ "lwsync", XSYNC(31,598,1), 0xffffffff, PPC, { 0 } },
4143{ "ptesync", XSYNC(31,598,2), 0xffffffff, PPC64, { 0 } }, 4328{ "ptesync", XSYNC(31,598,2), 0xffffffff, PPC64, { 0 } },
@@ -4145,9 +4330,11 @@ const struct powerpc_opcode powerpc_opcodes[] = {
4145{ "sync", X(31,598), XSYNC_MASK, PPCCOM, { LS } }, 4330{ "sync", X(31,598), XSYNC_MASK, PPCCOM, { LS } },
4146{ "dcs", X(31,598), 0xffffffff, PWRCOM, { 0 } }, 4331{ "dcs", X(31,598), 0xffffffff, PWRCOM, { 0 } },
4147 4332
4148{ "lfdx", X(31,599), X_MASK, COM, { FRT, RA, RB } }, 4333{ "lfdx", X(31,599), X_MASK, COM, { FRT, RA0, RB } },
4334
4335{ "lfdxe", X(31,607), X_MASK, BOOKE64, { FRT, RA0, RB } },
4149 4336
4150{ "lfdxe", X(31,607), X_MASK, BOOKE64, { FRT, RA, RB } }, 4337{ "mffgpr", XRC(31,607,0), XRA_MASK, POWER6, { FRT, RB } },
4151 4338
4152{ "mfsri", X(31,627), X_MASK, PWRCOM, { RT, RA, RB } }, 4339{ "mfsri", X(31,627), X_MASK, PWRCOM, { RT, RA, RB } },
4153 4340
@@ -4159,13 +4346,15 @@ const struct powerpc_opcode powerpc_opcodes[] = {
4159 4346
4160{ "mfsrin", X(31,659), XRA_MASK, PPC32, { RT, RB } }, 4347{ "mfsrin", X(31,659), XRA_MASK, PPC32, { RT, RB } },
4161 4348
4162{ "stswx", X(31,661), X_MASK, PPCCOM, { RS, RA, RB } }, 4349{ "stdbrx", X(31,660), X_MASK, CELL, { RS, RA0, RB } },
4163{ "stsx", X(31,661), X_MASK, PWRCOM, { RS, RA, RB } }, 4350
4351{ "stswx", X(31,661), X_MASK, PPCCOM, { RS, RA0, RB } },
4352{ "stsx", X(31,661), X_MASK, PWRCOM, { RS, RA0, RB } },
4164 4353
4165{ "stwbrx", X(31,662), X_MASK, PPCCOM, { RS, RA, RB } }, 4354{ "stwbrx", X(31,662), X_MASK, PPCCOM, { RS, RA0, RB } },
4166{ "stbrx", X(31,662), X_MASK, PWRCOM, { RS, RA, RB } }, 4355{ "stbrx", X(31,662), X_MASK, PWRCOM, { RS, RA0, RB } },
4167 4356
4168{ "stfsx", X(31,663), X_MASK, COM, { FRS, RA, RB } }, 4357{ "stfsx", X(31,663), X_MASK, COM, { FRS, RA0, RB } },
4169 4358
4170{ "srq", XRC(31,664,0), X_MASK, M601, { RA, RS, RB } }, 4359{ "srq", XRC(31,664,0), X_MASK, M601, { RA, RS, RB } },
4171{ "srq.", XRC(31,664,1), X_MASK, M601, { RA, RS, RB } }, 4360{ "srq.", XRC(31,664,1), X_MASK, M601, { RA, RS, RB } },
@@ -4173,9 +4362,9 @@ const struct powerpc_opcode powerpc_opcodes[] = {
4173{ "sre", XRC(31,665,0), X_MASK, M601, { RA, RS, RB } }, 4362{ "sre", XRC(31,665,0), X_MASK, M601, { RA, RS, RB } },
4174{ "sre.", XRC(31,665,1), X_MASK, M601, { RA, RS, RB } }, 4363{ "sre.", XRC(31,665,1), X_MASK, M601, { RA, RS, RB } },
4175 4364
4176{ "stwbrxe", X(31,670), X_MASK, BOOKE64, { RS, RA, RB } }, 4365{ "stwbrxe", X(31,670), X_MASK, BOOKE64, { RS, RA0, RB } },
4177 4366
4178{ "stfsxe", X(31,671), X_MASK, BOOKE64, { FRS, RA, RB } }, 4367{ "stfsxe", X(31,671), X_MASK, BOOKE64, { FRS, RA0, RB } },
4179 4368
4180{ "stfsux", X(31,695), X_MASK, COM, { FRS, RAS, RB } }, 4369{ "stfsux", X(31,695), X_MASK, COM, { FRS, RAS, RB } },
4181 4370
@@ -4184,10 +4373,10 @@ const struct powerpc_opcode powerpc_opcodes[] = {
4184 4373
4185{ "stfsuxe", X(31,703), X_MASK, BOOKE64, { FRS, RAS, RB } }, 4374{ "stfsuxe", X(31,703), X_MASK, BOOKE64, { FRS, RAS, RB } },
4186 4375
4187{ "stswi", X(31,725), X_MASK, PPCCOM, { RS, RA, NB } }, 4376{ "stswi", X(31,725), X_MASK, PPCCOM, { RS, RA0, NB } },
4188{ "stsi", X(31,725), X_MASK, PWRCOM, { RS, RA, NB } }, 4377{ "stsi", X(31,725), X_MASK, PWRCOM, { RS, RA0, NB } },
4189 4378
4190{ "stfdx", X(31,727), X_MASK, COM, { FRS, RA, RB } }, 4379{ "stfdx", X(31,727), X_MASK, COM, { FRS, RA0, RB } },
4191 4380
4192{ "srlq", XRC(31,728,0), X_MASK, M601, { RA, RS, RB } }, 4381{ "srlq", XRC(31,728,0), X_MASK, M601, { RA, RS, RB } },
4193{ "srlq.", XRC(31,728,1), X_MASK, M601, { RA, RS, RB } }, 4382{ "srlq.", XRC(31,728,1), X_MASK, M601, { RA, RS, RB } },
@@ -4195,7 +4384,9 @@ const struct powerpc_opcode powerpc_opcodes[] = {
4195{ "sreq", XRC(31,729,0), X_MASK, M601, { RA, RS, RB } }, 4384{ "sreq", XRC(31,729,0), X_MASK, M601, { RA, RS, RB } },
4196{ "sreq.", XRC(31,729,1), X_MASK, M601, { RA, RS, RB } }, 4385{ "sreq.", XRC(31,729,1), X_MASK, M601, { RA, RS, RB } },
4197 4386
4198{ "stfdxe", X(31,735), X_MASK, BOOKE64, { FRS, RA, RB } }, 4387{ "stfdxe", X(31,735), X_MASK, BOOKE64, { FRS, RA0, RB } },
4388
4389{ "mftgpr", XRC(31,735,0), XRA_MASK, POWER6, { RT, FRB } },
4199 4390
4200{ "dcba", X(31,758), XRT_MASK, PPC405 | BOOKE, { RA, RB } }, 4391{ "dcba", X(31,758), XRT_MASK, PPC405 | BOOKE, { RA, RB } },
4201 4392
@@ -4211,7 +4402,9 @@ const struct powerpc_opcode powerpc_opcodes[] = {
4211{ "tlbivax", X(31,786), XRT_MASK, BOOKE, { RA, RB } }, 4402{ "tlbivax", X(31,786), XRT_MASK, BOOKE, { RA, RB } },
4212{ "tlbivaxe",X(31,787), XRT_MASK, BOOKE64, { RA, RB } }, 4403{ "tlbivaxe",X(31,787), XRT_MASK, BOOKE64, { RA, RB } },
4213 4404
4214{ "lhbrx", X(31,790), X_MASK, COM, { RT, RA, RB } }, 4405{ "lwzcix", X(31,789), X_MASK, POWER6, { RT, RA0, RB } },
4406
4407{ "lhbrx", X(31,790), X_MASK, COM, { RT, RA0, RB } },
4215 4408
4216{ "sraw", XRC(31,792,0), X_MASK, PPCCOM, { RA, RS, RB } }, 4409{ "sraw", XRC(31,792,0), X_MASK, PPCCOM, { RA, RS, RB } },
4217{ "sra", XRC(31,792,0), X_MASK, PWRCOM, { RA, RS, RB } }, 4410{ "sra", XRC(31,792,0), X_MASK, PWRCOM, { RA, RS, RB } },
@@ -4221,13 +4414,15 @@ const struct powerpc_opcode powerpc_opcodes[] = {
4221{ "srad", XRC(31,794,0), X_MASK, PPC64, { RA, RS, RB } }, 4414{ "srad", XRC(31,794,0), X_MASK, PPC64, { RA, RS, RB } },
4222{ "srad.", XRC(31,794,1), X_MASK, PPC64, { RA, RS, RB } }, 4415{ "srad.", XRC(31,794,1), X_MASK, PPC64, { RA, RS, RB } },
4223 4416
4224{ "lhbrxe", X(31,798), X_MASK, BOOKE64, { RT, RA, RB } }, 4417{ "lhbrxe", X(31,798), X_MASK, BOOKE64, { RT, RA0, RB } },
4225 4418
4226{ "ldxe", X(31,799), X_MASK, BOOKE64, { RT, RA, RB } }, 4419{ "ldxe", X(31,799), X_MASK, BOOKE64, { RT, RA0, RB } },
4227{ "lduxe", X(31,831), X_MASK, BOOKE64, { RT, RA, RB } }, 4420{ "lduxe", X(31,831), X_MASK, BOOKE64, { RT, RA0, RB } },
4228 4421
4229{ "rac", X(31,818), X_MASK, PWRCOM, { RT, RA, RB } }, 4422{ "rac", X(31,818), X_MASK, PWRCOM, { RT, RA, RB } },
4230 4423
4424{ "lhzcix", X(31,821), X_MASK, POWER6, { RT, RA0, RB } },
4425
4231{ "dss", XDSS(31,822,0), XDSS_MASK, PPCVEC, { STRM } }, 4426{ "dss", XDSS(31,822,0), XDSS_MASK, PPCVEC, { STRM } },
4232{ "dssall", XDSS(31,822,1), XDSS_MASK, PPCVEC, { 0 } }, 4427{ "dssall", XDSS(31,822,1), XDSS_MASK, PPCVEC, { 0 } },
4233 4428
@@ -4238,19 +4433,25 @@ const struct powerpc_opcode powerpc_opcodes[] = {
4238 4433
4239{ "slbmfev", X(31,851), XRA_MASK, PPC64, { RT, RB } }, 4434{ "slbmfev", X(31,851), XRA_MASK, PPC64, { RT, RB } },
4240 4435
4436{ "lbzcix", X(31,853), X_MASK, POWER6, { RT, RA0, RB } },
4437
4241{ "mbar", X(31,854), X_MASK, BOOKE, { MO } }, 4438{ "mbar", X(31,854), X_MASK, BOOKE, { MO } },
4242{ "eieio", X(31,854), 0xffffffff, PPC, { 0 } }, 4439{ "eieio", X(31,854), 0xffffffff, PPC, { 0 } },
4243 4440
4244{ "tlbsx", XRC(31,914,0), X_MASK, BOOKE, { RA, RB } }, 4441{ "lfiwax", X(31,855), X_MASK, POWER6, { FRT, RA0, RB } },
4245{ "tlbsx", XRC(31,914,0), X_MASK, PPC403, { RT, RA, RB } }, 4442
4246{ "tlbsx.", XRC(31,914,1), X_MASK, BOOKE, { RA, RB } }, 4443{ "ldcix", X(31,885), X_MASK, POWER6, { RT, RA0, RB } },
4247{ "tlbsx.", XRC(31,914,1), X_MASK, PPC403, { RT, RA, RB } }, 4444
4445{ "tlbsx", XRC(31,914,0), X_MASK, PPC403|BOOKE, { RTO, RA, RB } },
4446{ "tlbsx.", XRC(31,914,1), X_MASK, PPC403|BOOKE, { RTO, RA, RB } },
4248{ "tlbsxe", XRC(31,915,0), X_MASK, BOOKE64, { RA, RB } }, 4447{ "tlbsxe", XRC(31,915,0), X_MASK, BOOKE64, { RA, RB } },
4249{ "tlbsxe.", XRC(31,915,1), X_MASK, BOOKE64, { RA, RB } }, 4448{ "tlbsxe.", XRC(31,915,1), X_MASK, BOOKE64, { RA, RB } },
4250 4449
4251{ "slbmfee", X(31,915), XRA_MASK, PPC64, { RT, RB } }, 4450{ "slbmfee", X(31,915), XRA_MASK, PPC64, { RT, RB } },
4252 4451
4253{ "sthbrx", X(31,918), X_MASK, COM, { RS, RA, RB } }, 4452{ "stwcix", X(31,917), X_MASK, POWER6, { RS, RA0, RB } },
4453
4454{ "sthbrx", X(31,918), X_MASK, COM, { RS, RA0, RB } },
4254 4455
4255{ "sraq", XRC(31,920,0), X_MASK, M601, { RA, RS, RB } }, 4456{ "sraq", XRC(31,920,0), X_MASK, M601, { RA, RS, RB } },
4256{ "sraq.", XRC(31,920,1), X_MASK, M601, { RA, RS, RB } }, 4457{ "sraq.", XRC(31,920,1), X_MASK, M601, { RA, RS, RB } },
@@ -4263,14 +4464,15 @@ const struct powerpc_opcode powerpc_opcodes[] = {
4263{ "extsh.", XRC(31,922,1), XRB_MASK, PPCCOM, { RA, RS } }, 4464{ "extsh.", XRC(31,922,1), XRB_MASK, PPCCOM, { RA, RS } },
4264{ "exts.", XRC(31,922,1), XRB_MASK, PWRCOM, { RA, RS } }, 4465{ "exts.", XRC(31,922,1), XRB_MASK, PWRCOM, { RA, RS } },
4265 4466
4266{ "sthbrxe", X(31,926), X_MASK, BOOKE64, { RS, RA, RB } }, 4467{ "sthbrxe", X(31,926), X_MASK, BOOKE64, { RS, RA0, RB } },
4267 4468
4268{ "stdxe", X(31,927), X_MASK, BOOKE64, { RS, RA, RB } }, 4469{ "stdxe", X(31,927), X_MASK, BOOKE64, { RS, RA0, RB } },
4269 4470
4270{ "tlbrehi", XTLB(31,946,0), XTLB_MASK, PPC403, { RT, RA } }, 4471{ "tlbrehi", XTLB(31,946,0), XTLB_MASK, PPC403, { RT, RA } },
4271{ "tlbrelo", XTLB(31,946,1), XTLB_MASK, PPC403, { RT, RA } }, 4472{ "tlbrelo", XTLB(31,946,1), XTLB_MASK, PPC403, { RT, RA } },
4272{ "tlbre", X(31,946), X_MASK, BOOKE, { 0 } }, 4473{ "tlbre", X(31,946), X_MASK, PPC403|BOOKE, { RSO, RAOPT, SHO } },
4273{ "tlbre", X(31,946), X_MASK, PPC403, { RS, RA, SH } }, 4474
4475{ "sthcix", X(31,949), X_MASK, POWER6, { RS, RA0, RB } },
4274 4476
4275{ "sraiq", XRC(31,952,0), X_MASK, M601, { RA, RS, SH } }, 4477{ "sraiq", XRC(31,952,0), X_MASK, M601, { RA, RS, SH } },
4276{ "sraiq.", XRC(31,952,1), X_MASK, M601, { RA, RS, SH } }, 4478{ "sraiq.", XRC(31,952,1), X_MASK, M601, { RA, RS, SH } },
@@ -4284,13 +4486,14 @@ const struct powerpc_opcode powerpc_opcodes[] = {
4284 4486
4285{ "tlbwehi", XTLB(31,978,0), XTLB_MASK, PPC403, { RT, RA } }, 4487{ "tlbwehi", XTLB(31,978,0), XTLB_MASK, PPC403, { RT, RA } },
4286{ "tlbwelo", XTLB(31,978,1), XTLB_MASK, PPC403, { RT, RA } }, 4488{ "tlbwelo", XTLB(31,978,1), XTLB_MASK, PPC403, { RT, RA } },
4287{ "tlbwe", X(31,978), X_MASK, BOOKE, { 0 } }, 4489{ "tlbwe", X(31,978), X_MASK, PPC403|BOOKE, { RSO, RAOPT, SHO } },
4288{ "tlbwe", X(31,978), X_MASK, PPC403, { RS, RA, SH } },
4289{ "tlbld", X(31,978), XRTRA_MASK, PPC, { RB } }, 4490{ "tlbld", X(31,978), XRTRA_MASK, PPC, { RB } },
4290 4491
4492{ "stbcix", X(31,981), X_MASK, POWER6, { RS, RA0, RB } },
4493
4291{ "icbi", X(31,982), XRT_MASK, PPC, { RA, RB } }, 4494{ "icbi", X(31,982), XRT_MASK, PPC, { RA, RB } },
4292 4495
4293{ "stfiwx", X(31,983), X_MASK, PPC, { FRS, RA, RB } }, 4496{ "stfiwx", X(31,983), X_MASK, PPC, { FRS, RA0, RB } },
4294 4497
4295{ "extsw", XRC(31,986,0), XRB_MASK, PPC64 | BOOKE64,{ RA, RS } }, 4498{ "extsw", XRC(31,986,0), XRB_MASK, PPC64 | BOOKE64,{ RA, RS } },
4296{ "extsw.", XRC(31,986,1), XRB_MASK, PPC64, { RA, RS } }, 4499{ "extsw.", XRC(31,986,1), XRB_MASK, PPC64, { RA, RS } },
@@ -4298,10 +4501,13 @@ const struct powerpc_opcode powerpc_opcodes[] = {
4298{ "icread", X(31,998), XRT_MASK, PPC403|PPC440, { RA, RB } }, 4501{ "icread", X(31,998), XRT_MASK, PPC403|PPC440, { RA, RB } },
4299 4502
4300{ "icbie", X(31,990), XRT_MASK, BOOKE64, { RA, RB } }, 4503{ "icbie", X(31,990), XRT_MASK, BOOKE64, { RA, RB } },
4301{ "stfiwxe", X(31,991), X_MASK, BOOKE64, { FRS, RA, RB } }, 4504{ "stfiwxe", X(31,991), X_MASK, BOOKE64, { FRS, RA0, RB } },
4302 4505
4303{ "tlbli", X(31,1010), XRTRA_MASK, PPC, { RB } }, 4506{ "tlbli", X(31,1010), XRTRA_MASK, PPC, { RB } },
4304 4507
4508{ "stdcix", X(31,1013), X_MASK, POWER6, { RS, RA0, RB } },
4509
4510{ "dcbzl", XOPL(31,1014,1), XRT_MASK,POWER4, { RA, RB } },
4305{ "dcbz", X(31,1014), XRT_MASK, PPC, { RA, RB } }, 4511{ "dcbz", X(31,1014), XRT_MASK, PPC, { RA, RB } },
4306{ "dclz", X(31,1014), XRT_MASK, PPC, { RA, RB } }, 4512{ "dclz", X(31,1014), XRT_MASK, PPC, { RA, RB } },
4307 4513
@@ -4320,86 +4526,104 @@ const struct powerpc_opcode powerpc_opcodes[] = {
4320{ "stvx", X(31, 231), X_MASK, PPCVEC, { VS, RA, RB } }, 4526{ "stvx", X(31, 231), X_MASK, PPCVEC, { VS, RA, RB } },
4321{ "stvxl", X(31, 487), X_MASK, PPCVEC, { VS, RA, RB } }, 4527{ "stvxl", X(31, 487), X_MASK, PPCVEC, { VS, RA, RB } },
4322 4528
4323{ "lwz", OP(32), OP_MASK, PPCCOM, { RT, D, RA } }, 4529/* New load/store left/right index vector instructions that are in the Cell only. */
4324{ "l", OP(32), OP_MASK, PWRCOM, { RT, D, RA } }, 4530{ "lvlx", X(31, 519), X_MASK, CELL, { VD, RA0, RB } },
4531{ "lvlxl", X(31, 775), X_MASK, CELL, { VD, RA0, RB } },
4532{ "lvrx", X(31, 551), X_MASK, CELL, { VD, RA0, RB } },
4533{ "lvrxl", X(31, 807), X_MASK, CELL, { VD, RA0, RB } },
4534{ "stvlx", X(31, 647), X_MASK, CELL, { VS, RA0, RB } },
4535{ "stvlxl", X(31, 903), X_MASK, CELL, { VS, RA0, RB } },
4536{ "stvrx", X(31, 679), X_MASK, CELL, { VS, RA0, RB } },
4537{ "stvrxl", X(31, 935), X_MASK, CELL, { VS, RA0, RB } },
4538
4539{ "lwz", OP(32), OP_MASK, PPCCOM, { RT, D, RA0 } },
4540{ "l", OP(32), OP_MASK, PWRCOM, { RT, D, RA0 } },
4325 4541
4326{ "lwzu", OP(33), OP_MASK, PPCCOM, { RT, D, RAL } }, 4542{ "lwzu", OP(33), OP_MASK, PPCCOM, { RT, D, RAL } },
4327{ "lu", OP(33), OP_MASK, PWRCOM, { RT, D, RA } }, 4543{ "lu", OP(33), OP_MASK, PWRCOM, { RT, D, RA0 } },
4328 4544
4329{ "lbz", OP(34), OP_MASK, COM, { RT, D, RA } }, 4545{ "lbz", OP(34), OP_MASK, COM, { RT, D, RA0 } },
4330 4546
4331{ "lbzu", OP(35), OP_MASK, COM, { RT, D, RAL } }, 4547{ "lbzu", OP(35), OP_MASK, COM, { RT, D, RAL } },
4332 4548
4333{ "stw", OP(36), OP_MASK, PPCCOM, { RS, D, RA } }, 4549{ "stw", OP(36), OP_MASK, PPCCOM, { RS, D, RA0 } },
4334{ "st", OP(36), OP_MASK, PWRCOM, { RS, D, RA } }, 4550{ "st", OP(36), OP_MASK, PWRCOM, { RS, D, RA0 } },
4335 4551
4336{ "stwu", OP(37), OP_MASK, PPCCOM, { RS, D, RAS } }, 4552{ "stwu", OP(37), OP_MASK, PPCCOM, { RS, D, RAS } },
4337{ "stu", OP(37), OP_MASK, PWRCOM, { RS, D, RA } }, 4553{ "stu", OP(37), OP_MASK, PWRCOM, { RS, D, RA0 } },
4338 4554
4339{ "stb", OP(38), OP_MASK, COM, { RS, D, RA } }, 4555{ "stb", OP(38), OP_MASK, COM, { RS, D, RA0 } },
4340 4556
4341{ "stbu", OP(39), OP_MASK, COM, { RS, D, RAS } }, 4557{ "stbu", OP(39), OP_MASK, COM, { RS, D, RAS } },
4342 4558
4343{ "lhz", OP(40), OP_MASK, COM, { RT, D, RA } }, 4559{ "lhz", OP(40), OP_MASK, COM, { RT, D, RA0 } },
4344 4560
4345{ "lhzu", OP(41), OP_MASK, COM, { RT, D, RAL } }, 4561{ "lhzu", OP(41), OP_MASK, COM, { RT, D, RAL } },
4346 4562
4347{ "lha", OP(42), OP_MASK, COM, { RT, D, RA } }, 4563{ "lha", OP(42), OP_MASK, COM, { RT, D, RA0 } },
4348 4564
4349{ "lhau", OP(43), OP_MASK, COM, { RT, D, RAL } }, 4565{ "lhau", OP(43), OP_MASK, COM, { RT, D, RAL } },
4350 4566
4351{ "sth", OP(44), OP_MASK, COM, { RS, D, RA } }, 4567{ "sth", OP(44), OP_MASK, COM, { RS, D, RA0 } },
4352 4568
4353{ "sthu", OP(45), OP_MASK, COM, { RS, D, RAS } }, 4569{ "sthu", OP(45), OP_MASK, COM, { RS, D, RAS } },
4354 4570
4355{ "lmw", OP(46), OP_MASK, PPCCOM, { RT, D, RAM } }, 4571{ "lmw", OP(46), OP_MASK, PPCCOM, { RT, D, RAM } },
4356{ "lm", OP(46), OP_MASK, PWRCOM, { RT, D, RA } }, 4572{ "lm", OP(46), OP_MASK, PWRCOM, { RT, D, RA0 } },
4357 4573
4358{ "stmw", OP(47), OP_MASK, PPCCOM, { RS, D, RA } }, 4574{ "stmw", OP(47), OP_MASK, PPCCOM, { RS, D, RA0 } },
4359{ "stm", OP(47), OP_MASK, PWRCOM, { RS, D, RA } }, 4575{ "stm", OP(47), OP_MASK, PWRCOM, { RS, D, RA0 } },
4360 4576
4361{ "lfs", OP(48), OP_MASK, COM, { FRT, D, RA } }, 4577{ "lfs", OP(48), OP_MASK, COM, { FRT, D, RA0 } },
4362 4578
4363{ "lfsu", OP(49), OP_MASK, COM, { FRT, D, RAS } }, 4579{ "lfsu", OP(49), OP_MASK, COM, { FRT, D, RAS } },
4364 4580
4365{ "lfd", OP(50), OP_MASK, COM, { FRT, D, RA } }, 4581{ "lfd", OP(50), OP_MASK, COM, { FRT, D, RA0 } },
4366 4582
4367{ "lfdu", OP(51), OP_MASK, COM, { FRT, D, RAS } }, 4583{ "lfdu", OP(51), OP_MASK, COM, { FRT, D, RAS } },
4368 4584
4369{ "stfs", OP(52), OP_MASK, COM, { FRS, D, RA } }, 4585{ "stfs", OP(52), OP_MASK, COM, { FRS, D, RA0 } },
4370 4586
4371{ "stfsu", OP(53), OP_MASK, COM, { FRS, D, RAS } }, 4587{ "stfsu", OP(53), OP_MASK, COM, { FRS, D, RAS } },
4372 4588
4373{ "stfd", OP(54), OP_MASK, COM, { FRS, D, RA } }, 4589{ "stfd", OP(54), OP_MASK, COM, { FRS, D, RA0 } },
4374 4590
4375{ "stfdu", OP(55), OP_MASK, COM, { FRS, D, RAS } }, 4591{ "stfdu", OP(55), OP_MASK, COM, { FRS, D, RAS } },
4376 4592
4377{ "lq", OP(56), OP_MASK, POWER4, { RTQ, DQ, RAQ } }, 4593{ "lq", OP(56), OP_MASK, POWER4, { RTQ, DQ, RAQ } },
4378 4594
4379{ "lfq", OP(56), OP_MASK, POWER2, { FRT, D, RA } }, 4595{ "lfq", OP(56), OP_MASK, POWER2, { FRT, D, RA0 } },
4596
4597{ "lfqu", OP(57), OP_MASK, POWER2, { FRT, D, RA0 } },
4380 4598
4381{ "lfqu", OP(57), OP_MASK, POWER2, { FRT, D, RA } }, 4599{ "lfdp", OP(57), OP_MASK, POWER6, { FRT, D, RA0 } },
4382 4600
4383{ "lbze", DEO(58,0), DE_MASK, BOOKE64, { RT, DE, RA } }, 4601{ "lbze", DEO(58,0), DE_MASK, BOOKE64, { RT, DE, RA0 } },
4384{ "lbzue", DEO(58,1), DE_MASK, BOOKE64, { RT, DE, RAL } }, 4602{ "lbzue", DEO(58,1), DE_MASK, BOOKE64, { RT, DE, RAL } },
4385{ "lhze", DEO(58,2), DE_MASK, BOOKE64, { RT, DE, RA } }, 4603{ "lhze", DEO(58,2), DE_MASK, BOOKE64, { RT, DE, RA0 } },
4386{ "lhzue", DEO(58,3), DE_MASK, BOOKE64, { RT, DE, RAL } }, 4604{ "lhzue", DEO(58,3), DE_MASK, BOOKE64, { RT, DE, RAL } },
4387{ "lhae", DEO(58,4), DE_MASK, BOOKE64, { RT, DE, RA } }, 4605{ "lhae", DEO(58,4), DE_MASK, BOOKE64, { RT, DE, RA0 } },
4388{ "lhaue", DEO(58,5), DE_MASK, BOOKE64, { RT, DE, RAL } }, 4606{ "lhaue", DEO(58,5), DE_MASK, BOOKE64, { RT, DE, RAL } },
4389{ "lwze", DEO(58,6), DE_MASK, BOOKE64, { RT, DE, RA } }, 4607{ "lwze", DEO(58,6), DE_MASK, BOOKE64, { RT, DE, RA0 } },
4390{ "lwzue", DEO(58,7), DE_MASK, BOOKE64, { RT, DE, RAL } }, 4608{ "lwzue", DEO(58,7), DE_MASK, BOOKE64, { RT, DE, RAL } },
4391{ "stbe", DEO(58,8), DE_MASK, BOOKE64, { RS, DE, RA } }, 4609{ "stbe", DEO(58,8), DE_MASK, BOOKE64, { RS, DE, RA0 } },
4392{ "stbue", DEO(58,9), DE_MASK, BOOKE64, { RS, DE, RAS } }, 4610{ "stbue", DEO(58,9), DE_MASK, BOOKE64, { RS, DE, RAS } },
4393{ "sthe", DEO(58,10), DE_MASK, BOOKE64, { RS, DE, RA } }, 4611{ "sthe", DEO(58,10), DE_MASK, BOOKE64, { RS, DE, RA0 } },
4394{ "sthue", DEO(58,11), DE_MASK, BOOKE64, { RS, DE, RAS } }, 4612{ "sthue", DEO(58,11), DE_MASK, BOOKE64, { RS, DE, RAS } },
4395{ "stwe", DEO(58,14), DE_MASK, BOOKE64, { RS, DE, RA } }, 4613{ "stwe", DEO(58,14), DE_MASK, BOOKE64, { RS, DE, RA0 } },
4396{ "stwue", DEO(58,15), DE_MASK, BOOKE64, { RS, DE, RAS } }, 4614{ "stwue", DEO(58,15), DE_MASK, BOOKE64, { RS, DE, RAS } },
4397 4615
4398{ "ld", DSO(58,0), DS_MASK, PPC64, { RT, DS, RA } }, 4616{ "ld", DSO(58,0), DS_MASK, PPC64, { RT, DS, RA0 } },
4399 4617
4400{ "ldu", DSO(58,1), DS_MASK, PPC64, { RT, DS, RAL } }, 4618{ "ldu", DSO(58,1), DS_MASK, PPC64, { RT, DS, RAL } },
4401 4619
4402{ "lwa", DSO(58,2), DS_MASK, PPC64, { RT, DS, RA } }, 4620{ "lwa", DSO(58,2), DS_MASK, PPC64, { RT, DS, RA0 } },
4621
4622{ "dadd", XRC(59,2,0), X_MASK, POWER6, { FRT, FRA, FRB } },
4623{ "dadd.", XRC(59,2,1), X_MASK, POWER6, { FRT, FRA, FRB } },
4624
4625{ "dqua", ZRC(59,3,0), Z_MASK, POWER6, { FRT, FRA, FRB, RMC } },
4626{ "dqua.", ZRC(59,3,1), Z_MASK, POWER6, { FRT, FRA, FRB, RMC } },
4403 4627
4404{ "fdivs", A(59,18,0), AFRC_MASK, PPC, { FRT, FRA, FRB } }, 4628{ "fdivs", A(59,18,0), AFRC_MASK, PPC, { FRT, FRA, FRB } },
4405{ "fdivs.", A(59,18,1), AFRC_MASK, PPC, { FRT, FRA, FRB } }, 4629{ "fdivs.", A(59,18,1), AFRC_MASK, PPC, { FRT, FRA, FRB } },
@@ -4413,12 +4637,15 @@ const struct powerpc_opcode powerpc_opcodes[] = {
4413{ "fsqrts", A(59,22,0), AFRAFRC_MASK, PPC, { FRT, FRB } }, 4637{ "fsqrts", A(59,22,0), AFRAFRC_MASK, PPC, { FRT, FRB } },
4414{ "fsqrts.", A(59,22,1), AFRAFRC_MASK, PPC, { FRT, FRB } }, 4638{ "fsqrts.", A(59,22,1), AFRAFRC_MASK, PPC, { FRT, FRB } },
4415 4639
4416{ "fres", A(59,24,0), AFRAFRC_MASK, PPC, { FRT, FRB } }, 4640{ "fres", A(59,24,0), AFRALFRC_MASK, PPC, { FRT, FRB, A_L } },
4417{ "fres.", A(59,24,1), AFRAFRC_MASK, PPC, { FRT, FRB } }, 4641{ "fres.", A(59,24,1), AFRALFRC_MASK, PPC, { FRT, FRB, A_L } },
4418 4642
4419{ "fmuls", A(59,25,0), AFRB_MASK, PPC, { FRT, FRA, FRC } }, 4643{ "fmuls", A(59,25,0), AFRB_MASK, PPC, { FRT, FRA, FRC } },
4420{ "fmuls.", A(59,25,1), AFRB_MASK, PPC, { FRT, FRA, FRC } }, 4644{ "fmuls.", A(59,25,1), AFRB_MASK, PPC, { FRT, FRA, FRC } },
4421 4645
4646{ "frsqrtes", A(59,26,0), AFRALFRC_MASK,POWER5, { FRT, FRB, A_L } },
4647{ "frsqrtes.",A(59,26,1), AFRALFRC_MASK,POWER5, { FRT, FRB, A_L } },
4648
4422{ "fmsubs", A(59,28,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } }, 4649{ "fmsubs", A(59,28,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
4423{ "fmsubs.", A(59,28,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } }, 4650{ "fmsubs.", A(59,28,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
4424 4651
@@ -4431,31 +4658,103 @@ const struct powerpc_opcode powerpc_opcodes[] = {
4431{ "fnmadds", A(59,31,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } }, 4658{ "fnmadds", A(59,31,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
4432{ "fnmadds.",A(59,31,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } }, 4659{ "fnmadds.",A(59,31,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
4433 4660
4661{ "dmul", XRC(59,34,0), X_MASK, POWER6, { FRT, FRA, FRB } },
4662{ "dmul.", XRC(59,34,1), X_MASK, POWER6, { FRT, FRA, FRB } },
4663
4664{ "drrnd", ZRC(59,35,0), Z_MASK, POWER6, { FRT, FRA, FRB, RMC } },
4665{ "drrnd.", ZRC(59,35,1), Z_MASK, POWER6, { FRT, FRA, FRB, RMC } },
4666
4667{ "dscli", ZRC(59,66,0), Z_MASK, POWER6, { FRT, FRA, SH16 } },
4668{ "dscli.", ZRC(59,66,1), Z_MASK, POWER6, { FRT, FRA, SH16 } },
4669
4670{ "dquai", ZRC(59,67,0), Z_MASK, POWER6, { TE, FRT, FRB, RMC } },
4671{ "dquai.", ZRC(59,67,1), Z_MASK, POWER6, { TE, FRT, FRB, RMC } },
4672
4673{ "dscri", ZRC(59,98,0), Z_MASK, POWER6, { FRT, FRA, SH16 } },
4674{ "dscri.", ZRC(59,98,1), Z_MASK, POWER6, { FRT, FRA, SH16 } },
4675
4676{ "drintx", ZRC(59,99,0), Z_MASK, POWER6, { R, FRT, FRB, RMC } },
4677{ "drintx.", ZRC(59,99,1), Z_MASK, POWER6, { R, FRT, FRB, RMC } },
4678
4679{ "dcmpo", X(59,130), X_MASK, POWER6, { BF, FRA, FRB } },
4680
4681{ "dtstex", X(59,162), X_MASK, POWER6, { BF, FRA, FRB } },
4682{ "dtstdc", Z(59,194), Z_MASK, POWER6, { BF, FRA, DCM } },
4683{ "dtstdg", Z(59,226), Z_MASK, POWER6, { BF, FRA, DGM } },
4684
4685{ "drintn", ZRC(59,227,0), Z_MASK, POWER6, { R, FRT, FRB, RMC } },
4686{ "drintn.", ZRC(59,227,1), Z_MASK, POWER6, { R, FRT, FRB, RMC } },
4687
4688{ "dctdp", XRC(59,258,0), X_MASK, POWER6, { FRT, FRB } },
4689{ "dctdp.", XRC(59,258,1), X_MASK, POWER6, { FRT, FRB } },
4690
4691{ "dctfix", XRC(59,290,0), X_MASK, POWER6, { FRT, FRB } },
4692{ "dctfix.", XRC(59,290,1), X_MASK, POWER6, { FRT, FRB } },
4693
4694{ "ddedpd", XRC(59,322,0), X_MASK, POWER6, { SP, FRT, FRB } },
4695{ "ddedpd.", XRC(59,322,1), X_MASK, POWER6, { SP, FRT, FRB } },
4696
4697{ "dxex", XRC(59,354,0), X_MASK, POWER6, { FRT, FRB } },
4698{ "dxex.", XRC(59,354,1), X_MASK, POWER6, { FRT, FRB } },
4699
4700{ "dsub", XRC(59,514,0), X_MASK, POWER6, { FRT, FRA, FRB } },
4701{ "dsub.", XRC(59,514,1), X_MASK, POWER6, { FRT, FRA, FRB } },
4702
4703{ "ddiv", XRC(59,546,0), X_MASK, POWER6, { FRT, FRA, FRB } },
4704{ "ddiv.", XRC(59,546,1), X_MASK, POWER6, { FRT, FRA, FRB } },
4705
4706{ "dcmpu", X(59,642), X_MASK, POWER6, { BF, FRA, FRB } },
4707
4708{ "dtstsf", X(59,674), X_MASK, POWER6, { BF, FRA, FRB } },
4709
4710{ "drsp", XRC(59,770,0), X_MASK, POWER6, { FRT, FRB } },
4711{ "drsp.", XRC(59,770,1), X_MASK, POWER6, { FRT, FRB } },
4712
4713{ "dcffix", XRC(59,802,0), X_MASK, POWER6, { FRT, FRB } },
4714{ "dcffix.", XRC(59,802,1), X_MASK, POWER6, { FRT, FRB } },
4715
4716{ "denbcd", XRC(59,834,0), X_MASK, POWER6, { S, FRT, FRB } },
4717{ "denbcd.", XRC(59,834,1), X_MASK, POWER6, { S, FRT, FRB } },
4718
4719{ "diex", XRC(59,866,0), X_MASK, POWER6, { FRT, FRA, FRB } },
4720{ "diex.", XRC(59,866,1), X_MASK, POWER6, { FRT, FRA, FRB } },
4721
4434{ "stfq", OP(60), OP_MASK, POWER2, { FRS, D, RA } }, 4722{ "stfq", OP(60), OP_MASK, POWER2, { FRS, D, RA } },
4435 4723
4436{ "stfqu", OP(61), OP_MASK, POWER2, { FRS, D, RA } }, 4724{ "stfqu", OP(61), OP_MASK, POWER2, { FRS, D, RA } },
4437 4725
4438{ "lde", DEO(62,0), DE_MASK, BOOKE64, { RT, DES, RA } }, 4726{ "stfdp", OP(61), OP_MASK, POWER6, { FRT, D, RA0 } },
4439{ "ldue", DEO(62,1), DE_MASK, BOOKE64, { RT, DES, RA } }, 4727
4440{ "lfse", DEO(62,4), DE_MASK, BOOKE64, { FRT, DES, RA } }, 4728{ "lde", DEO(62,0), DE_MASK, BOOKE64, { RT, DES, RA0 } },
4729{ "ldue", DEO(62,1), DE_MASK, BOOKE64, { RT, DES, RA0 } },
4730{ "lfse", DEO(62,4), DE_MASK, BOOKE64, { FRT, DES, RA0 } },
4441{ "lfsue", DEO(62,5), DE_MASK, BOOKE64, { FRT, DES, RAS } }, 4731{ "lfsue", DEO(62,5), DE_MASK, BOOKE64, { FRT, DES, RAS } },
4442{ "lfde", DEO(62,6), DE_MASK, BOOKE64, { FRT, DES, RA } }, 4732{ "lfde", DEO(62,6), DE_MASK, BOOKE64, { FRT, DES, RA0 } },
4443{ "lfdue", DEO(62,7), DE_MASK, BOOKE64, { FRT, DES, RAS } }, 4733{ "lfdue", DEO(62,7), DE_MASK, BOOKE64, { FRT, DES, RAS } },
4444{ "stde", DEO(62,8), DE_MASK, BOOKE64, { RS, DES, RA } }, 4734{ "stde", DEO(62,8), DE_MASK, BOOKE64, { RS, DES, RA0 } },
4445{ "stdue", DEO(62,9), DE_MASK, BOOKE64, { RS, DES, RAS } }, 4735{ "stdue", DEO(62,9), DE_MASK, BOOKE64, { RS, DES, RAS } },
4446{ "stfse", DEO(62,12), DE_MASK, BOOKE64, { FRS, DES, RA } }, 4736{ "stfse", DEO(62,12), DE_MASK, BOOKE64, { FRS, DES, RA0 } },
4447{ "stfsue", DEO(62,13), DE_MASK, BOOKE64, { FRS, DES, RAS } }, 4737{ "stfsue", DEO(62,13), DE_MASK, BOOKE64, { FRS, DES, RAS } },
4448{ "stfde", DEO(62,14), DE_MASK, BOOKE64, { FRS, DES, RA } }, 4738{ "stfde", DEO(62,14), DE_MASK, BOOKE64, { FRS, DES, RA0 } },
4449{ "stfdue", DEO(62,15), DE_MASK, BOOKE64, { FRS, DES, RAS } }, 4739{ "stfdue", DEO(62,15), DE_MASK, BOOKE64, { FRS, DES, RAS } },
4450 4740
4451{ "std", DSO(62,0), DS_MASK, PPC64, { RS, DS, RA } }, 4741{ "std", DSO(62,0), DS_MASK, PPC64, { RS, DS, RA0 } },
4452 4742
4453{ "stdu", DSO(62,1), DS_MASK, PPC64, { RS, DS, RAS } }, 4743{ "stdu", DSO(62,1), DS_MASK, PPC64, { RS, DS, RAS } },
4454 4744
4455{ "stq", DSO(62,2), DS_MASK, POWER4, { RSQ, DS, RA } }, 4745{ "stq", DSO(62,2), DS_MASK, POWER4, { RSQ, DS, RA0 } },
4456 4746
4457{ "fcmpu", X(63,0), X_MASK|(3<<21), COM, { BF, FRA, FRB } }, 4747{ "fcmpu", X(63,0), X_MASK|(3<<21), COM, { BF, FRA, FRB } },
4458 4748
4749{ "daddq", XRC(63,2,0), X_MASK, POWER6, { FRT, FRA, FRB } },
4750{ "daddq.", XRC(63,2,1), X_MASK, POWER6, { FRT, FRA, FRB } },
4751
4752{ "dquaq", ZRC(63,3,0), Z_MASK, POWER6, { FRT, FRA, FRB, RMC } },
4753{ "dquaq.", ZRC(63,3,1), Z_MASK, POWER6, { FRT, FRA, FRB, RMC } },
4754
4755{ "fcpsgn", XRC(63,8,0), X_MASK, POWER6, { FRT, FRA, FRB } },
4756{ "fcpsgn.", XRC(63,8,1), X_MASK, POWER6, { FRT, FRA, FRB } },
4757
4459{ "frsp", XRC(63,12,0), XRA_MASK, COM, { FRT, FRB } }, 4758{ "frsp", XRC(63,12,0), XRA_MASK, COM, { FRT, FRB } },
4460{ "frsp.", XRC(63,12,1), XRA_MASK, COM, { FRT, FRB } }, 4759{ "frsp.", XRC(63,12,1), XRA_MASK, COM, { FRT, FRB } },
4461 4760
@@ -4490,13 +4789,16 @@ const struct powerpc_opcode powerpc_opcodes[] = {
4490{ "fsel", A(63,23,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } }, 4789{ "fsel", A(63,23,0), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
4491{ "fsel.", A(63,23,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } }, 4790{ "fsel.", A(63,23,1), A_MASK, PPC, { FRT,FRA,FRC,FRB } },
4492 4791
4792{ "fre", A(63,24,0), AFRALFRC_MASK, POWER5, { FRT, FRB, A_L } },
4793{ "fre.", A(63,24,1), AFRALFRC_MASK, POWER5, { FRT, FRB, A_L } },
4794
4493{ "fmul", A(63,25,0), AFRB_MASK, PPCCOM, { FRT, FRA, FRC } }, 4795{ "fmul", A(63,25,0), AFRB_MASK, PPCCOM, { FRT, FRA, FRC } },
4494{ "fm", A(63,25,0), AFRB_MASK, PWRCOM, { FRT, FRA, FRC } }, 4796{ "fm", A(63,25,0), AFRB_MASK, PWRCOM, { FRT, FRA, FRC } },
4495{ "fmul.", A(63,25,1), AFRB_MASK, PPCCOM, { FRT, FRA, FRC } }, 4797{ "fmul.", A(63,25,1), AFRB_MASK, PPCCOM, { FRT, FRA, FRC } },
4496{ "fm.", A(63,25,1), AFRB_MASK, PWRCOM, { FRT, FRA, FRC } }, 4798{ "fm.", A(63,25,1), AFRB_MASK, PWRCOM, { FRT, FRA, FRC } },
4497 4799
4498{ "frsqrte", A(63,26,0), AFRAFRC_MASK, PPC, { FRT, FRB } }, 4800{ "frsqrte", A(63,26,0), AFRALFRC_MASK, PPC, { FRT, FRB, A_L } },
4499{ "frsqrte.",A(63,26,1), AFRAFRC_MASK, PPC, { FRT, FRB } }, 4801{ "frsqrte.",A(63,26,1), AFRALFRC_MASK, PPC, { FRT, FRB, A_L } },
4500 4802
4501{ "fmsub", A(63,28,0), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB } }, 4803{ "fmsub", A(63,28,0), A_MASK, PPCCOM, { FRT,FRA,FRC,FRB } },
4502{ "fms", A(63,28,0), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB } }, 4804{ "fms", A(63,28,0), A_MASK, PWRCOM, { FRT,FRA,FRC,FRB } },
@@ -4520,6 +4822,12 @@ const struct powerpc_opcode powerpc_opcodes[] = {
4520 4822
4521{ "fcmpo", X(63,32), X_MASK|(3<<21), COM, { BF, FRA, FRB } }, 4823{ "fcmpo", X(63,32), X_MASK|(3<<21), COM, { BF, FRA, FRB } },
4522 4824
4825{ "dmulq", XRC(63,34,0), X_MASK, POWER6, { FRT, FRA, FRB } },
4826{ "dmulq.", XRC(63,34,1), X_MASK, POWER6, { FRT, FRA, FRB } },
4827
4828{ "drrndq", ZRC(63,35,0), Z_MASK, POWER6, { FRT, FRA, FRB, RMC } },
4829{ "drrndq.", ZRC(63,35,1), Z_MASK, POWER6, { FRT, FRA, FRB, RMC } },
4830
4523{ "mtfsb1", XRC(63,38,0), XRARB_MASK, COM, { BT } }, 4831{ "mtfsb1", XRC(63,38,0), XRARB_MASK, COM, { BT } },
4524{ "mtfsb1.", XRC(63,38,1), XRARB_MASK, COM, { BT } }, 4832{ "mtfsb1.", XRC(63,38,1), XRARB_MASK, COM, { BT } },
4525 4833
@@ -4528,36 +4836,100 @@ const struct powerpc_opcode powerpc_opcodes[] = {
4528 4836
4529{ "mcrfs", X(63,64), XRB_MASK|(3<<21)|(3<<16), COM, { BF, BFA } }, 4837{ "mcrfs", X(63,64), XRB_MASK|(3<<21)|(3<<16), COM, { BF, BFA } },
4530 4838
4839{ "dscliq", ZRC(63,66,0), Z_MASK, POWER6, { FRT, FRA, SH16 } },
4840{ "dscliq.", ZRC(63,66,1), Z_MASK, POWER6, { FRT, FRA, SH16 } },
4841
4842{ "dquaiq", ZRC(63,67,0), Z_MASK, POWER6, { TE, FRT, FRB, RMC } },
4843{ "dquaiq.", ZRC(63,67,1), Z_MASK, POWER6, { FRT, FRA, FRB, RMC } },
4844
4531{ "mtfsb0", XRC(63,70,0), XRARB_MASK, COM, { BT } }, 4845{ "mtfsb0", XRC(63,70,0), XRARB_MASK, COM, { BT } },
4532{ "mtfsb0.", XRC(63,70,1), XRARB_MASK, COM, { BT } }, 4846{ "mtfsb0.", XRC(63,70,1), XRARB_MASK, COM, { BT } },
4533 4847
4534{ "fmr", XRC(63,72,0), XRA_MASK, COM, { FRT, FRB } }, 4848{ "fmr", XRC(63,72,0), XRA_MASK, COM, { FRT, FRB } },
4535{ "fmr.", XRC(63,72,1), XRA_MASK, COM, { FRT, FRB } }, 4849{ "fmr.", XRC(63,72,1), XRA_MASK, COM, { FRT, FRB } },
4536 4850
4851{ "dscriq", ZRC(63,98,0), Z_MASK, POWER6, { FRT, FRA, SH16 } },
4852{ "dscriq.", ZRC(63,98,1), Z_MASK, POWER6, { FRT, FRA, SH16 } },
4853
4854{ "drintxq", ZRC(63,99,0), Z_MASK, POWER6, { R, FRT, FRB, RMC } },
4855{ "drintxq.",ZRC(63,99,1), Z_MASK, POWER6, { R, FRT, FRB, RMC } },
4856
4857{ "dcmpoq", X(63,130), X_MASK, POWER6, { BF, FRA, FRB } },
4858
4537{ "mtfsfi", XRC(63,134,0), XRA_MASK|(3<<21)|(1<<11), COM, { BF, U } }, 4859{ "mtfsfi", XRC(63,134,0), XRA_MASK|(3<<21)|(1<<11), COM, { BF, U } },
4538{ "mtfsfi.", XRC(63,134,1), XRA_MASK|(3<<21)|(1<<11), COM, { BF, U } }, 4860{ "mtfsfi.", XRC(63,134,1), XRA_MASK|(3<<21)|(1<<11), COM, { BF, U } },
4539 4861
4540{ "fnabs", XRC(63,136,0), XRA_MASK, COM, { FRT, FRB } }, 4862{ "fnabs", XRC(63,136,0), XRA_MASK, COM, { FRT, FRB } },
4541{ "fnabs.", XRC(63,136,1), XRA_MASK, COM, { FRT, FRB } }, 4863{ "fnabs.", XRC(63,136,1), XRA_MASK, COM, { FRT, FRB } },
4542 4864
4865{ "dtstexq", X(63,162), X_MASK, POWER6, { BF, FRA, FRB } },
4866{ "dtstdcq", Z(63,194), Z_MASK, POWER6, { BF, FRA, DCM } },
4867{ "dtstdgq", Z(63,226), Z_MASK, POWER6, { BF, FRA, DGM } },
4868
4869{ "drintnq", ZRC(63,227,0), Z_MASK, POWER6, { R, FRT, FRB, RMC } },
4870{ "drintnq.",ZRC(63,227,1), Z_MASK, POWER6, { R, FRT, FRB, RMC } },
4871
4872{ "dctqpq", XRC(63,258,0), X_MASK, POWER6, { FRT, FRB } },
4873{ "dctqpq.", XRC(63,258,1), X_MASK, POWER6, { FRT, FRB } },
4874
4543{ "fabs", XRC(63,264,0), XRA_MASK, COM, { FRT, FRB } }, 4875{ "fabs", XRC(63,264,0), XRA_MASK, COM, { FRT, FRB } },
4544{ "fabs.", XRC(63,264,1), XRA_MASK, COM, { FRT, FRB } }, 4876{ "fabs.", XRC(63,264,1), XRA_MASK, COM, { FRT, FRB } },
4545 4877
4878{ "dctfixq", XRC(63,290,0), X_MASK, POWER6, { FRT, FRB } },
4879{ "dctfixq.",XRC(63,290,1), X_MASK, POWER6, { FRT, FRB } },
4880
4881{ "ddedpdq", XRC(63,322,0), X_MASK, POWER6, { SP, FRT, FRB } },
4882{ "ddedpdq.",XRC(63,322,1), X_MASK, POWER6, { SP, FRT, FRB } },
4883
4884{ "dxexq", XRC(63,354,0), X_MASK, POWER6, { FRT, FRB } },
4885{ "dxexq.", XRC(63,354,1), X_MASK, POWER6, { FRT, FRB } },
4886
4887{ "frin", XRC(63,392,0), XRA_MASK, POWER5, { FRT, FRB } },
4888{ "frin.", XRC(63,392,1), XRA_MASK, POWER5, { FRT, FRB } },
4889{ "friz", XRC(63,424,0), XRA_MASK, POWER5, { FRT, FRB } },
4890{ "friz.", XRC(63,424,1), XRA_MASK, POWER5, { FRT, FRB } },
4891{ "frip", XRC(63,456,0), XRA_MASK, POWER5, { FRT, FRB } },
4892{ "frip.", XRC(63,456,1), XRA_MASK, POWER5, { FRT, FRB } },
4893{ "frim", XRC(63,488,0), XRA_MASK, POWER5, { FRT, FRB } },
4894{ "frim.", XRC(63,488,1), XRA_MASK, POWER5, { FRT, FRB } },
4895
4896{ "dsubq", XRC(63,514,0), X_MASK, POWER6, { FRT, FRA, FRB } },
4897{ "dsubq.", XRC(63,514,1), X_MASK, POWER6, { FRT, FRA, FRB } },
4898
4899{ "ddivq", XRC(63,546,0), X_MASK, POWER6, { FRT, FRA, FRB } },
4900{ "ddivq.", XRC(63,546,1), X_MASK, POWER6, { FRT, FRA, FRB } },
4901
4546{ "mffs", XRC(63,583,0), XRARB_MASK, COM, { FRT } }, 4902{ "mffs", XRC(63,583,0), XRARB_MASK, COM, { FRT } },
4547{ "mffs.", XRC(63,583,1), XRARB_MASK, COM, { FRT } }, 4903{ "mffs.", XRC(63,583,1), XRARB_MASK, COM, { FRT } },
4548 4904
4905{ "dcmpuq", X(63,642), X_MASK, POWER6, { BF, FRA, FRB } },
4906
4907{ "dtstsfq", X(63,674), X_MASK, POWER6, { BF, FRA, FRB } },
4908
4549{ "mtfsf", XFL(63,711,0), XFL_MASK, COM, { FLM, FRB } }, 4909{ "mtfsf", XFL(63,711,0), XFL_MASK, COM, { FLM, FRB } },
4550{ "mtfsf.", XFL(63,711,1), XFL_MASK, COM, { FLM, FRB } }, 4910{ "mtfsf.", XFL(63,711,1), XFL_MASK, COM, { FLM, FRB } },
4551 4911
4912{ "drdpq", XRC(63,770,0), X_MASK, POWER6, { FRT, FRB } },
4913{ "drdpq.", XRC(63,770,1), X_MASK, POWER6, { FRT, FRB } },
4914
4915{ "dcffixq", XRC(63,802,0), X_MASK, POWER6, { FRT, FRB } },
4916{ "dcffixq.",XRC(63,802,1), X_MASK, POWER6, { FRT, FRB } },
4917
4552{ "fctid", XRC(63,814,0), XRA_MASK, PPC64, { FRT, FRB } }, 4918{ "fctid", XRC(63,814,0), XRA_MASK, PPC64, { FRT, FRB } },
4553{ "fctid.", XRC(63,814,1), XRA_MASK, PPC64, { FRT, FRB } }, 4919{ "fctid.", XRC(63,814,1), XRA_MASK, PPC64, { FRT, FRB } },
4554 4920
4555{ "fctidz", XRC(63,815,0), XRA_MASK, PPC64, { FRT, FRB } }, 4921{ "fctidz", XRC(63,815,0), XRA_MASK, PPC64, { FRT, FRB } },
4556{ "fctidz.", XRC(63,815,1), XRA_MASK, PPC64, { FRT, FRB } }, 4922{ "fctidz.", XRC(63,815,1), XRA_MASK, PPC64, { FRT, FRB } },
4557 4923
4924{ "denbcdq", XRC(63,834,0), X_MASK, POWER6, { S, FRT, FRB } },
4925{ "denbcdq.",XRC(63,834,1), X_MASK, POWER6, { S, FRT, FRB } },
4926
4558{ "fcfid", XRC(63,846,0), XRA_MASK, PPC64, { FRT, FRB } }, 4927{ "fcfid", XRC(63,846,0), XRA_MASK, PPC64, { FRT, FRB } },
4559{ "fcfid.", XRC(63,846,1), XRA_MASK, PPC64, { FRT, FRB } }, 4928{ "fcfid.", XRC(63,846,1), XRA_MASK, PPC64, { FRT, FRB } },
4560 4929
4930{ "diexq", XRC(63,866,0), X_MASK, POWER6, { FRT, FRA, FRB } },
4931{ "diexq.", XRC(63,866,1), X_MASK, POWER6, { FRT, FRA, FRB } },
4932
4561}; 4933};
4562 4934
4563const int powerpc_num_opcodes = 4935const int powerpc_num_opcodes =
diff --git a/arch/powerpc/xmon/ppc.h b/arch/powerpc/xmon/ppc.h
index 342237e8dd69..110df96354b4 100644
--- a/arch/powerpc/xmon/ppc.h
+++ b/arch/powerpc/xmon/ppc.h
@@ -1,5 +1,5 @@
1/* ppc.h -- Header file for PowerPC opcode table 1/* ppc.h -- Header file for PowerPC opcode table
2 Copyright 1994, 1995, 1999, 2000, 2001, 2002, 2003 2 Copyright 1994, 1995, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
3 Free Software Foundation, Inc. 3 Free Software Foundation, Inc.
4 Written by Ian Lance Taylor, Cygnus Support 4 Written by Ian Lance Taylor, Cygnus Support
5 5
@@ -17,7 +17,7 @@ the GNU General Public License for more details.
17 17
18You should have received a copy of the GNU General Public License 18You should have received a copy of the GNU General Public License
19along with this file; see the file COPYING. If not, write to the Free 19along with this file; see the file COPYING. If not, write to the Free
20Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 20Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
21 21
22#ifndef PPC_H 22#ifndef PPC_H
23#define PPC_H 23#define PPC_H
@@ -134,6 +134,18 @@ extern const int powerpc_num_opcodes;
134/* Opcode is supported by machine check APU. */ 134/* Opcode is supported by machine check APU. */
135#define PPC_OPCODE_RFMCI 0x800000 135#define PPC_OPCODE_RFMCI 0x800000
136 136
137/* Opcode is only supported by Power5 architecture. */
138#define PPC_OPCODE_POWER5 0x1000000
139
140/* Opcode is supported by PowerPC e300 family. */
141#define PPC_OPCODE_E300 0x2000000
142
143/* Opcode is only supported by Power6 architecture. */
144#define PPC_OPCODE_POWER6 0x4000000
145
146/* Opcode is only supported by PowerPC Cell family. */
147#define PPC_OPCODE_CELL 0x8000000
148
137/* A macro to extract the major opcode from an instruction. */ 149/* A macro to extract the major opcode from an instruction. */
138#define PPC_OP(i) (((i) >> 26) & 0x3f) 150#define PPC_OP(i) (((i) >> 26) & 0x3f)
139 151
@@ -233,25 +245,28 @@ extern const struct powerpc_operand powerpc_operands[];
233 register names with a leading 'r'. */ 245 register names with a leading 'r'. */
234#define PPC_OPERAND_GPR (040) 246#define PPC_OPERAND_GPR (040)
235 247
248/* Like PPC_OPERAND_GPR, but don't print a leading 'r' for r0. */
249#define PPC_OPERAND_GPR_0 (0100)
250
236/* This operand names a floating point register. The disassembler 251/* This operand names a floating point register. The disassembler
237 prints these with a leading 'f'. */ 252 prints these with a leading 'f'. */
238#define PPC_OPERAND_FPR (0100) 253#define PPC_OPERAND_FPR (0200)
239 254
240/* This operand is a relative branch displacement. The disassembler 255/* This operand is a relative branch displacement. The disassembler
241 prints these symbolically if possible. */ 256 prints these symbolically if possible. */
242#define PPC_OPERAND_RELATIVE (0200) 257#define PPC_OPERAND_RELATIVE (0400)
243 258
244/* This operand is an absolute branch address. The disassembler 259/* This operand is an absolute branch address. The disassembler
245 prints these symbolically if possible. */ 260 prints these symbolically if possible. */
246#define PPC_OPERAND_ABSOLUTE (0400) 261#define PPC_OPERAND_ABSOLUTE (01000)
247 262
248/* This operand is optional, and is zero if omitted. This is used for 263/* This operand is optional, and is zero if omitted. This is used for
249 the optional BF and L fields in the comparison instructions. The 264 example, in the optional BF field in the comparison instructions. The
250 assembler must count the number of operands remaining on the line, 265 assembler must count the number of operands remaining on the line,
251 and the number of operands remaining for the opcode, and decide 266 and the number of operands remaining for the opcode, and decide
252 whether this operand is present or not. The disassembler should 267 whether this operand is present or not. The disassembler should
253 print this operand out only if it is not zero. */ 268 print this operand out only if it is not zero. */
254#define PPC_OPERAND_OPTIONAL (01000) 269#define PPC_OPERAND_OPTIONAL (02000)
255 270
256/* This flag is only used with PPC_OPERAND_OPTIONAL. If this operand 271/* This flag is only used with PPC_OPERAND_OPTIONAL. If this operand
257 is omitted, then for the next operand use this operand value plus 272 is omitted, then for the next operand use this operand value plus
@@ -259,24 +274,24 @@ extern const struct powerpc_operand powerpc_operands[];
259 hack is needed because the Power rotate instructions can take 274 hack is needed because the Power rotate instructions can take
260 either 4 or 5 operands. The disassembler should print this operand 275 either 4 or 5 operands. The disassembler should print this operand
261 out regardless of the PPC_OPERAND_OPTIONAL field. */ 276 out regardless of the PPC_OPERAND_OPTIONAL field. */
262#define PPC_OPERAND_NEXT (02000) 277#define PPC_OPERAND_NEXT (04000)
263 278
264/* This operand should be regarded as a negative number for the 279/* This operand should be regarded as a negative number for the
265 purposes of overflow checking (i.e., the normal most negative 280 purposes of overflow checking (i.e., the normal most negative
266 number is disallowed and one more than the normal most positive 281 number is disallowed and one more than the normal most positive
267 number is allowed). This flag will only be set for a signed 282 number is allowed). This flag will only be set for a signed
268 operand. */ 283 operand. */
269#define PPC_OPERAND_NEGATIVE (04000) 284#define PPC_OPERAND_NEGATIVE (010000)
270 285
271/* This operand names a vector unit register. The disassembler 286/* This operand names a vector unit register. The disassembler
272 prints these with a leading 'v'. */ 287 prints these with a leading 'v'. */
273#define PPC_OPERAND_VR (010000) 288#define PPC_OPERAND_VR (020000)
274 289
275/* This operand is for the DS field in a DS form instruction. */ 290/* This operand is for the DS field in a DS form instruction. */
276#define PPC_OPERAND_DS (020000) 291#define PPC_OPERAND_DS (040000)
277 292
278/* This operand is for the DQ field in a DQ form instruction. */ 293/* This operand is for the DQ field in a DQ form instruction. */
279#define PPC_OPERAND_DQ (040000) 294#define PPC_OPERAND_DQ (0100000)
280 295
281/* The POWER and PowerPC assemblers use a few macros. We keep them 296/* The POWER and PowerPC assemblers use a few macros. We keep them
282 with the operands table for simplicity. The macro table is an 297 with the operands table for simplicity. The macro table is an
diff --git a/arch/powerpc/xmon/spu-dis.c b/arch/powerpc/xmon/spu-dis.c
new file mode 100644
index 000000000000..ee929c641bf3
--- /dev/null
+++ b/arch/powerpc/xmon/spu-dis.c
@@ -0,0 +1,248 @@
1/* Disassemble SPU instructions
2
3 Copyright 2006 Free Software Foundation, Inc.
4
5 This file is part of GDB, GAS, and the GNU binutils.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
20
21#include <linux/string.h>
22#include "nonstdio.h"
23#include "ansidecl.h"
24#include "spu.h"
25#include "dis-asm.h"
26
27/* This file provides a disassembler function which uses
28 the disassembler interface defined in dis-asm.h. */
29
30extern const struct spu_opcode spu_opcodes[];
31extern const int spu_num_opcodes;
32
33#define SPU_DISASM_TBL_SIZE (1 << 11)
34static const struct spu_opcode *spu_disassemble_table[SPU_DISASM_TBL_SIZE];
35
36static void
37init_spu_disassemble (void)
38{
39 int i;
40
41 /* If two instructions have the same opcode then we prefer the first
42 * one. In most cases it is just an alternate mnemonic. */
43 for (i = 0; i < spu_num_opcodes; i++)
44 {
45 int o = spu_opcodes[i].opcode;
46 if (o >= SPU_DISASM_TBL_SIZE)
47 continue; /* abort (); */
48 if (spu_disassemble_table[o] == 0)
49 spu_disassemble_table[o] = &spu_opcodes[i];
50 }
51}
52
53/* Determine the instruction from the 10 least significant bits. */
54static const struct spu_opcode *
55get_index_for_opcode (unsigned int insn)
56{
57 const struct spu_opcode *index;
58 unsigned int opcode = insn >> (32-11);
59
60 /* Init the table. This assumes that element 0/opcode 0 (currently
61 * NOP) is always used */
62 if (spu_disassemble_table[0] == 0)
63 init_spu_disassemble ();
64
65 if ((index = spu_disassemble_table[opcode & 0x780]) != 0
66 && index->insn_type == RRR)
67 return index;
68
69 if ((index = spu_disassemble_table[opcode & 0x7f0]) != 0
70 && (index->insn_type == RI18 || index->insn_type == LBT))
71 return index;
72
73 if ((index = spu_disassemble_table[opcode & 0x7f8]) != 0
74 && index->insn_type == RI10)
75 return index;
76
77 if ((index = spu_disassemble_table[opcode & 0x7fc]) != 0
78 && (index->insn_type == RI16))
79 return index;
80
81 if ((index = spu_disassemble_table[opcode & 0x7fe]) != 0
82 && (index->insn_type == RI8))
83 return index;
84
85 if ((index = spu_disassemble_table[opcode & 0x7ff]) != 0)
86 return index;
87
88 return 0;
89}
90
91/* Print a Spu instruction. */
92
93int
94print_insn_spu (unsigned long insn, unsigned long memaddr)
95{
96 int value;
97 int hex_value;
98 const struct spu_opcode *index;
99 enum spu_insns tag;
100
101 index = get_index_for_opcode (insn);
102
103 if (index == 0)
104 {
105 printf(".long 0x%x", insn);
106 }
107 else
108 {
109 int i;
110 int paren = 0;
111 tag = (enum spu_insns)(index - spu_opcodes);
112 printf("%s", index->mnemonic);
113 if (tag == M_BI || tag == M_BISL || tag == M_IRET || tag == M_BISLED
114 || tag == M_BIHNZ || tag == M_BIHZ || tag == M_BINZ || tag == M_BIZ
115 || tag == M_SYNC || tag == M_HBR)
116 {
117 int fb = (insn >> (32-18)) & 0x7f;
118 if (fb & 0x40)
119 printf(tag == M_SYNC ? "c" : "p");
120 if (fb & 0x20)
121 printf("d");
122 if (fb & 0x10)
123 printf("e");
124 }
125 if (index->arg[0] != 0)
126 printf("\t");
127 hex_value = 0;
128 for (i = 1; i <= index->arg[0]; i++)
129 {
130 int arg = index->arg[i];
131 if (arg != A_P && !paren && i > 1)
132 printf(",");
133
134 switch (arg)
135 {
136 case A_T:
137 printf("$%d",
138 DECODE_INSN_RT (insn));
139 break;
140 case A_A:
141 printf("$%d",
142 DECODE_INSN_RA (insn));
143 break;
144 case A_B:
145 printf("$%d",
146 DECODE_INSN_RB (insn));
147 break;
148 case A_C:
149 printf("$%d",
150 DECODE_INSN_RC (insn));
151 break;
152 case A_S:
153 printf("$sp%d",
154 DECODE_INSN_RA (insn));
155 break;
156 case A_H:
157 printf("$ch%d",
158 DECODE_INSN_RA (insn));
159 break;
160 case A_P:
161 paren++;
162 printf("(");
163 break;
164 case A_U7A:
165 printf("%d",
166 173 - DECODE_INSN_U8 (insn));
167 break;
168 case A_U7B:
169 printf("%d",
170 155 - DECODE_INSN_U8 (insn));
171 break;
172 case A_S3:
173 case A_S6:
174 case A_S7:
175 case A_S7N:
176 case A_U3:
177 case A_U5:
178 case A_U6:
179 case A_U7:
180 hex_value = DECODE_INSN_I7 (insn);
181 printf("%d", hex_value);
182 break;
183 case A_S11:
184 print_address(memaddr + DECODE_INSN_I9a (insn) * 4);
185 break;
186 case A_S11I:
187 print_address(memaddr + DECODE_INSN_I9b (insn) * 4);
188 break;
189 case A_S10:
190 case A_S10B:
191 hex_value = DECODE_INSN_I10 (insn);
192 printf("%d", hex_value);
193 break;
194 case A_S14:
195 hex_value = DECODE_INSN_I10 (insn) * 16;
196 printf("%d", hex_value);
197 break;
198 case A_S16:
199 hex_value = DECODE_INSN_I16 (insn);
200 printf("%d", hex_value);
201 break;
202 case A_X16:
203 hex_value = DECODE_INSN_U16 (insn);
204 printf("%u", hex_value);
205 break;
206 case A_R18:
207 value = DECODE_INSN_I16 (insn) * 4;
208 if (value == 0)
209 printf("%d", value);
210 else
211 {
212 hex_value = memaddr + value;
213 print_address(hex_value & 0x3ffff);
214 }
215 break;
216 case A_S18:
217 value = DECODE_INSN_U16 (insn) * 4;
218 if (value == 0)
219 printf("%d", value);
220 else
221 print_address(value);
222 break;
223 case A_U18:
224 value = DECODE_INSN_U18 (insn);
225 if (value == 0 || 1)
226 {
227 hex_value = value;
228 printf("%u", value);
229 }
230 else
231 print_address(value);
232 break;
233 case A_U14:
234 hex_value = DECODE_INSN_U14 (insn);
235 printf("%u", hex_value);
236 break;
237 }
238 if (arg != A_P && paren)
239 {
240 printf(")");
241 paren--;
242 }
243 }
244 if (hex_value > 16)
245 printf("\t# %x", hex_value);
246 }
247 return 4;
248}
diff --git a/arch/powerpc/xmon/spu-insns.h b/arch/powerpc/xmon/spu-insns.h
new file mode 100644
index 000000000000..99dc452821ac
--- /dev/null
+++ b/arch/powerpc/xmon/spu-insns.h
@@ -0,0 +1,410 @@
1/* SPU ELF support for BFD.
2
3 Copyright 2006 Free Software Foundation, Inc.
4
5 This file is part of BFD, the Binary File Descriptor library.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
20
21/* SPU Opcode Table
22
23-=-=-= FORMAT =-=-=-
24
25 +----+-------+-------+-------+-------+ +------------+-------+-------+-------+
26RRR | op | RC | RB | RA | RT | RI7 | op | I7 | RA | RT |
27 +----+-------+-------+-------+-------+ +------------+-------+-------+-------+
28 0 3 1 1 2 3 0 1 1 2 3
29 0 7 4 1 0 7 4 1
30
31 +-----------+--------+-------+-------+ +---------+----------+-------+-------+
32RI8 | op | I8 | RA | RT | RI10 | op | I10 | RA | RT |
33 +-----------+--------+-------+-------+ +---------+----------+-------+-------+
34 0 9 1 2 3 0 7 1 2 3
35 7 4 1 7 4 1
36
37 +----------+-----------------+-------+ +--------+-------------------+-------+
38RI16 | op | I16 | RT | RI18 | op | I18 | RT |
39 +----------+-----------------+-------+ +--------+-------------------+-------+
40 0 8 2 3 0 6 2 3
41 4 1 4 1
42
43 +------------+-------+-------+-------+ +-------+--+-----------------+-------+
44RR | op | RB | RA | RT | LBT | op |RO| I16 | RO |
45 +------------+-------+-------+-------+ +-------+--+-----------------+-------+
46 0 1 1 2 3 0 6 8 2 3
47 0 7 4 1 4 1
48
49 +------------+----+--+-------+-------+
50 LBTI | op | // |RO| RA | RO |
51 +------------+----+--+-------+-------+
52 0 1 1 1 2 3
53 0 5 7 4 1
54
55-=-=-= OPCODE =-=-=-
56
57OPCODE field specifies the most significant 11bit of the instruction. Some formats don't have 11bits for opcode field, and in this
58case, bit field other than op are defined as 0s. For example, opcode of fma instruction which is RRR format is defined as 0x700,
59since 0x700 -> 11'b11100000000, this means opcode is 4'b1110, and other 7bits are defined as 7'b0000000.
60
61-=-=-= ASM_FORMAT =-=-=-
62
63RRR category RI7 category
64 ASM_RRR mnemonic RC, RA, RB, RT ASM_RI4 mnemonic RT, RA, I4
65 ASM_RI7 mnemonic RT, RA, I7
66
67RI8 category RI10 category
68 ASM_RUI8 mnemonic RT, RA, UI8 ASM_AI10 mnemonic RA, I10
69 ASM_RI10 mnemonic RT, RA, R10
70 ASM_RI10IDX mnemonic RT, I10(RA)
71
72RI16 category RI18 category
73 ASM_I16W mnemonic I16W ASM_RI18 mnemonic RT, I18
74 ASM_RI16 mnemonic RT, I16
75 ASM_RI16W mnemonic RT, I16W
76
77RR category LBT category
78 ASM_MFSPR mnemonic RT, SA ASM_LBT mnemonic brinst, brtarg
79 ASM_MTSPR mnemonic SA, RT
80 ASM_NOOP mnemonic LBTI category
81 ASM_RA mnemonic RA ASM_LBTI mnemonic brinst, RA
82 ASM_RAB mnemonic RA, RB
83 ASM_RDCH mnemonic RT, CA
84 ASM_RR mnemonic RT, RA, RB
85 ASM_RT mnemonic RT
86 ASM_RTA mnemonic RT, RA
87 ASM_WRCH mnemonic CA, RT
88
89Note that RRR instructions have the names for RC and RT reversed from
90what's in the ISA, in order to put RT in the same position it appears
91for other formats.
92
93-=-=-= DEPENDENCY =-=-=-
94
95DEPENDENCY filed consists of 5 digits. This represents which register is used as source and which register is used as target.
96The first(most significant) digit is always 0. Then it is followd by RC, RB, RA and RT digits.
97If the digit is 0, this means the corresponding register is not used in the instruction.
98If the digit is 1, this means the corresponding register is used as a source in the instruction.
99If the digit is 2, this means the corresponding register is used as a target in the instruction.
100If the digit is 3, this means the corresponding register is used as both source and target in the instruction.
101For example, fms instruction has 00113 as the DEPENDENCY field. This means RC is not used in this operation, RB and RA are
102used as sources and RT is the target.
103
104-=-=-= PIPE =-=-=-
105
106This field shows which execution pipe is used for the instruction
107
108pipe0 execution pipelines:
109 FP6 SP floating pipeline
110 FP7 integer operations executed in SP floating pipeline
111 FPD DP floating pipeline
112 FX2 FXU pipeline
113 FX3 Rotate/Shift pipeline
114 FXB Byte pipeline
115 NOP No pipeline
116
117pipe1 execution pipelines:
118 BR Branch pipeline
119 LNOP No pipeline
120 LS Load/Store pipeline
121 SHUF Shuffle pipeline
122 SPR SPR/CH pipeline
123
124*/
125
126#define _A0() {0}
127#define _A1(a) {1,a}
128#define _A2(a,b) {2,a,b}
129#define _A3(a,b,c) {3,a,b,c}
130#define _A4(a,b,c,d) {4,a,b,c,d}
131
132/* TAG FORMAT OPCODE MNEMONIC ASM_FORMAT DEPENDENCY PIPE COMMENT */
133/* 0[RC][RB][RA][RT] */
134/* 1:src, 2:target */
135
136APUOP(M_BR, RI16, 0x190, "br", _A1(A_R18), 00000, BR) /* BRel IP<-IP+I16 */
137APUOP(M_BRSL, RI16, 0x198, "brsl", _A2(A_T,A_R18), 00002, BR) /* BRelSetLink RT,IP<-IP,IP+I16 */
138APUOP(M_BRA, RI16, 0x180, "bra", _A1(A_S18), 00000, BR) /* BRAbs IP<-I16 */
139APUOP(M_BRASL, RI16, 0x188, "brasl", _A2(A_T,A_S18), 00002, BR) /* BRAbsSetLink RT,IP<-IP,I16 */
140APUOP(M_FSMBI, RI16, 0x194, "fsmbi", _A2(A_T,A_X16), 00002, SHUF) /* FormSelMask%I RT<-fsm(I16) */
141APUOP(M_LQA, RI16, 0x184, "lqa", _A2(A_T,A_S18), 00002, LS) /* LoadQAbs RT<-M[I16] */
142APUOP(M_LQR, RI16, 0x19C, "lqr", _A2(A_T,A_R18), 00002, LS) /* LoadQRel RT<-M[IP+I16] */
143APUOP(M_STOP, RR, 0x000, "stop", _A0(), 00000, BR) /* STOP stop */
144APUOP(M_STOP2, RR, 0x000, "stop", _A1(A_U14), 00000, BR) /* STOP stop */
145APUOP(M_STOPD, RR, 0x140, "stopd", _A3(A_T,A_A,A_B), 00111, BR) /* STOPD stop (with register dependencies) */
146APUOP(M_LNOP, RR, 0x001, "lnop", _A0(), 00000, LNOP) /* LNOP no_operation */
147APUOP(M_SYNC, RR, 0x002, "sync", _A0(), 00000, BR) /* SYNC flush_pipe */
148APUOP(M_DSYNC, RR, 0x003, "dsync", _A0(), 00000, BR) /* DSYNC flush_store_queue */
149APUOP(M_MFSPR, RR, 0x00c, "mfspr", _A2(A_T,A_S), 00002, SPR) /* MFSPR RT<-SA */
150APUOP(M_RDCH, RR, 0x00d, "rdch", _A2(A_T,A_H), 00002, SPR) /* ReaDCHannel RT<-CA:data */
151APUOP(M_RCHCNT, RR, 0x00f, "rchcnt", _A2(A_T,A_H), 00002, SPR) /* ReaDCHanCouNT RT<-CA:count */
152APUOP(M_HBRA, LBT, 0x080, "hbra", _A2(A_S11,A_S18), 00000, LS) /* HBRA BTB[B9]<-M[I16] */
153APUOP(M_HBRR, LBT, 0x090, "hbrr", _A2(A_S11,A_R18), 00000, LS) /* HBRR BTB[B9]<-M[IP+I16] */
154APUOP(M_BRZ, RI16, 0x100, "brz", _A2(A_T,A_R18), 00001, BR) /* BRZ IP<-IP+I16_if(RT) */
155APUOP(M_BRNZ, RI16, 0x108, "brnz", _A2(A_T,A_R18), 00001, BR) /* BRNZ IP<-IP+I16_if(RT) */
156APUOP(M_BRHZ, RI16, 0x110, "brhz", _A2(A_T,A_R18), 00001, BR) /* BRHZ IP<-IP+I16_if(RT) */
157APUOP(M_BRHNZ, RI16, 0x118, "brhnz", _A2(A_T,A_R18), 00001, BR) /* BRHNZ IP<-IP+I16_if(RT) */
158APUOP(M_STQA, RI16, 0x104, "stqa", _A2(A_T,A_S18), 00001, LS) /* SToreQAbs M[I16]<-RT */
159APUOP(M_STQR, RI16, 0x11C, "stqr", _A2(A_T,A_R18), 00001, LS) /* SToreQRel M[IP+I16]<-RT */
160APUOP(M_MTSPR, RR, 0x10c, "mtspr", _A2(A_S,A_T), 00001, SPR) /* MTSPR SA<-RT */
161APUOP(M_WRCH, RR, 0x10d, "wrch", _A2(A_H,A_T), 00001, SPR) /* ChanWRite CA<-RT */
162APUOP(M_LQD, RI10, 0x1a0, "lqd", _A4(A_T,A_S14,A_P,A_A), 00012, LS) /* LoadQDisp RT<-M[Ra+I10] */
163APUOP(M_BI, RR, 0x1a8, "bi", _A1(A_A), 00010, BR) /* BI IP<-RA */
164APUOP(M_BISL, RR, 0x1a9, "bisl", _A2(A_T,A_A), 00012, BR) /* BISL RT,IP<-IP,RA */
165APUOP(M_IRET, RR, 0x1aa, "iret", _A1(A_A), 00010, BR) /* IRET IP<-SRR0 */
166APUOP(M_IRET2, RR, 0x1aa, "iret", _A0(), 00010, BR) /* IRET IP<-SRR0 */
167APUOP(M_BISLED, RR, 0x1ab, "bisled", _A2(A_T,A_A), 00012, BR) /* BISLED RT,IP<-IP,RA_if(ext) */
168APUOP(M_HBR, LBTI, 0x1ac, "hbr", _A2(A_S11I,A_A), 00010, LS) /* HBR BTB[B9]<-M[Ra] */
169APUOP(M_FREST, RR, 0x1b8, "frest", _A2(A_T,A_A), 00012, SHUF) /* FREST RT<-recip(RA) */
170APUOP(M_FRSQEST, RR, 0x1b9, "frsqest", _A2(A_T,A_A), 00012, SHUF) /* FRSQEST RT<-rsqrt(RA) */
171APUOP(M_FSM, RR, 0x1b4, "fsm", _A2(A_T,A_A), 00012, SHUF) /* FormSelMask% RT<-expand(Ra) */
172APUOP(M_FSMH, RR, 0x1b5, "fsmh", _A2(A_T,A_A), 00012, SHUF) /* FormSelMask% RT<-expand(Ra) */
173APUOP(M_FSMB, RR, 0x1b6, "fsmb", _A2(A_T,A_A), 00012, SHUF) /* FormSelMask% RT<-expand(Ra) */
174APUOP(M_GB, RR, 0x1b0, "gb", _A2(A_T,A_A), 00012, SHUF) /* GatherBits% RT<-gather(RA) */
175APUOP(M_GBH, RR, 0x1b1, "gbh", _A2(A_T,A_A), 00012, SHUF) /* GatherBits% RT<-gather(RA) */
176APUOP(M_GBB, RR, 0x1b2, "gbb", _A2(A_T,A_A), 00012, SHUF) /* GatherBits% RT<-gather(RA) */
177APUOP(M_CBD, RI7, 0x1f4, "cbd", _A4(A_T,A_U7,A_P,A_A), 00012, SHUF) /* genCtl%%insD RT<-sta(Ra+I4,siz) */
178APUOP(M_CHD, RI7, 0x1f5, "chd", _A4(A_T,A_U7,A_P,A_A), 00012, SHUF) /* genCtl%%insD RT<-sta(Ra+I4,siz) */
179APUOP(M_CWD, RI7, 0x1f6, "cwd", _A4(A_T,A_U7,A_P,A_A), 00012, SHUF) /* genCtl%%insD RT<-sta(Ra+I4,siz) */
180APUOP(M_CDD, RI7, 0x1f7, "cdd", _A4(A_T,A_U7,A_P,A_A), 00012, SHUF) /* genCtl%%insD RT<-sta(Ra+I4,siz) */
181APUOP(M_ROTQBII, RI7, 0x1f8, "rotqbii", _A3(A_T,A_A,A_U3), 00012, SHUF) /* ROTQBII RT<-RA<<<I7 */
182APUOP(M_ROTQBYI, RI7, 0x1fc, "rotqbyi", _A3(A_T,A_A,A_S7N), 00012, SHUF) /* ROTQBYI RT<-RA<<<(I7*8) */
183APUOP(M_ROTQMBII, RI7, 0x1f9, "rotqmbii", _A3(A_T,A_A,A_S3), 00012, SHUF) /* ROTQMBII RT<-RA<<I7 */
184APUOP(M_ROTQMBYI, RI7, 0x1fd, "rotqmbyi", _A3(A_T,A_A,A_S6), 00012, SHUF) /* ROTQMBYI RT<-RA<<I7 */
185APUOP(M_SHLQBII, RI7, 0x1fb, "shlqbii", _A3(A_T,A_A,A_U3), 00012, SHUF) /* SHLQBII RT<-RA<<I7 */
186APUOP(M_SHLQBYI, RI7, 0x1ff, "shlqbyi", _A3(A_T,A_A,A_U5), 00012, SHUF) /* SHLQBYI RT<-RA<<I7 */
187APUOP(M_STQD, RI10, 0x120, "stqd", _A4(A_T,A_S14,A_P,A_A), 00011, LS) /* SToreQDisp M[Ra+I10]<-RT */
188APUOP(M_BIHNZ, RR, 0x12b, "bihnz", _A2(A_T,A_A), 00011, BR) /* BIHNZ IP<-RA_if(RT) */
189APUOP(M_BIHZ, RR, 0x12a, "bihz", _A2(A_T,A_A), 00011, BR) /* BIHZ IP<-RA_if(RT) */
190APUOP(M_BINZ, RR, 0x129, "binz", _A2(A_T,A_A), 00011, BR) /* BINZ IP<-RA_if(RT) */
191APUOP(M_BIZ, RR, 0x128, "biz", _A2(A_T,A_A), 00011, BR) /* BIZ IP<-RA_if(RT) */
192APUOP(M_CBX, RR, 0x1d4, "cbx", _A3(A_T,A_A,A_B), 00112, SHUF) /* genCtl%%insX RT<-sta(Ra+Rb,siz) */
193APUOP(M_CHX, RR, 0x1d5, "chx", _A3(A_T,A_A,A_B), 00112, SHUF) /* genCtl%%insX RT<-sta(Ra+Rb,siz) */
194APUOP(M_CWX, RR, 0x1d6, "cwx", _A3(A_T,A_A,A_B), 00112, SHUF) /* genCtl%%insX RT<-sta(Ra+Rb,siz) */
195APUOP(M_CDX, RR, 0x1d7, "cdx", _A3(A_T,A_A,A_B), 00112, SHUF) /* genCtl%%insX RT<-sta(Ra+Rb,siz) */
196APUOP(M_LQX, RR, 0x1c4, "lqx", _A3(A_T,A_A,A_B), 00112, LS) /* LoadQindeX RT<-M[Ra+Rb] */
197APUOP(M_ROTQBI, RR, 0x1d8, "rotqbi", _A3(A_T,A_A,A_B), 00112, SHUF) /* ROTQBI RT<-RA<<<Rb */
198APUOP(M_ROTQMBI, RR, 0x1d9, "rotqmbi", _A3(A_T,A_A,A_B), 00112, SHUF) /* ROTQMBI RT<-RA<<Rb */
199APUOP(M_SHLQBI, RR, 0x1db, "shlqbi", _A3(A_T,A_A,A_B), 00112, SHUF) /* SHLQBI RT<-RA<<Rb */
200APUOP(M_ROTQBY, RR, 0x1dc, "rotqby", _A3(A_T,A_A,A_B), 00112, SHUF) /* ROTQBY RT<-RA<<<(Rb*8) */
201APUOP(M_ROTQMBY, RR, 0x1dd, "rotqmby", _A3(A_T,A_A,A_B), 00112, SHUF) /* ROTQMBY RT<-RA<<Rb */
202APUOP(M_SHLQBY, RR, 0x1df, "shlqby", _A3(A_T,A_A,A_B), 00112, SHUF) /* SHLQBY RT<-RA<<Rb */
203APUOP(M_ROTQBYBI, RR, 0x1cc, "rotqbybi", _A3(A_T,A_A,A_B), 00112, SHUF) /* ROTQBYBI RT<-RA<<Rb */
204APUOP(M_ROTQMBYBI, RR, 0x1cd, "rotqmbybi", _A3(A_T,A_A,A_B), 00112, SHUF) /* ROTQMBYBI RT<-RA<<Rb */
205APUOP(M_SHLQBYBI, RR, 0x1cf, "shlqbybi", _A3(A_T,A_A,A_B), 00112, SHUF) /* SHLQBYBI RT<-RA<<Rb */
206APUOP(M_STQX, RR, 0x144, "stqx", _A3(A_T,A_A,A_B), 00111, LS) /* SToreQindeX M[Ra+Rb]<-RT */
207APUOP(M_SHUFB, RRR, 0x580, "shufb", _A4(A_C,A_A,A_B,A_T), 02111, SHUF) /* SHUFfleBytes RC<-f(RA,RB,RT) */
208APUOP(M_IL, RI16, 0x204, "il", _A2(A_T,A_S16), 00002, FX2) /* ImmLoad RT<-sxt(I16) */
209APUOP(M_ILH, RI16, 0x20c, "ilh", _A2(A_T,A_X16), 00002, FX2) /* ImmLoadH RT<-I16 */
210APUOP(M_ILHU, RI16, 0x208, "ilhu", _A2(A_T,A_X16), 00002, FX2) /* ImmLoadHUpper RT<-I16<<16 */
211APUOP(M_ILA, RI18, 0x210, "ila", _A2(A_T,A_U18), 00002, FX2) /* ImmLoadAddr RT<-zxt(I18) */
212APUOP(M_NOP, RR, 0x201, "nop", _A1(A_T), 00000, NOP) /* XNOP no_operation */
213APUOP(M_NOP2, RR, 0x201, "nop", _A0(), 00000, NOP) /* XNOP no_operation */
214APUOP(M_IOHL, RI16, 0x304, "iohl", _A2(A_T,A_X16), 00003, FX2) /* AddImmeXt RT<-RT+sxt(I16) */
215APUOP(M_ANDBI, RI10, 0x0b0, "andbi", _A3(A_T,A_A,A_S10B), 00012, FX2) /* AND%I RT<-RA&I10 */
216APUOP(M_ANDHI, RI10, 0x0a8, "andhi", _A3(A_T,A_A,A_S10), 00012, FX2) /* AND%I RT<-RA&I10 */
217APUOP(M_ANDI, RI10, 0x0a0, "andi", _A3(A_T,A_A,A_S10), 00012, FX2) /* AND%I RT<-RA&I10 */
218APUOP(M_ORBI, RI10, 0x030, "orbi", _A3(A_T,A_A,A_S10B), 00012, FX2) /* OR%I RT<-RA|I10 */
219APUOP(M_ORHI, RI10, 0x028, "orhi", _A3(A_T,A_A,A_S10), 00012, FX2) /* OR%I RT<-RA|I10 */
220APUOP(M_ORI, RI10, 0x020, "ori", _A3(A_T,A_A,A_S10), 00012, FX2) /* OR%I RT<-RA|I10 */
221APUOP(M_ORX, RR, 0x1f0, "orx", _A2(A_T,A_A), 00012, BR) /* ORX RT<-RA.w0|RA.w1|RA.w2|RA.w3 */
222APUOP(M_XORBI, RI10, 0x230, "xorbi", _A3(A_T,A_A,A_S10B), 00012, FX2) /* XOR%I RT<-RA^I10 */
223APUOP(M_XORHI, RI10, 0x228, "xorhi", _A3(A_T,A_A,A_S10), 00012, FX2) /* XOR%I RT<-RA^I10 */
224APUOP(M_XORI, RI10, 0x220, "xori", _A3(A_T,A_A,A_S10), 00012, FX2) /* XOR%I RT<-RA^I10 */
225APUOP(M_AHI, RI10, 0x0e8, "ahi", _A3(A_T,A_A,A_S10), 00012, FX2) /* Add%Immed RT<-RA+I10 */
226APUOP(M_AI, RI10, 0x0e0, "ai", _A3(A_T,A_A,A_S10), 00012, FX2) /* Add%Immed RT<-RA+I10 */
227APUOP(M_SFHI, RI10, 0x068, "sfhi", _A3(A_T,A_A,A_S10), 00012, FX2) /* SubFrom%Imm RT<-I10-RA */
228APUOP(M_SFI, RI10, 0x060, "sfi", _A3(A_T,A_A,A_S10), 00012, FX2) /* SubFrom%Imm RT<-I10-RA */
229APUOP(M_CGTBI, RI10, 0x270, "cgtbi", _A3(A_T,A_A,A_S10B), 00012, FX2) /* CGT%I RT<-(RA>I10) */
230APUOP(M_CGTHI, RI10, 0x268, "cgthi", _A3(A_T,A_A,A_S10), 00012, FX2) /* CGT%I RT<-(RA>I10) */
231APUOP(M_CGTI, RI10, 0x260, "cgti", _A3(A_T,A_A,A_S10), 00012, FX2) /* CGT%I RT<-(RA>I10) */
232APUOP(M_CLGTBI, RI10, 0x2f0, "clgtbi", _A3(A_T,A_A,A_S10B), 00012, FX2) /* CLGT%I RT<-(RA>I10) */
233APUOP(M_CLGTHI, RI10, 0x2e8, "clgthi", _A3(A_T,A_A,A_S10), 00012, FX2) /* CLGT%I RT<-(RA>I10) */
234APUOP(M_CLGTI, RI10, 0x2e0, "clgti", _A3(A_T,A_A,A_S10), 00012, FX2) /* CLGT%I RT<-(RA>I10) */
235APUOP(M_CEQBI, RI10, 0x3f0, "ceqbi", _A3(A_T,A_A,A_S10B), 00012, FX2) /* CEQ%I RT<-(RA=I10) */
236APUOP(M_CEQHI, RI10, 0x3e8, "ceqhi", _A3(A_T,A_A,A_S10), 00012, FX2) /* CEQ%I RT<-(RA=I10) */
237APUOP(M_CEQI, RI10, 0x3e0, "ceqi", _A3(A_T,A_A,A_S10), 00012, FX2) /* CEQ%I RT<-(RA=I10) */
238APUOP(M_HGTI, RI10, 0x278, "hgti", _A3(A_T,A_A,A_S10), 00010, FX2) /* HaltGTI halt_if(RA>I10) */
239APUOP(M_HGTI2, RI10, 0x278, "hgti", _A2(A_A,A_S10), 00010, FX2) /* HaltGTI halt_if(RA>I10) */
240APUOP(M_HLGTI, RI10, 0x2f8, "hlgti", _A3(A_T,A_A,A_S10), 00010, FX2) /* HaltLGTI halt_if(RA>I10) */
241APUOP(M_HLGTI2, RI10, 0x2f8, "hlgti", _A2(A_A,A_S10), 00010, FX2) /* HaltLGTI halt_if(RA>I10) */
242APUOP(M_HEQI, RI10, 0x3f8, "heqi", _A3(A_T,A_A,A_S10), 00010, FX2) /* HaltEQImm halt_if(RA=I10) */
243APUOP(M_HEQI2, RI10, 0x3f8, "heqi", _A2(A_A,A_S10), 00010, FX2) /* HaltEQImm halt_if(RA=I10) */
244APUOP(M_MPYI, RI10, 0x3a0, "mpyi", _A3(A_T,A_A,A_S10), 00012, FP7) /* MPYI RT<-RA*I10 */
245APUOP(M_MPYUI, RI10, 0x3a8, "mpyui", _A3(A_T,A_A,A_S10), 00012, FP7) /* MPYUI RT<-RA*I10 */
246APUOP(M_CFLTS, RI8, 0x3b0, "cflts", _A3(A_T,A_A,A_U7A), 00012, FP7) /* CFLTS RT<-int(RA,I8) */
247APUOP(M_CFLTU, RI8, 0x3b2, "cfltu", _A3(A_T,A_A,A_U7A), 00012, FP7) /* CFLTU RT<-int(RA,I8) */
248APUOP(M_CSFLT, RI8, 0x3b4, "csflt", _A3(A_T,A_A,A_U7B), 00012, FP7) /* CSFLT RT<-flt(RA,I8) */
249APUOP(M_CUFLT, RI8, 0x3b6, "cuflt", _A3(A_T,A_A,A_U7B), 00012, FP7) /* CUFLT RT<-flt(RA,I8) */
250APUOP(M_FESD, RR, 0x3b8, "fesd", _A2(A_T,A_A), 00012, FPD) /* FESD RT<-double(RA) */
251APUOP(M_FRDS, RR, 0x3b9, "frds", _A2(A_T,A_A), 00012, FPD) /* FRDS RT<-single(RA) */
252APUOP(M_FSCRRD, RR, 0x398, "fscrrd", _A1(A_T), 00002, FPD) /* FSCRRD RT<-FP_status */
253APUOP(M_FSCRWR, RR, 0x3ba, "fscrwr", _A2(A_T,A_A), 00010, FP7) /* FSCRWR FP_status<-RA */
254APUOP(M_FSCRWR2, RR, 0x3ba, "fscrwr", _A1(A_A), 00010, FP7) /* FSCRWR FP_status<-RA */
255APUOP(M_CLZ, RR, 0x2a5, "clz", _A2(A_T,A_A), 00012, FX2) /* CLZ RT<-clz(RA) */
256APUOP(M_CNTB, RR, 0x2b4, "cntb", _A2(A_T,A_A), 00012, FXB) /* CNT RT<-pop(RA) */
257APUOP(M_XSBH, RR, 0x2b6, "xsbh", _A2(A_T,A_A), 00012, FX2) /* eXtSignBtoH RT<-sign_ext(RA) */
258APUOP(M_XSHW, RR, 0x2ae, "xshw", _A2(A_T,A_A), 00012, FX2) /* eXtSignHtoW RT<-sign_ext(RA) */
259APUOP(M_XSWD, RR, 0x2a6, "xswd", _A2(A_T,A_A), 00012, FX2) /* eXtSignWtoD RT<-sign_ext(RA) */
260APUOP(M_ROTI, RI7, 0x078, "roti", _A3(A_T,A_A,A_S7N), 00012, FX3) /* ROT%I RT<-RA<<<I7 */
261APUOP(M_ROTMI, RI7, 0x079, "rotmi", _A3(A_T,A_A,A_S7), 00012, FX3) /* ROT%MI RT<-RA<<I7 */
262APUOP(M_ROTMAI, RI7, 0x07a, "rotmai", _A3(A_T,A_A,A_S7), 00012, FX3) /* ROTMA%I RT<-RA<<I7 */
263APUOP(M_SHLI, RI7, 0x07b, "shli", _A3(A_T,A_A,A_U6), 00012, FX3) /* SHL%I RT<-RA<<I7 */
264APUOP(M_ROTHI, RI7, 0x07c, "rothi", _A3(A_T,A_A,A_S7N), 00012, FX3) /* ROT%I RT<-RA<<<I7 */
265APUOP(M_ROTHMI, RI7, 0x07d, "rothmi", _A3(A_T,A_A,A_S6), 00012, FX3) /* ROT%MI RT<-RA<<I7 */
266APUOP(M_ROTMAHI, RI7, 0x07e, "rotmahi", _A3(A_T,A_A,A_S6), 00012, FX3) /* ROTMA%I RT<-RA<<I7 */
267APUOP(M_SHLHI, RI7, 0x07f, "shlhi", _A3(A_T,A_A,A_U5), 00012, FX3) /* SHL%I RT<-RA<<I7 */
268APUOP(M_A, RR, 0x0c0, "a", _A3(A_T,A_A,A_B), 00112, FX2) /* Add% RT<-RA+RB */
269APUOP(M_AH, RR, 0x0c8, "ah", _A3(A_T,A_A,A_B), 00112, FX2) /* Add% RT<-RA+RB */
270APUOP(M_SF, RR, 0x040, "sf", _A3(A_T,A_A,A_B), 00112, FX2) /* SubFrom% RT<-RB-RA */
271APUOP(M_SFH, RR, 0x048, "sfh", _A3(A_T,A_A,A_B), 00112, FX2) /* SubFrom% RT<-RB-RA */
272APUOP(M_CGT, RR, 0x240, "cgt", _A3(A_T,A_A,A_B), 00112, FX2) /* CGT% RT<-(RA>RB) */
273APUOP(M_CGTB, RR, 0x250, "cgtb", _A3(A_T,A_A,A_B), 00112, FX2) /* CGT% RT<-(RA>RB) */
274APUOP(M_CGTH, RR, 0x248, "cgth", _A3(A_T,A_A,A_B), 00112, FX2) /* CGT% RT<-(RA>RB) */
275APUOP(M_CLGT, RR, 0x2c0, "clgt", _A3(A_T,A_A,A_B), 00112, FX2) /* CLGT% RT<-(RA>RB) */
276APUOP(M_CLGTB, RR, 0x2d0, "clgtb", _A3(A_T,A_A,A_B), 00112, FX2) /* CLGT% RT<-(RA>RB) */
277APUOP(M_CLGTH, RR, 0x2c8, "clgth", _A3(A_T,A_A,A_B), 00112, FX2) /* CLGT% RT<-(RA>RB) */
278APUOP(M_CEQ, RR, 0x3c0, "ceq", _A3(A_T,A_A,A_B), 00112, FX2) /* CEQ% RT<-(RA=RB) */
279APUOP(M_CEQB, RR, 0x3d0, "ceqb", _A3(A_T,A_A,A_B), 00112, FX2) /* CEQ% RT<-(RA=RB) */
280APUOP(M_CEQH, RR, 0x3c8, "ceqh", _A3(A_T,A_A,A_B), 00112, FX2) /* CEQ% RT<-(RA=RB) */
281APUOP(M_HGT, RR, 0x258, "hgt", _A3(A_T,A_A,A_B), 00110, FX2) /* HaltGT halt_if(RA>RB) */
282APUOP(M_HGT2, RR, 0x258, "hgt", _A2(A_A,A_B), 00110, FX2) /* HaltGT halt_if(RA>RB) */
283APUOP(M_HLGT, RR, 0x2d8, "hlgt", _A3(A_T,A_A,A_B), 00110, FX2) /* HaltLGT halt_if(RA>RB) */
284APUOP(M_HLGT2, RR, 0x2d8, "hlgt", _A2(A_A,A_B), 00110, FX2) /* HaltLGT halt_if(RA>RB) */
285APUOP(M_HEQ, RR, 0x3d8, "heq", _A3(A_T,A_A,A_B), 00110, FX2) /* HaltEQ halt_if(RA=RB) */
286APUOP(M_HEQ2, RR, 0x3d8, "heq", _A2(A_A,A_B), 00110, FX2) /* HaltEQ halt_if(RA=RB) */
287APUOP(M_FCEQ, RR, 0x3c2, "fceq", _A3(A_T,A_A,A_B), 00112, FX2) /* FCEQ RT<-(RA=RB) */
288APUOP(M_FCMEQ, RR, 0x3ca, "fcmeq", _A3(A_T,A_A,A_B), 00112, FX2) /* FCMEQ RT<-(|RA|=|RB|) */
289APUOP(M_FCGT, RR, 0x2c2, "fcgt", _A3(A_T,A_A,A_B), 00112, FX2) /* FCGT RT<-(RA<RB) */
290APUOP(M_FCMGT, RR, 0x2ca, "fcmgt", _A3(A_T,A_A,A_B), 00112, FX2) /* FCMGT RT<-(|RA|<|RB|) */
291APUOP(M_AND, RR, 0x0c1, "and", _A3(A_T,A_A,A_B), 00112, FX2) /* AND RT<-RA&RB */
292APUOP(M_NAND, RR, 0x0c9, "nand", _A3(A_T,A_A,A_B), 00112, FX2) /* NAND RT<-!(RA&RB) */
293APUOP(M_OR, RR, 0x041, "or", _A3(A_T,A_A,A_B), 00112, FX2) /* OR RT<-RA|RB */
294APUOP(M_NOR, RR, 0x049, "nor", _A3(A_T,A_A,A_B), 00112, FX2) /* NOR RT<-!(RA&RB) */
295APUOP(M_XOR, RR, 0x241, "xor", _A3(A_T,A_A,A_B), 00112, FX2) /* XOR RT<-RA^RB */
296APUOP(M_EQV, RR, 0x249, "eqv", _A3(A_T,A_A,A_B), 00112, FX2) /* EQuiValent RT<-!(RA^RB) */
297APUOP(M_ANDC, RR, 0x2c1, "andc", _A3(A_T,A_A,A_B), 00112, FX2) /* ANDComplement RT<-RA&!RB */
298APUOP(M_ORC, RR, 0x2c9, "orc", _A3(A_T,A_A,A_B), 00112, FX2) /* ORComplement RT<-RA|!RB */
299APUOP(M_ABSDB, RR, 0x053, "absdb", _A3(A_T,A_A,A_B), 00112, FXB) /* ABSoluteDiff RT<-|RA-RB| */
300APUOP(M_AVGB, RR, 0x0d3, "avgb", _A3(A_T,A_A,A_B), 00112, FXB) /* AVG% RT<-(RA+RB+1)/2 */
301APUOP(M_SUMB, RR, 0x253, "sumb", _A3(A_T,A_A,A_B), 00112, FXB) /* SUM% RT<-f(RA,RB) */
302APUOP(M_DFA, RR, 0x2cc, "dfa", _A3(A_T,A_A,A_B), 00112, FPD) /* DFAdd RT<-RA+RB */
303APUOP(M_DFM, RR, 0x2ce, "dfm", _A3(A_T,A_A,A_B), 00112, FPD) /* DFMul RT<-RA*RB */
304APUOP(M_DFS, RR, 0x2cd, "dfs", _A3(A_T,A_A,A_B), 00112, FPD) /* DFSub RT<-RA-RB */
305APUOP(M_FA, RR, 0x2c4, "fa", _A3(A_T,A_A,A_B), 00112, FP6) /* FAdd RT<-RA+RB */
306APUOP(M_FM, RR, 0x2c6, "fm", _A3(A_T,A_A,A_B), 00112, FP6) /* FMul RT<-RA*RB */
307APUOP(M_FS, RR, 0x2c5, "fs", _A3(A_T,A_A,A_B), 00112, FP6) /* FSub RT<-RA-RB */
308APUOP(M_MPY, RR, 0x3c4, "mpy", _A3(A_T,A_A,A_B), 00112, FP7) /* MPY RT<-RA*RB */
309APUOP(M_MPYH, RR, 0x3c5, "mpyh", _A3(A_T,A_A,A_B), 00112, FP7) /* MPYH RT<-(RAh*RB)<<16 */
310APUOP(M_MPYHH, RR, 0x3c6, "mpyhh", _A3(A_T,A_A,A_B), 00112, FP7) /* MPYHH RT<-RAh*RBh */
311APUOP(M_MPYHHU, RR, 0x3ce, "mpyhhu", _A3(A_T,A_A,A_B), 00112, FP7) /* MPYHHU RT<-RAh*RBh */
312APUOP(M_MPYS, RR, 0x3c7, "mpys", _A3(A_T,A_A,A_B), 00112, FP7) /* MPYS RT<-(RA*RB)>>16 */
313APUOP(M_MPYU, RR, 0x3cc, "mpyu", _A3(A_T,A_A,A_B), 00112, FP7) /* MPYU RT<-RA*RB */
314APUOP(M_FI, RR, 0x3d4, "fi", _A3(A_T,A_A,A_B), 00112, FP7) /* FInterpolate RT<-f(RA,RB) */
315APUOP(M_ROT, RR, 0x058, "rot", _A3(A_T,A_A,A_B), 00112, FX3) /* ROT% RT<-RA<<<RB */
316APUOP(M_ROTM, RR, 0x059, "rotm", _A3(A_T,A_A,A_B), 00112, FX3) /* ROT%M RT<-RA<<Rb */
317APUOP(M_ROTMA, RR, 0x05a, "rotma", _A3(A_T,A_A,A_B), 00112, FX3) /* ROTMA% RT<-RA<<Rb */
318APUOP(M_SHL, RR, 0x05b, "shl", _A3(A_T,A_A,A_B), 00112, FX3) /* SHL% RT<-RA<<Rb */
319APUOP(M_ROTH, RR, 0x05c, "roth", _A3(A_T,A_A,A_B), 00112, FX3) /* ROT% RT<-RA<<<RB */
320APUOP(M_ROTHM, RR, 0x05d, "rothm", _A3(A_T,A_A,A_B), 00112, FX3) /* ROT%M RT<-RA<<Rb */
321APUOP(M_ROTMAH, RR, 0x05e, "rotmah", _A3(A_T,A_A,A_B), 00112, FX3) /* ROTMA% RT<-RA<<Rb */
322APUOP(M_SHLH, RR, 0x05f, "shlh", _A3(A_T,A_A,A_B), 00112, FX3) /* SHL% RT<-RA<<Rb */
323APUOP(M_MPYHHA, RR, 0x346, "mpyhha", _A3(A_T,A_A,A_B), 00113, FP7) /* MPYHHA RT<-RAh*RBh+RT */
324APUOP(M_MPYHHAU, RR, 0x34e, "mpyhhau", _A3(A_T,A_A,A_B), 00113, FP7) /* MPYHHAU RT<-RAh*RBh+RT */
325APUOP(M_DFMA, RR, 0x35c, "dfma", _A3(A_T,A_A,A_B), 00113, FPD) /* DFMAdd RT<-RT+RA*RB */
326APUOP(M_DFMS, RR, 0x35d, "dfms", _A3(A_T,A_A,A_B), 00113, FPD) /* DFMSub RT<-RA*RB-RT */
327APUOP(M_DFNMS, RR, 0x35e, "dfnms", _A3(A_T,A_A,A_B), 00113, FPD) /* DFNMSub RT<-RT-RA*RB */
328APUOP(M_DFNMA, RR, 0x35f, "dfnma", _A3(A_T,A_A,A_B), 00113, FPD) /* DFNMAdd RT<-(-RT)-RA*RB */
329APUOP(M_FMA, RRR, 0x700, "fma", _A4(A_C,A_A,A_B,A_T), 02111, FP6) /* FMAdd RC<-RT+RA*RB */
330APUOP(M_FMS, RRR, 0x780, "fms", _A4(A_C,A_A,A_B,A_T), 02111, FP6) /* FMSub RC<-RA*RB-RT */
331APUOP(M_FNMS, RRR, 0x680, "fnms", _A4(A_C,A_A,A_B,A_T), 02111, FP6) /* FNMSub RC<-RT-RA*RB */
332APUOP(M_MPYA, RRR, 0x600, "mpya", _A4(A_C,A_A,A_B,A_T), 02111, FP7) /* MPYA RC<-RA*RB+RT */
333APUOP(M_SELB, RRR, 0x400, "selb", _A4(A_C,A_A,A_B,A_T), 02111, FX2) /* SELectBits RC<-RA&RT|RB&!RT */
334/* for system function call, this uses op-code of mtspr */
335APUOP(M_SYSCALL, RI7, 0x10c, "syscall", _A3(A_T,A_A,A_S7N), 00002, SPR) /* System Call */
336/*
337pseudo instruction:
338system call
339value of I9 operation
3400 halt
3411 rt[0] = open(MEM[ra[0]], ra[1])
3422 rt[0] = close(ra[0])
3433 rt[0] = read(ra[0], MEM[ra[1]], ra[2])
3444 rt[0] = write(ra[0], MEM[ra[1]], ra[2])
3455 printf(MEM[ra[0]], ra[1], ra[2], ra[3])
34642 rt[0] = clock()
34752 rt[0] = lseek(ra0, ra1, ra2)
348
349*/
350
351
352/* new multiprecision add/sub */
353APUOP(M_ADDX, RR, 0x340, "addx", _A3(A_T,A_A,A_B), 00113, FX2) /* Add_eXtended RT<-RA+RB+RT */
354APUOP(M_CG, RR, 0x0c2, "cg", _A3(A_T,A_A,A_B), 00112, FX2) /* CarryGenerate RT<-cout(RA+RB) */
355APUOP(M_CGX, RR, 0x342, "cgx", _A3(A_T,A_A,A_B), 00113, FX2) /* CarryGen_eXtd RT<-cout(RA+RB+RT) */
356APUOP(M_SFX, RR, 0x341, "sfx", _A3(A_T,A_A,A_B), 00113, FX2) /* Add_eXtended RT<-RA+RB+RT */
357APUOP(M_BG, RR, 0x042, "bg", _A3(A_T,A_A,A_B), 00112, FX2) /* CarryGenerate RT<-cout(RA+RB) */
358APUOP(M_BGX, RR, 0x343, "bgx", _A3(A_T,A_A,A_B), 00113, FX2) /* CarryGen_eXtd RT<-cout(RA+RB+RT) */
359
360/*
361
362The following ops are a subset of above except with feature bits set.
363Feature bits are bits 11-17 of the instruction:
364
365 11 - C & P feature bit
366 12 - disable interrupts
367 13 - enable interrupts
368
369*/
370APUOPFB(M_BID, RR, 0x1a8, 0x20, "bid", _A1(A_A), 00010, BR) /* BI IP<-RA */
371APUOPFB(M_BIE, RR, 0x1a8, 0x10, "bie", _A1(A_A), 00010, BR) /* BI IP<-RA */
372APUOPFB(M_BISLD, RR, 0x1a9, 0x20, "bisld", _A2(A_T,A_A), 00012, BR) /* BISL RT,IP<-IP,RA */
373APUOPFB(M_BISLE, RR, 0x1a9, 0x10, "bisle", _A2(A_T,A_A), 00012, BR) /* BISL RT,IP<-IP,RA */
374APUOPFB(M_IRETD, RR, 0x1aa, 0x20, "iretd", _A1(A_A), 00010, BR) /* IRET IP<-SRR0 */
375APUOPFB(M_IRETD2, RR, 0x1aa, 0x20, "iretd", _A0(), 00010, BR) /* IRET IP<-SRR0 */
376APUOPFB(M_IRETE, RR, 0x1aa, 0x10, "irete", _A1(A_A), 00010, BR) /* IRET IP<-SRR0 */
377APUOPFB(M_IRETE2, RR, 0x1aa, 0x10, "irete", _A0(), 00010, BR) /* IRET IP<-SRR0 */
378APUOPFB(M_BISLEDD, RR, 0x1ab, 0x20, "bisledd", _A2(A_T,A_A), 00012, BR) /* BISLED RT,IP<-IP,RA_if(ext) */
379APUOPFB(M_BISLEDE, RR, 0x1ab, 0x10, "bislede", _A2(A_T,A_A), 00012, BR) /* BISLED RT,IP<-IP,RA_if(ext) */
380APUOPFB(M_BIHNZD, RR, 0x12b, 0x20, "bihnzd", _A2(A_T,A_A), 00011, BR) /* BIHNZ IP<-RA_if(RT) */
381APUOPFB(M_BIHNZE, RR, 0x12b, 0x10, "bihnze", _A2(A_T,A_A), 00011, BR) /* BIHNZ IP<-RA_if(RT) */
382APUOPFB(M_BIHZD, RR, 0x12a, 0x20, "bihzd", _A2(A_T,A_A), 00011, BR) /* BIHZ IP<-RA_if(RT) */
383APUOPFB(M_BIHZE, RR, 0x12a, 0x10, "bihze", _A2(A_T,A_A), 00011, BR) /* BIHZ IP<-RA_if(RT) */
384APUOPFB(M_BINZD, RR, 0x129, 0x20, "binzd", _A2(A_T,A_A), 00011, BR) /* BINZ IP<-RA_if(RT) */
385APUOPFB(M_BINZE, RR, 0x129, 0x10, "binze", _A2(A_T,A_A), 00011, BR) /* BINZ IP<-RA_if(RT) */
386APUOPFB(M_BIZD, RR, 0x128, 0x20, "bizd", _A2(A_T,A_A), 00011, BR) /* BIZ IP<-RA_if(RT) */
387APUOPFB(M_BIZE, RR, 0x128, 0x10, "bize", _A2(A_T,A_A), 00011, BR) /* BIZ IP<-RA_if(RT) */
388APUOPFB(M_SYNCC, RR, 0x002, 0x40, "syncc", _A0(), 00000, BR) /* SYNCC flush_pipe */
389APUOPFB(M_HBRP, LBTI, 0x1ac, 0x40, "hbrp", _A0(), 00010, LS) /* HBR BTB[B9]<-M[Ra] */
390
391/* Synonyms required by the AS manual. */
392APUOP(M_LR, RI10, 0x020, "lr", _A2(A_T,A_A), 00012, FX2) /* OR%I RT<-RA|I10 */
393APUOP(M_BIHT, RR, 0x12b, "biht", _A2(A_T,A_A), 00011, BR) /* BIHNZ IP<-RA_if(RT) */
394APUOP(M_BIHF, RR, 0x12a, "bihf", _A2(A_T,A_A), 00011, BR) /* BIHZ IP<-RA_if(RT) */
395APUOP(M_BIT, RR, 0x129, "bit", _A2(A_T,A_A), 00011, BR) /* BINZ IP<-RA_if(RT) */
396APUOP(M_BIF, RR, 0x128, "bif", _A2(A_T,A_A), 00011, BR) /* BIZ IP<-RA_if(RT) */
397APUOPFB(M_BIHTD, RR, 0x12b, 0x20, "bihtd", _A2(A_T,A_A), 00011, BR) /* BIHNF IP<-RA_if(RT) */
398APUOPFB(M_BIHTE, RR, 0x12b, 0x10, "bihte", _A2(A_T,A_A), 00011, BR) /* BIHNF IP<-RA_if(RT) */
399APUOPFB(M_BIHFD, RR, 0x12a, 0x20, "bihfd", _A2(A_T,A_A), 00011, BR) /* BIHZ IP<-RA_if(RT) */
400APUOPFB(M_BIHFE, RR, 0x12a, 0x10, "bihfe", _A2(A_T,A_A), 00011, BR) /* BIHZ IP<-RA_if(RT) */
401APUOPFB(M_BITD, RR, 0x129, 0x20, "bitd", _A2(A_T,A_A), 00011, BR) /* BINF IP<-RA_if(RT) */
402APUOPFB(M_BITE, RR, 0x129, 0x10, "bite", _A2(A_T,A_A), 00011, BR) /* BINF IP<-RA_if(RT) */
403APUOPFB(M_BIFD, RR, 0x128, 0x20, "bifd", _A2(A_T,A_A), 00011, BR) /* BIZ IP<-RA_if(RT) */
404APUOPFB(M_BIFE, RR, 0x128, 0x10, "bife", _A2(A_T,A_A), 00011, BR) /* BIZ IP<-RA_if(RT) */
405
406#undef _A0
407#undef _A1
408#undef _A2
409#undef _A3
410#undef _A4
diff --git a/arch/powerpc/xmon/spu-opc.c b/arch/powerpc/xmon/spu-opc.c
new file mode 100644
index 000000000000..efffde9edc6e
--- /dev/null
+++ b/arch/powerpc/xmon/spu-opc.c
@@ -0,0 +1,44 @@
1/* SPU opcode list
2
3 Copyright 2006 Free Software Foundation, Inc.
4
5 This file is part of GDB, GAS, and the GNU binutils.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License along
18 with this program; if not, write to the Free Software Foundation, Inc.,
19 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
20
21#include "spu.h"
22
23/* This file holds the Spu opcode table */
24
25
26/*
27 Example contents of spu-insn.h
28 id_tag mode mode type opcode mnemonic asmtype dependency FPU L/S? branch? instruction
29 QUAD WORD (0,RC,RB,RA,RT) latency
30 APUOP(M_LQD, 1, 0, RI9, 0x1f8, "lqd", ASM_RI9IDX, 00012, FXU, 1, 0) Load Quadword d-form
31 */
32
33const struct spu_opcode spu_opcodes[] = {
34#define APUOP(TAG,MACFORMAT,OPCODE,MNEMONIC,ASMFORMAT,DEP,PIPE) \
35 { MACFORMAT, OPCODE, MNEMONIC, ASMFORMAT },
36#define APUOPFB(TAG,MACFORMAT,OPCODE,FB,MNEMONIC,ASMFORMAT,DEP,PIPE) \
37 { MACFORMAT, OPCODE, MNEMONIC, ASMFORMAT },
38#include "spu-insns.h"
39#undef APUOP
40#undef APUOPFB
41};
42
43const int spu_num_opcodes =
44 sizeof (spu_opcodes) / sizeof (spu_opcodes[0]);
diff --git a/arch/powerpc/xmon/spu.h b/arch/powerpc/xmon/spu.h
new file mode 100644
index 000000000000..c761fc8f35d8
--- /dev/null
+++ b/arch/powerpc/xmon/spu.h
@@ -0,0 +1,126 @@
1/* SPU ELF support for BFD.
2
3 Copyright 2006 Free Software Foundation, Inc.
4
5 This file is part of GDB, GAS, and the GNU binutils.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software Foundation,
19 Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
20
21
22/* These two enums are from rel_apu/common/spu_asm_format.h */
23/* definition of instruction format */
24typedef enum {
25 RRR,
26 RI18,
27 RI16,
28 RI10,
29 RI8,
30 RI7,
31 RR,
32 LBT,
33 LBTI,
34 IDATA,
35 UNKNOWN_IFORMAT
36} spu_iformat;
37
38/* These values describe assembly instruction arguments. They indicate
39 * how to encode, range checking and which relocation to use. */
40typedef enum {
41 A_T, /* register at pos 0 */
42 A_A, /* register at pos 7 */
43 A_B, /* register at pos 14 */
44 A_C, /* register at pos 21 */
45 A_S, /* special purpose register at pos 7 */
46 A_H, /* channel register at pos 7 */
47 A_P, /* parenthesis, this has to separate regs from immediates */
48 A_S3,
49 A_S6,
50 A_S7N,
51 A_S7,
52 A_U7A,
53 A_U7B,
54 A_S10B,
55 A_S10,
56 A_S11,
57 A_S11I,
58 A_S14,
59 A_S16,
60 A_S18,
61 A_R18,
62 A_U3,
63 A_U5,
64 A_U6,
65 A_U7,
66 A_U14,
67 A_X16,
68 A_U18,
69 A_MAX
70} spu_aformat;
71
72enum spu_insns {
73#define APUOP(TAG,MACFORMAT,OPCODE,MNEMONIC,ASMFORMAT,DEP,PIPE) \
74 TAG,
75#define APUOPFB(TAG,MACFORMAT,OPCODE,FB,MNEMONIC,ASMFORMAT,DEP,PIPE) \
76 TAG,
77#include "spu-insns.h"
78#undef APUOP
79#undef APUOPFB
80 M_SPU_MAX
81};
82
83struct spu_opcode
84{
85 spu_iformat insn_type;
86 unsigned int opcode;
87 char *mnemonic;
88 int arg[5];
89};
90
91#define SIGNED_EXTRACT(insn,size,pos) (((int)((insn) << (32-size-pos))) >> (32-size))
92#define UNSIGNED_EXTRACT(insn,size,pos) (((insn) >> pos) & ((1 << size)-1))
93
94#define DECODE_INSN_RT(insn) (insn & 0x7f)
95#define DECODE_INSN_RA(insn) ((insn >> 7) & 0x7f)
96#define DECODE_INSN_RB(insn) ((insn >> 14) & 0x7f)
97#define DECODE_INSN_RC(insn) ((insn >> 21) & 0x7f)
98
99#define DECODE_INSN_I10(insn) SIGNED_EXTRACT(insn,10,14)
100#define DECODE_INSN_U10(insn) UNSIGNED_EXTRACT(insn,10,14)
101
102/* For branching, immediate loads, hbr and lqa/stqa. */
103#define DECODE_INSN_I16(insn) SIGNED_EXTRACT(insn,16,7)
104#define DECODE_INSN_U16(insn) UNSIGNED_EXTRACT(insn,16,7)
105
106/* for stop */
107#define DECODE_INSN_U14(insn) UNSIGNED_EXTRACT(insn,14,0)
108
109/* For ila */
110#define DECODE_INSN_I18(insn) SIGNED_EXTRACT(insn,18,7)
111#define DECODE_INSN_U18(insn) UNSIGNED_EXTRACT(insn,18,7)
112
113/* For rotate and shift and generate control mask */
114#define DECODE_INSN_I7(insn) SIGNED_EXTRACT(insn,7,14)
115#define DECODE_INSN_U7(insn) UNSIGNED_EXTRACT(insn,7,14)
116
117/* For float <-> int conversion */
118#define DECODE_INSN_I8(insn) SIGNED_EXTRACT(insn,8,14)
119#define DECODE_INSN_U8(insn) UNSIGNED_EXTRACT(insn,8,14)
120
121/* For hbr */
122#define DECODE_INSN_I9a(insn) ((SIGNED_EXTRACT(insn,2,23) << 7) | UNSIGNED_EXTRACT(insn,7,0))
123#define DECODE_INSN_I9b(insn) ((SIGNED_EXTRACT(insn,2,14) << 7) | UNSIGNED_EXTRACT(insn,7,0))
124#define DECODE_INSN_U9a(insn) ((UNSIGNED_EXTRACT(insn,2,23) << 7) | UNSIGNED_EXTRACT(insn,7,0))
125#define DECODE_INSN_U9b(insn) ((UNSIGNED_EXTRACT(insn,2,14) << 7) | UNSIGNED_EXTRACT(insn,7,0))
126
diff --git a/arch/powerpc/xmon/xmon.c b/arch/powerpc/xmon/xmon.c
index f56ffef4defa..a34ed49e0356 100644
--- a/arch/powerpc/xmon/xmon.c
+++ b/arch/powerpc/xmon/xmon.c
@@ -37,13 +37,18 @@
37#include <asm/sstep.h> 37#include <asm/sstep.h>
38#include <asm/bug.h> 38#include <asm/bug.h>
39#include <asm/irq_regs.h> 39#include <asm/irq_regs.h>
40#include <asm/spu.h>
41#include <asm/spu_priv1.h>
42#include <asm/firmware.h>
40 43
41#ifdef CONFIG_PPC64 44#ifdef CONFIG_PPC64
42#include <asm/hvcall.h> 45#include <asm/hvcall.h>
43#include <asm/paca.h> 46#include <asm/paca.h>
47#include <asm/iseries/it_lp_reg_save.h>
44#endif 48#endif
45 49
46#include "nonstdio.h" 50#include "nonstdio.h"
51#include "dis-asm.h"
47 52
48#define scanhex xmon_scanhex 53#define scanhex xmon_scanhex
49#define skipbl xmon_skipbl 54#define skipbl xmon_skipbl
@@ -107,7 +112,6 @@ static int bsesc(void);
107static void dump(void); 112static void dump(void);
108static void prdump(unsigned long, long); 113static void prdump(unsigned long, long);
109static int ppc_inst_dump(unsigned long, long, int); 114static int ppc_inst_dump(unsigned long, long, int);
110void print_address(unsigned long);
111static void backtrace(struct pt_regs *); 115static void backtrace(struct pt_regs *);
112static void excprint(struct pt_regs *); 116static void excprint(struct pt_regs *);
113static void prregs(struct pt_regs *); 117static void prregs(struct pt_regs *);
@@ -147,9 +151,9 @@ static void xmon_print_symbol(unsigned long address, const char *mid,
147 const char *after); 151 const char *after);
148static const char *getvecname(unsigned long vec); 152static const char *getvecname(unsigned long vec);
149 153
150int xmon_no_auto_backtrace; 154static int do_spu_cmd(void);
151 155
152extern int print_insn_powerpc(unsigned long, unsigned long, int); 156int xmon_no_auto_backtrace;
153 157
154extern void xmon_enter(void); 158extern void xmon_enter(void);
155extern void xmon_leave(void); 159extern void xmon_leave(void);
@@ -209,8 +213,15 @@ Commands:\n\
209 mi show information about memory allocation\n\ 213 mi show information about memory allocation\n\
210 p call a procedure\n\ 214 p call a procedure\n\
211 r print registers\n\ 215 r print registers\n\
212 s single step\n\ 216 s single step\n"
213 S print special registers\n\ 217#ifdef CONFIG_SPU_BASE
218" ss stop execution on all spus\n\
219 sr restore execution on stopped spus\n\
220 sf # dump spu fields for spu # (in hex)\n\
221 sd # dump spu local store for spu # (in hex)\
222 sdi # disassemble spu local store for spu # (in hex)\n"
223#endif
224" S print special registers\n\
214 t print backtrace\n\ 225 t print backtrace\n\
215 x exit monitor and recover\n\ 226 x exit monitor and recover\n\
216 X exit monitor and dont recover\n" 227 X exit monitor and dont recover\n"
@@ -518,6 +529,7 @@ int xmon(struct pt_regs *excp)
518 xmon_save_regs(&regs); 529 xmon_save_regs(&regs);
519 excp = &regs; 530 excp = &regs;
520 } 531 }
532
521 return xmon_core(excp, 0); 533 return xmon_core(excp, 0);
522} 534}
523EXPORT_SYMBOL(xmon); 535EXPORT_SYMBOL(xmon);
@@ -809,6 +821,8 @@ cmds(struct pt_regs *excp)
809 cacheflush(); 821 cacheflush();
810 break; 822 break;
811 case 's': 823 case 's':
824 if (do_spu_cmd() == 0)
825 break;
812 if (do_step(excp)) 826 if (do_step(excp))
813 return cmd; 827 return cmd;
814 break; 828 break;
@@ -1555,11 +1569,6 @@ void super_regs(void)
1555{ 1569{
1556 int cmd; 1570 int cmd;
1557 unsigned long val; 1571 unsigned long val;
1558#ifdef CONFIG_PPC_ISERIES
1559 struct paca_struct *ptrPaca = NULL;
1560 struct lppaca *ptrLpPaca = NULL;
1561 struct ItLpRegSave *ptrLpRegSave = NULL;
1562#endif
1563 1572
1564 cmd = skipbl(); 1573 cmd = skipbl();
1565 if (cmd == '\n') { 1574 if (cmd == '\n') {
@@ -1576,26 +1585,32 @@ void super_regs(void)
1576 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3)); 1585 printf("sp = "REG" sprg3= "REG"\n", sp, mfspr(SPRN_SPRG3));
1577 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR)); 1586 printf("toc = "REG" dar = "REG"\n", toc, mfspr(SPRN_DAR));
1578#ifdef CONFIG_PPC_ISERIES 1587#ifdef CONFIG_PPC_ISERIES
1579 // Dump out relevant Paca data areas. 1588 if (firmware_has_feature(FW_FEATURE_ISERIES)) {
1580 printf("Paca: \n"); 1589 struct paca_struct *ptrPaca;
1581 ptrPaca = get_paca(); 1590 struct lppaca *ptrLpPaca;
1582 1591 struct ItLpRegSave *ptrLpRegSave;
1583 printf(" Local Processor Control Area (LpPaca): \n"); 1592
1584 ptrLpPaca = ptrPaca->lppaca_ptr; 1593 /* Dump out relevant Paca data areas. */
1585 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n", 1594 printf("Paca: \n");
1586 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1); 1595 ptrPaca = get_paca();
1587 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n", 1596
1588 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4); 1597 printf(" Local Processor Control Area (LpPaca): \n");
1589 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5); 1598 ptrLpPaca = ptrPaca->lppaca_ptr;
1590 1599 printf(" Saved Srr0=%.16lx Saved Srr1=%.16lx \n",
1591 printf(" Local Processor Register Save Area (LpRegSave): \n"); 1600 ptrLpPaca->saved_srr0, ptrLpPaca->saved_srr1);
1592 ptrLpRegSave = ptrPaca->reg_save_ptr; 1601 printf(" Saved Gpr3=%.16lx Saved Gpr4=%.16lx \n",
1593 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n", 1602 ptrLpPaca->saved_gpr3, ptrLpPaca->saved_gpr4);
1594 ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0); 1603 printf(" Saved Gpr5=%.16lx \n", ptrLpPaca->saved_gpr5);
1595 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n", 1604
1596 ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3); 1605 printf(" Local Processor Register Save Area (LpRegSave): \n");
1597 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n", 1606 ptrLpRegSave = ptrPaca->reg_save_ptr;
1598 ptrLpRegSave->xMSR, ptrLpRegSave->xNIA); 1607 printf(" Saved Sprg0=%.16lx Saved Sprg1=%.16lx \n",
1608 ptrLpRegSave->xSPRG0, ptrLpRegSave->xSPRG0);
1609 printf(" Saved Sprg2=%.16lx Saved Sprg3=%.16lx \n",
1610 ptrLpRegSave->xSPRG2, ptrLpRegSave->xSPRG3);
1611 printf(" Saved Msr =%.16lx Saved Nia =%.16lx \n",
1612 ptrLpRegSave->xMSR, ptrLpRegSave->xNIA);
1613 }
1599#endif 1614#endif
1600 1615
1601 return; 1616 return;
@@ -2053,8 +2068,11 @@ prdump(unsigned long adrs, long ndump)
2053 } 2068 }
2054} 2069}
2055 2070
2071typedef int (*instruction_dump_func)(unsigned long inst, unsigned long addr);
2072
2056int 2073int
2057ppc_inst_dump(unsigned long adr, long count, int praddr) 2074generic_inst_dump(unsigned long adr, long count, int praddr,
2075 instruction_dump_func dump_func)
2058{ 2076{
2059 int nr, dotted; 2077 int nr, dotted;
2060 unsigned long first_adr; 2078 unsigned long first_adr;
@@ -2084,12 +2102,18 @@ ppc_inst_dump(unsigned long adr, long count, int praddr)
2084 if (praddr) 2102 if (praddr)
2085 printf(REG" %.8x", adr, inst); 2103 printf(REG" %.8x", adr, inst);
2086 printf("\t"); 2104 printf("\t");
2087 print_insn_powerpc(inst, adr, 0); /* always returns 4 */ 2105 dump_func(inst, adr);
2088 printf("\n"); 2106 printf("\n");
2089 } 2107 }
2090 return adr - first_adr; 2108 return adr - first_adr;
2091} 2109}
2092 2110
2111int
2112ppc_inst_dump(unsigned long adr, long count, int praddr)
2113{
2114 return generic_inst_dump(adr, count, praddr, print_insn_powerpc);
2115}
2116
2093void 2117void
2094print_address(unsigned long addr) 2118print_address(unsigned long addr)
2095{ 2119{
@@ -2557,6 +2581,10 @@ void dump_segments(void)
2557 2581
2558void xmon_init(int enable) 2582void xmon_init(int enable)
2559{ 2583{
2584#ifdef CONFIG_PPC_ISERIES
2585 if (firmware_has_feature(FW_FEATURE_ISERIES))
2586 return;
2587#endif
2560 if (enable) { 2588 if (enable) {
2561 __debugger = xmon; 2589 __debugger = xmon;
2562 __debugger_ipi = xmon_ipi; 2590 __debugger_ipi = xmon_ipi;
@@ -2594,6 +2622,10 @@ static struct sysrq_key_op sysrq_xmon_op =
2594 2622
2595static int __init setup_xmon_sysrq(void) 2623static int __init setup_xmon_sysrq(void)
2596{ 2624{
2625#ifdef CONFIG_PPC_ISERIES
2626 if (firmware_has_feature(FW_FEATURE_ISERIES))
2627 return 0;
2628#endif
2597 register_sysrq_key('x', &sysrq_xmon_op); 2629 register_sysrq_key('x', &sysrq_xmon_op);
2598 return 0; 2630 return 0;
2599} 2631}
@@ -2630,3 +2662,263 @@ void __init xmon_setup(void)
2630 if (xmon_early) 2662 if (xmon_early)
2631 debugger(NULL); 2663 debugger(NULL);
2632} 2664}
2665
2666#ifdef CONFIG_SPU_BASE
2667
2668struct spu_info {
2669 struct spu *spu;
2670 u64 saved_mfc_sr1_RW;
2671 u32 saved_spu_runcntl_RW;
2672 unsigned long dump_addr;
2673 u8 stopped_ok;
2674};
2675
2676#define XMON_NUM_SPUS 16 /* Enough for current hardware */
2677
2678static struct spu_info spu_info[XMON_NUM_SPUS];
2679
2680void xmon_register_spus(struct list_head *list)
2681{
2682 struct spu *spu;
2683
2684 list_for_each_entry(spu, list, full_list) {
2685 if (spu->number >= XMON_NUM_SPUS) {
2686 WARN_ON(1);
2687 continue;
2688 }
2689
2690 spu_info[spu->number].spu = spu;
2691 spu_info[spu->number].stopped_ok = 0;
2692 spu_info[spu->number].dump_addr = (unsigned long)
2693 spu_info[spu->number].spu->local_store;
2694 }
2695}
2696
2697static void stop_spus(void)
2698{
2699 struct spu *spu;
2700 int i;
2701 u64 tmp;
2702
2703 for (i = 0; i < XMON_NUM_SPUS; i++) {
2704 if (!spu_info[i].spu)
2705 continue;
2706
2707 if (setjmp(bus_error_jmp) == 0) {
2708 catch_memory_errors = 1;
2709 sync();
2710
2711 spu = spu_info[i].spu;
2712
2713 spu_info[i].saved_spu_runcntl_RW =
2714 in_be32(&spu->problem->spu_runcntl_RW);
2715
2716 tmp = spu_mfc_sr1_get(spu);
2717 spu_info[i].saved_mfc_sr1_RW = tmp;
2718
2719 tmp &= ~MFC_STATE1_MASTER_RUN_CONTROL_MASK;
2720 spu_mfc_sr1_set(spu, tmp);
2721
2722 sync();
2723 __delay(200);
2724
2725 spu_info[i].stopped_ok = 1;
2726
2727 printf("Stopped spu %.2d (was %s)\n", i,
2728 spu_info[i].saved_spu_runcntl_RW ?
2729 "running" : "stopped");
2730 } else {
2731 catch_memory_errors = 0;
2732 printf("*** Error stopping spu %.2d\n", i);
2733 }
2734 catch_memory_errors = 0;
2735 }
2736}
2737
2738static void restart_spus(void)
2739{
2740 struct spu *spu;
2741 int i;
2742
2743 for (i = 0; i < XMON_NUM_SPUS; i++) {
2744 if (!spu_info[i].spu)
2745 continue;
2746
2747 if (!spu_info[i].stopped_ok) {
2748 printf("*** Error, spu %d was not successfully stopped"
2749 ", not restarting\n", i);
2750 continue;
2751 }
2752
2753 if (setjmp(bus_error_jmp) == 0) {
2754 catch_memory_errors = 1;
2755 sync();
2756
2757 spu = spu_info[i].spu;
2758 spu_mfc_sr1_set(spu, spu_info[i].saved_mfc_sr1_RW);
2759 out_be32(&spu->problem->spu_runcntl_RW,
2760 spu_info[i].saved_spu_runcntl_RW);
2761
2762 sync();
2763 __delay(200);
2764
2765 printf("Restarted spu %.2d\n", i);
2766 } else {
2767 catch_memory_errors = 0;
2768 printf("*** Error restarting spu %.2d\n", i);
2769 }
2770 catch_memory_errors = 0;
2771 }
2772}
2773
2774#define DUMP_WIDTH 23
2775#define DUMP_VALUE(format, field, value) \
2776do { \
2777 if (setjmp(bus_error_jmp) == 0) { \
2778 catch_memory_errors = 1; \
2779 sync(); \
2780 printf(" %-*s = "format"\n", DUMP_WIDTH, \
2781 #field, value); \
2782 sync(); \
2783 __delay(200); \
2784 } else { \
2785 catch_memory_errors = 0; \
2786 printf(" %-*s = *** Error reading field.\n", \
2787 DUMP_WIDTH, #field); \
2788 } \
2789 catch_memory_errors = 0; \
2790} while (0)
2791
2792#define DUMP_FIELD(obj, format, field) \
2793 DUMP_VALUE(format, field, obj->field)
2794
2795static void dump_spu_fields(struct spu *spu)
2796{
2797 printf("Dumping spu fields at address %p:\n", spu);
2798
2799 DUMP_FIELD(spu, "0x%x", number);
2800 DUMP_FIELD(spu, "%s", name);
2801 DUMP_FIELD(spu, "0x%lx", local_store_phys);
2802 DUMP_FIELD(spu, "0x%p", local_store);
2803 DUMP_FIELD(spu, "0x%lx", ls_size);
2804 DUMP_FIELD(spu, "0x%x", node);
2805 DUMP_FIELD(spu, "0x%lx", flags);
2806 DUMP_FIELD(spu, "0x%lx", dar);
2807 DUMP_FIELD(spu, "0x%lx", dsisr);
2808 DUMP_FIELD(spu, "%d", class_0_pending);
2809 DUMP_FIELD(spu, "0x%lx", irqs[0]);
2810 DUMP_FIELD(spu, "0x%lx", irqs[1]);
2811 DUMP_FIELD(spu, "0x%lx", irqs[2]);
2812 DUMP_FIELD(spu, "0x%x", slb_replace);
2813 DUMP_FIELD(spu, "%d", pid);
2814 DUMP_FIELD(spu, "%d", prio);
2815 DUMP_FIELD(spu, "0x%p", mm);
2816 DUMP_FIELD(spu, "0x%p", ctx);
2817 DUMP_FIELD(spu, "0x%p", rq);
2818 DUMP_FIELD(spu, "0x%p", timestamp);
2819 DUMP_FIELD(spu, "0x%lx", problem_phys);
2820 DUMP_FIELD(spu, "0x%p", problem);
2821 DUMP_VALUE("0x%x", problem->spu_runcntl_RW,
2822 in_be32(&spu->problem->spu_runcntl_RW));
2823 DUMP_VALUE("0x%x", problem->spu_status_R,
2824 in_be32(&spu->problem->spu_status_R));
2825 DUMP_VALUE("0x%x", problem->spu_npc_RW,
2826 in_be32(&spu->problem->spu_npc_RW));
2827 DUMP_FIELD(spu, "0x%p", priv2);
2828 DUMP_FIELD(spu, "0x%p", pdata);
2829}
2830
2831int
2832spu_inst_dump(unsigned long adr, long count, int praddr)
2833{
2834 return generic_inst_dump(adr, count, praddr, print_insn_spu);
2835}
2836
2837static void dump_spu_ls(unsigned long num, int subcmd)
2838{
2839 unsigned long offset, addr, ls_addr;
2840
2841 if (setjmp(bus_error_jmp) == 0) {
2842 catch_memory_errors = 1;
2843 sync();
2844 ls_addr = (unsigned long)spu_info[num].spu->local_store;
2845 sync();
2846 __delay(200);
2847 } else {
2848 catch_memory_errors = 0;
2849 printf("*** Error: accessing spu info for spu %d\n", num);
2850 return;
2851 }
2852 catch_memory_errors = 0;
2853
2854 if (scanhex(&offset))
2855 addr = ls_addr + offset;
2856 else
2857 addr = spu_info[num].dump_addr;
2858
2859 if (addr >= ls_addr + LS_SIZE) {
2860 printf("*** Error: address outside of local store\n");
2861 return;
2862 }
2863
2864 switch (subcmd) {
2865 case 'i':
2866 addr += spu_inst_dump(addr, 16, 1);
2867 last_cmd = "sdi\n";
2868 break;
2869 default:
2870 prdump(addr, 64);
2871 addr += 64;
2872 last_cmd = "sd\n";
2873 break;
2874 }
2875
2876 spu_info[num].dump_addr = addr;
2877}
2878
2879static int do_spu_cmd(void)
2880{
2881 static unsigned long num = 0;
2882 int cmd, subcmd = 0;
2883
2884 cmd = inchar();
2885 switch (cmd) {
2886 case 's':
2887 stop_spus();
2888 break;
2889 case 'r':
2890 restart_spus();
2891 break;
2892 case 'd':
2893 subcmd = inchar();
2894 if (isxdigit(subcmd) || subcmd == '\n')
2895 termch = subcmd;
2896 case 'f':
2897 scanhex(&num);
2898 if (num >= XMON_NUM_SPUS || !spu_info[num].spu) {
2899 printf("*** Error: invalid spu number\n");
2900 return 0;
2901 }
2902
2903 switch (cmd) {
2904 case 'f':
2905 dump_spu_fields(spu_info[num].spu);
2906 break;
2907 default:
2908 dump_spu_ls(num, subcmd);
2909 break;
2910 }
2911
2912 break;
2913 default:
2914 return -1;
2915 }
2916
2917 return 0;
2918}
2919#else /* ! CONFIG_SPU_BASE */
2920static int do_spu_cmd(void)
2921{
2922 return -1;
2923}
2924#endif
diff --git a/arch/ppc/.gitignore b/arch/ppc/.gitignore
new file mode 100644
index 000000000000..a1a869c8c840
--- /dev/null
+++ b/arch/ppc/.gitignore
@@ -0,0 +1 @@
include
diff --git a/arch/ppc/Kconfig b/arch/ppc/Kconfig
index ef018e25fb07..edf71a4ecc95 100644
--- a/arch/ppc/Kconfig
+++ b/arch/ppc/Kconfig
@@ -77,9 +77,11 @@ config 6xx
77 77
78config 40x 78config 40x
79 bool "40x" 79 bool "40x"
80 select PPC_DCR_NATIVE
80 81
81config 44x 82config 44x
82 bool "44x" 83 bool "44x"
84 select PPC_DCR_NATIVE
83 85
84config 8xx 86config 8xx
85 bool "8xx" 87 bool "8xx"
@@ -95,6 +97,15 @@ endchoice
95config PPC_FPU 97config PPC_FPU
96 bool 98 bool
97 99
100config PPC_DCR_NATIVE
101 bool
102 default n
103
104config PPC_DCR
105 bool
106 depends on PPC_DCR_NATIVE
107 default y
108
98config BOOKE 109config BOOKE
99 bool 110 bool
100 depends on E200 || E500 111 depends on E200 || E500
diff --git a/arch/ppc/boot/images/.gitignore b/arch/ppc/boot/images/.gitignore
new file mode 100644
index 000000000000..21c2dc5b6b78
--- /dev/null
+++ b/arch/ppc/boot/images/.gitignore
@@ -0,0 +1,6 @@
1sImage
2vmapus
3vmlinux*
4miboot*
5zImage*
6uImage
diff --git a/arch/ppc/boot/lib/.gitignore b/arch/ppc/boot/lib/.gitignore
new file mode 100644
index 000000000000..1629a6167755
--- /dev/null
+++ b/arch/ppc/boot/lib/.gitignore
@@ -0,0 +1,3 @@
1inffast.c
2inflate.c
3inftrees.c
diff --git a/arch/ppc/boot/utils/.gitignore b/arch/ppc/boot/utils/.gitignore
new file mode 100644
index 000000000000..bbdfb3b9c532
--- /dev/null
+++ b/arch/ppc/boot/utils/.gitignore
@@ -0,0 +1,3 @@
1mkprep
2mkbugboot
3mktree
diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c
index 27faeca2c7a2..3c506af19880 100644
--- a/arch/ppc/kernel/setup.c
+++ b/arch/ppc/kernel/setup.c
@@ -313,7 +313,7 @@ early_init(int r3, int r4, int r5)
313 * Identify the CPU type and fix up code sections 313 * Identify the CPU type and fix up code sections
314 * that depend on which cpu we have. 314 * that depend on which cpu we have.
315 */ 315 */
316 spec = identify_cpu(offset); 316 spec = identify_cpu(offset, mfspr(SPRN_PVR));
317 do_feature_fixups(spec->cpu_features, 317 do_feature_fixups(spec->cpu_features,
318 PTRRELOC(&__start___ftr_fixup), 318 PTRRELOC(&__start___ftr_fixup),
319 PTRRELOC(&__stop___ftr_fixup)); 319 PTRRELOC(&__stop___ftr_fixup));
diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c
index 9661a91183b3..2f835b9e95e4 100644
--- a/arch/ppc/kernel/traps.c
+++ b/arch/ppc/kernel/traps.c
@@ -316,7 +316,7 @@ void machine_check_exception(struct pt_regs *regs)
316 if (reason & MCSR_BUS_RBERR) 316 if (reason & MCSR_BUS_RBERR)
317 printk("Bus - Read Data Bus Error\n"); 317 printk("Bus - Read Data Bus Error\n");
318 if (reason & MCSR_BUS_WBERR) 318 if (reason & MCSR_BUS_WBERR)
319 printk("Bus - Read Data Bus Error\n"); 319 printk("Bus - Write Data Bus Error\n");
320 if (reason & MCSR_BUS_IPERR) 320 if (reason & MCSR_BUS_IPERR)
321 printk("Bus - Instruction Parity Error\n"); 321 printk("Bus - Instruction Parity Error\n");
322 if (reason & MCSR_BUS_RPERR) 322 if (reason & MCSR_BUS_RPERR)
diff --git a/arch/ppc/platforms/4xx/bubinga.c b/arch/ppc/platforms/4xx/bubinga.c
index 4009f4983ca6..75857b38e894 100644
--- a/arch/ppc/platforms/4xx/bubinga.c
+++ b/arch/ppc/platforms/4xx/bubinga.c
@@ -116,6 +116,7 @@ bubinga_early_serial_map(void)
116void __init 116void __init
117bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip) 117bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip)
118{ 118{
119#ifdef CONFIG_PCI
119 120
120 unsigned int bar_response, bar; 121 unsigned int bar_response, bar;
121 /* 122 /*
@@ -212,6 +213,7 @@ bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip)
212 printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la))); 213 printk(" ptm2la\t0x%x\n", in_le32(&(pcip->ptm2la)));
213 214
214#endif 215#endif
216#endif
215} 217}
216 218
217void __init 219void __init
diff --git a/arch/ppc/platforms/4xx/cpci405.c b/arch/ppc/platforms/4xx/cpci405.c
index 367430998fc5..8474b05b795a 100644
--- a/arch/ppc/platforms/4xx/cpci405.c
+++ b/arch/ppc/platforms/4xx/cpci405.c
@@ -126,6 +126,7 @@ cpci405_setup_arch(void)
126void __init 126void __init
127bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip) 127bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip)
128{ 128{
129#ifdef CONFIG_PCI
129 unsigned int bar_response, bar; 130 unsigned int bar_response, bar;
130 131
131 /* Disable region first */ 132 /* Disable region first */
@@ -167,6 +168,7 @@ bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip)
167 PCI_FUNC(hose->first_busno), bar, 168 PCI_FUNC(hose->first_busno), bar,
168 &bar_response); 169 &bar_response);
169 } 170 }
171#endif
170} 172}
171 173
172void __init 174void __init
diff --git a/arch/ppc/platforms/4xx/ep405.c b/arch/ppc/platforms/4xx/ep405.c
index ae5c82081c95..e5adf9ba1fca 100644
--- a/arch/ppc/platforms/4xx/ep405.c
+++ b/arch/ppc/platforms/4xx/ep405.c
@@ -68,6 +68,7 @@ ep405_setup_arch(void)
68void __init 68void __init
69bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip) 69bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip)
70{ 70{
71#ifdef CONFIG_PCI
71 unsigned int bar_response, bar; 72 unsigned int bar_response, bar;
72 /* 73 /*
73 * Expected PCI mapping: 74 * Expected PCI mapping:
@@ -130,6 +131,7 @@ bios_fixup(struct pci_controller *hose, struct pcil0_regs *pcip)
130 PCI_FUNC(hose->first_busno), bar, bar_response); 131 PCI_FUNC(hose->first_busno), bar, bar_response);
131 } 132 }
132 /* end work arround */ 133 /* end work arround */
134#endif
133} 135}
134 136
135void __init 137void __init
diff --git a/arch/ppc/platforms/83xx/mpc834x_sys.c b/arch/ppc/platforms/83xx/mpc834x_sys.c
index 3397f0de1592..b84f8df325c4 100644
--- a/arch/ppc/platforms/83xx/mpc834x_sys.c
+++ b/arch/ppc/platforms/83xx/mpc834x_sys.c
@@ -121,8 +121,8 @@ mpc834x_sys_setup_arch(void)
121 121
122 mdata->irq[0] = MPC83xx_IRQ_EXT1; 122 mdata->irq[0] = MPC83xx_IRQ_EXT1;
123 mdata->irq[1] = MPC83xx_IRQ_EXT2; 123 mdata->irq[1] = MPC83xx_IRQ_EXT2;
124 mdata->irq[2] = -1; 124 mdata->irq[2] = PHY_POLL;
125 mdata->irq[31] = -1; 125 mdata->irq[31] = PHY_POLL;
126 126
127 /* setup the board related information for the enet controllers */ 127 /* setup the board related information for the enet controllers */
128 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC1); 128 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC83xx_TSEC1);
diff --git a/arch/ppc/platforms/85xx/mpc8540_ads.c b/arch/ppc/platforms/85xx/mpc8540_ads.c
index 4f839da6782f..00a3ba57063f 100644
--- a/arch/ppc/platforms/85xx/mpc8540_ads.c
+++ b/arch/ppc/platforms/85xx/mpc8540_ads.c
@@ -92,9 +92,9 @@ mpc8540ads_setup_arch(void)
92 92
93 mdata->irq[0] = MPC85xx_IRQ_EXT5; 93 mdata->irq[0] = MPC85xx_IRQ_EXT5;
94 mdata->irq[1] = MPC85xx_IRQ_EXT5; 94 mdata->irq[1] = MPC85xx_IRQ_EXT5;
95 mdata->irq[2] = -1; 95 mdata->irq[2] = PHY_POLL;
96 mdata->irq[3] = MPC85xx_IRQ_EXT5; 96 mdata->irq[3] = MPC85xx_IRQ_EXT5;
97 mdata->irq[31] = -1; 97 mdata->irq[31] = PHY_POLL;
98 98
99 /* setup the board related information for the enet controllers */ 99 /* setup the board related information for the enet controllers */
100 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); 100 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
diff --git a/arch/ppc/platforms/85xx/mpc8560_ads.c b/arch/ppc/platforms/85xx/mpc8560_ads.c
index 14ecec7bbed7..3a060468dd95 100644
--- a/arch/ppc/platforms/85xx/mpc8560_ads.c
+++ b/arch/ppc/platforms/85xx/mpc8560_ads.c
@@ -156,9 +156,9 @@ mpc8560ads_setup_arch(void)
156 156
157 mdata->irq[0] = MPC85xx_IRQ_EXT5; 157 mdata->irq[0] = MPC85xx_IRQ_EXT5;
158 mdata->irq[1] = MPC85xx_IRQ_EXT5; 158 mdata->irq[1] = MPC85xx_IRQ_EXT5;
159 mdata->irq[2] = -1; 159 mdata->irq[2] = PHY_POLL;
160 mdata->irq[3] = MPC85xx_IRQ_EXT5; 160 mdata->irq[3] = MPC85xx_IRQ_EXT5;
161 mdata->irq[31] = -1; 161 mdata->irq[31] = PHY_POLL;
162 162
163 /* setup the board related information for the enet controllers */ 163 /* setup the board related information for the enet controllers */
164 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); 164 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
diff --git a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
index 5ce0f69c1db6..2d59eb776c95 100644
--- a/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
+++ b/arch/ppc/platforms/85xx/mpc85xx_cds_common.c
@@ -451,9 +451,9 @@ mpc85xx_cds_setup_arch(void)
451 451
452 mdata->irq[0] = MPC85xx_IRQ_EXT5; 452 mdata->irq[0] = MPC85xx_IRQ_EXT5;
453 mdata->irq[1] = MPC85xx_IRQ_EXT5; 453 mdata->irq[1] = MPC85xx_IRQ_EXT5;
454 mdata->irq[2] = -1; 454 mdata->irq[2] = PHY_POLL;
455 mdata->irq[3] = -1; 455 mdata->irq[3] = PHY_POLL;
456 mdata->irq[31] = -1; 456 mdata->irq[31] = PHY_POLL;
457 457
458 /* setup the board related information for the enet controllers */ 458 /* setup the board related information for the enet controllers */
459 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); 459 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
diff --git a/arch/ppc/platforms/85xx/sbc8560.c b/arch/ppc/platforms/85xx/sbc8560.c
index 764d580ff535..1d10ab98f66d 100644
--- a/arch/ppc/platforms/85xx/sbc8560.c
+++ b/arch/ppc/platforms/85xx/sbc8560.c
@@ -129,7 +129,7 @@ sbc8560_setup_arch(void)
129 129
130 mdata->irq[25] = MPC85xx_IRQ_EXT6; 130 mdata->irq[25] = MPC85xx_IRQ_EXT6;
131 mdata->irq[26] = MPC85xx_IRQ_EXT7; 131 mdata->irq[26] = MPC85xx_IRQ_EXT7;
132 mdata->irq[31] = -1; 132 mdata->irq[31] = PHY_POLL;
133 133
134 /* setup the board related information for the enet controllers */ 134 /* setup the board related information for the enet controllers */
135 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); 135 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
diff --git a/arch/ppc/platforms/85xx/stx_gp3.c b/arch/ppc/platforms/85xx/stx_gp3.c
index 4bb18ab27672..b1f5b737c70d 100644
--- a/arch/ppc/platforms/85xx/stx_gp3.c
+++ b/arch/ppc/platforms/85xx/stx_gp3.c
@@ -123,7 +123,7 @@ gp3_setup_arch(void)
123 123
124 mdata->irq[2] = MPC85xx_IRQ_EXT5; 124 mdata->irq[2] = MPC85xx_IRQ_EXT5;
125 mdata->irq[4] = MPC85xx_IRQ_EXT5; 125 mdata->irq[4] = MPC85xx_IRQ_EXT5;
126 mdata->irq[31] = -1; 126 mdata->irq[31] = PHY_POLL;
127 127
128 /* setup the board related information for the enet controllers */ 128 /* setup the board related information for the enet controllers */
129 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); 129 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
diff --git a/arch/ppc/platforms/85xx/tqm85xx.c b/arch/ppc/platforms/85xx/tqm85xx.c
index dd45f2e18449..4ee2bd156dc5 100644
--- a/arch/ppc/platforms/85xx/tqm85xx.c
+++ b/arch/ppc/platforms/85xx/tqm85xx.c
@@ -137,9 +137,9 @@ tqm85xx_setup_arch(void)
137 137
138 mdata->irq[0] = MPC85xx_IRQ_EXT8; 138 mdata->irq[0] = MPC85xx_IRQ_EXT8;
139 mdata->irq[1] = MPC85xx_IRQ_EXT8; 139 mdata->irq[1] = MPC85xx_IRQ_EXT8;
140 mdata->irq[2] = -1; 140 mdata->irq[2] = PHY_POLL;
141 mdata->irq[3] = MPC85xx_IRQ_EXT8; 141 mdata->irq[3] = MPC85xx_IRQ_EXT8;
142 mdata->irq[31] = -1; 142 mdata->irq[31] = PHY_POLL;
143 143
144 /* setup the board related information for the enet controllers */ 144 /* setup the board related information for the enet controllers */
145 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1); 145 pdata = (struct gianfar_platform_data *) ppc_sys_get_pdata(MPC85xx_TSEC1);
diff --git a/arch/ppc/platforms/mpc8272ads_setup.c b/arch/ppc/platforms/mpc8272ads_setup.c
index 1f9ea36837b1..0bc06768cf24 100644
--- a/arch/ppc/platforms/mpc8272ads_setup.c
+++ b/arch/ppc/platforms/mpc8272ads_setup.c
@@ -266,10 +266,10 @@ static void __init mpc8272ads_fixup_mdio_pdata(struct platform_device *pdev,
266 int idx) 266 int idx)
267{ 267{
268 m82xx_mii_bb_pdata.irq[0] = PHY_INTERRUPT; 268 m82xx_mii_bb_pdata.irq[0] = PHY_INTERRUPT;
269 m82xx_mii_bb_pdata.irq[1] = -1; 269 m82xx_mii_bb_pdata.irq[1] = PHY_POLL;
270 m82xx_mii_bb_pdata.irq[2] = -1; 270 m82xx_mii_bb_pdata.irq[2] = PHY_POLL;
271 m82xx_mii_bb_pdata.irq[3] = PHY_INTERRUPT; 271 m82xx_mii_bb_pdata.irq[3] = PHY_INTERRUPT;
272 m82xx_mii_bb_pdata.irq[31] = -1; 272 m82xx_mii_bb_pdata.irq[31] = PHY_POLL;
273 273
274 274
275 m82xx_mii_bb_pdata.mdio_dat.offset = 275 m82xx_mii_bb_pdata.mdio_dat.offset =
diff --git a/arch/ppc/platforms/mpc866ads_setup.c b/arch/ppc/platforms/mpc866ads_setup.c
index e95d2c111747..8a0c07eb4449 100644
--- a/arch/ppc/platforms/mpc866ads_setup.c
+++ b/arch/ppc/platforms/mpc866ads_setup.c
@@ -361,7 +361,7 @@ int __init mpc866ads_init(void)
361 361
362 fmpi->mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1; 362 fmpi->mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1;
363 /* No PHY interrupt line here */ 363 /* No PHY interrupt line here */
364 fmpi->irq[0xf] = -1; 364 fmpi->irq[0xf] = PHY_POLL;
365 365
366/* Since either of the uarts could be used as console, they need to ready */ 366/* Since either of the uarts could be used as console, they need to ready */
367#ifdef CONFIG_SERIAL_CPM_SMC1 367#ifdef CONFIG_SERIAL_CPM_SMC1
@@ -380,7 +380,7 @@ int __init mpc866ads_init(void)
380 380
381 fmpi->mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1; 381 fmpi->mii_speed = ((((bd->bi_intfreq + 4999999) / 2500000) / 2) & 0x3F) << 1;
382 /* No PHY interrupt line here */ 382 /* No PHY interrupt line here */
383 fmpi->irq[0xf] = -1; 383 fmpi->irq[0xf] = PHY_POLL;
384 384
385 return 0; 385 return 0;
386} 386}
diff --git a/arch/ppc/syslib/mpc8xx_devices.c b/arch/ppc/syslib/mpc8xx_devices.c
index cf5ab47487a7..31fb56593d17 100644
--- a/arch/ppc/syslib/mpc8xx_devices.c
+++ b/arch/ppc/syslib/mpc8xx_devices.c
@@ -78,7 +78,7 @@ struct platform_device ppc_sys_platform_devices[] = {
78 { 78 {
79 .name = "pram", 79 .name = "pram",
80 .start = 0x3c00, 80 .start = 0x3c00,
81 .end = 0x3c80, 81 .end = 0x3c7f,
82 .flags = IORESOURCE_MEM, 82 .flags = IORESOURCE_MEM,
83 }, 83 },
84 { 84 {
@@ -103,7 +103,7 @@ struct platform_device ppc_sys_platform_devices[] = {
103 { 103 {
104 .name = "pram", 104 .name = "pram",
105 .start = 0x3d00, 105 .start = 0x3d00,
106 .end = 0x3d80, 106 .end = 0x3d7f,
107 .flags = IORESOURCE_MEM, 107 .flags = IORESOURCE_MEM,
108 }, 108 },
109 109
@@ -129,7 +129,7 @@ struct platform_device ppc_sys_platform_devices[] = {
129 { 129 {
130 .name = "pram", 130 .name = "pram",
131 .start = 0x3e00, 131 .start = 0x3e00,
132 .end = 0x3e80, 132 .end = 0x3e7f,
133 .flags = IORESOURCE_MEM, 133 .flags = IORESOURCE_MEM,
134 }, 134 },
135 135
@@ -155,7 +155,7 @@ struct platform_device ppc_sys_platform_devices[] = {
155 { 155 {
156 .name = "pram", 156 .name = "pram",
157 .start = 0x3f00, 157 .start = 0x3f00,
158 .end = 0x3f80, 158 .end = 0x3f7f,
159 .flags = IORESOURCE_MEM, 159 .flags = IORESOURCE_MEM,
160 }, 160 },
161 161
diff --git a/arch/s390/Kconfig b/arch/s390/Kconfig
index 245b81bc7157..583d9ff0a571 100644
--- a/arch/s390/Kconfig
+++ b/arch/s390/Kconfig
@@ -33,9 +33,6 @@ config GENERIC_CALIBRATE_DELAY
33config GENERIC_TIME 33config GENERIC_TIME
34 def_bool y 34 def_bool y
35 35
36config GENERIC_BUST_SPINLOCK
37 bool
38
39mainmenu "Linux Kernel Configuration" 36mainmenu "Linux Kernel Configuration"
40 37
41config S390 38config S390
@@ -181,7 +178,7 @@ config PACK_STACK
181 178
182config SMALL_STACK 179config SMALL_STACK
183 bool "Use 4kb/8kb for kernel stack instead of 8kb/16kb" 180 bool "Use 4kb/8kb for kernel stack instead of 8kb/16kb"
184 depends on PACK_STACK 181 depends on PACK_STACK && !LOCKDEP
185 help 182 help
186 If you say Y here and the compiler supports the -mkernel-backchain 183 If you say Y here and the compiler supports the -mkernel-backchain
187 option the kernel will use a smaller kernel stack size. For 31 bit 184 option the kernel will use a smaller kernel stack size. For 31 bit
diff --git a/arch/s390/Makefile b/arch/s390/Makefile
index 5deb9f7544a1..6598e5268573 100644
--- a/arch/s390/Makefile
+++ b/arch/s390/Makefile
@@ -35,6 +35,9 @@ cflags-$(CONFIG_MARCH_Z900) += $(call cc-option,-march=z900)
35cflags-$(CONFIG_MARCH_Z990) += $(call cc-option,-march=z990) 35cflags-$(CONFIG_MARCH_Z990) += $(call cc-option,-march=z990)
36cflags-$(CONFIG_MARCH_Z9_109) += $(call cc-option,-march=z9-109) 36cflags-$(CONFIG_MARCH_Z9_109) += $(call cc-option,-march=z9-109)
37 37
38#KBUILD_IMAGE is necessary for make rpm
39KBUILD_IMAGE :=arch/s390/boot/image
40
38# 41#
39# Prevent tail-call optimizations, to get clearer backtraces: 42# Prevent tail-call optimizations, to get clearer backtraces:
40# 43#
diff --git a/arch/s390/kernel/Makefile b/arch/s390/kernel/Makefile
index aa978978d3d1..a81881c9b297 100644
--- a/arch/s390/kernel/Makefile
+++ b/arch/s390/kernel/Makefile
@@ -4,7 +4,7 @@
4 4
5EXTRA_AFLAGS := -traditional 5EXTRA_AFLAGS := -traditional
6 6
7obj-y := bitmap.o traps.o time.o process.o \ 7obj-y := bitmap.o traps.o time.o process.o reset.o \
8 setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \ 8 setup.o sys_s390.o ptrace.o signal.o cpcmd.o ebcdic.o \
9 semaphore.o s390_ext.o debug.o profile.o irq.o ipl.o 9 semaphore.o s390_ext.o debug.o profile.o irq.o ipl.o
10 10
diff --git a/arch/s390/kernel/cpcmd.c b/arch/s390/kernel/cpcmd.c
index 1eae74e72f95..a5972f1541fe 100644
--- a/arch/s390/kernel/cpcmd.c
+++ b/arch/s390/kernel/cpcmd.c
@@ -21,14 +21,15 @@ static DEFINE_SPINLOCK(cpcmd_lock);
21static char cpcmd_buf[241]; 21static char cpcmd_buf[241];
22 22
23/* 23/*
24 * the caller of __cpcmd has to ensure that the response buffer is below 2 GB 24 * __cpcmd has some restrictions over cpcmd
25 * - the response buffer must reside below 2GB (if any)
26 * - __cpcmd is unlocked and therefore not SMP-safe
25 */ 27 */
26int __cpcmd(const char *cmd, char *response, int rlen, int *response_code) 28int __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
27{ 29{
28 unsigned long flags, cmdlen; 30 unsigned cmdlen;
29 int return_code, return_len; 31 int return_code, return_len;
30 32
31 spin_lock_irqsave(&cpcmd_lock, flags);
32 cmdlen = strlen(cmd); 33 cmdlen = strlen(cmd);
33 BUG_ON(cmdlen > 240); 34 BUG_ON(cmdlen > 240);
34 memcpy(cpcmd_buf, cmd, cmdlen); 35 memcpy(cpcmd_buf, cmd, cmdlen);
@@ -74,7 +75,6 @@ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
74 : "+d" (reg3) : "d" (reg2) : "cc"); 75 : "+d" (reg3) : "d" (reg2) : "cc");
75 return_code = (int) reg3; 76 return_code = (int) reg3;
76 } 77 }
77 spin_unlock_irqrestore(&cpcmd_lock, flags);
78 if (response_code != NULL) 78 if (response_code != NULL)
79 *response_code = return_code; 79 *response_code = return_code;
80 return return_len; 80 return return_len;
@@ -82,15 +82,18 @@ int __cpcmd(const char *cmd, char *response, int rlen, int *response_code)
82 82
83EXPORT_SYMBOL(__cpcmd); 83EXPORT_SYMBOL(__cpcmd);
84 84
85#ifdef CONFIG_64BIT
86int cpcmd(const char *cmd, char *response, int rlen, int *response_code) 85int cpcmd(const char *cmd, char *response, int rlen, int *response_code)
87{ 86{
88 char *lowbuf; 87 char *lowbuf;
89 int len; 88 int len;
89 unsigned long flags;
90 90
91 if ((rlen == 0) || (response == NULL) 91 if ((rlen == 0) || (response == NULL)
92 || !((unsigned long)response >> 31)) 92 || !((unsigned long)response >> 31)) {
93 spin_lock_irqsave(&cpcmd_lock, flags);
93 len = __cpcmd(cmd, response, rlen, response_code); 94 len = __cpcmd(cmd, response, rlen, response_code);
95 spin_unlock_irqrestore(&cpcmd_lock, flags);
96 }
94 else { 97 else {
95 lowbuf = kmalloc(rlen, GFP_KERNEL | GFP_DMA); 98 lowbuf = kmalloc(rlen, GFP_KERNEL | GFP_DMA);
96 if (!lowbuf) { 99 if (!lowbuf) {
@@ -98,7 +101,9 @@ int cpcmd(const char *cmd, char *response, int rlen, int *response_code)
98 "cpcmd: could not allocate response buffer\n"); 101 "cpcmd: could not allocate response buffer\n");
99 return -ENOMEM; 102 return -ENOMEM;
100 } 103 }
104 spin_lock_irqsave(&cpcmd_lock, flags);
101 len = __cpcmd(cmd, lowbuf, rlen, response_code); 105 len = __cpcmd(cmd, lowbuf, rlen, response_code);
106 spin_unlock_irqrestore(&cpcmd_lock, flags);
102 memcpy(response, lowbuf, rlen); 107 memcpy(response, lowbuf, rlen);
103 kfree(lowbuf); 108 kfree(lowbuf);
104 } 109 }
@@ -106,4 +111,3 @@ int cpcmd(const char *cmd, char *response, int rlen, int *response_code)
106} 111}
107 112
108EXPORT_SYMBOL(cpcmd); 113EXPORT_SYMBOL(cpcmd);
109#endif /* CONFIG_64BIT */
diff --git a/arch/s390/kernel/head.S b/arch/s390/kernel/head.S
index 0cf59bb7a857..8f8c802f1bcf 100644
--- a/arch/s390/kernel/head.S
+++ b/arch/s390/kernel/head.S
@@ -418,24 +418,6 @@ start:
418.gotr: 418.gotr:
419 l %r10,.tbl # EBCDIC to ASCII table 419 l %r10,.tbl # EBCDIC to ASCII table
420 tr 0(240,%r8),0(%r10) 420 tr 0(240,%r8),0(%r10)
421 stidp __LC_CPUID # Are we running on VM maybe
422 cli __LC_CPUID,0xff
423 bnz .test
424 .long 0x83300060 # diag 3,0,x'0060' - storage size
425 b .done
426.test:
427 mvc 0x68(8),.pgmnw # set up pgm check handler
428 l %r2,.fourmeg
429 lr %r3,%r2
430 bctr %r3,%r0 # 4M-1
431.loop: iske %r0,%r3
432 ar %r3,%r2
433.pgmx:
434 sr %r3,%r2
435 la %r3,1(%r3)
436.done:
437 l %r1,.memsize
438 st %r3,ARCH_OFFSET(%r1)
439 slr %r0,%r0 421 slr %r0,%r0
440 st %r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11) 422 st %r0,INITRD_SIZE+ARCH_OFFSET-PARMAREA(%r11)
441 st %r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11) 423 st %r0,INITRD_START+ARCH_OFFSET-PARMAREA(%r11)
@@ -443,9 +425,6 @@ start:
443.tbl: .long _ebcasc # translate table 425.tbl: .long _ebcasc # translate table
444.cmd: .long COMMAND_LINE # address of command line buffer 426.cmd: .long COMMAND_LINE # address of command line buffer
445.parm: .long PARMAREA 427.parm: .long PARMAREA
446.memsize: .long memory_size
447.fourmeg: .long 0x00400000 # 4M
448.pgmnw: .long 0x00080000,.pgmx
449.lowcase: 428.lowcase:
450 .byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07 429 .byte 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07
451 .byte 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f 430 .byte 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
diff --git a/arch/s390/kernel/head31.S b/arch/s390/kernel/head31.S
index 0a2c929486ab..4388b3309e0c 100644
--- a/arch/s390/kernel/head31.S
+++ b/arch/s390/kernel/head31.S
@@ -131,10 +131,11 @@ startup_continue:
131 .long init_thread_union 131 .long init_thread_union
132.Lpmask: 132.Lpmask:
133 .byte 0 133 .byte 0
134.align 8 134 .align 8
135.Lpcext:.long 0x00080000,0x80000000 135.Lpcext:.long 0x00080000,0x80000000
136.Lcr: 136.Lcr:
137 .long 0x00 # place holder for cr0 137 .long 0x00 # place holder for cr0
138 .align 8
138.Lwaitsclp: 139.Lwaitsclp:
139 .long 0x010a0000,0x80000000 + .Lsclph 140 .long 0x010a0000,0x80000000 + .Lsclph
140.Lrcp: 141.Lrcp:
@@ -156,7 +157,7 @@ startup_continue:
156 slr %r4,%r4 # set start of chunk to zero 157 slr %r4,%r4 # set start of chunk to zero
157 slr %r5,%r5 # set end of chunk to zero 158 slr %r5,%r5 # set end of chunk to zero
158 slr %r6,%r6 # set access code to zero 159 slr %r6,%r6 # set access code to zero
159 la %r10, MEMORY_CHUNKS # number of chunks 160 la %r10,MEMORY_CHUNKS # number of chunks
160.Lloop: 161.Lloop:
161 tprot 0(%r5),0 # test protection of first byte 162 tprot 0(%r5),0 # test protection of first byte
162 ipm %r7 163 ipm %r7
@@ -176,8 +177,6 @@ startup_continue:
176 st %r0,4(%r3) # store size of chunk 177 st %r0,4(%r3) # store size of chunk
177 st %r6,8(%r3) # store type of chunk 178 st %r6,8(%r3) # store type of chunk
178 la %r3,12(%r3) 179 la %r3,12(%r3)
179 l %r4,.Lmemsize-.LPG1(%r13) # address of variable memory_size
180 st %r5,0(%r4) # store last end to memory size
181 ahi %r10,-1 # update chunk number 180 ahi %r10,-1 # update chunk number
182.Lchkloop: 181.Lchkloop:
183 lr %r6,%r7 # set access code to last cc 182 lr %r6,%r7 # set access code to last cc
@@ -292,7 +291,6 @@ startup_continue:
292.Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg 291.Lpcmvpg:.long 0x00080000,0x80000000 + .Lchkmvpg
293.Lpcidte:.long 0x00080000,0x80000000 + .Lchkidte 292.Lpcidte:.long 0x00080000,0x80000000 + .Lchkidte
294.Lpcdiag9c:.long 0x00080000,0x80000000 + .Lchkdiag9c 293.Lpcdiag9c:.long 0x00080000,0x80000000 + .Lchkdiag9c
295.Lmemsize:.long memory_size
296.Lmchunk:.long memory_chunk 294.Lmchunk:.long memory_chunk
297.Lmflags:.long machine_flags 295.Lmflags:.long machine_flags
298.Lbss_bgn: .long __bss_start 296.Lbss_bgn: .long __bss_start
diff --git a/arch/s390/kernel/head64.S b/arch/s390/kernel/head64.S
index 42f54d482441..c526279e1123 100644
--- a/arch/s390/kernel/head64.S
+++ b/arch/s390/kernel/head64.S
@@ -70,7 +70,20 @@ startup_continue:
70 sgr %r5,%r5 # set src,length and pad to zero 70 sgr %r5,%r5 # set src,length and pad to zero
71 mvcle %r2,%r4,0 # clear mem 71 mvcle %r2,%r4,0 # clear mem
72 jo .-4 # branch back, if not finish 72 jo .-4 # branch back, if not finish
73 # set program check new psw mask
74 mvc __LC_PGM_NEW_PSW(8),.Lpcmsk-.LPG1(%r13)
75 larl %r1,.Lslowmemdetect # set program check address
76 stg %r1,__LC_PGM_NEW_PSW+8
77 lghi %r1,0xc
78 diag %r0,%r1,0x260 # get memory size of virtual machine
79 cgr %r0,%r1 # different? -> old detection routine
80 jne .Lslowmemdetect
81 aghi %r1,1 # size is one more than end
82 larl %r2,memory_chunk
83 stg %r1,8(%r2) # store size of chunk
84 j .Ldonemem
73 85
86.Lslowmemdetect:
74 l %r2,.Lrcp-.LPG1(%r13) # Read SCP forced command word 87 l %r2,.Lrcp-.LPG1(%r13) # Read SCP forced command word
75.Lservicecall: 88.Lservicecall:
76 stosm .Lpmask-.LPG1(%r13),0x01 # authorize ext interrupts 89 stosm .Lpmask-.LPG1(%r13),0x01 # authorize ext interrupts
@@ -139,8 +152,6 @@ startup_continue:
139 .int 0x100000 152 .int 0x100000
140 153
141.Lfchunk: 154.Lfchunk:
142 # set program check new psw mask
143 mvc __LC_PGM_NEW_PSW(8),.Lpcmsk-.LPG1(%r13)
144 155
145# 156#
146# find memory chunks. 157# find memory chunks.
@@ -175,8 +186,6 @@ startup_continue:
175 stg %r0,8(%r3) # store size of chunk 186 stg %r0,8(%r3) # store size of chunk
176 st %r6,20(%r3) # store type of chunk 187 st %r6,20(%r3) # store type of chunk
177 la %r3,24(%r3) 188 la %r3,24(%r3)
178 larl %r8,memory_size
179 stg %r5,0(%r8) # store memory size
180 ahi %r10,-1 # update chunk number 189 ahi %r10,-1 # update chunk number
181.Lchkloop: 190.Lchkloop:
182 lr %r6,%r7 # set access code to last cc 191 lr %r6,%r7 # set access code to last cc
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 1f5e782b3d05..a36bea1188d9 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -13,12 +13,21 @@
13#include <linux/device.h> 13#include <linux/device.h>
14#include <linux/delay.h> 14#include <linux/delay.h>
15#include <linux/reboot.h> 15#include <linux/reboot.h>
16#include <linux/ctype.h>
16#include <asm/smp.h> 17#include <asm/smp.h>
17#include <asm/setup.h> 18#include <asm/setup.h>
18#include <asm/cpcmd.h> 19#include <asm/cpcmd.h>
19#include <asm/cio.h> 20#include <asm/cio.h>
21#include <asm/ebcdic.h>
22#include <asm/reset.h>
20 23
21#define IPL_PARM_BLOCK_VERSION 0 24#define IPL_PARM_BLOCK_VERSION 0
25#define LOADPARM_LEN 8
26
27extern char s390_readinfo_sccb[];
28#define SCCB_VALID (*((__u16*)&s390_readinfo_sccb[6]) == 0x0010)
29#define SCCB_LOADPARM (&s390_readinfo_sccb[24])
30#define SCCB_FLAG (s390_readinfo_sccb[91])
22 31
23enum ipl_type { 32enum ipl_type {
24 IPL_TYPE_NONE = 1, 33 IPL_TYPE_NONE = 1,
@@ -289,9 +298,25 @@ static struct attribute_group ipl_fcp_attr_group = {
289 298
290/* CCW ipl device attributes */ 299/* CCW ipl device attributes */
291 300
301static ssize_t ipl_ccw_loadparm_show(struct subsystem *subsys, char *page)
302{
303 char loadparm[LOADPARM_LEN + 1] = {};
304
305 if (!SCCB_VALID)
306 return sprintf(page, "#unknown#\n");
307 memcpy(loadparm, SCCB_LOADPARM, LOADPARM_LEN);
308 EBCASC(loadparm, LOADPARM_LEN);
309 strstrip(loadparm);
310 return sprintf(page, "%s\n", loadparm);
311}
312
313static struct subsys_attribute sys_ipl_ccw_loadparm_attr =
314 __ATTR(loadparm, 0444, ipl_ccw_loadparm_show, NULL);
315
292static struct attribute *ipl_ccw_attrs[] = { 316static struct attribute *ipl_ccw_attrs[] = {
293 &sys_ipl_type_attr.attr, 317 &sys_ipl_type_attr.attr,
294 &sys_ipl_device_attr.attr, 318 &sys_ipl_device_attr.attr,
319 &sys_ipl_ccw_loadparm_attr.attr,
295 NULL, 320 NULL,
296}; 321};
297 322
@@ -348,8 +373,57 @@ static struct attribute_group reipl_fcp_attr_group = {
348DEFINE_IPL_ATTR_RW(reipl_ccw, device, "0.0.%04llx\n", "0.0.%llx\n", 373DEFINE_IPL_ATTR_RW(reipl_ccw, device, "0.0.%04llx\n", "0.0.%llx\n",
349 reipl_block_ccw->ipl_info.ccw.devno); 374 reipl_block_ccw->ipl_info.ccw.devno);
350 375
376static void reipl_get_ascii_loadparm(char *loadparm)
377{
378 memcpy(loadparm, &reipl_block_ccw->ipl_info.ccw.load_param,
379 LOADPARM_LEN);
380 EBCASC(loadparm, LOADPARM_LEN);
381 loadparm[LOADPARM_LEN] = 0;
382 strstrip(loadparm);
383}
384
385static ssize_t reipl_ccw_loadparm_show(struct subsystem *subsys, char *page)
386{
387 char buf[LOADPARM_LEN + 1];
388
389 reipl_get_ascii_loadparm(buf);
390 return sprintf(page, "%s\n", buf);
391}
392
393static ssize_t reipl_ccw_loadparm_store(struct subsystem *subsys,
394 const char *buf, size_t len)
395{
396 int i, lp_len;
397
398 /* ignore trailing newline */
399 lp_len = len;
400 if ((len > 0) && (buf[len - 1] == '\n'))
401 lp_len--;
402 /* loadparm can have max 8 characters and must not start with a blank */
403 if ((lp_len > LOADPARM_LEN) || ((lp_len > 0) && (buf[0] == ' ')))
404 return -EINVAL;
405 /* loadparm can only contain "a-z,A-Z,0-9,SP,." */
406 for (i = 0; i < lp_len; i++) {
407 if (isalpha(buf[i]) || isdigit(buf[i]) || (buf[i] == ' ') ||
408 (buf[i] == '.'))
409 continue;
410 return -EINVAL;
411 }
412 /* initialize loadparm with blanks */
413 memset(&reipl_block_ccw->ipl_info.ccw.load_param, ' ', LOADPARM_LEN);
414 /* copy and convert to ebcdic */
415 memcpy(&reipl_block_ccw->ipl_info.ccw.load_param, buf, lp_len);
416 ASCEBC(reipl_block_ccw->ipl_info.ccw.load_param, LOADPARM_LEN);
417 return len;
418}
419
420static struct subsys_attribute sys_reipl_ccw_loadparm_attr =
421 __ATTR(loadparm, 0644, reipl_ccw_loadparm_show,
422 reipl_ccw_loadparm_store);
423
351static struct attribute *reipl_ccw_attrs[] = { 424static struct attribute *reipl_ccw_attrs[] = {
352 &sys_reipl_ccw_device_attr.attr, 425 &sys_reipl_ccw_device_attr.attr,
426 &sys_reipl_ccw_loadparm_attr.attr,
353 NULL, 427 NULL,
354}; 428};
355 429
@@ -502,23 +576,6 @@ static struct subsys_attribute dump_type_attr =
502 576
503static decl_subsys(dump, NULL, NULL); 577static decl_subsys(dump, NULL, NULL);
504 578
505#ifdef CONFIG_SMP
506static void dump_smp_stop_all(void)
507{
508 int cpu;
509 preempt_disable();
510 for_each_online_cpu(cpu) {
511 if (cpu == smp_processor_id())
512 continue;
513 while (signal_processor(cpu, sigp_stop) == sigp_busy)
514 udelay(10);
515 }
516 preempt_enable();
517}
518#else
519#define dump_smp_stop_all() do { } while (0)
520#endif
521
522/* 579/*
523 * Shutdown actions section 580 * Shutdown actions section
524 */ 581 */
@@ -571,11 +628,14 @@ void do_reipl(void)
571{ 628{
572 struct ccw_dev_id devid; 629 struct ccw_dev_id devid;
573 static char buf[100]; 630 static char buf[100];
631 char loadparm[LOADPARM_LEN + 1];
574 632
575 switch (reipl_type) { 633 switch (reipl_type) {
576 case IPL_TYPE_CCW: 634 case IPL_TYPE_CCW:
635 reipl_get_ascii_loadparm(loadparm);
577 printk(KERN_EMERG "reboot on ccw device: 0.0.%04x\n", 636 printk(KERN_EMERG "reboot on ccw device: 0.0.%04x\n",
578 reipl_block_ccw->ipl_info.ccw.devno); 637 reipl_block_ccw->ipl_info.ccw.devno);
638 printk(KERN_EMERG "loadparm = '%s'\n", loadparm);
579 break; 639 break;
580 case IPL_TYPE_FCP: 640 case IPL_TYPE_FCP:
581 printk(KERN_EMERG "reboot on fcp device:\n"); 641 printk(KERN_EMERG "reboot on fcp device:\n");
@@ -588,12 +648,19 @@ void do_reipl(void)
588 switch (reipl_method) { 648 switch (reipl_method) {
589 case IPL_METHOD_CCW_CIO: 649 case IPL_METHOD_CCW_CIO:
590 devid.devno = reipl_block_ccw->ipl_info.ccw.devno; 650 devid.devno = reipl_block_ccw->ipl_info.ccw.devno;
651 if (ipl_get_type() == IPL_TYPE_CCW && devid.devno == ipl_devno)
652 diag308(DIAG308_IPL, NULL);
591 devid.ssid = 0; 653 devid.ssid = 0;
592 reipl_ccw_dev(&devid); 654 reipl_ccw_dev(&devid);
593 break; 655 break;
594 case IPL_METHOD_CCW_VM: 656 case IPL_METHOD_CCW_VM:
595 sprintf(buf, "IPL %X", reipl_block_ccw->ipl_info.ccw.devno); 657 if (strlen(loadparm) == 0)
596 cpcmd(buf, NULL, 0, NULL); 658 sprintf(buf, "IPL %X",
659 reipl_block_ccw->ipl_info.ccw.devno);
660 else
661 sprintf(buf, "IPL %X LOADPARM '%s'",
662 reipl_block_ccw->ipl_info.ccw.devno, loadparm);
663 __cpcmd(buf, NULL, 0, NULL);
597 break; 664 break;
598 case IPL_METHOD_CCW_DIAG: 665 case IPL_METHOD_CCW_DIAG:
599 diag308(DIAG308_SET, reipl_block_ccw); 666 diag308(DIAG308_SET, reipl_block_ccw);
@@ -607,16 +674,17 @@ void do_reipl(void)
607 diag308(DIAG308_IPL, NULL); 674 diag308(DIAG308_IPL, NULL);
608 break; 675 break;
609 case IPL_METHOD_FCP_RO_VM: 676 case IPL_METHOD_FCP_RO_VM:
610 cpcmd("IPL", NULL, 0, NULL); 677 __cpcmd("IPL", NULL, 0, NULL);
611 break; 678 break;
612 case IPL_METHOD_NONE: 679 case IPL_METHOD_NONE:
613 default: 680 default:
614 if (MACHINE_IS_VM) 681 if (MACHINE_IS_VM)
615 cpcmd("IPL", NULL, 0, NULL); 682 __cpcmd("IPL", NULL, 0, NULL);
616 diag308(DIAG308_IPL, NULL); 683 diag308(DIAG308_IPL, NULL);
617 break; 684 break;
618 } 685 }
619 panic("reipl failed!\n"); 686 printk(KERN_EMERG "reboot failed!\n");
687 signal_processor(smp_processor_id(), sigp_stop_and_store_status);
620} 688}
621 689
622static void do_dump(void) 690static void do_dump(void)
@@ -639,17 +707,17 @@ static void do_dump(void)
639 707
640 switch (dump_method) { 708 switch (dump_method) {
641 case IPL_METHOD_CCW_CIO: 709 case IPL_METHOD_CCW_CIO:
642 dump_smp_stop_all(); 710 smp_send_stop();
643 devid.devno = dump_block_ccw->ipl_info.ccw.devno; 711 devid.devno = dump_block_ccw->ipl_info.ccw.devno;
644 devid.ssid = 0; 712 devid.ssid = 0;
645 reipl_ccw_dev(&devid); 713 reipl_ccw_dev(&devid);
646 break; 714 break;
647 case IPL_METHOD_CCW_VM: 715 case IPL_METHOD_CCW_VM:
648 dump_smp_stop_all(); 716 smp_send_stop();
649 sprintf(buf, "STORE STATUS"); 717 sprintf(buf, "STORE STATUS");
650 cpcmd(buf, NULL, 0, NULL); 718 __cpcmd(buf, NULL, 0, NULL);
651 sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno); 719 sprintf(buf, "IPL %X", dump_block_ccw->ipl_info.ccw.devno);
652 cpcmd(buf, NULL, 0, NULL); 720 __cpcmd(buf, NULL, 0, NULL);
653 break; 721 break;
654 case IPL_METHOD_CCW_DIAG: 722 case IPL_METHOD_CCW_DIAG:
655 diag308(DIAG308_SET, dump_block_ccw); 723 diag308(DIAG308_SET, dump_block_ccw);
@@ -746,6 +814,17 @@ static int __init reipl_ccw_init(void)
746 reipl_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION; 814 reipl_block_ccw->hdr.version = IPL_PARM_BLOCK_VERSION;
747 reipl_block_ccw->hdr.blk0_len = sizeof(reipl_block_ccw->ipl_info.ccw); 815 reipl_block_ccw->hdr.blk0_len = sizeof(reipl_block_ccw->ipl_info.ccw);
748 reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW; 816 reipl_block_ccw->hdr.pbt = DIAG308_IPL_TYPE_CCW;
817 /* check if read scp info worked and set loadparm */
818 if (SCCB_VALID)
819 memcpy(reipl_block_ccw->ipl_info.ccw.load_param,
820 SCCB_LOADPARM, LOADPARM_LEN);
821 else
822 /* read scp info failed: set empty loadparm (EBCDIC blanks) */
823 memset(reipl_block_ccw->ipl_info.ccw.load_param, 0x40,
824 LOADPARM_LEN);
825 /* FIXME: check for diag308_set_works when enabling diag ccw reipl */
826 if (!MACHINE_IS_VM)
827 sys_reipl_ccw_loadparm_attr.attr.mode = S_IRUGO;
749 if (ipl_get_type() == IPL_TYPE_CCW) 828 if (ipl_get_type() == IPL_TYPE_CCW)
750 reipl_block_ccw->ipl_info.ccw.devno = ipl_devno; 829 reipl_block_ccw->ipl_info.ccw.devno = ipl_devno;
751 reipl_capabilities |= IPL_TYPE_CCW; 830 reipl_capabilities |= IPL_TYPE_CCW;
@@ -827,13 +906,11 @@ static int __init dump_ccw_init(void)
827 return 0; 906 return 0;
828} 907}
829 908
830extern char s390_readinfo_sccb[];
831
832static int __init dump_fcp_init(void) 909static int __init dump_fcp_init(void)
833{ 910{
834 int rc; 911 int rc;
835 912
836 if(!(s390_readinfo_sccb[91] & 0x2)) 913 if(!(SCCB_FLAG & 0x2) || !SCCB_VALID)
837 return 0; /* LDIPL DUMP is not installed */ 914 return 0; /* LDIPL DUMP is not installed */
838 if (!diag308_set_works) 915 if (!diag308_set_works)
839 return 0; 916 return 0;
@@ -931,3 +1008,53 @@ static int __init s390_ipl_init(void)
931} 1008}
932 1009
933__initcall(s390_ipl_init); 1010__initcall(s390_ipl_init);
1011
1012static LIST_HEAD(rcall);
1013static DEFINE_MUTEX(rcall_mutex);
1014
1015void register_reset_call(struct reset_call *reset)
1016{
1017 mutex_lock(&rcall_mutex);
1018 list_add(&reset->list, &rcall);
1019 mutex_unlock(&rcall_mutex);
1020}
1021EXPORT_SYMBOL_GPL(register_reset_call);
1022
1023void unregister_reset_call(struct reset_call *reset)
1024{
1025 mutex_lock(&rcall_mutex);
1026 list_del(&reset->list);
1027 mutex_unlock(&rcall_mutex);
1028}
1029EXPORT_SYMBOL_GPL(unregister_reset_call);
1030
1031static void do_reset_calls(void)
1032{
1033 struct reset_call *reset;
1034
1035 list_for_each_entry(reset, &rcall, list)
1036 reset->fn();
1037}
1038
1039extern void reset_mcck_handler(void);
1040
1041void s390_reset_system(void)
1042{
1043 struct _lowcore *lc;
1044
1045 /* Stack for interrupt/machine check handler */
1046 lc = (struct _lowcore *)(unsigned long) store_prefix();
1047 lc->panic_stack = S390_lowcore.panic_stack;
1048
1049 /* Disable prefixing */
1050 set_prefix(0);
1051
1052 /* Disable lowcore protection */
1053 __ctl_clear_bit(0,28);
1054
1055 /* Set new machine check handler */
1056 S390_lowcore.mcck_new_psw.mask = PSW_KERNEL_BITS & ~PSW_MASK_MCHECK;
1057 S390_lowcore.mcck_new_psw.addr =
1058 PSW_ADDR_AMODE | (unsigned long) &reset_mcck_handler;
1059 do_reset_calls();
1060}
diff --git a/arch/s390/kernel/machine_kexec.c b/arch/s390/kernel/machine_kexec.c
index 60b1ea9f946b..f6d9bcc0f75b 100644
--- a/arch/s390/kernel/machine_kexec.c
+++ b/arch/s390/kernel/machine_kexec.c
@@ -1,15 +1,10 @@
1/* 1/*
2 * arch/s390/kernel/machine_kexec.c 2 * arch/s390/kernel/machine_kexec.c
3 * 3 *
4 * (C) Copyright IBM Corp. 2005 4 * Copyright IBM Corp. 2005,2006
5 * 5 *
6 * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com> 6 * Author(s): Rolf Adelsberger,
7 * 7 * Heiko Carstens <heiko.carstens@de.ibm.com>
8 */
9
10/*
11 * s390_machine_kexec.c - handle the transition of Linux booting another kernel
12 * on the S390 architecture.
13 */ 8 */
14 9
15#include <linux/device.h> 10#include <linux/device.h>
@@ -22,86 +17,49 @@
22#include <asm/pgalloc.h> 17#include <asm/pgalloc.h>
23#include <asm/system.h> 18#include <asm/system.h>
24#include <asm/smp.h> 19#include <asm/smp.h>
20#include <asm/reset.h>
25 21
26static void kexec_halt_all_cpus(void *); 22typedef void (*relocate_kernel_t)(kimage_entry_t *, unsigned long);
27
28typedef void (*relocate_kernel_t) (kimage_entry_t *, unsigned long);
29 23
30extern const unsigned char relocate_kernel[]; 24extern const unsigned char relocate_kernel[];
31extern const unsigned long long relocate_kernel_len; 25extern const unsigned long long relocate_kernel_len;
32 26
33int 27int machine_kexec_prepare(struct kimage *image)
34machine_kexec_prepare(struct kimage *image)
35{ 28{
36 unsigned long reboot_code_buffer; 29 void *reboot_code_buffer;
37 30
38 /* We don't support anything but the default image type for now. */ 31 /* We don't support anything but the default image type for now. */
39 if (image->type != KEXEC_TYPE_DEFAULT) 32 if (image->type != KEXEC_TYPE_DEFAULT)
40 return -EINVAL; 33 return -EINVAL;
41 34
42 /* Get the destination where the assembler code should be copied to.*/ 35 /* Get the destination where the assembler code should be copied to.*/
43 reboot_code_buffer = page_to_pfn(image->control_code_page)<<PAGE_SHIFT; 36 reboot_code_buffer = (void *) page_to_phys(image->control_code_page);
44 37
45 /* Then copy it */ 38 /* Then copy it */
46 memcpy((void *) reboot_code_buffer, relocate_kernel, 39 memcpy(reboot_code_buffer, relocate_kernel, relocate_kernel_len);
47 relocate_kernel_len);
48 return 0; 40 return 0;
49} 41}
50 42
51void 43void machine_kexec_cleanup(struct kimage *image)
52machine_kexec_cleanup(struct kimage *image)
53{ 44{
54} 45}
55 46
56void 47void machine_shutdown(void)
57machine_shutdown(void)
58{ 48{
59 printk(KERN_INFO "kexec: machine_shutdown called\n"); 49 printk(KERN_INFO "kexec: machine_shutdown called\n");
60} 50}
61 51
62NORET_TYPE void 52void machine_kexec(struct kimage *image)
63machine_kexec(struct kimage *image)
64{ 53{
65 clear_all_subchannels();
66 cio_reset_channel_paths();
67
68 /* Disable lowcore protection */
69 ctl_clear_bit(0,28);
70
71 on_each_cpu(kexec_halt_all_cpus, image, 0, 0);
72 for (;;);
73}
74
75extern void pfault_fini(void);
76
77static void
78kexec_halt_all_cpus(void *kernel_image)
79{
80 static atomic_t cpuid = ATOMIC_INIT(-1);
81 int cpu;
82 struct kimage *image;
83 relocate_kernel_t data_mover; 54 relocate_kernel_t data_mover;
84 55
85#ifdef CONFIG_PFAULT 56 smp_send_stop();
86 if (MACHINE_IS_VM) 57 pfault_fini();
87 pfault_fini(); 58 s390_reset_system();
88#endif
89 59
90 if (atomic_cmpxchg(&cpuid, -1, smp_processor_id()) != -1) 60 data_mover = (relocate_kernel_t) page_to_phys(image->control_code_page);
91 signal_processor(smp_processor_id(), sigp_stop);
92
93 /* Wait for all other cpus to enter stopped state */
94 for_each_online_cpu(cpu) {
95 if (cpu == smp_processor_id())
96 continue;
97 while (!smp_cpu_not_running(cpu))
98 cpu_relax();
99 }
100
101 image = (struct kimage *) kernel_image;
102 data_mover = (relocate_kernel_t)
103 (page_to_pfn(image->control_code_page) << PAGE_SHIFT);
104 61
105 /* Call the moving routine */ 62 /* Call the moving routine */
106 (*data_mover) (&image->head, image->start); 63 (*data_mover)(&image->head, image->start);
64 for (;;);
107} 65}
diff --git a/arch/s390/kernel/reipl.S b/arch/s390/kernel/reipl.S
index 0340477f3b08..f9434d42ce9f 100644
--- a/arch/s390/kernel/reipl.S
+++ b/arch/s390/kernel/reipl.S
@@ -11,19 +11,10 @@
11 .globl do_reipl_asm 11 .globl do_reipl_asm
12do_reipl_asm: basr %r13,0 12do_reipl_asm: basr %r13,0
13.Lpg0: lpsw .Lnewpsw-.Lpg0(%r13) 13.Lpg0: lpsw .Lnewpsw-.Lpg0(%r13)
14 14.Lpg1: # do store status of all registers
15 # switch off lowcore protection
16
17.Lpg1: stctl %c0,%c0,.Lctlsave1-.Lpg0(%r13)
18 stctl %c0,%c0,.Lctlsave2-.Lpg0(%r13)
19 ni .Lctlsave1-.Lpg0(%r13),0xef
20 lctl %c0,%c0,.Lctlsave1-.Lpg0(%r13)
21
22 # do store status of all registers
23 15
24 stm %r0,%r15,__LC_GPREGS_SAVE_AREA 16 stm %r0,%r15,__LC_GPREGS_SAVE_AREA
25 stctl %c0,%c15,__LC_CREGS_SAVE_AREA 17 stctl %c0,%c15,__LC_CREGS_SAVE_AREA
26 mvc __LC_CREGS_SAVE_AREA(4),.Lctlsave2-.Lpg0(%r13)
27 stam %a0,%a15,__LC_AREGS_SAVE_AREA 18 stam %a0,%a15,__LC_AREGS_SAVE_AREA
28 stpx __LC_PREFIX_SAVE_AREA 19 stpx __LC_PREFIX_SAVE_AREA
29 stckc .Lclkcmp-.Lpg0(%r13) 20 stckc .Lclkcmp-.Lpg0(%r13)
@@ -56,8 +47,7 @@ do_reipl_asm: basr %r13,0
56.L002: tm .Liplirb+8-.Lpg0(%r13),0xf3 47.L002: tm .Liplirb+8-.Lpg0(%r13),0xf3
57 jz .L003 48 jz .L003
58 bas %r14,.Ldisab-.Lpg0(%r13) 49 bas %r14,.Ldisab-.Lpg0(%r13)
59.L003: spx .Lnull-.Lpg0(%r13) 50.L003: st %r1,__LC_SUBCHANNEL_ID
60 st %r1,__LC_SUBCHANNEL_ID
61 lpsw 0 51 lpsw 0
62 sigp 0,0,0(6) 52 sigp 0,0,0(6)
63.Ldisab: st %r14,.Ldispsw+4-.Lpg0(%r13) 53.Ldisab: st %r14,.Ldispsw+4-.Lpg0(%r13)
@@ -65,9 +55,6 @@ do_reipl_asm: basr %r13,0
65 .align 8 55 .align 8
66.Lclkcmp: .quad 0x0000000000000000 56.Lclkcmp: .quad 0x0000000000000000
67.Lall: .long 0xff000000 57.Lall: .long 0xff000000
68.Lnull: .long 0x00000000
69.Lctlsave1: .long 0x00000000
70.Lctlsave2: .long 0x00000000
71 .align 8 58 .align 8
72.Lnewpsw: .long 0x00080000,0x80000000+.Lpg1 59.Lnewpsw: .long 0x00080000,0x80000000+.Lpg1
73.Lpcnew: .long 0x00080000,0x80000000+.Lecs 60.Lpcnew: .long 0x00080000,0x80000000+.Lecs
diff --git a/arch/s390/kernel/reipl64.S b/arch/s390/kernel/reipl64.S
index de7435054f7c..f18ef260ca23 100644
--- a/arch/s390/kernel/reipl64.S
+++ b/arch/s390/kernel/reipl64.S
@@ -10,10 +10,10 @@
10#include <asm/lowcore.h> 10#include <asm/lowcore.h>
11 .globl do_reipl_asm 11 .globl do_reipl_asm
12do_reipl_asm: basr %r13,0 12do_reipl_asm: basr %r13,0
13.Lpg0: lpswe .Lnewpsw-.Lpg0(%r13)
14.Lpg1: # do store status of all registers
13 15
14 # do store status of all registers 16 stg %r1,.Lregsave-.Lpg0(%r13)
15
16.Lpg0: stg %r1,.Lregsave-.Lpg0(%r13)
17 lghi %r1,0x1000 17 lghi %r1,0x1000
18 stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-0x1000(%r1) 18 stmg %r0,%r15,__LC_GPREGS_SAVE_AREA-0x1000(%r1)
19 lg %r0,.Lregsave-.Lpg0(%r13) 19 lg %r0,.Lregsave-.Lpg0(%r13)
@@ -27,11 +27,7 @@ do_reipl_asm: basr %r13,0
27 stpt __LC_CPU_TIMER_SAVE_AREA-0x1000(%r1) 27 stpt __LC_CPU_TIMER_SAVE_AREA-0x1000(%r1)
28 stg %r13, __LC_PSW_SAVE_AREA-0x1000+8(%r1) 28 stg %r13, __LC_PSW_SAVE_AREA-0x1000+8(%r1)
29 29
30 lpswe .Lnewpsw-.Lpg0(%r13) 30 lctlg %c6,%c6,.Lall-.Lpg0(%r13)
31.Lpg1: lctlg %c6,%c6,.Lall-.Lpg0(%r13)
32 stctg %c0,%c0,.Lregsave-.Lpg0(%r13)
33 ni .Lregsave+4-.Lpg0(%r13),0xef
34 lctlg %c0,%c0,.Lregsave-.Lpg0(%r13)
35 lgr %r1,%r2 31 lgr %r1,%r2
36 mvc __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13) 32 mvc __LC_PGM_NEW_PSW(16),.Lpcnew-.Lpg0(%r13)
37 stsch .Lschib-.Lpg0(%r13) 33 stsch .Lschib-.Lpg0(%r13)
@@ -56,8 +52,7 @@ do_reipl_asm: basr %r13,0
56.L002: tm .Liplirb+8-.Lpg0(%r13),0xf3 52.L002: tm .Liplirb+8-.Lpg0(%r13),0xf3
57 jz .L003 53 jz .L003
58 bas %r14,.Ldisab-.Lpg0(%r13) 54 bas %r14,.Ldisab-.Lpg0(%r13)
59.L003: spx .Lnull-.Lpg0(%r13) 55.L003: st %r1,__LC_SUBCHANNEL_ID
60 st %r1,__LC_SUBCHANNEL_ID
61 lhi %r1,0 # mode 0 = esa 56 lhi %r1,0 # mode 0 = esa
62 slr %r0,%r0 # set cpuid to zero 57 slr %r0,%r0 # set cpuid to zero
63 sigp %r1,%r0,0x12 # switch to esa mode 58 sigp %r1,%r0,0x12 # switch to esa mode
@@ -70,7 +65,6 @@ do_reipl_asm: basr %r13,0
70.Lclkcmp: .quad 0x0000000000000000 65.Lclkcmp: .quad 0x0000000000000000
71.Lall: .quad 0x00000000ff000000 66.Lall: .quad 0x00000000ff000000
72.Lregsave: .quad 0x0000000000000000 67.Lregsave: .quad 0x0000000000000000
73.Lnull: .long 0x0000000000000000
74 .align 16 68 .align 16
75/* 69/*
76 * These addresses have to be 31 bit otherwise 70 * These addresses have to be 31 bit otherwise
diff --git a/arch/s390/kernel/relocate_kernel.S b/arch/s390/kernel/relocate_kernel.S
index f9899ff2e5b0..3b456b80bcee 100644
--- a/arch/s390/kernel/relocate_kernel.S
+++ b/arch/s390/kernel/relocate_kernel.S
@@ -26,8 +26,7 @@
26 relocate_kernel: 26 relocate_kernel:
27 basr %r13,0 # base address 27 basr %r13,0 # base address
28 .base: 28 .base:
29 stnsm sys_msk-.base(%r13),0xf8 # disable DAT and IRQ (external) 29 stnsm sys_msk-.base(%r13),0xfb # disable DAT
30 spx zero64-.base(%r13) # absolute addressing mode
31 stctl %c0,%c15,ctlregs-.base(%r13) 30 stctl %c0,%c15,ctlregs-.base(%r13)
32 stm %r0,%r15,gprregs-.base(%r13) 31 stm %r0,%r15,gprregs-.base(%r13)
33 la %r1,load_psw-.base(%r13) 32 la %r1,load_psw-.base(%r13)
@@ -97,8 +96,6 @@
97 lpsw 0 # hopefully start new kernel... 96 lpsw 0 # hopefully start new kernel...
98 97
99 .align 8 98 .align 8
100 zero64:
101 .quad 0
102 load_psw: 99 load_psw:
103 .long 0x00080000,0x80000000 100 .long 0x00080000,0x80000000
104 sys_msk: 101 sys_msk:
diff --git a/arch/s390/kernel/relocate_kernel64.S b/arch/s390/kernel/relocate_kernel64.S
index 4fb443042d9c..1f9ea2067b59 100644
--- a/arch/s390/kernel/relocate_kernel64.S
+++ b/arch/s390/kernel/relocate_kernel64.S
@@ -27,8 +27,7 @@
27 relocate_kernel: 27 relocate_kernel:
28 basr %r13,0 # base address 28 basr %r13,0 # base address
29 .base: 29 .base:
30 stnsm sys_msk-.base(%r13),0xf8 # disable DAT and IRQs 30 stnsm sys_msk-.base(%r13),0xfb # disable DAT
31 spx zero64-.base(%r13) # absolute addressing mode
32 stctg %c0,%c15,ctlregs-.base(%r13) 31 stctg %c0,%c15,ctlregs-.base(%r13)
33 stmg %r0,%r15,gprregs-.base(%r13) 32 stmg %r0,%r15,gprregs-.base(%r13)
34 lghi %r0,3 33 lghi %r0,3
@@ -100,8 +99,6 @@
100 lpsw 0 # hopefully start new kernel... 99 lpsw 0 # hopefully start new kernel...
101 100
102 .align 8 101 .align 8
103 zero64:
104 .quad 0
105 load_psw: 102 load_psw:
106 .long 0x00080000,0x80000000 103 .long 0x00080000,0x80000000
107 sys_msk: 104 sys_msk:
diff --git a/arch/s390/kernel/reset.S b/arch/s390/kernel/reset.S
new file mode 100644
index 000000000000..be8688c0665c
--- /dev/null
+++ b/arch/s390/kernel/reset.S
@@ -0,0 +1,48 @@
1/*
2 * arch/s390/kernel/reset.S
3 *
4 * Copyright (C) IBM Corp. 2006
5 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
6 */
7
8#include <asm/ptrace.h>
9#include <asm/lowcore.h>
10
11#ifdef CONFIG_64BIT
12
13 .globl reset_mcck_handler
14reset_mcck_handler:
15 basr %r13,0
160: lg %r15,__LC_PANIC_STACK # load panic stack
17 aghi %r15,-STACK_FRAME_OVERHEAD
18 lg %r1,s390_reset_mcck_handler-0b(%r13)
19 ltgr %r1,%r1
20 jz 1f
21 basr %r14,%r1
221: la %r1,4095
23 lmg %r0,%r15,__LC_GPREGS_SAVE_AREA-4095(%r1)
24 lpswe __LC_MCK_OLD_PSW
25
26 .globl s390_reset_mcck_handler
27s390_reset_mcck_handler:
28 .quad 0
29
30#else /* CONFIG_64BIT */
31
32 .globl reset_mcck_handler
33reset_mcck_handler:
34 basr %r13,0
350: l %r15,__LC_PANIC_STACK # load panic stack
36 ahi %r15,-STACK_FRAME_OVERHEAD
37 l %r1,s390_reset_mcck_handler-0b(%r13)
38 ltr %r1,%r1
39 jz 1f
40 basr %r14,%r1
411: lm %r0,%r15,__LC_GPREGS_SAVE_AREA
42 lpsw __LC_MCK_OLD_PSW
43
44 .globl s390_reset_mcck_handler
45s390_reset_mcck_handler:
46 .long 0
47
48#endif /* CONFIG_64BIT */
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index 2aa13e8e000a..b928fecdc743 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -62,13 +62,9 @@ EXPORT_SYMBOL_GPL(uaccess);
62unsigned int console_mode = 0; 62unsigned int console_mode = 0;
63unsigned int console_devno = -1; 63unsigned int console_devno = -1;
64unsigned int console_irq = -1; 64unsigned int console_irq = -1;
65unsigned long memory_size = 0;
66unsigned long machine_flags = 0; 65unsigned long machine_flags = 0;
67struct { 66
68 unsigned long addr, size, type; 67struct mem_chunk memory_chunk[MEMORY_CHUNKS];
69} memory_chunk[MEMORY_CHUNKS] = { { 0 } };
70#define CHUNK_READ_WRITE 0
71#define CHUNK_READ_ONLY 1
72volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */ 68volatile int __cpu_logical_map[NR_CPUS]; /* logical cpu to cpu address */
73unsigned long __initdata zholes_size[MAX_NR_ZONES]; 69unsigned long __initdata zholes_size[MAX_NR_ZONES];
74static unsigned long __initdata memory_end; 70static unsigned long __initdata memory_end;
@@ -229,11 +225,11 @@ static void __init conmode_default(void)
229 char *ptr; 225 char *ptr;
230 226
231 if (MACHINE_IS_VM) { 227 if (MACHINE_IS_VM) {
232 __cpcmd("QUERY CONSOLE", query_buffer, 1024, NULL); 228 cpcmd("QUERY CONSOLE", query_buffer, 1024, NULL);
233 console_devno = simple_strtoul(query_buffer + 5, NULL, 16); 229 console_devno = simple_strtoul(query_buffer + 5, NULL, 16);
234 ptr = strstr(query_buffer, "SUBCHANNEL ="); 230 ptr = strstr(query_buffer, "SUBCHANNEL =");
235 console_irq = simple_strtoul(ptr + 13, NULL, 16); 231 console_irq = simple_strtoul(ptr + 13, NULL, 16);
236 __cpcmd("QUERY TERM", query_buffer, 1024, NULL); 232 cpcmd("QUERY TERM", query_buffer, 1024, NULL);
237 ptr = strstr(query_buffer, "CONMODE"); 233 ptr = strstr(query_buffer, "CONMODE");
238 /* 234 /*
239 * Set the conmode to 3215 so that the device recognition 235 * Set the conmode to 3215 so that the device recognition
@@ -242,7 +238,7 @@ static void __init conmode_default(void)
242 * 3215 and the 3270 driver will try to access the console 238 * 3215 and the 3270 driver will try to access the console
243 * device (3215 as console and 3270 as normal tty). 239 * device (3215 as console and 3270 as normal tty).
244 */ 240 */
245 __cpcmd("TERM CONMODE 3215", NULL, 0, NULL); 241 cpcmd("TERM CONMODE 3215", NULL, 0, NULL);
246 if (ptr == NULL) { 242 if (ptr == NULL) {
247#if defined(CONFIG_SCLP_CONSOLE) 243#if defined(CONFIG_SCLP_CONSOLE)
248 SET_CONSOLE_SCLP; 244 SET_CONSOLE_SCLP;
@@ -299,14 +295,14 @@ static void do_machine_restart_nonsmp(char * __unused)
299static void do_machine_halt_nonsmp(void) 295static void do_machine_halt_nonsmp(void)
300{ 296{
301 if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0) 297 if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0)
302 cpcmd(vmhalt_cmd, NULL, 0, NULL); 298 __cpcmd(vmhalt_cmd, NULL, 0, NULL);
303 signal_processor(smp_processor_id(), sigp_stop_and_store_status); 299 signal_processor(smp_processor_id(), sigp_stop_and_store_status);
304} 300}
305 301
306static void do_machine_power_off_nonsmp(void) 302static void do_machine_power_off_nonsmp(void)
307{ 303{
308 if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0) 304 if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0)
309 cpcmd(vmpoff_cmd, NULL, 0, NULL); 305 __cpcmd(vmpoff_cmd, NULL, 0, NULL);
310 signal_processor(smp_processor_id(), sigp_stop_and_store_status); 306 signal_processor(smp_processor_id(), sigp_stop_and_store_status);
311} 307}
312 308
@@ -489,6 +485,37 @@ setup_resources(void)
489 } 485 }
490} 486}
491 487
488static void __init setup_memory_end(void)
489{
490 unsigned long real_size, memory_size;
491 unsigned long max_mem, max_phys;
492 int i;
493
494 memory_size = real_size = 0;
495 max_phys = VMALLOC_END - VMALLOC_MIN_SIZE;
496 memory_end &= PAGE_MASK;
497
498 max_mem = memory_end ? min(max_phys, memory_end) : max_phys;
499
500 for (i = 0; i < MEMORY_CHUNKS; i++) {
501 struct mem_chunk *chunk = &memory_chunk[i];
502
503 real_size = max(real_size, chunk->addr + chunk->size);
504 if (chunk->addr >= max_mem) {
505 memset(chunk, 0, sizeof(*chunk));
506 continue;
507 }
508 if (chunk->addr + chunk->size > max_mem)
509 chunk->size = max_mem - chunk->addr;
510 memory_size = max(memory_size, chunk->addr + chunk->size);
511 }
512 if (!memory_end)
513 memory_end = memory_size;
514 if (real_size > memory_end)
515 printk("More memory detected than supported. Unused: %luk\n",
516 (real_size - memory_end) >> 10);
517}
518
492static void __init 519static void __init
493setup_memory(void) 520setup_memory(void)
494{ 521{
@@ -645,8 +672,6 @@ setup_arch(char **cmdline_p)
645 init_mm.end_data = (unsigned long) &_edata; 672 init_mm.end_data = (unsigned long) &_edata;
646 init_mm.brk = (unsigned long) &_end; 673 init_mm.brk = (unsigned long) &_end;
647 674
648 memory_end = memory_size;
649
650 if (MACHINE_HAS_MVCOS) 675 if (MACHINE_HAS_MVCOS)
651 memcpy(&uaccess, &uaccess_mvcos, sizeof(uaccess)); 676 memcpy(&uaccess, &uaccess_mvcos, sizeof(uaccess));
652 else 677 else
@@ -654,20 +679,7 @@ setup_arch(char **cmdline_p)
654 679
655 parse_early_param(); 680 parse_early_param();
656 681
657#ifndef CONFIG_64BIT 682 setup_memory_end();
658 memory_end &= ~0x400000UL;
659
660 /*
661 * We need some free virtual space to be able to do vmalloc.
662 * On a machine with 2GB memory we make sure that we have at
663 * least 128 MB free space for vmalloc.
664 */
665 if (memory_end > 1920*1024*1024)
666 memory_end = 1920*1024*1024;
667#else /* CONFIG_64BIT */
668 memory_end &= ~0x200000UL;
669#endif /* CONFIG_64BIT */
670
671 setup_memory(); 683 setup_memory();
672 setup_resources(); 684 setup_resources();
673 setup_lowcore(); 685 setup_lowcore();
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 62822245f9be..19090f7d4f51 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -230,18 +230,37 @@ static inline void do_store_status(void)
230 } 230 }
231} 231}
232 232
233static inline void do_wait_for_stop(void)
234{
235 int cpu;
236
237 /* Wait for all other cpus to enter stopped state */
238 for_each_online_cpu(cpu) {
239 if (cpu == smp_processor_id())
240 continue;
241 while(!smp_cpu_not_running(cpu))
242 cpu_relax();
243 }
244}
245
233/* 246/*
234 * this function sends a 'stop' sigp to all other CPUs in the system. 247 * this function sends a 'stop' sigp to all other CPUs in the system.
235 * it goes straight through. 248 * it goes straight through.
236 */ 249 */
237void smp_send_stop(void) 250void smp_send_stop(void)
238{ 251{
252 /* Disable all interrupts/machine checks */
253 __load_psw_mask(PSW_KERNEL_BITS & ~PSW_MASK_MCHECK);
254
239 /* write magic number to zero page (absolute 0) */ 255 /* write magic number to zero page (absolute 0) */
240 lowcore_ptr[smp_processor_id()]->panic_magic = __PANIC_MAGIC; 256 lowcore_ptr[smp_processor_id()]->panic_magic = __PANIC_MAGIC;
241 257
242 /* stop other processors. */ 258 /* stop other processors. */
243 do_send_stop(); 259 do_send_stop();
244 260
261 /* wait until other processors are stopped */
262 do_wait_for_stop();
263
245 /* store status of other processors. */ 264 /* store status of other processors. */
246 do_store_status(); 265 do_store_status();
247} 266}
@@ -250,88 +269,28 @@ void smp_send_stop(void)
250 * Reboot, halt and power_off routines for SMP. 269 * Reboot, halt and power_off routines for SMP.
251 */ 270 */
252 271
253static void do_machine_restart(void * __unused)
254{
255 int cpu;
256 static atomic_t cpuid = ATOMIC_INIT(-1);
257
258 if (atomic_cmpxchg(&cpuid, -1, smp_processor_id()) != -1)
259 signal_processor(smp_processor_id(), sigp_stop);
260
261 /* Wait for all other cpus to enter stopped state */
262 for_each_online_cpu(cpu) {
263 if (cpu == smp_processor_id())
264 continue;
265 while(!smp_cpu_not_running(cpu))
266 cpu_relax();
267 }
268
269 /* Store status of other cpus. */
270 do_store_status();
271
272 /*
273 * Finally call reipl. Because we waited for all other
274 * cpus to enter this function we know that they do
275 * not hold any s390irq-locks (the cpus have been
276 * interrupted by an external interrupt and s390irq
277 * locks are always held disabled).
278 */
279 do_reipl();
280}
281
282void machine_restart_smp(char * __unused) 272void machine_restart_smp(char * __unused)
283{ 273{
284 on_each_cpu(do_machine_restart, NULL, 0, 0); 274 smp_send_stop();
285} 275 do_reipl();
286
287static void do_wait_for_stop(void)
288{
289 unsigned long cr[16];
290
291 __ctl_store(cr, 0, 15);
292 cr[0] &= ~0xffff;
293 cr[6] = 0;
294 __ctl_load(cr, 0, 15);
295 for (;;)
296 enabled_wait();
297}
298
299static void do_machine_halt(void * __unused)
300{
301 static atomic_t cpuid = ATOMIC_INIT(-1);
302
303 if (atomic_cmpxchg(&cpuid, -1, smp_processor_id()) == -1) {
304 smp_send_stop();
305 if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0)
306 cpcmd(vmhalt_cmd, NULL, 0, NULL);
307 signal_processor(smp_processor_id(),
308 sigp_stop_and_store_status);
309 }
310 do_wait_for_stop();
311} 276}
312 277
313void machine_halt_smp(void) 278void machine_halt_smp(void)
314{ 279{
315 on_each_cpu(do_machine_halt, NULL, 0, 0); 280 smp_send_stop();
316} 281 if (MACHINE_IS_VM && strlen(vmhalt_cmd) > 0)
317 282 __cpcmd(vmhalt_cmd, NULL, 0, NULL);
318static void do_machine_power_off(void * __unused) 283 signal_processor(smp_processor_id(), sigp_stop_and_store_status);
319{ 284 for (;;);
320 static atomic_t cpuid = ATOMIC_INIT(-1);
321
322 if (atomic_cmpxchg(&cpuid, -1, smp_processor_id()) == -1) {
323 smp_send_stop();
324 if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0)
325 cpcmd(vmpoff_cmd, NULL, 0, NULL);
326 signal_processor(smp_processor_id(),
327 sigp_stop_and_store_status);
328 }
329 do_wait_for_stop();
330} 285}
331 286
332void machine_power_off_smp(void) 287void machine_power_off_smp(void)
333{ 288{
334 on_each_cpu(do_machine_power_off, NULL, 0, 0); 289 smp_send_stop();
290 if (MACHINE_IS_VM && strlen(vmpoff_cmd) > 0)
291 __cpcmd(vmpoff_cmd, NULL, 0, NULL);
292 signal_processor(smp_processor_id(), sigp_stop_and_store_status);
293 for (;;);
335} 294}
336 295
337/* 296/*
@@ -501,8 +460,6 @@ __init smp_count_cpus(void)
501 */ 460 */
502extern void init_cpu_timer(void); 461extern void init_cpu_timer(void);
503extern void init_cpu_vtimer(void); 462extern void init_cpu_vtimer(void);
504extern int pfault_init(void);
505extern void pfault_fini(void);
506 463
507int __devinit start_secondary(void *cpuvoid) 464int __devinit start_secondary(void *cpuvoid)
508{ 465{
@@ -514,11 +471,9 @@ int __devinit start_secondary(void *cpuvoid)
514#ifdef CONFIG_VIRT_TIMER 471#ifdef CONFIG_VIRT_TIMER
515 init_cpu_vtimer(); 472 init_cpu_vtimer();
516#endif 473#endif
517#ifdef CONFIG_PFAULT
518 /* Enable pfault pseudo page faults on this cpu. */ 474 /* Enable pfault pseudo page faults on this cpu. */
519 if (MACHINE_IS_VM) 475 pfault_init();
520 pfault_init(); 476
521#endif
522 /* Mark this cpu as online */ 477 /* Mark this cpu as online */
523 cpu_set(smp_processor_id(), cpu_online_map); 478 cpu_set(smp_processor_id(), cpu_online_map);
524 /* Switch on interrupts */ 479 /* Switch on interrupts */
@@ -708,11 +663,8 @@ __cpu_disable(void)
708 } 663 }
709 cpu_clear(cpu, cpu_online_map); 664 cpu_clear(cpu, cpu_online_map);
710 665
711#ifdef CONFIG_PFAULT
712 /* Disable pfault pseudo page faults on this cpu. */ 666 /* Disable pfault pseudo page faults on this cpu. */
713 if (MACHINE_IS_VM) 667 pfault_fini();
714 pfault_fini();
715#endif
716 668
717 memset(&cr_parms.orvals, 0, sizeof(cr_parms.orvals)); 669 memset(&cr_parms.orvals, 0, sizeof(cr_parms.orvals));
718 memset(&cr_parms.andvals, 0xff, sizeof(cr_parms.andvals)); 670 memset(&cr_parms.andvals, 0xff, sizeof(cr_parms.andvals));
@@ -860,4 +812,3 @@ EXPORT_SYMBOL(smp_ctl_clear_bit);
860EXPORT_SYMBOL(smp_call_function); 812EXPORT_SYMBOL(smp_call_function);
861EXPORT_SYMBOL(smp_get_cpu); 813EXPORT_SYMBOL(smp_get_cpu);
862EXPORT_SYMBOL(smp_put_cpu); 814EXPORT_SYMBOL(smp_put_cpu);
863
diff --git a/arch/s390/kernel/traps.c b/arch/s390/kernel/traps.c
index 92ecffbc8d82..3cbb0dcf1f1d 100644
--- a/arch/s390/kernel/traps.c
+++ b/arch/s390/kernel/traps.c
@@ -58,12 +58,6 @@ int sysctl_userprocess_debug = 0;
58 58
59extern pgm_check_handler_t do_protection_exception; 59extern pgm_check_handler_t do_protection_exception;
60extern pgm_check_handler_t do_dat_exception; 60extern pgm_check_handler_t do_dat_exception;
61#ifdef CONFIG_PFAULT
62extern int pfault_init(void);
63extern void pfault_fini(void);
64extern void pfault_interrupt(__u16 error_code);
65static ext_int_info_t ext_int_pfault;
66#endif
67extern pgm_check_handler_t do_monitor_call; 61extern pgm_check_handler_t do_monitor_call;
68 62
69#define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; }) 63#define stack_pointer ({ void **sp; asm("la %0,0(15)" : "=&d" (sp)); sp; })
@@ -135,7 +129,7 @@ __show_trace(unsigned long sp, unsigned long low, unsigned long high)
135 } 129 }
136} 130}
137 131
138void show_trace(struct task_struct *task, unsigned long * stack) 132void show_trace(struct task_struct *task, unsigned long *stack)
139{ 133{
140 register unsigned long __r15 asm ("15"); 134 register unsigned long __r15 asm ("15");
141 unsigned long sp; 135 unsigned long sp;
@@ -157,6 +151,9 @@ void show_trace(struct task_struct *task, unsigned long * stack)
157 __show_trace(sp, S390_lowcore.thread_info, 151 __show_trace(sp, S390_lowcore.thread_info,
158 S390_lowcore.thread_info + THREAD_SIZE); 152 S390_lowcore.thread_info + THREAD_SIZE);
159 printk("\n"); 153 printk("\n");
154 if (!task)
155 task = current;
156 debug_show_held_locks(task);
160} 157}
161 158
162void show_stack(struct task_struct *task, unsigned long *sp) 159void show_stack(struct task_struct *task, unsigned long *sp)
@@ -739,22 +736,5 @@ void __init trap_init(void)
739 pgm_check_table[0x1C] = &space_switch_exception; 736 pgm_check_table[0x1C] = &space_switch_exception;
740 pgm_check_table[0x1D] = &hfp_sqrt_exception; 737 pgm_check_table[0x1D] = &hfp_sqrt_exception;
741 pgm_check_table[0x40] = &do_monitor_call; 738 pgm_check_table[0x40] = &do_monitor_call;
742 739 pfault_irq_init();
743 if (MACHINE_IS_VM) {
744#ifdef CONFIG_PFAULT
745 /*
746 * Try to get pfault pseudo page faults going.
747 */
748 if (register_early_external_interrupt(0x2603, pfault_interrupt,
749 &ext_int_pfault) != 0)
750 panic("Couldn't request external interrupt 0x2603");
751
752 if (pfault_init() == 0)
753 return;
754
755 /* Tough luck, no pfault. */
756 unregister_early_external_interrupt(0x2603, pfault_interrupt,
757 &ext_int_pfault);
758#endif
759 }
760} 740}
diff --git a/arch/s390/lib/Makefile b/arch/s390/lib/Makefile
index b0cfa6c4883d..b5f94cf3bde8 100644
--- a/arch/s390/lib/Makefile
+++ b/arch/s390/lib/Makefile
@@ -4,7 +4,7 @@
4 4
5EXTRA_AFLAGS := -traditional 5EXTRA_AFLAGS := -traditional
6 6
7lib-y += delay.o string.o uaccess_std.o 7lib-y += delay.o string.o uaccess_std.o uaccess_pt.o
8lib-$(CONFIG_32BIT) += div64.o 8lib-$(CONFIG_32BIT) += div64.o
9lib-$(CONFIG_64BIT) += uaccess_mvcos.o 9lib-$(CONFIG_64BIT) += uaccess_mvcos.o
10lib-$(CONFIG_SMP) += spinlock.o 10lib-$(CONFIG_SMP) += spinlock.o
diff --git a/arch/s390/lib/uaccess_mvcos.c b/arch/s390/lib/uaccess_mvcos.c
index 121b2935a422..f9a23d57eb79 100644
--- a/arch/s390/lib/uaccess_mvcos.c
+++ b/arch/s390/lib/uaccess_mvcos.c
@@ -27,6 +27,9 @@
27#define SLR "slgr" 27#define SLR "slgr"
28#endif 28#endif
29 29
30extern size_t copy_from_user_std(size_t, const void __user *, void *);
31extern size_t copy_to_user_std(size_t, void __user *, const void *);
32
30size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x) 33size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x)
31{ 34{
32 register unsigned long reg0 asm("0") = 0x81UL; 35 register unsigned long reg0 asm("0") = 0x81UL;
@@ -66,6 +69,13 @@ size_t copy_from_user_mvcos(size_t size, const void __user *ptr, void *x)
66 return size; 69 return size;
67} 70}
68 71
72size_t copy_from_user_mvcos_check(size_t size, const void __user *ptr, void *x)
73{
74 if (size <= 256)
75 return copy_from_user_std(size, ptr, x);
76 return copy_from_user_mvcos(size, ptr, x);
77}
78
69size_t copy_to_user_mvcos(size_t size, void __user *ptr, const void *x) 79size_t copy_to_user_mvcos(size_t size, void __user *ptr, const void *x)
70{ 80{
71 register unsigned long reg0 asm("0") = 0x810000UL; 81 register unsigned long reg0 asm("0") = 0x810000UL;
@@ -95,6 +105,13 @@ size_t copy_to_user_mvcos(size_t size, void __user *ptr, const void *x)
95 return size; 105 return size;
96} 106}
97 107
108size_t copy_to_user_mvcos_check(size_t size, void __user *ptr, const void *x)
109{
110 if (size <= 256)
111 return copy_to_user_std(size, ptr, x);
112 return copy_to_user_mvcos(size, ptr, x);
113}
114
98size_t copy_in_user_mvcos(size_t size, void __user *to, const void __user *from) 115size_t copy_in_user_mvcos(size_t size, void __user *to, const void __user *from)
99{ 116{
100 register unsigned long reg0 asm("0") = 0x810081UL; 117 register unsigned long reg0 asm("0") = 0x810081UL;
@@ -145,18 +162,16 @@ size_t clear_user_mvcos(size_t size, void __user *to)
145 return size; 162 return size;
146} 163}
147 164
148extern size_t copy_from_user_std_small(size_t, const void __user *, void *);
149extern size_t copy_to_user_std_small(size_t, void __user *, const void *);
150extern size_t strnlen_user_std(size_t, const char __user *); 165extern size_t strnlen_user_std(size_t, const char __user *);
151extern size_t strncpy_from_user_std(size_t, const char __user *, char *); 166extern size_t strncpy_from_user_std(size_t, const char __user *, char *);
152extern int futex_atomic_op(int, int __user *, int, int *); 167extern int futex_atomic_op(int, int __user *, int, int *);
153extern int futex_atomic_cmpxchg(int __user *, int, int); 168extern int futex_atomic_cmpxchg(int __user *, int, int);
154 169
155struct uaccess_ops uaccess_mvcos = { 170struct uaccess_ops uaccess_mvcos = {
156 .copy_from_user = copy_from_user_mvcos, 171 .copy_from_user = copy_from_user_mvcos_check,
157 .copy_from_user_small = copy_from_user_std_small, 172 .copy_from_user_small = copy_from_user_std,
158 .copy_to_user = copy_to_user_mvcos, 173 .copy_to_user = copy_to_user_mvcos_check,
159 .copy_to_user_small = copy_to_user_std_small, 174 .copy_to_user_small = copy_to_user_std,
160 .copy_in_user = copy_in_user_mvcos, 175 .copy_in_user = copy_in_user_mvcos,
161 .clear_user = clear_user_mvcos, 176 .clear_user = clear_user_mvcos,
162 .strnlen_user = strnlen_user_std, 177 .strnlen_user = strnlen_user_std,
diff --git a/arch/s390/lib/uaccess_pt.c b/arch/s390/lib/uaccess_pt.c
new file mode 100644
index 000000000000..8741bdc09299
--- /dev/null
+++ b/arch/s390/lib/uaccess_pt.c
@@ -0,0 +1,153 @@
1/*
2 * arch/s390/lib/uaccess_pt.c
3 *
4 * User access functions based on page table walks.
5 *
6 * Copyright IBM Corp. 2006
7 * Author(s): Gerald Schaefer (gerald.schaefer@de.ibm.com)
8 */
9
10#include <linux/errno.h>
11#include <asm/uaccess.h>
12#include <linux/mm.h>
13#include <asm/futex.h>
14
15static inline int __handle_fault(struct mm_struct *mm, unsigned long address,
16 int write_access)
17{
18 struct vm_area_struct *vma;
19 int ret = -EFAULT;
20
21 down_read(&mm->mmap_sem);
22 vma = find_vma(mm, address);
23 if (unlikely(!vma))
24 goto out;
25 if (unlikely(vma->vm_start > address)) {
26 if (!(vma->vm_flags & VM_GROWSDOWN))
27 goto out;
28 if (expand_stack(vma, address))
29 goto out;
30 }
31
32 if (!write_access) {
33 /* page not present, check vm flags */
34 if (!(vma->vm_flags & (VM_READ | VM_EXEC | VM_WRITE)))
35 goto out;
36 } else {
37 if (!(vma->vm_flags & VM_WRITE))
38 goto out;
39 }
40
41survive:
42 switch (handle_mm_fault(mm, vma, address, write_access)) {
43 case VM_FAULT_MINOR:
44 current->min_flt++;
45 break;
46 case VM_FAULT_MAJOR:
47 current->maj_flt++;
48 break;
49 case VM_FAULT_SIGBUS:
50 goto out_sigbus;
51 case VM_FAULT_OOM:
52 goto out_of_memory;
53 default:
54 BUG();
55 }
56 ret = 0;
57out:
58 up_read(&mm->mmap_sem);
59 return ret;
60
61out_of_memory:
62 up_read(&mm->mmap_sem);
63 if (current->pid == 1) {
64 yield();
65 goto survive;
66 }
67 printk("VM: killing process %s\n", current->comm);
68 return ret;
69
70out_sigbus:
71 up_read(&mm->mmap_sem);
72 current->thread.prot_addr = address;
73 current->thread.trap_no = 0x11;
74 force_sig(SIGBUS, current);
75 return ret;
76}
77
78static inline size_t __user_copy_pt(unsigned long uaddr, void *kptr,
79 size_t n, int write_user)
80{
81 struct mm_struct *mm = current->mm;
82 unsigned long offset, pfn, done, size;
83 pgd_t *pgd;
84 pmd_t *pmd;
85 pte_t *pte;
86 void *from, *to;
87
88 done = 0;
89retry:
90 spin_lock(&mm->page_table_lock);
91 do {
92 pgd = pgd_offset(mm, uaddr);
93 if (pgd_none(*pgd) || unlikely(pgd_bad(*pgd)))
94 goto fault;
95
96 pmd = pmd_offset(pgd, uaddr);
97 if (pmd_none(*pmd) || unlikely(pmd_bad(*pmd)))
98 goto fault;
99
100 pte = pte_offset_map(pmd, uaddr);
101 if (!pte || !pte_present(*pte) ||
102 (write_user && !pte_write(*pte)))
103 goto fault;
104
105 pfn = pte_pfn(*pte);
106 if (!pfn_valid(pfn))
107 goto out;
108
109 offset = uaddr & (PAGE_SIZE - 1);
110 size = min(n - done, PAGE_SIZE - offset);
111 if (write_user) {
112 to = (void *)((pfn << PAGE_SHIFT) + offset);
113 from = kptr + done;
114 } else {
115 from = (void *)((pfn << PAGE_SHIFT) + offset);
116 to = kptr + done;
117 }
118 memcpy(to, from, size);
119 done += size;
120 uaddr += size;
121 } while (done < n);
122out:
123 spin_unlock(&mm->page_table_lock);
124 return n - done;
125fault:
126 spin_unlock(&mm->page_table_lock);
127 if (__handle_fault(mm, uaddr, write_user))
128 return n - done;
129 goto retry;
130}
131
132size_t copy_from_user_pt(size_t n, const void __user *from, void *to)
133{
134 size_t rc;
135
136 if (segment_eq(get_fs(), KERNEL_DS)) {
137 memcpy(to, (void __kernel __force *) from, n);
138 return 0;
139 }
140 rc = __user_copy_pt((unsigned long) from, to, n, 0);
141 if (unlikely(rc))
142 memset(to + n - rc, 0, rc);
143 return rc;
144}
145
146size_t copy_to_user_pt(size_t n, void __user *to, const void *from)
147{
148 if (segment_eq(get_fs(), KERNEL_DS)) {
149 memcpy((void __kernel __force *) to, from, n);
150 return 0;
151 }
152 return __user_copy_pt((unsigned long) to, (void *) from, n, 1);
153}
diff --git a/arch/s390/lib/uaccess_std.c b/arch/s390/lib/uaccess_std.c
index f44f0078b354..2d549ed2e113 100644
--- a/arch/s390/lib/uaccess_std.c
+++ b/arch/s390/lib/uaccess_std.c
@@ -28,6 +28,9 @@
28#define SLR "slgr" 28#define SLR "slgr"
29#endif 29#endif
30 30
31extern size_t copy_from_user_pt(size_t n, const void __user *from, void *to);
32extern size_t copy_to_user_pt(size_t n, void __user *to, const void *from);
33
31size_t copy_from_user_std(size_t size, const void __user *ptr, void *x) 34size_t copy_from_user_std(size_t size, const void __user *ptr, void *x)
32{ 35{
33 unsigned long tmp1, tmp2; 36 unsigned long tmp1, tmp2;
@@ -69,34 +72,11 @@ size_t copy_from_user_std(size_t size, const void __user *ptr, void *x)
69 return size; 72 return size;
70} 73}
71 74
72size_t copy_from_user_std_small(size_t size, const void __user *ptr, void *x) 75size_t copy_from_user_std_check(size_t size, const void __user *ptr, void *x)
73{ 76{
74 unsigned long tmp1, tmp2; 77 if (size <= 1024)
75 78 return copy_from_user_std(size, ptr, x);
76 tmp1 = 0UL; 79 return copy_from_user_pt(size, ptr, x);
77 asm volatile(
78 "0: mvcp 0(%0,%2),0(%1),%3\n"
79 " "SLR" %0,%0\n"
80 " j 5f\n"
81 "1: la %4,255(%1)\n" /* %4 = ptr + 255 */
82 " "LHI" %3,-4096\n"
83 " nr %4,%3\n" /* %4 = (ptr + 255) & -4096 */
84 " "SLR" %4,%1\n"
85 " "CLR" %0,%4\n" /* copy crosses next page boundary? */
86 " jnh 5f\n"
87 "2: mvcp 0(%4,%2),0(%1),%3\n"
88 " "SLR" %0,%4\n"
89 " "ALR" %2,%4\n"
90 "3:"LHI" %4,-1\n"
91 " "ALR" %4,%0\n" /* copy remaining size, subtract 1 */
92 " bras %3,4f\n"
93 " xc 0(1,%2),0(%2)\n"
94 "4: ex %4,0(%3)\n"
95 "5:\n"
96 EX_TABLE(0b,1b) EX_TABLE(2b,3b)
97 : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
98 : : "cc", "memory");
99 return size;
100} 80}
101 81
102size_t copy_to_user_std(size_t size, void __user *ptr, const void *x) 82size_t copy_to_user_std(size_t size, void __user *ptr, const void *x)
@@ -130,28 +110,11 @@ size_t copy_to_user_std(size_t size, void __user *ptr, const void *x)
130 return size; 110 return size;
131} 111}
132 112
133size_t copy_to_user_std_small(size_t size, void __user *ptr, const void *x) 113size_t copy_to_user_std_check(size_t size, void __user *ptr, const void *x)
134{ 114{
135 unsigned long tmp1, tmp2; 115 if (size <= 1024)
136 116 return copy_to_user_std(size, ptr, x);
137 tmp1 = 0UL; 117 return copy_to_user_pt(size, ptr, x);
138 asm volatile(
139 "0: mvcs 0(%0,%1),0(%2),%3\n"
140 " "SLR" %0,%0\n"
141 " j 3f\n"
142 "1: la %4,255(%1)\n" /* ptr + 255 */
143 " "LHI" %3,-4096\n"
144 " nr %4,%3\n" /* (ptr + 255) & -4096UL */
145 " "SLR" %4,%1\n"
146 " "CLR" %0,%4\n" /* copy crosses next page boundary? */
147 " jnh 3f\n"
148 "2: mvcs 0(%4,%1),0(%2),%3\n"
149 " "SLR" %0,%4\n"
150 "3:\n"
151 EX_TABLE(0b,1b) EX_TABLE(2b,3b)
152 : "+a" (size), "+a" (ptr), "+a" (x), "+a" (tmp1), "=a" (tmp2)
153 : : "cc", "memory");
154 return size;
155} 118}
156 119
157size_t copy_in_user_std(size_t size, void __user *to, const void __user *from) 120size_t copy_in_user_std(size_t size, void __user *to, const void __user *from)
@@ -343,10 +306,10 @@ int futex_atomic_cmpxchg(int __user *uaddr, int oldval, int newval)
343} 306}
344 307
345struct uaccess_ops uaccess_std = { 308struct uaccess_ops uaccess_std = {
346 .copy_from_user = copy_from_user_std, 309 .copy_from_user = copy_from_user_std_check,
347 .copy_from_user_small = copy_from_user_std_small, 310 .copy_from_user_small = copy_from_user_std,
348 .copy_to_user = copy_to_user_std, 311 .copy_to_user = copy_to_user_std_check,
349 .copy_to_user_small = copy_to_user_std_small, 312 .copy_to_user_small = copy_to_user_std,
350 .copy_in_user = copy_in_user_std, 313 .copy_in_user = copy_in_user_std,
351 .clear_user = clear_user_std, 314 .clear_user = clear_user_std,
352 .strnlen_user = strnlen_user_std, 315 .strnlen_user = strnlen_user_std,
diff --git a/arch/s390/mm/extmem.c b/arch/s390/mm/extmem.c
index 226275d5c4f6..9e9bc48463a5 100644
--- a/arch/s390/mm/extmem.c
+++ b/arch/s390/mm/extmem.c
@@ -14,12 +14,13 @@
14#include <linux/slab.h> 14#include <linux/slab.h>
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/bootmem.h> 16#include <linux/bootmem.h>
17#include <linux/ctype.h>
17#include <asm/page.h> 18#include <asm/page.h>
18#include <asm/ebcdic.h> 19#include <asm/ebcdic.h>
19#include <asm/errno.h> 20#include <asm/errno.h>
20#include <asm/extmem.h> 21#include <asm/extmem.h>
21#include <asm/cpcmd.h> 22#include <asm/cpcmd.h>
22#include <linux/ctype.h> 23#include <asm/setup.h>
23 24
24#define DCSS_DEBUG /* Debug messages on/off */ 25#define DCSS_DEBUG /* Debug messages on/off */
25 26
@@ -77,15 +78,11 @@ struct dcss_segment {
77 int segcnt; 78 int segcnt;
78}; 79};
79 80
80static DEFINE_SPINLOCK(dcss_lock); 81static DEFINE_MUTEX(dcss_lock);
81static struct list_head dcss_list = LIST_HEAD_INIT(dcss_list); 82static struct list_head dcss_list = LIST_HEAD_INIT(dcss_list);
82static char *segtype_string[] = { "SW", "EW", "SR", "ER", "SN", "EN", "SC", 83static char *segtype_string[] = { "SW", "EW", "SR", "ER", "SN", "EN", "SC",
83 "EW/EN-MIXED" }; 84 "EW/EN-MIXED" };
84 85
85extern struct {
86 unsigned long addr, size, type;
87} memory_chunk[MEMORY_CHUNKS];
88
89/* 86/*
90 * Create the 8 bytes, ebcdic VM segment name from 87 * Create the 8 bytes, ebcdic VM segment name from
91 * an ascii name. 88 * an ascii name.
@@ -117,7 +114,7 @@ segment_by_name (char *name)
117 struct list_head *l; 114 struct list_head *l;
118 struct dcss_segment *tmp, *retval = NULL; 115 struct dcss_segment *tmp, *retval = NULL;
119 116
120 assert_spin_locked(&dcss_lock); 117 BUG_ON(!mutex_is_locked(&dcss_lock));
121 dcss_mkname (name, dcss_name); 118 dcss_mkname (name, dcss_name);
122 list_for_each (l, &dcss_list) { 119 list_for_each (l, &dcss_list) {
123 tmp = list_entry (l, struct dcss_segment, list); 120 tmp = list_entry (l, struct dcss_segment, list);
@@ -249,8 +246,8 @@ segment_overlaps_storage(struct dcss_segment *seg)
249{ 246{
250 int i; 247 int i;
251 248
252 for (i=0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) { 249 for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) {
253 if (memory_chunk[i].type != 0) 250 if (memory_chunk[i].type != CHUNK_READ_WRITE)
254 continue; 251 continue;
255 if ((memory_chunk[i].addr >> 20) > (seg->end >> 20)) 252 if ((memory_chunk[i].addr >> 20) > (seg->end >> 20))
256 continue; 253 continue;
@@ -272,7 +269,7 @@ segment_overlaps_others (struct dcss_segment *seg)
272 struct list_head *l; 269 struct list_head *l;
273 struct dcss_segment *tmp; 270 struct dcss_segment *tmp;
274 271
275 assert_spin_locked(&dcss_lock); 272 BUG_ON(!mutex_is_locked(&dcss_lock));
276 list_for_each(l, &dcss_list) { 273 list_for_each(l, &dcss_list) {
277 tmp = list_entry(l, struct dcss_segment, list); 274 tmp = list_entry(l, struct dcss_segment, list);
278 if ((tmp->start_addr >> 20) > (seg->end >> 20)) 275 if ((tmp->start_addr >> 20) > (seg->end >> 20))
@@ -429,7 +426,7 @@ segment_load (char *name, int do_nonshared, unsigned long *addr,
429 if (!MACHINE_IS_VM) 426 if (!MACHINE_IS_VM)
430 return -ENOSYS; 427 return -ENOSYS;
431 428
432 spin_lock (&dcss_lock); 429 mutex_lock(&dcss_lock);
433 seg = segment_by_name (name); 430 seg = segment_by_name (name);
434 if (seg == NULL) 431 if (seg == NULL)
435 rc = __segment_load (name, do_nonshared, addr, end); 432 rc = __segment_load (name, do_nonshared, addr, end);
@@ -444,7 +441,7 @@ segment_load (char *name, int do_nonshared, unsigned long *addr,
444 rc = -EPERM; 441 rc = -EPERM;
445 } 442 }
446 } 443 }
447 spin_unlock (&dcss_lock); 444 mutex_unlock(&dcss_lock);
448 return rc; 445 return rc;
449} 446}
450 447
@@ -467,7 +464,7 @@ segment_modify_shared (char *name, int do_nonshared)
467 unsigned long dummy; 464 unsigned long dummy;
468 int dcss_command, rc, diag_cc; 465 int dcss_command, rc, diag_cc;
469 466
470 spin_lock (&dcss_lock); 467 mutex_lock(&dcss_lock);
471 seg = segment_by_name (name); 468 seg = segment_by_name (name);
472 if (seg == NULL) { 469 if (seg == NULL) {
473 rc = -EINVAL; 470 rc = -EINVAL;
@@ -508,7 +505,7 @@ segment_modify_shared (char *name, int do_nonshared)
508 &dummy, &dummy); 505 &dummy, &dummy);
509 kfree(seg); 506 kfree(seg);
510 out_unlock: 507 out_unlock:
511 spin_unlock(&dcss_lock); 508 mutex_unlock(&dcss_lock);
512 return rc; 509 return rc;
513} 510}
514 511
@@ -526,7 +523,7 @@ segment_unload(char *name)
526 if (!MACHINE_IS_VM) 523 if (!MACHINE_IS_VM)
527 return; 524 return;
528 525
529 spin_lock(&dcss_lock); 526 mutex_lock(&dcss_lock);
530 seg = segment_by_name (name); 527 seg = segment_by_name (name);
531 if (seg == NULL) { 528 if (seg == NULL) {
532 PRINT_ERR ("could not find segment %s in segment_unload, " 529 PRINT_ERR ("could not find segment %s in segment_unload, "
@@ -540,7 +537,7 @@ segment_unload(char *name)
540 kfree(seg); 537 kfree(seg);
541 } 538 }
542out_unlock: 539out_unlock:
543 spin_unlock(&dcss_lock); 540 mutex_unlock(&dcss_lock);
544} 541}
545 542
546/* 543/*
@@ -559,12 +556,13 @@ segment_save(char *name)
559 if (!MACHINE_IS_VM) 556 if (!MACHINE_IS_VM)
560 return; 557 return;
561 558
562 spin_lock(&dcss_lock); 559 mutex_lock(&dcss_lock);
563 seg = segment_by_name (name); 560 seg = segment_by_name (name);
564 561
565 if (seg == NULL) { 562 if (seg == NULL) {
566 PRINT_ERR ("could not find segment %s in segment_save, please report to linux390@de.ibm.com\n",name); 563 PRINT_ERR("could not find segment %s in segment_save, please "
567 return; 564 "report to linux390@de.ibm.com\n", name);
565 goto out;
568 } 566 }
569 567
570 startpfn = seg->start_addr >> PAGE_SHIFT; 568 startpfn = seg->start_addr >> PAGE_SHIFT;
@@ -591,7 +589,7 @@ segment_save(char *name)
591 goto out; 589 goto out;
592 } 590 }
593out: 591out:
594 spin_unlock(&dcss_lock); 592 mutex_unlock(&dcss_lock);
595} 593}
596 594
597EXPORT_SYMBOL(segment_load); 595EXPORT_SYMBOL(segment_load);
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 1c323bbfda91..cd85e34d8703 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -31,6 +31,7 @@
31#include <asm/uaccess.h> 31#include <asm/uaccess.h>
32#include <asm/pgtable.h> 32#include <asm/pgtable.h>
33#include <asm/kdebug.h> 33#include <asm/kdebug.h>
34#include <asm/s390_ext.h>
34 35
35#ifndef CONFIG_64BIT 36#ifndef CONFIG_64BIT
36#define __FAIL_ADDR_MASK 0x7ffff000 37#define __FAIL_ADDR_MASK 0x7ffff000
@@ -394,6 +395,7 @@ void do_dat_exception(struct pt_regs *regs, unsigned long error_code)
394/* 395/*
395 * 'pfault' pseudo page faults routines. 396 * 'pfault' pseudo page faults routines.
396 */ 397 */
398static ext_int_info_t ext_int_pfault;
397static int pfault_disable = 0; 399static int pfault_disable = 0;
398 400
399static int __init nopfault(char *str) 401static int __init nopfault(char *str)
@@ -422,7 +424,7 @@ int pfault_init(void)
422 __PF_RES_FIELD }; 424 __PF_RES_FIELD };
423 int rc; 425 int rc;
424 426
425 if (pfault_disable) 427 if (!MACHINE_IS_VM || pfault_disable)
426 return -1; 428 return -1;
427 asm volatile( 429 asm volatile(
428 " diag %1,%0,0x258\n" 430 " diag %1,%0,0x258\n"
@@ -440,7 +442,7 @@ void pfault_fini(void)
440 pfault_refbk_t refbk = 442 pfault_refbk_t refbk =
441 { 0x258, 1, 5, 2, 0ULL, 0ULL, 0ULL, 0ULL }; 443 { 0x258, 1, 5, 2, 0ULL, 0ULL, 0ULL, 0ULL };
442 444
443 if (pfault_disable) 445 if (!MACHINE_IS_VM || pfault_disable)
444 return; 446 return;
445 __ctl_clear_bit(0,9); 447 __ctl_clear_bit(0,9);
446 asm volatile( 448 asm volatile(
@@ -500,5 +502,25 @@ pfault_interrupt(__u16 error_code)
500 set_tsk_need_resched(tsk); 502 set_tsk_need_resched(tsk);
501 } 503 }
502} 504}
503#endif
504 505
506void __init pfault_irq_init(void)
507{
508 if (!MACHINE_IS_VM)
509 return;
510
511 /*
512 * Try to get pfault pseudo page faults going.
513 */
514 if (register_early_external_interrupt(0x2603, pfault_interrupt,
515 &ext_int_pfault) != 0)
516 panic("Couldn't request external interrupt 0x2603");
517
518 if (pfault_init() == 0)
519 return;
520
521 /* Tough luck, no pfault. */
522 pfault_disable = 1;
523 unregister_early_external_interrupt(0x2603, pfault_interrupt,
524 &ext_int_pfault);
525}
526#endif
diff --git a/block/Kconfig b/block/Kconfig
index 83766a6bdee2..a50f48111647 100644
--- a/block/Kconfig
+++ b/block/Kconfig
@@ -19,11 +19,9 @@ config BLOCK
19 19
20if BLOCK 20if BLOCK
21 21
22#XXX - it makes sense to enable this only for 32-bit subarch's, not for x86_64
23#for instance.
24config LBD 22config LBD
25 bool "Support for Large Block Devices" 23 bool "Support for Large Block Devices"
26 depends on X86 || (MIPS && 32BIT) || PPC32 || (S390 && !64BIT) || SUPERH || UML 24 depends on !64BIT
27 help 25 help
28 Say Y here if you want to attach large (bigger than 2TB) discs to 26 Say Y here if you want to attach large (bigger than 2TB) discs to
29 your machine, or if you want to have a raid or loopback device 27 your machine, or if you want to have a raid or loopback device
@@ -44,7 +42,7 @@ config BLK_DEV_IO_TRACE
44 42
45config LSF 43config LSF
46 bool "Support for Large Single Files" 44 bool "Support for Large Single Files"
47 depends on X86 || (MIPS && 32BIT) || PPC32 || ARCH_S390_31 || SUPERH || UML 45 depends on !64BIT
48 help 46 help
49 Say Y here if you want to be able to handle very large files (bigger 47 Say Y here if you want to be able to handle very large files (bigger
50 than 2TB), otherwise say N. 48 than 2TB), otherwise say N.
diff --git a/block/blktrace.c b/block/blktrace.c
index 562ca7cbf858..74e02c04b2da 100644
--- a/block/blktrace.c
+++ b/block/blktrace.c
@@ -31,26 +31,24 @@ static unsigned int blktrace_seq __read_mostly = 1;
31/* 31/*
32 * Send out a notify message. 32 * Send out a notify message.
33 */ 33 */
34static inline unsigned int trace_note(struct blk_trace *bt, 34static void trace_note(struct blk_trace *bt, pid_t pid, int action,
35 pid_t pid, int action, 35 const void *data, size_t len)
36 const void *data, size_t len)
37{ 36{
38 struct blk_io_trace *t; 37 struct blk_io_trace *t;
39 int cpu = smp_processor_id();
40 38
41 t = relay_reserve(bt->rchan, sizeof(*t) + len); 39 t = relay_reserve(bt->rchan, sizeof(*t) + len);
42 if (t == NULL) 40 if (t) {
43 return 0; 41 const int cpu = smp_processor_id();
44 42
45 t->magic = BLK_IO_TRACE_MAGIC | BLK_IO_TRACE_VERSION; 43 t->magic = BLK_IO_TRACE_MAGIC | BLK_IO_TRACE_VERSION;
46 t->time = sched_clock() - per_cpu(blk_trace_cpu_offset, cpu); 44 t->time = sched_clock() - per_cpu(blk_trace_cpu_offset, cpu);
47 t->device = bt->dev; 45 t->device = bt->dev;
48 t->action = action; 46 t->action = action;
49 t->pid = pid; 47 t->pid = pid;
50 t->cpu = cpu; 48 t->cpu = cpu;
51 t->pdu_len = len; 49 t->pdu_len = len;
52 memcpy((void *) t + sizeof(*t), data, len); 50 memcpy((void *) t + sizeof(*t), data, len);
53 return blktrace_seq; 51 }
54} 52}
55 53
56/* 54/*
@@ -59,9 +57,8 @@ static inline unsigned int trace_note(struct blk_trace *bt,
59 */ 57 */
60static void trace_note_tsk(struct blk_trace *bt, struct task_struct *tsk) 58static void trace_note_tsk(struct blk_trace *bt, struct task_struct *tsk)
61{ 59{
62 tsk->btrace_seq = trace_note(bt, tsk->pid, 60 tsk->btrace_seq = blktrace_seq;
63 BLK_TN_PROCESS, 61 trace_note(bt, tsk->pid, BLK_TN_PROCESS, tsk->comm, sizeof(tsk->comm));
64 tsk->comm, sizeof(tsk->comm));
65} 62}
66 63
67static void trace_note_time(struct blk_trace *bt) 64static void trace_note_time(struct blk_trace *bt)
diff --git a/drivers/Makefile b/drivers/Makefile
index 4ac14dab3079..67711770b1d9 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -77,3 +77,4 @@ obj-$(CONFIG_CRYPTO) += crypto/
77obj-$(CONFIG_SUPERH) += sh/ 77obj-$(CONFIG_SUPERH) += sh/
78obj-$(CONFIG_GENERIC_TIME) += clocksource/ 78obj-$(CONFIG_GENERIC_TIME) += clocksource/
79obj-$(CONFIG_DMA_ENGINE) += dma/ 79obj-$(CONFIG_DMA_ENGINE) += dma/
80obj-$(CONFIG_PPC_PS3) += ps3/
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 578b99b71d9c..bf5b79ed3613 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -27,6 +27,7 @@
27#include <linux/init.h> 27#include <linux/init.h>
28#include <linux/types.h> 28#include <linux/types.h>
29#include <linux/notifier.h> 29#include <linux/notifier.h>
30#include <linux/jiffies.h>
30#include <acpi/acpi_bus.h> 31#include <acpi/acpi_bus.h>
31#include <acpi/acpi_drivers.h> 32#include <acpi/acpi_drivers.h>
32 33
diff --git a/drivers/ata/Kconfig b/drivers/ata/Kconfig
index 03f6338acc8f..984ab284382a 100644
--- a/drivers/ata/Kconfig
+++ b/drivers/ata/Kconfig
@@ -328,6 +328,15 @@ config PATA_TRIFLEX
328 328
329 If unsure, say N. 329 If unsure, say N.
330 330
331config PATA_MARVELL
332 tristate "Marvell PATA support via legacy mode"
333 depends on PCI
334 help
335 This option enables limited support for the Marvell 88SE6145 ATA
336 controller.
337
338 If unsure, say N.
339
331config PATA_MPIIX 340config PATA_MPIIX
332 tristate "Intel PATA MPIIX support" 341 tristate "Intel PATA MPIIX support"
333 depends on PCI 342 depends on PCI
@@ -483,6 +492,32 @@ config PATA_WINBOND
483 492
484 If unsure, say N. 493 If unsure, say N.
485 494
495config PATA_WINBOND_VLB
496 tristate "Winbond W83759A VLB PATA support (Experimental)"
497 depends on ISA && EXPERIMENTAL
498 help
499 Support for the Winbond W83759A controller on Vesa Local Bus
500 systems.
501
502config PATA_PLATFORM
503 tristate "Generic platform device PATA support"
504 depends on EMBEDDED
505 help
506 This option enables support for generic directly connected ATA
507 devices commonly found on embedded systems.
508
509 If unsure, say N.
510
511config PATA_IXP4XX_CF
512 tristate "IXP4XX Compact Flash support"
513 depends on ARCH_IXP4XX
514 help
515 This option enables support for a Compact Flash connected on
516 the ixp4xx expansion bus. This driver had been written for
517 Loft/Avila boards in mind but can work with others.
518
519 If unsure, say N.
520
486endif 521endif
487endmenu 522endmenu
488 523
diff --git a/drivers/ata/Makefile b/drivers/ata/Makefile
index 72243a677f9b..bc3d81ae757e 100644
--- a/drivers/ata/Makefile
+++ b/drivers/ata/Makefile
@@ -38,6 +38,7 @@ obj-$(CONFIG_PATA_NETCELL) += pata_netcell.o
38obj-$(CONFIG_PATA_NS87410) += pata_ns87410.o 38obj-$(CONFIG_PATA_NS87410) += pata_ns87410.o
39obj-$(CONFIG_PATA_OPTI) += pata_opti.o 39obj-$(CONFIG_PATA_OPTI) += pata_opti.o
40obj-$(CONFIG_PATA_OPTIDMA) += pata_optidma.o 40obj-$(CONFIG_PATA_OPTIDMA) += pata_optidma.o
41obj-$(CONFIG_PATA_MARVELL) += pata_marvell.o
41obj-$(CONFIG_PATA_MPIIX) += pata_mpiix.o 42obj-$(CONFIG_PATA_MPIIX) += pata_mpiix.o
42obj-$(CONFIG_PATA_OLDPIIX) += pata_oldpiix.o 43obj-$(CONFIG_PATA_OLDPIIX) += pata_oldpiix.o
43obj-$(CONFIG_PATA_PCMCIA) += pata_pcmcia.o 44obj-$(CONFIG_PATA_PCMCIA) += pata_pcmcia.o
@@ -51,8 +52,11 @@ obj-$(CONFIG_PATA_SERVERWORKS) += pata_serverworks.o
51obj-$(CONFIG_PATA_SIL680) += pata_sil680.o 52obj-$(CONFIG_PATA_SIL680) += pata_sil680.o
52obj-$(CONFIG_PATA_VIA) += pata_via.o 53obj-$(CONFIG_PATA_VIA) += pata_via.o
53obj-$(CONFIG_PATA_WINBOND) += pata_sl82c105.o 54obj-$(CONFIG_PATA_WINBOND) += pata_sl82c105.o
55obj-$(CONFIG_PATA_WINBOND_VLB) += pata_winbond.o
54obj-$(CONFIG_PATA_SIS) += pata_sis.o 56obj-$(CONFIG_PATA_SIS) += pata_sis.o
55obj-$(CONFIG_PATA_TRIFLEX) += pata_triflex.o 57obj-$(CONFIG_PATA_TRIFLEX) += pata_triflex.o
58obj-$(CONFIG_PATA_IXP4XX_CF) += pata_ixp4xx_cf.o
59obj-$(CONFIG_PATA_PLATFORM) += pata_platform.o
56# Should be last but one libata driver 60# Should be last but one libata driver
57obj-$(CONFIG_ATA_GENERIC) += ata_generic.o 61obj-$(CONFIG_ATA_GENERIC) += ata_generic.o
58# Should be last libata driver 62# Should be last libata driver
diff --git a/drivers/ata/ahci.c b/drivers/ata/ahci.c
index bddb14e91d3c..f36da488a2c1 100644
--- a/drivers/ata/ahci.c
+++ b/drivers/ata/ahci.c
@@ -53,6 +53,7 @@
53 53
54enum { 54enum {
55 AHCI_PCI_BAR = 5, 55 AHCI_PCI_BAR = 5,
56 AHCI_MAX_PORTS = 32,
56 AHCI_MAX_SG = 168, /* hardware max is 64K */ 57 AHCI_MAX_SG = 168, /* hardware max is 64K */
57 AHCI_DMA_BOUNDARY = 0xffffffff, 58 AHCI_DMA_BOUNDARY = 0xffffffff,
58 AHCI_USE_CLUSTERING = 0, 59 AHCI_USE_CLUSTERING = 0,
@@ -77,8 +78,9 @@ enum {
77 RX_FIS_UNK = 0x60, /* offset of Unknown FIS data */ 78 RX_FIS_UNK = 0x60, /* offset of Unknown FIS data */
78 79
79 board_ahci = 0, 80 board_ahci = 0,
80 board_ahci_vt8251 = 1, 81 board_ahci_pi = 1,
81 board_ahci_ign_iferr = 2, 82 board_ahci_vt8251 = 2,
83 board_ahci_ign_iferr = 3,
82 84
83 /* global controller registers */ 85 /* global controller registers */
84 HOST_CAP = 0x00, /* host capabilities */ 86 HOST_CAP = 0x00, /* host capabilities */
@@ -167,9 +169,9 @@ enum {
167 AHCI_FLAG_MSI = (1 << 0), 169 AHCI_FLAG_MSI = (1 << 0),
168 170
169 /* ap->flags bits */ 171 /* ap->flags bits */
170 AHCI_FLAG_RESET_NEEDS_CLO = (1 << 24), 172 AHCI_FLAG_NO_NCQ = (1 << 24),
171 AHCI_FLAG_NO_NCQ = (1 << 25), 173 AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 25), /* ignore IRQ_IF_ERR */
172 AHCI_FLAG_IGN_IRQ_IF_ERR = (1 << 26), /* ignore IRQ_IF_ERR */ 174 AHCI_FLAG_HONOR_PI = (1 << 26), /* honor PORTS_IMPL */
173}; 175};
174 176
175struct ahci_cmd_hdr { 177struct ahci_cmd_hdr {
@@ -216,6 +218,7 @@ static u8 ahci_check_status(struct ata_port *ap);
216static void ahci_freeze(struct ata_port *ap); 218static void ahci_freeze(struct ata_port *ap);
217static void ahci_thaw(struct ata_port *ap); 219static void ahci_thaw(struct ata_port *ap);
218static void ahci_error_handler(struct ata_port *ap); 220static void ahci_error_handler(struct ata_port *ap);
221static void ahci_vt8251_error_handler(struct ata_port *ap);
219static void ahci_post_internal_cmd(struct ata_queued_cmd *qc); 222static void ahci_post_internal_cmd(struct ata_queued_cmd *qc);
220static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg); 223static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg);
221static int ahci_port_resume(struct ata_port *ap); 224static int ahci_port_resume(struct ata_port *ap);
@@ -275,6 +278,37 @@ static const struct ata_port_operations ahci_ops = {
275 .port_stop = ahci_port_stop, 278 .port_stop = ahci_port_stop,
276}; 279};
277 280
281static const struct ata_port_operations ahci_vt8251_ops = {
282 .port_disable = ata_port_disable,
283
284 .check_status = ahci_check_status,
285 .check_altstatus = ahci_check_status,
286 .dev_select = ata_noop_dev_select,
287
288 .tf_read = ahci_tf_read,
289
290 .qc_prep = ahci_qc_prep,
291 .qc_issue = ahci_qc_issue,
292
293 .irq_handler = ahci_interrupt,
294 .irq_clear = ahci_irq_clear,
295
296 .scr_read = ahci_scr_read,
297 .scr_write = ahci_scr_write,
298
299 .freeze = ahci_freeze,
300 .thaw = ahci_thaw,
301
302 .error_handler = ahci_vt8251_error_handler,
303 .post_internal_cmd = ahci_post_internal_cmd,
304
305 .port_suspend = ahci_port_suspend,
306 .port_resume = ahci_port_resume,
307
308 .port_start = ahci_port_start,
309 .port_stop = ahci_port_stop,
310};
311
278static const struct ata_port_info ahci_port_info[] = { 312static const struct ata_port_info ahci_port_info[] = {
279 /* board_ahci */ 313 /* board_ahci */
280 { 314 {
@@ -286,16 +320,26 @@ static const struct ata_port_info ahci_port_info[] = {
286 .udma_mask = 0x7f, /* udma0-6 ; FIXME */ 320 .udma_mask = 0x7f, /* udma0-6 ; FIXME */
287 .port_ops = &ahci_ops, 321 .port_ops = &ahci_ops,
288 }, 322 },
323 /* board_ahci_pi */
324 {
325 .sht = &ahci_sht,
326 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
327 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
328 ATA_FLAG_SKIP_D2H_BSY | AHCI_FLAG_HONOR_PI,
329 .pio_mask = 0x1f, /* pio0-4 */
330 .udma_mask = 0x7f, /* udma0-6 ; FIXME */
331 .port_ops = &ahci_ops,
332 },
289 /* board_ahci_vt8251 */ 333 /* board_ahci_vt8251 */
290 { 334 {
291 .sht = &ahci_sht, 335 .sht = &ahci_sht,
292 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY | 336 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
293 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA | 337 ATA_FLAG_MMIO | ATA_FLAG_PIO_DMA |
294 ATA_FLAG_SKIP_D2H_BSY | 338 ATA_FLAG_SKIP_D2H_BSY |
295 AHCI_FLAG_RESET_NEEDS_CLO | AHCI_FLAG_NO_NCQ, 339 ATA_FLAG_HRST_TO_RESUME | AHCI_FLAG_NO_NCQ,
296 .pio_mask = 0x1f, /* pio0-4 */ 340 .pio_mask = 0x1f, /* pio0-4 */
297 .udma_mask = 0x7f, /* udma0-6 ; FIXME */ 341 .udma_mask = 0x7f, /* udma0-6 ; FIXME */
298 .port_ops = &ahci_ops, 342 .port_ops = &ahci_vt8251_ops,
299 }, 343 },
300 /* board_ahci_ign_iferr */ 344 /* board_ahci_ign_iferr */
301 { 345 {
@@ -322,22 +366,22 @@ static const struct pci_device_id ahci_pci_tbl[] = {
322 { PCI_VDEVICE(INTEL, 0x2682), board_ahci }, /* ESB2 */ 366 { PCI_VDEVICE(INTEL, 0x2682), board_ahci }, /* ESB2 */
323 { PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */ 367 { PCI_VDEVICE(INTEL, 0x2683), board_ahci }, /* ESB2 */
324 { PCI_VDEVICE(INTEL, 0x27c6), board_ahci }, /* ICH7-M DH */ 368 { PCI_VDEVICE(INTEL, 0x27c6), board_ahci }, /* ICH7-M DH */
325 { PCI_VDEVICE(INTEL, 0x2821), board_ahci }, /* ICH8 */ 369 { PCI_VDEVICE(INTEL, 0x2821), board_ahci_pi }, /* ICH8 */
326 { PCI_VDEVICE(INTEL, 0x2822), board_ahci }, /* ICH8 */ 370 { PCI_VDEVICE(INTEL, 0x2822), board_ahci_pi }, /* ICH8 */
327 { PCI_VDEVICE(INTEL, 0x2824), board_ahci }, /* ICH8 */ 371 { PCI_VDEVICE(INTEL, 0x2824), board_ahci_pi }, /* ICH8 */
328 { PCI_VDEVICE(INTEL, 0x2829), board_ahci }, /* ICH8M */ 372 { PCI_VDEVICE(INTEL, 0x2829), board_ahci_pi }, /* ICH8M */
329 { PCI_VDEVICE(INTEL, 0x282a), board_ahci }, /* ICH8M */ 373 { PCI_VDEVICE(INTEL, 0x282a), board_ahci_pi }, /* ICH8M */
330 { PCI_VDEVICE(INTEL, 0x2922), board_ahci }, /* ICH9 */ 374 { PCI_VDEVICE(INTEL, 0x2922), board_ahci_pi }, /* ICH9 */
331 { PCI_VDEVICE(INTEL, 0x2923), board_ahci }, /* ICH9 */ 375 { PCI_VDEVICE(INTEL, 0x2923), board_ahci_pi }, /* ICH9 */
332 { PCI_VDEVICE(INTEL, 0x2924), board_ahci }, /* ICH9 */ 376 { PCI_VDEVICE(INTEL, 0x2924), board_ahci_pi }, /* ICH9 */
333 { PCI_VDEVICE(INTEL, 0x2925), board_ahci }, /* ICH9 */ 377 { PCI_VDEVICE(INTEL, 0x2925), board_ahci_pi }, /* ICH9 */
334 { PCI_VDEVICE(INTEL, 0x2927), board_ahci }, /* ICH9 */ 378 { PCI_VDEVICE(INTEL, 0x2927), board_ahci_pi }, /* ICH9 */
335 { PCI_VDEVICE(INTEL, 0x2929), board_ahci }, /* ICH9M */ 379 { PCI_VDEVICE(INTEL, 0x2929), board_ahci_pi }, /* ICH9M */
336 { PCI_VDEVICE(INTEL, 0x292a), board_ahci }, /* ICH9M */ 380 { PCI_VDEVICE(INTEL, 0x292a), board_ahci_pi }, /* ICH9M */
337 { PCI_VDEVICE(INTEL, 0x292b), board_ahci }, /* ICH9M */ 381 { PCI_VDEVICE(INTEL, 0x292b), board_ahci_pi }, /* ICH9M */
338 { PCI_VDEVICE(INTEL, 0x292f), board_ahci }, /* ICH9M */ 382 { PCI_VDEVICE(INTEL, 0x292f), board_ahci_pi }, /* ICH9M */
339 { PCI_VDEVICE(INTEL, 0x294d), board_ahci }, /* ICH9 */ 383 { PCI_VDEVICE(INTEL, 0x294d), board_ahci_pi }, /* ICH9 */
340 { PCI_VDEVICE(INTEL, 0x294e), board_ahci }, /* ICH9M */ 384 { PCI_VDEVICE(INTEL, 0x294e), board_ahci_pi }, /* ICH9M */
341 385
342 /* JMicron */ 386 /* JMicron */
343 { PCI_VDEVICE(JMICRON, 0x2360), board_ahci_ign_iferr }, /* JMB360 */ 387 { PCI_VDEVICE(JMICRON, 0x2360), board_ahci_ign_iferr }, /* JMB360 */
@@ -372,6 +416,10 @@ static const struct pci_device_id ahci_pci_tbl[] = {
372 { PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 966 */ 416 { PCI_VDEVICE(SI, 0x1185), board_ahci }, /* SiS 966 */
373 { PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */ 417 { PCI_VDEVICE(SI, 0x0186), board_ahci }, /* SiS 968 */
374 418
419 /* Generic, PCI class code for AHCI */
420 { PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID,
421 0x010601, 0xffffff, board_ahci },
422
375 { } /* terminate list */ 423 { } /* terminate list */
376}; 424};
377 425
@@ -386,6 +434,11 @@ static struct pci_driver ahci_pci_driver = {
386}; 434};
387 435
388 436
437static inline int ahci_nr_ports(u32 cap)
438{
439 return (cap & 0x1f) + 1;
440}
441
389static inline unsigned long ahci_port_base_ul (unsigned long base, unsigned int port) 442static inline unsigned long ahci_port_base_ul (unsigned long base, unsigned int port)
390{ 443{
391 return base + 0x100 + (port * 0x80); 444 return base + 0x100 + (port * 0x80);
@@ -559,9 +612,6 @@ static void ahci_power_down(void __iomem *port_mmio, u32 cap)
559static void ahci_init_port(void __iomem *port_mmio, u32 cap, 612static void ahci_init_port(void __iomem *port_mmio, u32 cap,
560 dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma) 613 dma_addr_t cmd_slot_dma, dma_addr_t rx_fis_dma)
561{ 614{
562 /* power up */
563 ahci_power_up(port_mmio, cap);
564
565 /* enable FIS reception */ 615 /* enable FIS reception */
566 ahci_start_fis_rx(port_mmio, cap, cmd_slot_dma, rx_fis_dma); 616 ahci_start_fis_rx(port_mmio, cap, cmd_slot_dma, rx_fis_dma);
567 617
@@ -587,19 +637,17 @@ static int ahci_deinit_port(void __iomem *port_mmio, u32 cap, const char **emsg)
587 return rc; 637 return rc;
588 } 638 }
589 639
590 /* put device into slumber mode */
591 ahci_power_down(port_mmio, cap);
592
593 return 0; 640 return 0;
594} 641}
595 642
596static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev) 643static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
597{ 644{
598 u32 cap_save, tmp; 645 u32 cap_save, impl_save, tmp;
599 646
600 cap_save = readl(mmio + HOST_CAP); 647 cap_save = readl(mmio + HOST_CAP);
601 cap_save &= ( (1<<28) | (1<<17) ); 648 cap_save &= ( (1<<28) | (1<<17) );
602 cap_save |= (1 << 27); 649 cap_save |= (1 << 27);
650 impl_save = readl(mmio + HOST_PORTS_IMPL);
603 651
604 /* global controller reset */ 652 /* global controller reset */
605 tmp = readl(mmio + HOST_CTL); 653 tmp = readl(mmio + HOST_CTL);
@@ -620,10 +668,21 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
620 return -EIO; 668 return -EIO;
621 } 669 }
622 670
671 /* turn on AHCI mode */
623 writel(HOST_AHCI_EN, mmio + HOST_CTL); 672 writel(HOST_AHCI_EN, mmio + HOST_CTL);
624 (void) readl(mmio + HOST_CTL); /* flush */ 673 (void) readl(mmio + HOST_CTL); /* flush */
674
675 /* These write-once registers are normally cleared on reset.
676 * Restore BIOS values... which we HOPE were present before
677 * reset.
678 */
679 if (!impl_save) {
680 impl_save = (1 << ahci_nr_ports(cap_save)) - 1;
681 dev_printk(KERN_WARNING, &pdev->dev,
682 "PORTS_IMPL is zero, forcing 0x%x\n", impl_save);
683 }
625 writel(cap_save, mmio + HOST_CAP); 684 writel(cap_save, mmio + HOST_CAP);
626 writel(0xf, mmio + HOST_PORTS_IMPL); 685 writel(impl_save, mmio + HOST_PORTS_IMPL);
627 (void) readl(mmio + HOST_PORTS_IMPL); /* flush */ 686 (void) readl(mmio + HOST_PORTS_IMPL); /* flush */
628 687
629 if (pdev->vendor == PCI_VENDOR_ID_INTEL) { 688 if (pdev->vendor == PCI_VENDOR_ID_INTEL) {
@@ -639,7 +698,8 @@ static int ahci_reset_controller(void __iomem *mmio, struct pci_dev *pdev)
639} 698}
640 699
641static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev, 700static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev,
642 int n_ports, u32 cap) 701 int n_ports, unsigned int port_flags,
702 struct ahci_host_priv *hpriv)
643{ 703{
644 int i, rc; 704 int i, rc;
645 u32 tmp; 705 u32 tmp;
@@ -648,13 +708,12 @@ static void ahci_init_controller(void __iomem *mmio, struct pci_dev *pdev,
648 void __iomem *port_mmio = ahci_port_base(mmio, i); 708 void __iomem *port_mmio = ahci_port_base(mmio, i);
649 const char *emsg = NULL; 709 const char *emsg = NULL;
650 710
651#if 0 /* BIOSen initialize this incorrectly */ 711 if ((port_flags & AHCI_FLAG_HONOR_PI) &&
652 if (!(hpriv->port_map & (1 << i))) 712 !(hpriv->port_map & (1 << i)))
653 continue; 713 continue;
654#endif
655 714
656 /* make sure port is not active */ 715 /* make sure port is not active */
657 rc = ahci_deinit_port(port_mmio, cap, &emsg); 716 rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
658 if (rc) 717 if (rc)
659 dev_printk(KERN_WARNING, &pdev->dev, 718 dev_printk(KERN_WARNING, &pdev->dev,
660 "%s (%d)\n", emsg, rc); 719 "%s (%d)\n", emsg, rc);
@@ -729,17 +788,6 @@ static int ahci_clo(struct ata_port *ap)
729 return 0; 788 return 0;
730} 789}
731 790
732static int ahci_prereset(struct ata_port *ap)
733{
734 if ((ap->flags & AHCI_FLAG_RESET_NEEDS_CLO) &&
735 (ata_busy_wait(ap, ATA_BUSY, 1000) & ATA_BUSY)) {
736 /* ATA_BUSY hasn't cleared, so send a CLO */
737 ahci_clo(ap);
738 }
739
740 return ata_std_prereset(ap);
741}
742
743static int ahci_softreset(struct ata_port *ap, unsigned int *class) 791static int ahci_softreset(struct ata_port *ap, unsigned int *class)
744{ 792{
745 struct ahci_port_priv *pp = ap->private_data; 793 struct ahci_port_priv *pp = ap->private_data;
@@ -877,6 +925,31 @@ static int ahci_hardreset(struct ata_port *ap, unsigned int *class)
877 return rc; 925 return rc;
878} 926}
879 927
928static int ahci_vt8251_hardreset(struct ata_port *ap, unsigned int *class)
929{
930 void __iomem *mmio = ap->host->mmio_base;
931 void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
932 int rc;
933
934 DPRINTK("ENTER\n");
935
936 ahci_stop_engine(port_mmio);
937
938 rc = sata_port_hardreset(ap, sata_ehc_deb_timing(&ap->eh_context));
939
940 /* vt8251 needs SError cleared for the port to operate */
941 ahci_scr_write(ap, SCR_ERROR, ahci_scr_read(ap, SCR_ERROR));
942
943 ahci_start_engine(port_mmio);
944
945 DPRINTK("EXIT, rc=%d, class=%u\n", rc, *class);
946
947 /* vt8251 doesn't clear BSY on signature FIS reception,
948 * request follow-up softreset.
949 */
950 return rc ?: -EAGAIN;
951}
952
880static void ahci_postreset(struct ata_port *ap, unsigned int *class) 953static void ahci_postreset(struct ata_port *ap, unsigned int *class)
881{ 954{
882 void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr; 955 void __iomem *port_mmio = (void __iomem *) ap->ioaddr.cmd_addr;
@@ -1196,7 +1269,23 @@ static void ahci_error_handler(struct ata_port *ap)
1196 } 1269 }
1197 1270
1198 /* perform recovery */ 1271 /* perform recovery */
1199 ata_do_eh(ap, ahci_prereset, ahci_softreset, ahci_hardreset, 1272 ata_do_eh(ap, ata_std_prereset, ahci_softreset, ahci_hardreset,
1273 ahci_postreset);
1274}
1275
1276static void ahci_vt8251_error_handler(struct ata_port *ap)
1277{
1278 void __iomem *mmio = ap->host->mmio_base;
1279 void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
1280
1281 if (!(ap->pflags & ATA_PFLAG_FROZEN)) {
1282 /* restart engine */
1283 ahci_stop_engine(port_mmio);
1284 ahci_start_engine(port_mmio);
1285 }
1286
1287 /* perform recovery */
1288 ata_do_eh(ap, ata_std_prereset, ahci_softreset, ahci_vt8251_hardreset,
1200 ahci_postreset); 1289 ahci_postreset);
1201} 1290}
1202 1291
@@ -1226,7 +1315,9 @@ static int ahci_port_suspend(struct ata_port *ap, pm_message_t mesg)
1226 int rc; 1315 int rc;
1227 1316
1228 rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg); 1317 rc = ahci_deinit_port(port_mmio, hpriv->cap, &emsg);
1229 if (rc) { 1318 if (rc == 0)
1319 ahci_power_down(port_mmio, hpriv->cap);
1320 else {
1230 ata_port_printk(ap, KERN_ERR, "%s (%d)\n", emsg, rc); 1321 ata_port_printk(ap, KERN_ERR, "%s (%d)\n", emsg, rc);
1231 ahci_init_port(port_mmio, hpriv->cap, 1322 ahci_init_port(port_mmio, hpriv->cap,
1232 pp->cmd_slot_dma, pp->rx_fis_dma); 1323 pp->cmd_slot_dma, pp->rx_fis_dma);
@@ -1242,6 +1333,7 @@ static int ahci_port_resume(struct ata_port *ap)
1242 void __iomem *mmio = ap->host->mmio_base; 1333 void __iomem *mmio = ap->host->mmio_base;
1243 void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no); 1334 void __iomem *port_mmio = ahci_port_base(mmio, ap->port_no);
1244 1335
1336 ahci_power_up(port_mmio, hpriv->cap);
1245 ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma); 1337 ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma);
1246 1338
1247 return 0; 1339 return 0;
@@ -1281,7 +1373,8 @@ static int ahci_pci_device_resume(struct pci_dev *pdev)
1281 if (rc) 1373 if (rc)
1282 return rc; 1374 return rc;
1283 1375
1284 ahci_init_controller(mmio, pdev, host->n_ports, hpriv->cap); 1376 ahci_init_controller(mmio, pdev, host->n_ports,
1377 host->ports[0]->flags, hpriv);
1285 } 1378 }
1286 1379
1287 ata_host_resume(host); 1380 ata_host_resume(host);
@@ -1347,6 +1440,9 @@ static int ahci_port_start(struct ata_port *ap)
1347 1440
1348 ap->private_data = pp; 1441 ap->private_data = pp;
1349 1442
1443 /* power up port */
1444 ahci_power_up(port_mmio, hpriv->cap);
1445
1350 /* initialize port */ 1446 /* initialize port */
1351 ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma); 1447 ahci_init_port(port_mmio, hpriv->cap, pp->cmd_slot_dma, pp->rx_fis_dma);
1352 1448
@@ -1393,7 +1489,7 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
1393 struct ahci_host_priv *hpriv = probe_ent->private_data; 1489 struct ahci_host_priv *hpriv = probe_ent->private_data;
1394 struct pci_dev *pdev = to_pci_dev(probe_ent->dev); 1490 struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
1395 void __iomem *mmio = probe_ent->mmio_base; 1491 void __iomem *mmio = probe_ent->mmio_base;
1396 unsigned int i, using_dac; 1492 unsigned int i, cap_n_ports, using_dac;
1397 int rc; 1493 int rc;
1398 1494
1399 rc = ahci_reset_controller(mmio, pdev); 1495 rc = ahci_reset_controller(mmio, pdev);
@@ -1402,10 +1498,34 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
1402 1498
1403 hpriv->cap = readl(mmio + HOST_CAP); 1499 hpriv->cap = readl(mmio + HOST_CAP);
1404 hpriv->port_map = readl(mmio + HOST_PORTS_IMPL); 1500 hpriv->port_map = readl(mmio + HOST_PORTS_IMPL);
1405 probe_ent->n_ports = (hpriv->cap & 0x1f) + 1; 1501 cap_n_ports = ahci_nr_ports(hpriv->cap);
1406 1502
1407 VPRINTK("cap 0x%x port_map 0x%x n_ports %d\n", 1503 VPRINTK("cap 0x%x port_map 0x%x n_ports %d\n",
1408 hpriv->cap, hpriv->port_map, probe_ent->n_ports); 1504 hpriv->cap, hpriv->port_map, cap_n_ports);
1505
1506 if (probe_ent->port_flags & AHCI_FLAG_HONOR_PI) {
1507 unsigned int n_ports = cap_n_ports;
1508 u32 port_map = hpriv->port_map;
1509 int max_port = 0;
1510
1511 for (i = 0; i < AHCI_MAX_PORTS && n_ports; i++) {
1512 if (port_map & (1 << i)) {
1513 n_ports--;
1514 port_map &= ~(1 << i);
1515 max_port = i;
1516 } else
1517 probe_ent->dummy_port_mask |= 1 << i;
1518 }
1519
1520 if (n_ports || port_map)
1521 dev_printk(KERN_WARNING, &pdev->dev,
1522 "nr_ports (%u) and implemented port map "
1523 "(0x%x) don't match\n",
1524 cap_n_ports, hpriv->port_map);
1525
1526 probe_ent->n_ports = max_port + 1;
1527 } else
1528 probe_ent->n_ports = cap_n_ports;
1409 1529
1410 using_dac = hpriv->cap & HOST_CAP_64; 1530 using_dac = hpriv->cap & HOST_CAP_64;
1411 if (using_dac && 1531 if (using_dac &&
@@ -1437,7 +1557,8 @@ static int ahci_host_init(struct ata_probe_ent *probe_ent)
1437 for (i = 0; i < probe_ent->n_ports; i++) 1557 for (i = 0; i < probe_ent->n_ports; i++)
1438 ahci_setup_port(&probe_ent->port[i], (unsigned long) mmio, i); 1558 ahci_setup_port(&probe_ent->port[i], (unsigned long) mmio, i);
1439 1559
1440 ahci_init_controller(mmio, pdev, probe_ent->n_ports, hpriv->cap); 1560 ahci_init_controller(mmio, pdev, probe_ent->n_ports,
1561 probe_ent->port_flags, hpriv);
1441 1562
1442 pci_set_master(pdev); 1563 pci_set_master(pdev);
1443 1564
diff --git a/drivers/ata/ata_generic.c b/drivers/ata/ata_generic.c
index 4a80ff9312b8..908751d27e76 100644
--- a/drivers/ata/ata_generic.c
+++ b/drivers/ata/ata_generic.c
@@ -26,7 +26,7 @@
26#include <linux/libata.h> 26#include <linux/libata.h>
27 27
28#define DRV_NAME "ata_generic" 28#define DRV_NAME "ata_generic"
29#define DRV_VERSION "0.2.6" 29#define DRV_VERSION "0.2.10"
30 30
31/* 31/*
32 * A generic parallel ATA driver using libata 32 * A generic parallel ATA driver using libata
@@ -109,7 +109,6 @@ static struct scsi_host_template generic_sht = {
109 .can_queue = ATA_DEF_QUEUE, 109 .can_queue = ATA_DEF_QUEUE,
110 .this_id = ATA_SHT_THIS_ID, 110 .this_id = ATA_SHT_THIS_ID,
111 .sg_tablesize = LIBATA_MAX_PRD, 111 .sg_tablesize = LIBATA_MAX_PRD,
112 .max_sectors = ATA_MAX_SECTORS,
113 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 112 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
114 .emulated = ATA_SHT_EMULATED, 113 .emulated = ATA_SHT_EMULATED,
115 .use_clustering = ATA_SHT_USE_CLUSTERING, 114 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -118,6 +117,8 @@ static struct scsi_host_template generic_sht = {
118 .slave_configure = ata_scsi_slave_config, 117 .slave_configure = ata_scsi_slave_config,
119 .slave_destroy = ata_scsi_slave_destroy, 118 .slave_destroy = ata_scsi_slave_destroy,
120 .bios_param = ata_std_bios_param, 119 .bios_param = ata_std_bios_param,
120 .resume = ata_scsi_device_resume,
121 .suspend = ata_scsi_device_suspend,
121}; 122};
122 123
123static struct ata_port_operations generic_port_ops = { 124static struct ata_port_operations generic_port_ops = {
@@ -226,12 +227,14 @@ static struct pci_driver ata_generic_pci_driver = {
226 .name = DRV_NAME, 227 .name = DRV_NAME,
227 .id_table = ata_generic, 228 .id_table = ata_generic,
228 .probe = ata_generic_init_one, 229 .probe = ata_generic_init_one,
229 .remove = ata_pci_remove_one 230 .remove = ata_pci_remove_one,
231 .suspend = ata_pci_device_suspend,
232 .resume = ata_pci_device_resume,
230}; 233};
231 234
232static int __init ata_generic_init(void) 235static int __init ata_generic_init(void)
233{ 236{
234 return pci_module_init(&ata_generic_pci_driver); 237 return pci_register_driver(&ata_generic_pci_driver);
235} 238}
236 239
237 240
diff --git a/drivers/ata/ata_piix.c b/drivers/ata/ata_piix.c
index 720174d628fa..c7de0bb1591f 100644
--- a/drivers/ata/ata_piix.c
+++ b/drivers/ata/ata_piix.c
@@ -40,7 +40,7 @@
40 * Documentation 40 * Documentation
41 * Publically available from Intel web site. Errata documentation 41 * Publically available from Intel web site. Errata documentation
42 * is also publically available. As an aide to anyone hacking on this 42 * is also publically available. As an aide to anyone hacking on this
43 * driver the list of errata that are relevant is below.going back to 43 * driver the list of errata that are relevant is below, going back to
44 * PIIX4. Older device documentation is now a bit tricky to find. 44 * PIIX4. Older device documentation is now a bit tricky to find.
45 * 45 *
46 * The chipsets all follow very much the same design. The orginal Triton 46 * The chipsets all follow very much the same design. The orginal Triton
@@ -93,7 +93,7 @@
93#include <linux/libata.h> 93#include <linux/libata.h>
94 94
95#define DRV_NAME "ata_piix" 95#define DRV_NAME "ata_piix"
96#define DRV_VERSION "2.00ac6" 96#define DRV_VERSION "2.00ac7"
97 97
98enum { 98enum {
99 PIIX_IOCFG = 0x54, /* IDE I/O configuration register */ 99 PIIX_IOCFG = 0x54, /* IDE I/O configuration register */
@@ -101,11 +101,13 @@ enum {
101 ICH5_PCS = 0x92, /* port control and status */ 101 ICH5_PCS = 0x92, /* port control and status */
102 PIIX_SCC = 0x0A, /* sub-class code register */ 102 PIIX_SCC = 0x0A, /* sub-class code register */
103 103
104 PIIX_FLAG_IGNORE_PCS = (1 << 25), /* ignore PCS present bits */
105 PIIX_FLAG_SCR = (1 << 26), /* SCR available */ 104 PIIX_FLAG_SCR = (1 << 26), /* SCR available */
106 PIIX_FLAG_AHCI = (1 << 27), /* AHCI possible */ 105 PIIX_FLAG_AHCI = (1 << 27), /* AHCI possible */
107 PIIX_FLAG_CHECKINTR = (1 << 28), /* make sure PCI INTx enabled */ 106 PIIX_FLAG_CHECKINTR = (1 << 28), /* make sure PCI INTx enabled */
108 107
108 PIIX_PATA_FLAGS = ATA_FLAG_SLAVE_POSS,
109 PIIX_SATA_FLAGS = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR,
110
109 /* combined mode. if set, PATA is channel 0. 111 /* combined mode. if set, PATA is channel 0.
110 * if clear, PATA is channel 1. 112 * if clear, PATA is channel 1.
111 */ 113 */
@@ -122,11 +124,10 @@ enum {
122 ich_pata_100 = 3, /* ICH up to UDMA 100 */ 124 ich_pata_100 = 3, /* ICH up to UDMA 100 */
123 ich_pata_133 = 4, /* ICH up to UDMA 133 */ 125 ich_pata_133 = 4, /* ICH up to UDMA 133 */
124 ich5_sata = 5, 126 ich5_sata = 5,
125 esb_sata = 6, 127 ich6_sata = 6,
126 ich6_sata = 7, 128 ich6_sata_ahci = 7,
127 ich6_sata_ahci = 8, 129 ich6m_sata_ahci = 8,
128 ich6m_sata_ahci = 9, 130 ich8_sata_ahci = 9,
129 ich8_sata_ahci = 10,
130 131
131 /* constants for mapping table */ 132 /* constants for mapping table */
132 P0 = 0, /* port 0 */ 133 P0 = 0, /* port 0 */
@@ -143,13 +144,11 @@ enum {
143struct piix_map_db { 144struct piix_map_db {
144 const u32 mask; 145 const u32 mask;
145 const u16 port_enable; 146 const u16 port_enable;
146 const int present_shift;
147 const int map[][4]; 147 const int map[][4];
148}; 148};
149 149
150struct piix_host_priv { 150struct piix_host_priv {
151 const int *map; 151 const int *map;
152 const struct piix_map_db *map_db;
153}; 152};
154 153
155static int piix_init_one (struct pci_dev *pdev, 154static int piix_init_one (struct pci_dev *pdev,
@@ -214,9 +213,9 @@ static const struct pci_device_id piix_pci_tbl[] = {
214 /* 82801EB (ICH5) */ 213 /* 82801EB (ICH5) */
215 { 0x8086, 0x24df, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata }, 214 { 0x8086, 0x24df, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
216 /* 6300ESB (ICH5 variant with broken PCS present bits) */ 215 /* 6300ESB (ICH5 variant with broken PCS present bits) */
217 { 0x8086, 0x25a3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb_sata }, 216 { 0x8086, 0x25a3, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
218 /* 6300ESB pretending RAID */ 217 /* 6300ESB pretending RAID */
219 { 0x8086, 0x25b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, esb_sata }, 218 { 0x8086, 0x25b0, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich5_sata },
220 /* 82801FB/FW (ICH6/ICH6W) */ 219 /* 82801FB/FW (ICH6/ICH6W) */
221 { 0x8086, 0x2651, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata }, 220 { 0x8086, 0x2651, PCI_ANY_ID, PCI_ANY_ID, 0, 0, ich6_sata },
222 /* 82801FR/FRW (ICH6R/ICH6RW) */ 221 /* 82801FR/FRW (ICH6R/ICH6RW) */
@@ -367,7 +366,6 @@ static const struct ata_port_operations piix_sata_ops = {
367static const struct piix_map_db ich5_map_db = { 366static const struct piix_map_db ich5_map_db = {
368 .mask = 0x7, 367 .mask = 0x7,
369 .port_enable = 0x3, 368 .port_enable = 0x3,
370 .present_shift = 4,
371 .map = { 369 .map = {
372 /* PM PS SM SS MAP */ 370 /* PM PS SM SS MAP */
373 { P0, NA, P1, NA }, /* 000b */ 371 { P0, NA, P1, NA }, /* 000b */
@@ -384,7 +382,6 @@ static const struct piix_map_db ich5_map_db = {
384static const struct piix_map_db ich6_map_db = { 382static const struct piix_map_db ich6_map_db = {
385 .mask = 0x3, 383 .mask = 0x3,
386 .port_enable = 0xf, 384 .port_enable = 0xf,
387 .present_shift = 4,
388 .map = { 385 .map = {
389 /* PM PS SM SS MAP */ 386 /* PM PS SM SS MAP */
390 { P0, P2, P1, P3 }, /* 00b */ 387 { P0, P2, P1, P3 }, /* 00b */
@@ -397,7 +394,6 @@ static const struct piix_map_db ich6_map_db = {
397static const struct piix_map_db ich6m_map_db = { 394static const struct piix_map_db ich6m_map_db = {
398 .mask = 0x3, 395 .mask = 0x3,
399 .port_enable = 0x5, 396 .port_enable = 0x5,
400 .present_shift = 4,
401 397
402 /* Map 01b isn't specified in the doc but some notebooks use 398 /* Map 01b isn't specified in the doc but some notebooks use
403 * it anyway. MAP 01b have been spotted on both ICH6M and 399 * it anyway. MAP 01b have been spotted on both ICH6M and
@@ -415,7 +411,6 @@ static const struct piix_map_db ich6m_map_db = {
415static const struct piix_map_db ich8_map_db = { 411static const struct piix_map_db ich8_map_db = {
416 .mask = 0x3, 412 .mask = 0x3,
417 .port_enable = 0x3, 413 .port_enable = 0x3,
418 .present_shift = 8,
419 .map = { 414 .map = {
420 /* PM PS SM SS MAP */ 415 /* PM PS SM SS MAP */
421 { P0, P2, P1, P3 }, /* 00b (hardwired when in AHCI) */ 416 { P0, P2, P1, P3 }, /* 00b (hardwired when in AHCI) */
@@ -427,7 +422,6 @@ static const struct piix_map_db ich8_map_db = {
427 422
428static const struct piix_map_db *piix_map_db_table[] = { 423static const struct piix_map_db *piix_map_db_table[] = {
429 [ich5_sata] = &ich5_map_db, 424 [ich5_sata] = &ich5_map_db,
430 [esb_sata] = &ich5_map_db,
431 [ich6_sata] = &ich6_map_db, 425 [ich6_sata] = &ich6_map_db,
432 [ich6_sata_ahci] = &ich6_map_db, 426 [ich6_sata_ahci] = &ich6_map_db,
433 [ich6m_sata_ahci] = &ich6m_map_db, 427 [ich6m_sata_ahci] = &ich6m_map_db,
@@ -438,7 +432,7 @@ static struct ata_port_info piix_port_info[] = {
438 /* piix_pata_33: 0: PIIX3 or 4 at 33MHz */ 432 /* piix_pata_33: 0: PIIX3 or 4 at 33MHz */
439 { 433 {
440 .sht = &piix_sht, 434 .sht = &piix_sht,
441 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 435 .flags = PIIX_PATA_FLAGS,
442 .pio_mask = 0x1f, /* pio0-4 */ 436 .pio_mask = 0x1f, /* pio0-4 */
443 .mwdma_mask = 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */ 437 .mwdma_mask = 0x06, /* mwdma1-2 ?? CHECK 0 should be ok but slow */
444 .udma_mask = ATA_UDMA_MASK_40C, 438 .udma_mask = ATA_UDMA_MASK_40C,
@@ -448,7 +442,7 @@ static struct ata_port_info piix_port_info[] = {
448 /* ich_pata_33: 1 ICH0 - ICH at 33Mhz*/ 442 /* ich_pata_33: 1 ICH0 - ICH at 33Mhz*/
449 { 443 {
450 .sht = &piix_sht, 444 .sht = &piix_sht,
451 .flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, 445 .flags = PIIX_PATA_FLAGS,
452 .pio_mask = 0x1f, /* pio 0-4 */ 446 .pio_mask = 0x1f, /* pio 0-4 */
453 .mwdma_mask = 0x06, /* Check: maybe 0x07 */ 447 .mwdma_mask = 0x06, /* Check: maybe 0x07 */
454 .udma_mask = ATA_UDMA2, /* UDMA33 */ 448 .udma_mask = ATA_UDMA2, /* UDMA33 */
@@ -457,7 +451,7 @@ static struct ata_port_info piix_port_info[] = {
457 /* ich_pata_66: 2 ICH controllers up to 66MHz */ 451 /* ich_pata_66: 2 ICH controllers up to 66MHz */
458 { 452 {
459 .sht = &piix_sht, 453 .sht = &piix_sht,
460 .flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS, 454 .flags = PIIX_PATA_FLAGS,
461 .pio_mask = 0x1f, /* pio 0-4 */ 455 .pio_mask = 0x1f, /* pio 0-4 */
462 .mwdma_mask = 0x06, /* MWDMA0 is broken on chip */ 456 .mwdma_mask = 0x06, /* MWDMA0 is broken on chip */
463 .udma_mask = ATA_UDMA4, 457 .udma_mask = ATA_UDMA4,
@@ -467,7 +461,7 @@ static struct ata_port_info piix_port_info[] = {
467 /* ich_pata_100: 3 */ 461 /* ich_pata_100: 3 */
468 { 462 {
469 .sht = &piix_sht, 463 .sht = &piix_sht,
470 .flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS | PIIX_FLAG_CHECKINTR, 464 .flags = PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR,
471 .pio_mask = 0x1f, /* pio0-4 */ 465 .pio_mask = 0x1f, /* pio0-4 */
472 .mwdma_mask = 0x06, /* mwdma1-2 */ 466 .mwdma_mask = 0x06, /* mwdma1-2 */
473 .udma_mask = ATA_UDMA5, /* udma0-5 */ 467 .udma_mask = ATA_UDMA5, /* udma0-5 */
@@ -477,7 +471,7 @@ static struct ata_port_info piix_port_info[] = {
477 /* ich_pata_133: 4 ICH with full UDMA6 */ 471 /* ich_pata_133: 4 ICH with full UDMA6 */
478 { 472 {
479 .sht = &piix_sht, 473 .sht = &piix_sht,
480 .flags = ATA_FLAG_SRST | ATA_FLAG_SLAVE_POSS | PIIX_FLAG_CHECKINTR, 474 .flags = PIIX_PATA_FLAGS | PIIX_FLAG_CHECKINTR,
481 .pio_mask = 0x1f, /* pio 0-4 */ 475 .pio_mask = 0x1f, /* pio 0-4 */
482 .mwdma_mask = 0x06, /* Check: maybe 0x07 */ 476 .mwdma_mask = 0x06, /* Check: maybe 0x07 */
483 .udma_mask = ATA_UDMA6, /* UDMA133 */ 477 .udma_mask = ATA_UDMA6, /* UDMA133 */
@@ -487,41 +481,27 @@ static struct ata_port_info piix_port_info[] = {
487 /* ich5_sata: 5 */ 481 /* ich5_sata: 5 */
488 { 482 {
489 .sht = &piix_sht, 483 .sht = &piix_sht,
490 .flags = ATA_FLAG_SATA | PIIX_FLAG_CHECKINTR | 484 .flags = PIIX_SATA_FLAGS,
491 PIIX_FLAG_IGNORE_PCS,
492 .pio_mask = 0x1f, /* pio0-4 */
493 .mwdma_mask = 0x07, /* mwdma0-2 */
494 .udma_mask = 0x7f, /* udma0-6 */
495 .port_ops = &piix_sata_ops,
496 },
497
498 /* i6300esb_sata: 6 */
499 {
500 .sht = &piix_sht,
501 .flags = ATA_FLAG_SATA |
502 PIIX_FLAG_CHECKINTR | PIIX_FLAG_IGNORE_PCS,
503 .pio_mask = 0x1f, /* pio0-4 */ 485 .pio_mask = 0x1f, /* pio0-4 */
504 .mwdma_mask = 0x07, /* mwdma0-2 */ 486 .mwdma_mask = 0x07, /* mwdma0-2 */
505 .udma_mask = 0x7f, /* udma0-6 */ 487 .udma_mask = 0x7f, /* udma0-6 */
506 .port_ops = &piix_sata_ops, 488 .port_ops = &piix_sata_ops,
507 }, 489 },
508 490
509 /* ich6_sata: 7 */ 491 /* ich6_sata: 6 */
510 { 492 {
511 .sht = &piix_sht, 493 .sht = &piix_sht,
512 .flags = ATA_FLAG_SATA | 494 .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR,
513 PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR,
514 .pio_mask = 0x1f, /* pio0-4 */ 495 .pio_mask = 0x1f, /* pio0-4 */
515 .mwdma_mask = 0x07, /* mwdma0-2 */ 496 .mwdma_mask = 0x07, /* mwdma0-2 */
516 .udma_mask = 0x7f, /* udma0-6 */ 497 .udma_mask = 0x7f, /* udma0-6 */
517 .port_ops = &piix_sata_ops, 498 .port_ops = &piix_sata_ops,
518 }, 499 },
519 500
520 /* ich6_sata_ahci: 8 */ 501 /* ich6_sata_ahci: 7 */
521 { 502 {
522 .sht = &piix_sht, 503 .sht = &piix_sht,
523 .flags = ATA_FLAG_SATA | 504 .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR |
524 PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR |
525 PIIX_FLAG_AHCI, 505 PIIX_FLAG_AHCI,
526 .pio_mask = 0x1f, /* pio0-4 */ 506 .pio_mask = 0x1f, /* pio0-4 */
527 .mwdma_mask = 0x07, /* mwdma0-2 */ 507 .mwdma_mask = 0x07, /* mwdma0-2 */
@@ -529,11 +509,10 @@ static struct ata_port_info piix_port_info[] = {
529 .port_ops = &piix_sata_ops, 509 .port_ops = &piix_sata_ops,
530 }, 510 },
531 511
532 /* ich6m_sata_ahci: 9 */ 512 /* ich6m_sata_ahci: 8 */
533 { 513 {
534 .sht = &piix_sht, 514 .sht = &piix_sht,
535 .flags = ATA_FLAG_SATA | 515 .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR |
536 PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR |
537 PIIX_FLAG_AHCI, 516 PIIX_FLAG_AHCI,
538 .pio_mask = 0x1f, /* pio0-4 */ 517 .pio_mask = 0x1f, /* pio0-4 */
539 .mwdma_mask = 0x07, /* mwdma0-2 */ 518 .mwdma_mask = 0x07, /* mwdma0-2 */
@@ -541,11 +520,10 @@ static struct ata_port_info piix_port_info[] = {
541 .port_ops = &piix_sata_ops, 520 .port_ops = &piix_sata_ops,
542 }, 521 },
543 522
544 /* ich8_sata_ahci: 10 */ 523 /* ich8_sata_ahci: 9 */
545 { 524 {
546 .sht = &piix_sht, 525 .sht = &piix_sht,
547 .flags = ATA_FLAG_SATA | 526 .flags = PIIX_SATA_FLAGS | PIIX_FLAG_SCR |
548 PIIX_FLAG_CHECKINTR | PIIX_FLAG_SCR |
549 PIIX_FLAG_AHCI, 527 PIIX_FLAG_AHCI,
550 .pio_mask = 0x1f, /* pio0-4 */ 528 .pio_mask = 0x1f, /* pio0-4 */
551 .mwdma_mask = 0x07, /* mwdma0-2 */ 529 .mwdma_mask = 0x07, /* mwdma0-2 */
@@ -566,10 +544,22 @@ MODULE_LICENSE("GPL");
566MODULE_DEVICE_TABLE(pci, piix_pci_tbl); 544MODULE_DEVICE_TABLE(pci, piix_pci_tbl);
567MODULE_VERSION(DRV_VERSION); 545MODULE_VERSION(DRV_VERSION);
568 546
569static int force_pcs = 0; 547struct ich_laptop {
570module_param(force_pcs, int, 0444); 548 u16 device;
571MODULE_PARM_DESC(force_pcs, "force honoring or ignoring PCS to work around " 549 u16 subvendor;
572 "device mis-detection (0=default, 1=ignore PCS, 2=honor PCS)"); 550 u16 subdevice;
551};
552
553/*
554 * List of laptops that use short cables rather than 80 wire
555 */
556
557static const struct ich_laptop ich_laptop[] = {
558 /* devid, subvendor, subdev */
559 { 0x27DF, 0x0005, 0x0280 }, /* ICH7 on Acer 5602WLMi */
560 /* end marker */
561 { 0, }
562};
573 563
574/** 564/**
575 * piix_pata_cbl_detect - Probe host controller cable detect info 565 * piix_pata_cbl_detect - Probe host controller cable detect info
@@ -585,12 +575,24 @@ MODULE_PARM_DESC(force_pcs, "force honoring or ignoring PCS to work around "
585static void ich_pata_cbl_detect(struct ata_port *ap) 575static void ich_pata_cbl_detect(struct ata_port *ap)
586{ 576{
587 struct pci_dev *pdev = to_pci_dev(ap->host->dev); 577 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
578 const struct ich_laptop *lap = &ich_laptop[0];
588 u8 tmp, mask; 579 u8 tmp, mask;
589 580
590 /* no 80c support in host controller? */ 581 /* no 80c support in host controller? */
591 if ((ap->udma_mask & ~ATA_UDMA_MASK_40C) == 0) 582 if ((ap->udma_mask & ~ATA_UDMA_MASK_40C) == 0)
592 goto cbl40; 583 goto cbl40;
593 584
585 /* Check for specials - Acer Aspire 5602WLMi */
586 while (lap->device) {
587 if (lap->device == pdev->device &&
588 lap->subvendor == pdev->subsystem_vendor &&
589 lap->subdevice == pdev->subsystem_device) {
590 ap->cbl = ATA_CBL_PATA40_SHORT;
591 return;
592 }
593 lap++;
594 }
595
594 /* check BIOS cable detect results */ 596 /* check BIOS cable detect results */
595 mask = ap->port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC; 597 mask = ap->port_no == 0 ? PIIX_80C_PRI : PIIX_80C_SEC;
596 pci_read_config_byte(pdev, PIIX_IOCFG, &tmp); 598 pci_read_config_byte(pdev, PIIX_IOCFG, &tmp);
@@ -659,84 +661,9 @@ static void ich_pata_error_handler(struct ata_port *ap)
659 ata_std_postreset); 661 ata_std_postreset);
660} 662}
661 663
662/**
663 * piix_sata_present_mask - determine present mask for SATA host controller
664 * @ap: Target port
665 *
666 * Reads SATA PCI device's PCI config register Port Configuration
667 * and Status (PCS) to determine port and device availability.
668 *
669 * LOCKING:
670 * None (inherited from caller).
671 *
672 * RETURNS:
673 * determined present_mask
674 */
675static unsigned int piix_sata_present_mask(struct ata_port *ap)
676{
677 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
678 struct piix_host_priv *hpriv = ap->host->private_data;
679 const unsigned int *map = hpriv->map;
680 int base = 2 * ap->port_no;
681 unsigned int present_mask = 0;
682 int port, i;
683 u16 pcs;
684
685 pci_read_config_word(pdev, ICH5_PCS, &pcs);
686 DPRINTK("ata%u: ENTER, pcs=0x%x base=%d\n", ap->id, pcs, base);
687
688 for (i = 0; i < 2; i++) {
689 port = map[base + i];
690 if (port < 0)
691 continue;
692 if ((ap->flags & PIIX_FLAG_IGNORE_PCS) ||
693 (pcs & 1 << (hpriv->map_db->present_shift + port)))
694 present_mask |= 1 << i;
695 }
696
697 DPRINTK("ata%u: LEAVE, pcs=0x%x present_mask=0x%x\n",
698 ap->id, pcs, present_mask);
699
700 return present_mask;
701}
702
703/**
704 * piix_sata_softreset - reset SATA host port via ATA SRST
705 * @ap: port to reset
706 * @classes: resulting classes of attached devices
707 *
708 * Reset SATA host port via ATA SRST. On controllers with
709 * reliable PCS present bits, the bits are used to determine
710 * device presence.
711 *
712 * LOCKING:
713 * Kernel thread context (may sleep)
714 *
715 * RETURNS:
716 * 0 on success, -errno otherwise.
717 */
718static int piix_sata_softreset(struct ata_port *ap, unsigned int *classes)
719{
720 unsigned int present_mask;
721 int i, rc;
722
723 present_mask = piix_sata_present_mask(ap);
724
725 rc = ata_std_softreset(ap, classes);
726 if (rc)
727 return rc;
728
729 for (i = 0; i < ATA_MAX_DEVICES; i++) {
730 if (!(present_mask & (1 << i)))
731 classes[i] = ATA_DEV_NONE;
732 }
733
734 return 0;
735}
736
737static void piix_sata_error_handler(struct ata_port *ap) 664static void piix_sata_error_handler(struct ata_port *ap)
738{ 665{
739 ata_bmdma_drive_eh(ap, ata_std_prereset, piix_sata_softreset, NULL, 666 ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset, NULL,
740 ata_std_postreset); 667 ata_std_postreset);
741} 668}
742 669
@@ -1051,18 +978,6 @@ static void __devinit piix_init_pcs(struct pci_dev *pdev,
1051 pci_write_config_word(pdev, ICH5_PCS, new_pcs); 978 pci_write_config_word(pdev, ICH5_PCS, new_pcs);
1052 msleep(150); 979 msleep(150);
1053 } 980 }
1054
1055 if (force_pcs == 1) {
1056 dev_printk(KERN_INFO, &pdev->dev,
1057 "force ignoring PCS (0x%x)\n", new_pcs);
1058 pinfo[0].flags |= PIIX_FLAG_IGNORE_PCS;
1059 pinfo[1].flags |= PIIX_FLAG_IGNORE_PCS;
1060 } else if (force_pcs == 2) {
1061 dev_printk(KERN_INFO, &pdev->dev,
1062 "force honoring PCS (0x%x)\n", new_pcs);
1063 pinfo[0].flags &= ~PIIX_FLAG_IGNORE_PCS;
1064 pinfo[1].flags &= ~PIIX_FLAG_IGNORE_PCS;
1065 }
1066} 981}
1067 982
1068static void __devinit piix_init_sata_map(struct pci_dev *pdev, 983static void __devinit piix_init_sata_map(struct pci_dev *pdev,
@@ -1112,7 +1027,6 @@ static void __devinit piix_init_sata_map(struct pci_dev *pdev,
1112 "invalid MAP value %u\n", map_value); 1027 "invalid MAP value %u\n", map_value);
1113 1028
1114 hpriv->map = map; 1029 hpriv->map = map;
1115 hpriv->map_db = map_db;
1116} 1030}
1117 1031
1118/** 1032/**
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index b5f2da6ac80e..8816e30fb7a4 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -199,7 +199,8 @@ static const u8 ata_rw_cmds[] = {
199 199
200/** 200/**
201 * ata_rwcmd_protocol - set taskfile r/w commands and protocol 201 * ata_rwcmd_protocol - set taskfile r/w commands and protocol
202 * @qc: command to examine and configure 202 * @tf: command to examine and configure
203 * @dev: device tf belongs to
203 * 204 *
204 * Examine the device configuration and tf->flags to calculate 205 * Examine the device configuration and tf->flags to calculate
205 * the proper read/write commands and protocol to use. 206 * the proper read/write commands and protocol to use.
@@ -207,10 +208,8 @@ static const u8 ata_rw_cmds[] = {
207 * LOCKING: 208 * LOCKING:
208 * caller. 209 * caller.
209 */ 210 */
210int ata_rwcmd_protocol(struct ata_queued_cmd *qc) 211static int ata_rwcmd_protocol(struct ata_taskfile *tf, struct ata_device *dev)
211{ 212{
212 struct ata_taskfile *tf = &qc->tf;
213 struct ata_device *dev = qc->dev;
214 u8 cmd; 213 u8 cmd;
215 214
216 int index, fua, lba48, write; 215 int index, fua, lba48, write;
@@ -222,7 +221,7 @@ int ata_rwcmd_protocol(struct ata_queued_cmd *qc)
222 if (dev->flags & ATA_DFLAG_PIO) { 221 if (dev->flags & ATA_DFLAG_PIO) {
223 tf->protocol = ATA_PROT_PIO; 222 tf->protocol = ATA_PROT_PIO;
224 index = dev->multi_count ? 0 : 8; 223 index = dev->multi_count ? 0 : 8;
225 } else if (lba48 && (qc->ap->flags & ATA_FLAG_PIO_LBA48)) { 224 } else if (lba48 && (dev->ap->flags & ATA_FLAG_PIO_LBA48)) {
226 /* Unable to use DMA due to host limitation */ 225 /* Unable to use DMA due to host limitation */
227 tf->protocol = ATA_PROT_PIO; 226 tf->protocol = ATA_PROT_PIO;
228 index = dev->multi_count ? 0 : 8; 227 index = dev->multi_count ? 0 : 8;
@@ -240,6 +239,174 @@ int ata_rwcmd_protocol(struct ata_queued_cmd *qc)
240} 239}
241 240
242/** 241/**
242 * ata_tf_read_block - Read block address from ATA taskfile
243 * @tf: ATA taskfile of interest
244 * @dev: ATA device @tf belongs to
245 *
246 * LOCKING:
247 * None.
248 *
249 * Read block address from @tf. This function can handle all
250 * three address formats - LBA, LBA48 and CHS. tf->protocol and
251 * flags select the address format to use.
252 *
253 * RETURNS:
254 * Block address read from @tf.
255 */
256u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev)
257{
258 u64 block = 0;
259
260 if (tf->flags & ATA_TFLAG_LBA) {
261 if (tf->flags & ATA_TFLAG_LBA48) {
262 block |= (u64)tf->hob_lbah << 40;
263 block |= (u64)tf->hob_lbam << 32;
264 block |= tf->hob_lbal << 24;
265 } else
266 block |= (tf->device & 0xf) << 24;
267
268 block |= tf->lbah << 16;
269 block |= tf->lbam << 8;
270 block |= tf->lbal;
271 } else {
272 u32 cyl, head, sect;
273
274 cyl = tf->lbam | (tf->lbah << 8);
275 head = tf->device & 0xf;
276 sect = tf->lbal;
277
278 block = (cyl * dev->heads + head) * dev->sectors + sect;
279 }
280
281 return block;
282}
283
284/**
285 * ata_build_rw_tf - Build ATA taskfile for given read/write request
286 * @tf: Target ATA taskfile
287 * @dev: ATA device @tf belongs to
288 * @block: Block address
289 * @n_block: Number of blocks
290 * @tf_flags: RW/FUA etc...
291 * @tag: tag
292 *
293 * LOCKING:
294 * None.
295 *
296 * Build ATA taskfile @tf for read/write request described by
297 * @block, @n_block, @tf_flags and @tag on @dev.
298 *
299 * RETURNS:
300 *
301 * 0 on success, -ERANGE if the request is too large for @dev,
302 * -EINVAL if the request is invalid.
303 */
304int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
305 u64 block, u32 n_block, unsigned int tf_flags,
306 unsigned int tag)
307{
308 tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
309 tf->flags |= tf_flags;
310
311 if ((dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ_OFF |
312 ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ &&
313 likely(tag != ATA_TAG_INTERNAL)) {
314 /* yay, NCQ */
315 if (!lba_48_ok(block, n_block))
316 return -ERANGE;
317
318 tf->protocol = ATA_PROT_NCQ;
319 tf->flags |= ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
320
321 if (tf->flags & ATA_TFLAG_WRITE)
322 tf->command = ATA_CMD_FPDMA_WRITE;
323 else
324 tf->command = ATA_CMD_FPDMA_READ;
325
326 tf->nsect = tag << 3;
327 tf->hob_feature = (n_block >> 8) & 0xff;
328 tf->feature = n_block & 0xff;
329
330 tf->hob_lbah = (block >> 40) & 0xff;
331 tf->hob_lbam = (block >> 32) & 0xff;
332 tf->hob_lbal = (block >> 24) & 0xff;
333 tf->lbah = (block >> 16) & 0xff;
334 tf->lbam = (block >> 8) & 0xff;
335 tf->lbal = block & 0xff;
336
337 tf->device = 1 << 6;
338 if (tf->flags & ATA_TFLAG_FUA)
339 tf->device |= 1 << 7;
340 } else if (dev->flags & ATA_DFLAG_LBA) {
341 tf->flags |= ATA_TFLAG_LBA;
342
343 if (lba_28_ok(block, n_block)) {
344 /* use LBA28 */
345 tf->device |= (block >> 24) & 0xf;
346 } else if (lba_48_ok(block, n_block)) {
347 if (!(dev->flags & ATA_DFLAG_LBA48))
348 return -ERANGE;
349
350 /* use LBA48 */
351 tf->flags |= ATA_TFLAG_LBA48;
352
353 tf->hob_nsect = (n_block >> 8) & 0xff;
354
355 tf->hob_lbah = (block >> 40) & 0xff;
356 tf->hob_lbam = (block >> 32) & 0xff;
357 tf->hob_lbal = (block >> 24) & 0xff;
358 } else
359 /* request too large even for LBA48 */
360 return -ERANGE;
361
362 if (unlikely(ata_rwcmd_protocol(tf, dev) < 0))
363 return -EINVAL;
364
365 tf->nsect = n_block & 0xff;
366
367 tf->lbah = (block >> 16) & 0xff;
368 tf->lbam = (block >> 8) & 0xff;
369 tf->lbal = block & 0xff;
370
371 tf->device |= ATA_LBA;
372 } else {
373 /* CHS */
374 u32 sect, head, cyl, track;
375
376 /* The request -may- be too large for CHS addressing. */
377 if (!lba_28_ok(block, n_block))
378 return -ERANGE;
379
380 if (unlikely(ata_rwcmd_protocol(tf, dev) < 0))
381 return -EINVAL;
382
383 /* Convert LBA to CHS */
384 track = (u32)block / dev->sectors;
385 cyl = track / dev->heads;
386 head = track % dev->heads;
387 sect = (u32)block % dev->sectors + 1;
388
389 DPRINTK("block %u track %u cyl %u head %u sect %u\n",
390 (u32)block, track, cyl, head, sect);
391
392 /* Check whether the converted CHS can fit.
393 Cylinder: 0-65535
394 Head: 0-15
395 Sector: 1-255*/
396 if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect))
397 return -ERANGE;
398
399 tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */
400 tf->lbal = sect;
401 tf->lbam = cyl;
402 tf->lbah = cyl >> 8;
403 tf->device |= head;
404 }
405
406 return 0;
407}
408
409/**
243 * ata_pack_xfermask - Pack pio, mwdma and udma masks into xfer_mask 410 * ata_pack_xfermask - Pack pio, mwdma and udma masks into xfer_mask
244 * @pio_mask: pio_mask 411 * @pio_mask: pio_mask
245 * @mwdma_mask: mwdma_mask 412 * @mwdma_mask: mwdma_mask
@@ -997,13 +1164,13 @@ void ata_qc_complete_internal(struct ata_queued_cmd *qc)
997} 1164}
998 1165
999/** 1166/**
1000 * ata_exec_internal - execute libata internal command 1167 * ata_exec_internal_sg - execute libata internal command
1001 * @dev: Device to which the command is sent 1168 * @dev: Device to which the command is sent
1002 * @tf: Taskfile registers for the command and the result 1169 * @tf: Taskfile registers for the command and the result
1003 * @cdb: CDB for packet command 1170 * @cdb: CDB for packet command
1004 * @dma_dir: Data tranfer direction of the command 1171 * @dma_dir: Data tranfer direction of the command
1005 * @buf: Data buffer of the command 1172 * @sg: sg list for the data buffer of the command
1006 * @buflen: Length of data buffer 1173 * @n_elem: Number of sg entries
1007 * 1174 *
1008 * Executes libata internal command with timeout. @tf contains 1175 * Executes libata internal command with timeout. @tf contains
1009 * command on entry and result on return. Timeout and error 1176 * command on entry and result on return. Timeout and error
@@ -1017,9 +1184,10 @@ void ata_qc_complete_internal(struct ata_queued_cmd *qc)
1017 * RETURNS: 1184 * RETURNS:
1018 * Zero on success, AC_ERR_* mask on failure 1185 * Zero on success, AC_ERR_* mask on failure
1019 */ 1186 */
1020unsigned ata_exec_internal(struct ata_device *dev, 1187unsigned ata_exec_internal_sg(struct ata_device *dev,
1021 struct ata_taskfile *tf, const u8 *cdb, 1188 struct ata_taskfile *tf, const u8 *cdb,
1022 int dma_dir, void *buf, unsigned int buflen) 1189 int dma_dir, struct scatterlist *sg,
1190 unsigned int n_elem)
1023{ 1191{
1024 struct ata_port *ap = dev->ap; 1192 struct ata_port *ap = dev->ap;
1025 u8 command = tf->command; 1193 u8 command = tf->command;
@@ -1075,7 +1243,12 @@ unsigned ata_exec_internal(struct ata_device *dev,
1075 qc->flags |= ATA_QCFLAG_RESULT_TF; 1243 qc->flags |= ATA_QCFLAG_RESULT_TF;
1076 qc->dma_dir = dma_dir; 1244 qc->dma_dir = dma_dir;
1077 if (dma_dir != DMA_NONE) { 1245 if (dma_dir != DMA_NONE) {
1078 ata_sg_init_one(qc, buf, buflen); 1246 unsigned int i, buflen = 0;
1247
1248 for (i = 0; i < n_elem; i++)
1249 buflen += sg[i].length;
1250
1251 ata_sg_init(qc, sg, n_elem);
1079 qc->nsect = buflen / ATA_SECT_SIZE; 1252 qc->nsect = buflen / ATA_SECT_SIZE;
1080 } 1253 }
1081 1254
@@ -1159,6 +1332,35 @@ unsigned ata_exec_internal(struct ata_device *dev,
1159} 1332}
1160 1333
1161/** 1334/**
1335 * ata_exec_internal_sg - execute libata internal command
1336 * @dev: Device to which the command is sent
1337 * @tf: Taskfile registers for the command and the result
1338 * @cdb: CDB for packet command
1339 * @dma_dir: Data tranfer direction of the command
1340 * @buf: Data buffer of the command
1341 * @buflen: Length of data buffer
1342 *
1343 * Wrapper around ata_exec_internal_sg() which takes simple
1344 * buffer instead of sg list.
1345 *
1346 * LOCKING:
1347 * None. Should be called with kernel context, might sleep.
1348 *
1349 * RETURNS:
1350 * Zero on success, AC_ERR_* mask on failure
1351 */
1352unsigned ata_exec_internal(struct ata_device *dev,
1353 struct ata_taskfile *tf, const u8 *cdb,
1354 int dma_dir, void *buf, unsigned int buflen)
1355{
1356 struct scatterlist sg;
1357
1358 sg_init_one(&sg, buf, buflen);
1359
1360 return ata_exec_internal_sg(dev, tf, cdb, dma_dir, &sg, 1);
1361}
1362
1363/**
1162 * ata_do_simple_cmd - execute simple internal command 1364 * ata_do_simple_cmd - execute simple internal command
1163 * @dev: Device to which the command is sent 1365 * @dev: Device to which the command is sent
1164 * @cmd: Opcode to execute 1366 * @cmd: Opcode to execute
@@ -1222,7 +1424,7 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
1222 * ata_dev_read_id - Read ID data from the specified device 1424 * ata_dev_read_id - Read ID data from the specified device
1223 * @dev: target device 1425 * @dev: target device
1224 * @p_class: pointer to class of the target device (may be changed) 1426 * @p_class: pointer to class of the target device (may be changed)
1225 * @post_reset: is this read ID post-reset? 1427 * @flags: ATA_READID_* flags
1226 * @id: buffer to read IDENTIFY data into 1428 * @id: buffer to read IDENTIFY data into
1227 * 1429 *
1228 * Read ID data from the specified device. ATA_CMD_ID_ATA is 1430 * Read ID data from the specified device. ATA_CMD_ID_ATA is
@@ -1237,7 +1439,7 @@ unsigned int ata_pio_need_iordy(const struct ata_device *adev)
1237 * 0 on success, -errno otherwise. 1439 * 0 on success, -errno otherwise.
1238 */ 1440 */
1239int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, 1441int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
1240 int post_reset, u16 *id) 1442 unsigned int flags, u16 *id)
1241{ 1443{
1242 struct ata_port *ap = dev->ap; 1444 struct ata_port *ap = dev->ap;
1243 unsigned int class = *p_class; 1445 unsigned int class = *p_class;
@@ -1269,10 +1471,17 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
1269 } 1471 }
1270 1472
1271 tf.protocol = ATA_PROT_PIO; 1473 tf.protocol = ATA_PROT_PIO;
1474 tf.flags |= ATA_TFLAG_POLLING; /* for polling presence detection */
1272 1475
1273 err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE, 1476 err_mask = ata_exec_internal(dev, &tf, NULL, DMA_FROM_DEVICE,
1274 id, sizeof(id[0]) * ATA_ID_WORDS); 1477 id, sizeof(id[0]) * ATA_ID_WORDS);
1275 if (err_mask) { 1478 if (err_mask) {
1479 if (err_mask & AC_ERR_NODEV_HINT) {
1480 DPRINTK("ata%u.%d: NODEV after polling detection\n",
1481 ap->id, dev->devno);
1482 return -ENOENT;
1483 }
1484
1276 rc = -EIO; 1485 rc = -EIO;
1277 reason = "I/O error"; 1486 reason = "I/O error";
1278 goto err_out; 1487 goto err_out;
@@ -1292,7 +1501,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
1292 goto err_out; 1501 goto err_out;
1293 } 1502 }
1294 1503
1295 if (post_reset && class == ATA_DEV_ATA) { 1504 if ((flags & ATA_READID_POSTRESET) && class == ATA_DEV_ATA) {
1296 /* 1505 /*
1297 * The exact sequence expected by certain pre-ATA4 drives is: 1506 * The exact sequence expected by certain pre-ATA4 drives is:
1298 * SRST RESET 1507 * SRST RESET
@@ -1312,7 +1521,7 @@ int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
1312 /* current CHS translation info (id[53-58]) might be 1521 /* current CHS translation info (id[53-58]) might be
1313 * changed. reread the identify device info. 1522 * changed. reread the identify device info.
1314 */ 1523 */
1315 post_reset = 0; 1524 flags &= ~ATA_READID_POSTRESET;
1316 goto retry; 1525 goto retry;
1317 } 1526 }
1318 } 1527 }
@@ -1343,7 +1552,10 @@ static void ata_dev_config_ncq(struct ata_device *dev,
1343 desc[0] = '\0'; 1552 desc[0] = '\0';
1344 return; 1553 return;
1345 } 1554 }
1346 1555 if (ata_device_blacklisted(dev) & ATA_HORKAGE_NONCQ) {
1556 snprintf(desc, desc_sz, "NCQ (not used)");
1557 return;
1558 }
1347 if (ap->flags & ATA_FLAG_NCQ) { 1559 if (ap->flags & ATA_FLAG_NCQ) {
1348 hdepth = min(ap->scsi_host->can_queue, ATA_MAX_QUEUE - 1); 1560 hdepth = min(ap->scsi_host->can_queue, ATA_MAX_QUEUE - 1);
1349 dev->flags |= ATA_DFLAG_NCQ; 1561 dev->flags |= ATA_DFLAG_NCQ;
@@ -1372,7 +1584,6 @@ static void ata_set_port_max_cmd_len(struct ata_port *ap)
1372/** 1584/**
1373 * ata_dev_configure - Configure the specified ATA/ATAPI device 1585 * ata_dev_configure - Configure the specified ATA/ATAPI device
1374 * @dev: Target device to configure 1586 * @dev: Target device to configure
1375 * @print_info: Enable device info printout
1376 * 1587 *
1377 * Configure @dev according to @dev->id. Generic and low-level 1588 * Configure @dev according to @dev->id. Generic and low-level
1378 * driver specific fixups are also applied. 1589 * driver specific fixups are also applied.
@@ -1383,9 +1594,10 @@ static void ata_set_port_max_cmd_len(struct ata_port *ap)
1383 * RETURNS: 1594 * RETURNS:
1384 * 0 on success, -errno otherwise 1595 * 0 on success, -errno otherwise
1385 */ 1596 */
1386int ata_dev_configure(struct ata_device *dev, int print_info) 1597int ata_dev_configure(struct ata_device *dev)
1387{ 1598{
1388 struct ata_port *ap = dev->ap; 1599 struct ata_port *ap = dev->ap;
1600 int print_info = ap->eh_context.i.flags & ATA_EHI_PRINTINFO;
1389 const u16 *id = dev->id; 1601 const u16 *id = dev->id;
1390 unsigned int xfer_mask; 1602 unsigned int xfer_mask;
1391 char revbuf[7]; /* XYZ-99\0 */ 1603 char revbuf[7]; /* XYZ-99\0 */
@@ -1452,6 +1664,10 @@ int ata_dev_configure(struct ata_device *dev, int print_info)
1452 if (ata_id_has_lba48(id)) { 1664 if (ata_id_has_lba48(id)) {
1453 dev->flags |= ATA_DFLAG_LBA48; 1665 dev->flags |= ATA_DFLAG_LBA48;
1454 lba_desc = "LBA48"; 1666 lba_desc = "LBA48";
1667
1668 if (dev->n_sectors >= (1UL << 28) &&
1669 ata_id_has_flush_ext(id))
1670 dev->flags |= ATA_DFLAG_FLUSH_EXT;
1455 } 1671 }
1456 1672
1457 /* config NCQ */ 1673 /* config NCQ */
@@ -1528,6 +1744,11 @@ int ata_dev_configure(struct ata_device *dev, int print_info)
1528 cdb_intr_string); 1744 cdb_intr_string);
1529 } 1745 }
1530 1746
1747 /* determine max_sectors */
1748 dev->max_sectors = ATA_MAX_SECTORS;
1749 if (dev->flags & ATA_DFLAG_LBA48)
1750 dev->max_sectors = ATA_MAX_SECTORS_LBA48;
1751
1531 if (dev->horkage & ATA_HORKAGE_DIAGNOSTIC) { 1752 if (dev->horkage & ATA_HORKAGE_DIAGNOSTIC) {
1532 /* Let the user know. We don't want to disallow opens for 1753 /* Let the user know. We don't want to disallow opens for
1533 rescue purposes, or in case the vendor is just a blithering 1754 rescue purposes, or in case the vendor is just a blithering
@@ -1629,11 +1850,14 @@ int ata_bus_probe(struct ata_port *ap)
1629 if (!ata_dev_enabled(dev)) 1850 if (!ata_dev_enabled(dev))
1630 continue; 1851 continue;
1631 1852
1632 rc = ata_dev_read_id(dev, &dev->class, 1, dev->id); 1853 rc = ata_dev_read_id(dev, &dev->class, ATA_READID_POSTRESET,
1854 dev->id);
1633 if (rc) 1855 if (rc)
1634 goto fail; 1856 goto fail;
1635 1857
1636 rc = ata_dev_configure(dev, 1); 1858 ap->eh_context.i.flags |= ATA_EHI_PRINTINFO;
1859 rc = ata_dev_configure(dev);
1860 ap->eh_context.i.flags &= ~ATA_EHI_PRINTINFO;
1637 if (rc) 1861 if (rc)
1638 goto fail; 1862 goto fail;
1639 } 1863 }
@@ -2151,6 +2375,7 @@ int ata_down_xfermask_limit(struct ata_device *dev, int force_pio0)
2151 2375
2152static int ata_dev_set_mode(struct ata_device *dev) 2376static int ata_dev_set_mode(struct ata_device *dev)
2153{ 2377{
2378 struct ata_eh_context *ehc = &dev->ap->eh_context;
2154 unsigned int err_mask; 2379 unsigned int err_mask;
2155 int rc; 2380 int rc;
2156 2381
@@ -2165,7 +2390,9 @@ static int ata_dev_set_mode(struct ata_device *dev)
2165 return -EIO; 2390 return -EIO;
2166 } 2391 }
2167 2392
2393 ehc->i.flags |= ATA_EHI_POST_SETMODE;
2168 rc = ata_dev_revalidate(dev, 0); 2394 rc = ata_dev_revalidate(dev, 0);
2395 ehc->i.flags &= ~ATA_EHI_POST_SETMODE;
2169 if (rc) 2396 if (rc)
2170 return rc; 2397 return rc;
2171 2398
@@ -2323,11 +2550,14 @@ static inline void ata_tf_to_host(struct ata_port *ap,
2323 * Sleep until ATA Status register bit BSY clears, 2550 * Sleep until ATA Status register bit BSY clears,
2324 * or a timeout occurs. 2551 * or a timeout occurs.
2325 * 2552 *
2326 * LOCKING: None. 2553 * LOCKING:
2554 * Kernel thread context (may sleep).
2555 *
2556 * RETURNS:
2557 * 0 on success, -errno otherwise.
2327 */ 2558 */
2328 2559int ata_busy_sleep(struct ata_port *ap,
2329unsigned int ata_busy_sleep (struct ata_port *ap, 2560 unsigned long tmout_pat, unsigned long tmout)
2330 unsigned long tmout_pat, unsigned long tmout)
2331{ 2561{
2332 unsigned long timer_start, timeout; 2562 unsigned long timer_start, timeout;
2333 u8 status; 2563 u8 status;
@@ -2335,27 +2565,32 @@ unsigned int ata_busy_sleep (struct ata_port *ap,
2335 status = ata_busy_wait(ap, ATA_BUSY, 300); 2565 status = ata_busy_wait(ap, ATA_BUSY, 300);
2336 timer_start = jiffies; 2566 timer_start = jiffies;
2337 timeout = timer_start + tmout_pat; 2567 timeout = timer_start + tmout_pat;
2338 while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) { 2568 while (status != 0xff && (status & ATA_BUSY) &&
2569 time_before(jiffies, timeout)) {
2339 msleep(50); 2570 msleep(50);
2340 status = ata_busy_wait(ap, ATA_BUSY, 3); 2571 status = ata_busy_wait(ap, ATA_BUSY, 3);
2341 } 2572 }
2342 2573
2343 if (status & ATA_BUSY) 2574 if (status != 0xff && (status & ATA_BUSY))
2344 ata_port_printk(ap, KERN_WARNING, 2575 ata_port_printk(ap, KERN_WARNING,
2345 "port is slow to respond, please be patient " 2576 "port is slow to respond, please be patient "
2346 "(Status 0x%x)\n", status); 2577 "(Status 0x%x)\n", status);
2347 2578
2348 timeout = timer_start + tmout; 2579 timeout = timer_start + tmout;
2349 while ((status & ATA_BUSY) && (time_before(jiffies, timeout))) { 2580 while (status != 0xff && (status & ATA_BUSY) &&
2581 time_before(jiffies, timeout)) {
2350 msleep(50); 2582 msleep(50);
2351 status = ata_chk_status(ap); 2583 status = ata_chk_status(ap);
2352 } 2584 }
2353 2585
2586 if (status == 0xff)
2587 return -ENODEV;
2588
2354 if (status & ATA_BUSY) { 2589 if (status & ATA_BUSY) {
2355 ata_port_printk(ap, KERN_ERR, "port failed to respond " 2590 ata_port_printk(ap, KERN_ERR, "port failed to respond "
2356 "(%lu secs, Status 0x%x)\n", 2591 "(%lu secs, Status 0x%x)\n",
2357 tmout / HZ, status); 2592 tmout / HZ, status);
2358 return 1; 2593 return -EBUSY;
2359 } 2594 }
2360 2595
2361 return 0; 2596 return 0;
@@ -2446,10 +2681,8 @@ static unsigned int ata_bus_softreset(struct ata_port *ap,
2446 * the bus shows 0xFF because the odd clown forgets the D7 2681 * the bus shows 0xFF because the odd clown forgets the D7
2447 * pulldown resistor. 2682 * pulldown resistor.
2448 */ 2683 */
2449 if (ata_check_status(ap) == 0xFF) { 2684 if (ata_check_status(ap) == 0xFF)
2450 ata_port_printk(ap, KERN_ERR, "SRST failed (status 0xFF)\n"); 2685 return 0;
2451 return AC_ERR_OTHER;
2452 }
2453 2686
2454 ata_bus_post_reset(ap, devmask); 2687 ata_bus_post_reset(ap, devmask);
2455 2688
@@ -2775,9 +3008,9 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
2775} 3008}
2776 3009
2777/** 3010/**
2778 * sata_std_hardreset - reset host port via SATA phy reset 3011 * sata_port_hardreset - reset port via SATA phy reset
2779 * @ap: port to reset 3012 * @ap: port to reset
2780 * @class: resulting class of attached device 3013 * @timing: timing parameters { interval, duratinon, timeout } in msec
2781 * 3014 *
2782 * SATA phy-reset host port using DET bits of SControl register. 3015 * SATA phy-reset host port using DET bits of SControl register.
2783 * 3016 *
@@ -2787,10 +3020,8 @@ int ata_std_softreset(struct ata_port *ap, unsigned int *classes)
2787 * RETURNS: 3020 * RETURNS:
2788 * 0 on success, -errno otherwise. 3021 * 0 on success, -errno otherwise.
2789 */ 3022 */
2790int sata_std_hardreset(struct ata_port *ap, unsigned int *class) 3023int sata_port_hardreset(struct ata_port *ap, const unsigned long *timing)
2791{ 3024{
2792 struct ata_eh_context *ehc = &ap->eh_context;
2793 const unsigned long *timing = sata_ehc_deb_timing(ehc);
2794 u32 scontrol; 3025 u32 scontrol;
2795 int rc; 3026 int rc;
2796 3027
@@ -2803,24 +3034,24 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
2803 * and Sil3124. 3034 * and Sil3124.
2804 */ 3035 */
2805 if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol))) 3036 if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol)))
2806 return rc; 3037 goto out;
2807 3038
2808 scontrol = (scontrol & 0x0f0) | 0x304; 3039 scontrol = (scontrol & 0x0f0) | 0x304;
2809 3040
2810 if ((rc = sata_scr_write(ap, SCR_CONTROL, scontrol))) 3041 if ((rc = sata_scr_write(ap, SCR_CONTROL, scontrol)))
2811 return rc; 3042 goto out;
2812 3043
2813 sata_set_spd(ap); 3044 sata_set_spd(ap);
2814 } 3045 }
2815 3046
2816 /* issue phy wake/reset */ 3047 /* issue phy wake/reset */
2817 if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol))) 3048 if ((rc = sata_scr_read(ap, SCR_CONTROL, &scontrol)))
2818 return rc; 3049 goto out;
2819 3050
2820 scontrol = (scontrol & 0x0f0) | 0x301; 3051 scontrol = (scontrol & 0x0f0) | 0x301;
2821 3052
2822 if ((rc = sata_scr_write_flush(ap, SCR_CONTROL, scontrol))) 3053 if ((rc = sata_scr_write_flush(ap, SCR_CONTROL, scontrol)))
2823 return rc; 3054 goto out;
2824 3055
2825 /* Couldn't find anything in SATA I/II specs, but AHCI-1.1 3056 /* Couldn't find anything in SATA I/II specs, but AHCI-1.1
2826 * 10.4.2 says at least 1 ms. 3057 * 10.4.2 says at least 1 ms.
@@ -2828,7 +3059,40 @@ int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
2828 msleep(1); 3059 msleep(1);
2829 3060
2830 /* bring phy back */ 3061 /* bring phy back */
2831 sata_phy_resume(ap, timing); 3062 rc = sata_phy_resume(ap, timing);
3063 out:
3064 DPRINTK("EXIT, rc=%d\n", rc);
3065 return rc;
3066}
3067
3068/**
3069 * sata_std_hardreset - reset host port via SATA phy reset
3070 * @ap: port to reset
3071 * @class: resulting class of attached device
3072 *
3073 * SATA phy-reset host port using DET bits of SControl register,
3074 * wait for !BSY and classify the attached device.
3075 *
3076 * LOCKING:
3077 * Kernel thread context (may sleep)
3078 *
3079 * RETURNS:
3080 * 0 on success, -errno otherwise.
3081 */
3082int sata_std_hardreset(struct ata_port *ap, unsigned int *class)
3083{
3084 const unsigned long *timing = sata_ehc_deb_timing(&ap->eh_context);
3085 int rc;
3086
3087 DPRINTK("ENTER\n");
3088
3089 /* do hardreset */
3090 rc = sata_port_hardreset(ap, timing);
3091 if (rc) {
3092 ata_port_printk(ap, KERN_ERR,
3093 "COMRESET failed (errno=%d)\n", rc);
3094 return rc;
3095 }
2832 3096
2833 /* TODO: phy layer with polling, timeouts, etc. */ 3097 /* TODO: phy layer with polling, timeouts, etc. */
2834 if (ata_port_offline(ap)) { 3098 if (ata_port_offline(ap)) {
@@ -2967,7 +3231,7 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
2967/** 3231/**
2968 * ata_dev_revalidate - Revalidate ATA device 3232 * ata_dev_revalidate - Revalidate ATA device
2969 * @dev: device to revalidate 3233 * @dev: device to revalidate
2970 * @post_reset: is this revalidation after reset? 3234 * @readid_flags: read ID flags
2971 * 3235 *
2972 * Re-read IDENTIFY page and make sure @dev is still attached to 3236 * Re-read IDENTIFY page and make sure @dev is still attached to
2973 * the port. 3237 * the port.
@@ -2978,7 +3242,7 @@ static int ata_dev_same_device(struct ata_device *dev, unsigned int new_class,
2978 * RETURNS: 3242 * RETURNS:
2979 * 0 on success, negative errno otherwise 3243 * 0 on success, negative errno otherwise
2980 */ 3244 */
2981int ata_dev_revalidate(struct ata_device *dev, int post_reset) 3245int ata_dev_revalidate(struct ata_device *dev, unsigned int readid_flags)
2982{ 3246{
2983 unsigned int class = dev->class; 3247 unsigned int class = dev->class;
2984 u16 *id = (void *)dev->ap->sector_buf; 3248 u16 *id = (void *)dev->ap->sector_buf;
@@ -2990,7 +3254,7 @@ int ata_dev_revalidate(struct ata_device *dev, int post_reset)
2990 } 3254 }
2991 3255
2992 /* read ID data */ 3256 /* read ID data */
2993 rc = ata_dev_read_id(dev, &class, post_reset, id); 3257 rc = ata_dev_read_id(dev, &class, readid_flags, id);
2994 if (rc) 3258 if (rc)
2995 goto fail; 3259 goto fail;
2996 3260
@@ -3003,7 +3267,7 @@ int ata_dev_revalidate(struct ata_device *dev, int post_reset)
3003 memcpy(dev->id, id, sizeof(id[0]) * ATA_ID_WORDS); 3267 memcpy(dev->id, id, sizeof(id[0]) * ATA_ID_WORDS);
3004 3268
3005 /* configure device according to the new ID */ 3269 /* configure device according to the new ID */
3006 rc = ata_dev_configure(dev, 0); 3270 rc = ata_dev_configure(dev);
3007 if (rc == 0) 3271 if (rc == 0)
3008 return 0; 3272 return 0;
3009 3273
@@ -3012,37 +3276,55 @@ int ata_dev_revalidate(struct ata_device *dev, int post_reset)
3012 return rc; 3276 return rc;
3013} 3277}
3014 3278
3015static const char * const ata_dma_blacklist [] = { 3279struct ata_blacklist_entry {
3016 "WDC AC11000H", NULL, 3280 const char *model_num;
3017 "WDC AC22100H", NULL, 3281 const char *model_rev;
3018 "WDC AC32500H", NULL, 3282 unsigned long horkage;
3019 "WDC AC33100H", NULL, 3283};
3020 "WDC AC31600H", NULL, 3284
3021 "WDC AC32100H", "24.09P07", 3285static const struct ata_blacklist_entry ata_device_blacklist [] = {
3022 "WDC AC23200L", "21.10N21", 3286 /* Devices with DMA related problems under Linux */
3023 "Compaq CRD-8241B", NULL, 3287 { "WDC AC11000H", NULL, ATA_HORKAGE_NODMA },
3024 "CRD-8400B", NULL, 3288 { "WDC AC22100H", NULL, ATA_HORKAGE_NODMA },
3025 "CRD-8480B", NULL, 3289 { "WDC AC32500H", NULL, ATA_HORKAGE_NODMA },
3026 "CRD-8482B", NULL, 3290 { "WDC AC33100H", NULL, ATA_HORKAGE_NODMA },
3027 "CRD-84", NULL, 3291 { "WDC AC31600H", NULL, ATA_HORKAGE_NODMA },
3028 "SanDisk SDP3B", NULL, 3292 { "WDC AC32100H", "24.09P07", ATA_HORKAGE_NODMA },
3029 "SanDisk SDP3B-64", NULL, 3293 { "WDC AC23200L", "21.10N21", ATA_HORKAGE_NODMA },
3030 "SANYO CD-ROM CRD", NULL, 3294 { "Compaq CRD-8241B", NULL, ATA_HORKAGE_NODMA },
3031 "HITACHI CDR-8", NULL, 3295 { "CRD-8400B", NULL, ATA_HORKAGE_NODMA },
3032 "HITACHI CDR-8335", NULL, 3296 { "CRD-8480B", NULL, ATA_HORKAGE_NODMA },
3033 "HITACHI CDR-8435", NULL, 3297 { "CRD-8482B", NULL, ATA_HORKAGE_NODMA },
3034 "Toshiba CD-ROM XM-6202B", NULL, 3298 { "CRD-84", NULL, ATA_HORKAGE_NODMA },
3035 "TOSHIBA CD-ROM XM-1702BC", NULL, 3299 { "SanDisk SDP3B", NULL, ATA_HORKAGE_NODMA },
3036 "CD-532E-A", NULL, 3300 { "SanDisk SDP3B-64", NULL, ATA_HORKAGE_NODMA },
3037 "E-IDE CD-ROM CR-840", NULL, 3301 { "SANYO CD-ROM CRD", NULL, ATA_HORKAGE_NODMA },
3038 "CD-ROM Drive/F5A", NULL, 3302 { "HITACHI CDR-8", NULL, ATA_HORKAGE_NODMA },
3039 "WPI CDD-820", NULL, 3303 { "HITACHI CDR-8335", NULL, ATA_HORKAGE_NODMA },
3040 "SAMSUNG CD-ROM SC-148C", NULL, 3304 { "HITACHI CDR-8435", NULL, ATA_HORKAGE_NODMA },
3041 "SAMSUNG CD-ROM SC", NULL, 3305 { "Toshiba CD-ROM XM-6202B", NULL, ATA_HORKAGE_NODMA },
3042 "SanDisk SDP3B-64", NULL, 3306 { "TOSHIBA CD-ROM XM-1702BC", NULL, ATA_HORKAGE_NODMA },
3043 "ATAPI CD-ROM DRIVE 40X MAXIMUM",NULL, 3307 { "CD-532E-A", NULL, ATA_HORKAGE_NODMA },
3044 "_NEC DV5800A", NULL, 3308 { "E-IDE CD-ROM CR-840",NULL, ATA_HORKAGE_NODMA },
3045 "SAMSUNG CD-ROM SN-124", "N001" 3309 { "CD-ROM Drive/F5A", NULL, ATA_HORKAGE_NODMA },
3310 { "WPI CDD-820", NULL, ATA_HORKAGE_NODMA },
3311 { "SAMSUNG CD-ROM SC-148C", NULL, ATA_HORKAGE_NODMA },
3312 { "SAMSUNG CD-ROM SC", NULL, ATA_HORKAGE_NODMA },
3313 { "SanDisk SDP3B-64", NULL, ATA_HORKAGE_NODMA },
3314 { "ATAPI CD-ROM DRIVE 40X MAXIMUM",NULL,ATA_HORKAGE_NODMA },
3315 { "_NEC DV5800A", NULL, ATA_HORKAGE_NODMA },
3316 { "SAMSUNG CD-ROM SN-124","N001", ATA_HORKAGE_NODMA },
3317
3318 /* Devices we expect to fail diagnostics */
3319
3320 /* Devices where NCQ should be avoided */
3321 /* NCQ is slow */
3322 { "WDC WD740ADFD-00", NULL, ATA_HORKAGE_NONCQ },
3323
3324 /* Devices with NCQ limits */
3325
3326 /* End Marker */
3327 { }
3046}; 3328};
3047 3329
3048static int ata_strim(char *s, size_t len) 3330static int ata_strim(char *s, size_t len)
@@ -3057,20 +3339,12 @@ static int ata_strim(char *s, size_t len)
3057 return len; 3339 return len;
3058} 3340}
3059 3341
3060static int ata_dma_blacklisted(const struct ata_device *dev) 3342unsigned long ata_device_blacklisted(const struct ata_device *dev)
3061{ 3343{
3062 unsigned char model_num[40]; 3344 unsigned char model_num[40];
3063 unsigned char model_rev[16]; 3345 unsigned char model_rev[16];
3064 unsigned int nlen, rlen; 3346 unsigned int nlen, rlen;
3065 int i; 3347 const struct ata_blacklist_entry *ad = ata_device_blacklist;
3066
3067 /* We don't support polling DMA.
3068 * DMA blacklist those ATAPI devices with CDB-intr (and use PIO)
3069 * if the LLDD handles only interrupts in the HSM_ST_LAST state.
3070 */
3071 if ((dev->ap->flags & ATA_FLAG_PIO_POLLING) &&
3072 (dev->flags & ATA_DFLAG_CDB_INTR))
3073 return 1;
3074 3348
3075 ata_id_string(dev->id, model_num, ATA_ID_PROD_OFS, 3349 ata_id_string(dev->id, model_num, ATA_ID_PROD_OFS,
3076 sizeof(model_num)); 3350 sizeof(model_num));
@@ -3079,17 +3353,30 @@ static int ata_dma_blacklisted(const struct ata_device *dev)
3079 nlen = ata_strim(model_num, sizeof(model_num)); 3353 nlen = ata_strim(model_num, sizeof(model_num));
3080 rlen = ata_strim(model_rev, sizeof(model_rev)); 3354 rlen = ata_strim(model_rev, sizeof(model_rev));
3081 3355
3082 for (i = 0; i < ARRAY_SIZE(ata_dma_blacklist); i += 2) { 3356 while (ad->model_num) {
3083 if (!strncmp(ata_dma_blacklist[i], model_num, nlen)) { 3357 if (!strncmp(ad->model_num, model_num, nlen)) {
3084 if (ata_dma_blacklist[i+1] == NULL) 3358 if (ad->model_rev == NULL)
3085 return 1; 3359 return ad->horkage;
3086 if (!strncmp(ata_dma_blacklist[i], model_rev, rlen)) 3360 if (!strncmp(ad->model_rev, model_rev, rlen))
3087 return 1; 3361 return ad->horkage;
3088 } 3362 }
3363 ad++;
3089 } 3364 }
3090 return 0; 3365 return 0;
3091} 3366}
3092 3367
3368static int ata_dma_blacklisted(const struct ata_device *dev)
3369{
3370 /* We don't support polling DMA.
3371 * DMA blacklist those ATAPI devices with CDB-intr (and use PIO)
3372 * if the LLDD handles only interrupts in the HSM_ST_LAST state.
3373 */
3374 if ((dev->ap->flags & ATA_FLAG_PIO_POLLING) &&
3375 (dev->flags & ATA_DFLAG_CDB_INTR))
3376 return 1;
3377 return (ata_device_blacklisted(dev) & ATA_HORKAGE_NODMA) ? 1 : 0;
3378}
3379
3093/** 3380/**
3094 * ata_dev_xfermask - Compute supported xfermask of the given device 3381 * ata_dev_xfermask - Compute supported xfermask of the given device
3095 * @dev: Device to compute xfermask for 3382 * @dev: Device to compute xfermask for
@@ -3117,6 +3404,13 @@ static void ata_dev_xfermask(struct ata_device *dev)
3117 */ 3404 */
3118 if (ap->cbl == ATA_CBL_PATA40) 3405 if (ap->cbl == ATA_CBL_PATA40)
3119 xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA); 3406 xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
3407 /* Apply drive side cable rule. Unknown or 80 pin cables reported
3408 * host side are checked drive side as well. Cases where we know a
3409 * 40wire cable is used safely for 80 are not checked here.
3410 */
3411 if (ata_drive_40wire(dev->id) && (ap->cbl == ATA_CBL_PATA_UNK || ap->cbl == ATA_CBL_PATA80))
3412 xfer_mask &= ~(0xF8 << ATA_SHIFT_UDMA);
3413
3120 3414
3121 xfer_mask &= ata_pack_xfermask(dev->pio_mask, 3415 xfer_mask &= ata_pack_xfermask(dev->pio_mask,
3122 dev->mwdma_mask, dev->udma_mask); 3416 dev->mwdma_mask, dev->udma_mask);
@@ -3234,8 +3528,7 @@ static unsigned int ata_dev_init_params(struct ata_device *dev,
3234 * LOCKING: 3528 * LOCKING:
3235 * spin_lock_irqsave(host lock) 3529 * spin_lock_irqsave(host lock)
3236 */ 3530 */
3237 3531void ata_sg_clean(struct ata_queued_cmd *qc)
3238static void ata_sg_clean(struct ata_queued_cmd *qc)
3239{ 3532{
3240 struct ata_port *ap = qc->ap; 3533 struct ata_port *ap = qc->ap;
3241 struct scatterlist *sg = qc->__sg; 3534 struct scatterlist *sg = qc->__sg;
@@ -3393,19 +3686,15 @@ void ata_noop_qc_prep(struct ata_queued_cmd *qc) { }
3393 3686
3394void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen) 3687void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
3395{ 3688{
3396 struct scatterlist *sg;
3397
3398 qc->flags |= ATA_QCFLAG_SINGLE; 3689 qc->flags |= ATA_QCFLAG_SINGLE;
3399 3690
3400 memset(&qc->sgent, 0, sizeof(qc->sgent));
3401 qc->__sg = &qc->sgent; 3691 qc->__sg = &qc->sgent;
3402 qc->n_elem = 1; 3692 qc->n_elem = 1;
3403 qc->orig_n_elem = 1; 3693 qc->orig_n_elem = 1;
3404 qc->buf_virt = buf; 3694 qc->buf_virt = buf;
3405 qc->nbytes = buflen; 3695 qc->nbytes = buflen;
3406 3696
3407 sg = qc->__sg; 3697 sg_init_one(&qc->sgent, buf, buflen);
3408 sg_init_one(sg, buf, buflen);
3409} 3698}
3410 3699
3411/** 3700/**
@@ -4198,8 +4487,12 @@ fsm_start:
4198 /* device stops HSM for abort/error */ 4487 /* device stops HSM for abort/error */
4199 qc->err_mask |= AC_ERR_DEV; 4488 qc->err_mask |= AC_ERR_DEV;
4200 else 4489 else
4201 /* HSM violation. Let EH handle this */ 4490 /* HSM violation. Let EH handle this.
4202 qc->err_mask |= AC_ERR_HSM; 4491 * Phantom devices also trigger this
4492 * condition. Mark hint.
4493 */
4494 qc->err_mask |= AC_ERR_HSM |
4495 AC_ERR_NODEV_HINT;
4203 4496
4204 ap->hsm_task_state = HSM_ST_ERR; 4497 ap->hsm_task_state = HSM_ST_ERR;
4205 goto fsm_start; 4498 goto fsm_start;
@@ -4439,6 +4732,14 @@ void __ata_qc_complete(struct ata_queued_cmd *qc)
4439 qc->complete_fn(qc); 4732 qc->complete_fn(qc);
4440} 4733}
4441 4734
4735static void fill_result_tf(struct ata_queued_cmd *qc)
4736{
4737 struct ata_port *ap = qc->ap;
4738
4739 ap->ops->tf_read(ap, &qc->result_tf);
4740 qc->result_tf.flags = qc->tf.flags;
4741}
4742
4442/** 4743/**
4443 * ata_qc_complete - Complete an active ATA command 4744 * ata_qc_complete - Complete an active ATA command
4444 * @qc: Command to complete 4745 * @qc: Command to complete
@@ -4476,7 +4777,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
4476 if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) { 4777 if (unlikely(qc->flags & ATA_QCFLAG_FAILED)) {
4477 if (!ata_tag_internal(qc->tag)) { 4778 if (!ata_tag_internal(qc->tag)) {
4478 /* always fill result TF for failed qc */ 4779 /* always fill result TF for failed qc */
4479 ap->ops->tf_read(ap, &qc->result_tf); 4780 fill_result_tf(qc);
4480 ata_qc_schedule_eh(qc); 4781 ata_qc_schedule_eh(qc);
4481 return; 4782 return;
4482 } 4783 }
@@ -4484,7 +4785,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
4484 4785
4485 /* read result TF if requested */ 4786 /* read result TF if requested */
4486 if (qc->flags & ATA_QCFLAG_RESULT_TF) 4787 if (qc->flags & ATA_QCFLAG_RESULT_TF)
4487 ap->ops->tf_read(ap, &qc->result_tf); 4788 fill_result_tf(qc);
4488 4789
4489 __ata_qc_complete(qc); 4790 __ata_qc_complete(qc);
4490 } else { 4791 } else {
@@ -4493,7 +4794,7 @@ void ata_qc_complete(struct ata_queued_cmd *qc)
4493 4794
4494 /* read result TF if failed or requested */ 4795 /* read result TF if failed or requested */
4495 if (qc->err_mask || qc->flags & ATA_QCFLAG_RESULT_TF) 4796 if (qc->err_mask || qc->flags & ATA_QCFLAG_RESULT_TF)
4496 ap->ops->tf_read(ap, &qc->result_tf); 4797 fill_result_tf(qc);
4497 4798
4498 __ata_qc_complete(qc); 4799 __ata_qc_complete(qc);
4499 } 4800 }
@@ -4673,6 +4974,14 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
4673 } 4974 }
4674 } 4975 }
4675 4976
4977 /* Some controllers show flaky interrupt behavior after
4978 * setting xfer mode. Use polling instead.
4979 */
4980 if (unlikely(qc->tf.command == ATA_CMD_SET_FEATURES &&
4981 qc->tf.feature == SETFEATURES_XFER) &&
4982 (ap->flags & ATA_FLAG_SETXFER_POLLING))
4983 qc->tf.flags |= ATA_TFLAG_POLLING;
4984
4676 /* select the device */ 4985 /* select the device */
4677 ata_dev_select(ap, qc->dev->devno, 1, 0); 4986 ata_dev_select(ap, qc->dev->devno, 1, 0);
4678 4987
@@ -4781,6 +5090,7 @@ unsigned int ata_qc_issue_prot(struct ata_queued_cmd *qc)
4781inline unsigned int ata_host_intr (struct ata_port *ap, 5090inline unsigned int ata_host_intr (struct ata_port *ap,
4782 struct ata_queued_cmd *qc) 5091 struct ata_queued_cmd *qc)
4783{ 5092{
5093 struct ata_eh_info *ehi = &ap->eh_info;
4784 u8 status, host_stat = 0; 5094 u8 status, host_stat = 0;
4785 5095
4786 VPRINTK("ata%u: protocol %d task_state %d\n", 5096 VPRINTK("ata%u: protocol %d task_state %d\n",
@@ -4841,6 +5151,11 @@ inline unsigned int ata_host_intr (struct ata_port *ap,
4841 ap->ops->irq_clear(ap); 5151 ap->ops->irq_clear(ap);
4842 5152
4843 ata_hsm_move(ap, qc, status, 0); 5153 ata_hsm_move(ap, qc, status, 0);
5154
5155 if (unlikely(qc->err_mask) && (qc->tf.protocol == ATA_PROT_DMA ||
5156 qc->tf.protocol == ATA_PROT_ATAPI_DMA))
5157 ata_ehi_push_desc(ehi, "BMDMA stat 0x%x", host_stat);
5158
4844 return 1; /* irq handled */ 5159 return 1; /* irq handled */
4845 5160
4846idle_irq: 5161idle_irq:
@@ -5047,7 +5362,7 @@ int ata_flush_cache(struct ata_device *dev)
5047 if (!ata_try_flush_cache(dev)) 5362 if (!ata_try_flush_cache(dev))
5048 return 0; 5363 return 0;
5049 5364
5050 if (ata_id_has_flush_ext(dev->id)) 5365 if (dev->flags & ATA_DFLAG_FLUSH_EXT)
5051 cmd = ATA_CMD_FLUSH_EXT; 5366 cmd = ATA_CMD_FLUSH_EXT;
5052 else 5367 else
5053 cmd = ATA_CMD_FLUSH; 5368 cmd = ATA_CMD_FLUSH;
@@ -5519,9 +5834,8 @@ int ata_device_add(const struct ata_probe_ent *ent)
5519 ap->ioaddr.bmdma_addr, 5834 ap->ioaddr.bmdma_addr,
5520 irq_line); 5835 irq_line);
5521 5836
5522 ata_chk_status(ap); 5837 /* freeze port before requesting IRQ */
5523 host->ops->irq_clear(ap); 5838 ata_eh_freeze_port(ap);
5524 ata_eh_freeze_port(ap); /* freeze port before requesting IRQ */
5525 } 5839 }
5526 5840
5527 /* obtain irq, that may be shared between channels */ 5841 /* obtain irq, that may be shared between channels */
@@ -6119,6 +6433,7 @@ EXPORT_SYMBOL_GPL(__sata_phy_reset);
6119EXPORT_SYMBOL_GPL(ata_bus_reset); 6433EXPORT_SYMBOL_GPL(ata_bus_reset);
6120EXPORT_SYMBOL_GPL(ata_std_prereset); 6434EXPORT_SYMBOL_GPL(ata_std_prereset);
6121EXPORT_SYMBOL_GPL(ata_std_softreset); 6435EXPORT_SYMBOL_GPL(ata_std_softreset);
6436EXPORT_SYMBOL_GPL(sata_port_hardreset);
6122EXPORT_SYMBOL_GPL(sata_std_hardreset); 6437EXPORT_SYMBOL_GPL(sata_std_hardreset);
6123EXPORT_SYMBOL_GPL(ata_std_postreset); 6438EXPORT_SYMBOL_GPL(ata_std_postreset);
6124EXPORT_SYMBOL_GPL(ata_dev_classify); 6439EXPORT_SYMBOL_GPL(ata_dev_classify);
@@ -6145,6 +6460,7 @@ EXPORT_SYMBOL_GPL(ata_host_suspend);
6145EXPORT_SYMBOL_GPL(ata_host_resume); 6460EXPORT_SYMBOL_GPL(ata_host_resume);
6146EXPORT_SYMBOL_GPL(ata_id_string); 6461EXPORT_SYMBOL_GPL(ata_id_string);
6147EXPORT_SYMBOL_GPL(ata_id_c_string); 6462EXPORT_SYMBOL_GPL(ata_id_c_string);
6463EXPORT_SYMBOL_GPL(ata_device_blacklisted);
6148EXPORT_SYMBOL_GPL(ata_scsi_simulate); 6464EXPORT_SYMBOL_GPL(ata_scsi_simulate);
6149 6465
6150EXPORT_SYMBOL_GPL(ata_pio_need_iordy); 6466EXPORT_SYMBOL_GPL(ata_pio_need_iordy);
diff --git a/drivers/ata/libata-eh.c b/drivers/ata/libata-eh.c
index 9f6b7cc74fd9..08ad44b3e48f 100644
--- a/drivers/ata/libata-eh.c
+++ b/drivers/ata/libata-eh.c
@@ -1136,19 +1136,21 @@ static unsigned int ata_eh_analyze_tf(struct ata_queued_cmd *qc,
1136 break; 1136 break;
1137 1137
1138 case ATA_DEV_ATAPI: 1138 case ATA_DEV_ATAPI:
1139 tmp = atapi_eh_request_sense(qc->dev, 1139 if (!(qc->ap->pflags & ATA_PFLAG_FROZEN)) {
1140 qc->scsicmd->sense_buffer); 1140 tmp = atapi_eh_request_sense(qc->dev,
1141 if (!tmp) { 1141 qc->scsicmd->sense_buffer);
1142 /* ATA_QCFLAG_SENSE_VALID is used to tell 1142 if (!tmp) {
1143 * atapi_qc_complete() that sense data is 1143 /* ATA_QCFLAG_SENSE_VALID is used to
1144 * already valid. 1144 * tell atapi_qc_complete() that sense
1145 * 1145 * data is already valid.
1146 * TODO: interpret sense data and set 1146 *
1147 * appropriate err_mask. 1147 * TODO: interpret sense data and set
1148 */ 1148 * appropriate err_mask.
1149 qc->flags |= ATA_QCFLAG_SENSE_VALID; 1149 */
1150 } else 1150 qc->flags |= ATA_QCFLAG_SENSE_VALID;
1151 qc->err_mask |= tmp; 1151 } else
1152 qc->err_mask |= tmp;
1153 }
1152 } 1154 }
1153 1155
1154 if (qc->err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT | AC_ERR_ATA_BUS)) 1156 if (qc->err_mask & (AC_ERR_HSM | AC_ERR_TIMEOUT | AC_ERR_ATA_BUS))
@@ -1433,16 +1435,39 @@ static void ata_eh_report(struct ata_port *ap)
1433 } 1435 }
1434 1436
1435 for (tag = 0; tag < ATA_MAX_QUEUE; tag++) { 1437 for (tag = 0; tag < ATA_MAX_QUEUE; tag++) {
1438 static const char *dma_str[] = {
1439 [DMA_BIDIRECTIONAL] = "bidi",
1440 [DMA_TO_DEVICE] = "out",
1441 [DMA_FROM_DEVICE] = "in",
1442 [DMA_NONE] = "",
1443 };
1436 struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag); 1444 struct ata_queued_cmd *qc = __ata_qc_from_tag(ap, tag);
1445 struct ata_taskfile *cmd = &qc->tf, *res = &qc->result_tf;
1446 unsigned int nbytes;
1437 1447
1438 if (!(qc->flags & ATA_QCFLAG_FAILED) || !qc->err_mask) 1448 if (!(qc->flags & ATA_QCFLAG_FAILED) || !qc->err_mask)
1439 continue; 1449 continue;
1440 1450
1441 ata_dev_printk(qc->dev, KERN_ERR, "tag %d cmd 0x%x " 1451 nbytes = qc->nbytes;
1442 "Emask 0x%x stat 0x%x err 0x%x (%s)\n", 1452 if (!nbytes)
1443 qc->tag, qc->tf.command, qc->err_mask, 1453 nbytes = qc->nsect << 9;
1444 qc->result_tf.command, qc->result_tf.feature, 1454
1445 ata_err_string(qc->err_mask)); 1455 ata_dev_printk(qc->dev, KERN_ERR,
1456 "cmd %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x "
1457 "tag %d cdb 0x%x data %u %s\n "
1458 "res %02x/%02x:%02x:%02x:%02x:%02x/%02x:%02x:%02x:%02x:%02x/%02x "
1459 "Emask 0x%x (%s)\n",
1460 cmd->command, cmd->feature, cmd->nsect,
1461 cmd->lbal, cmd->lbam, cmd->lbah,
1462 cmd->hob_feature, cmd->hob_nsect,
1463 cmd->hob_lbal, cmd->hob_lbam, cmd->hob_lbah,
1464 cmd->device, qc->tag, qc->cdb[0], nbytes,
1465 dma_str[qc->dma_dir],
1466 res->command, res->feature, res->nsect,
1467 res->lbal, res->lbam, res->lbah,
1468 res->hob_feature, res->hob_nsect,
1469 res->hob_lbal, res->hob_lbam, res->hob_lbah,
1470 res->device, qc->err_mask, ata_err_string(qc->err_mask));
1446 } 1471 }
1447} 1472}
1448 1473
@@ -1634,11 +1659,14 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
1634 DPRINTK("ENTER\n"); 1659 DPRINTK("ENTER\n");
1635 1660
1636 for (i = 0; i < ATA_MAX_DEVICES; i++) { 1661 for (i = 0; i < ATA_MAX_DEVICES; i++) {
1637 unsigned int action; 1662 unsigned int action, readid_flags = 0;
1638 1663
1639 dev = &ap->device[i]; 1664 dev = &ap->device[i];
1640 action = ata_eh_dev_action(dev); 1665 action = ata_eh_dev_action(dev);
1641 1666
1667 if (ehc->i.flags & ATA_EHI_DID_RESET)
1668 readid_flags |= ATA_READID_POSTRESET;
1669
1642 if (action & ATA_EH_REVALIDATE && ata_dev_ready(dev)) { 1670 if (action & ATA_EH_REVALIDATE && ata_dev_ready(dev)) {
1643 if (ata_port_offline(ap)) { 1671 if (ata_port_offline(ap)) {
1644 rc = -EIO; 1672 rc = -EIO;
@@ -1646,13 +1674,17 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
1646 } 1674 }
1647 1675
1648 ata_eh_about_to_do(ap, dev, ATA_EH_REVALIDATE); 1676 ata_eh_about_to_do(ap, dev, ATA_EH_REVALIDATE);
1649 rc = ata_dev_revalidate(dev, 1677 rc = ata_dev_revalidate(dev, readid_flags);
1650 ehc->i.flags & ATA_EHI_DID_RESET);
1651 if (rc) 1678 if (rc)
1652 break; 1679 break;
1653 1680
1654 ata_eh_done(ap, dev, ATA_EH_REVALIDATE); 1681 ata_eh_done(ap, dev, ATA_EH_REVALIDATE);
1655 1682
1683 /* Configuration may have changed, reconfigure
1684 * transfer mode.
1685 */
1686 ehc->i.flags |= ATA_EHI_SETMODE;
1687
1656 /* schedule the scsi_rescan_device() here */ 1688 /* schedule the scsi_rescan_device() here */
1657 queue_work(ata_aux_wq, &(ap->scsi_rescan_task)); 1689 queue_work(ata_aux_wq, &(ap->scsi_rescan_task));
1658 } else if (dev->class == ATA_DEV_UNKNOWN && 1690 } else if (dev->class == ATA_DEV_UNKNOWN &&
@@ -1660,18 +1692,35 @@ static int ata_eh_revalidate_and_attach(struct ata_port *ap,
1660 ata_class_enabled(ehc->classes[dev->devno])) { 1692 ata_class_enabled(ehc->classes[dev->devno])) {
1661 dev->class = ehc->classes[dev->devno]; 1693 dev->class = ehc->classes[dev->devno];
1662 1694
1663 rc = ata_dev_read_id(dev, &dev->class, 1, dev->id); 1695 rc = ata_dev_read_id(dev, &dev->class, readid_flags,
1664 if (rc == 0) 1696 dev->id);
1665 rc = ata_dev_configure(dev, 1); 1697 if (rc == 0) {
1698 ehc->i.flags |= ATA_EHI_PRINTINFO;
1699 rc = ata_dev_configure(dev);
1700 ehc->i.flags &= ~ATA_EHI_PRINTINFO;
1701 } else if (rc == -ENOENT) {
1702 /* IDENTIFY was issued to non-existent
1703 * device. No need to reset. Just
1704 * thaw and kill the device.
1705 */
1706 ata_eh_thaw_port(ap);
1707 dev->class = ATA_DEV_UNKNOWN;
1708 rc = 0;
1709 }
1666 1710
1667 if (rc) { 1711 if (rc) {
1668 dev->class = ATA_DEV_UNKNOWN; 1712 dev->class = ATA_DEV_UNKNOWN;
1669 break; 1713 break;
1670 } 1714 }
1671 1715
1672 spin_lock_irqsave(ap->lock, flags); 1716 if (ata_dev_enabled(dev)) {
1673 ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG; 1717 spin_lock_irqsave(ap->lock, flags);
1674 spin_unlock_irqrestore(ap->lock, flags); 1718 ap->pflags |= ATA_PFLAG_SCSI_HOTPLUG;
1719 spin_unlock_irqrestore(ap->lock, flags);
1720
1721 /* new device discovered, configure xfermode */
1722 ehc->i.flags |= ATA_EHI_SETMODE;
1723 }
1675 } 1724 }
1676 } 1725 }
1677 1726
@@ -1987,13 +2036,14 @@ static int ata_eh_recover(struct ata_port *ap, ata_prereset_fn_t prereset,
1987 if (rc) 2036 if (rc)
1988 goto dev_fail; 2037 goto dev_fail;
1989 2038
1990 /* configure transfer mode if the port has been reset */ 2039 /* configure transfer mode if necessary */
1991 if (ehc->i.flags & ATA_EHI_DID_RESET) { 2040 if (ehc->i.flags & ATA_EHI_SETMODE) {
1992 rc = ata_set_mode(ap, &dev); 2041 rc = ata_set_mode(ap, &dev);
1993 if (rc) { 2042 if (rc) {
1994 down_xfermask = 1; 2043 down_xfermask = 1;
1995 goto dev_fail; 2044 goto dev_fail;
1996 } 2045 }
2046 ehc->i.flags &= ~ATA_EHI_SETMODE;
1997 } 2047 }
1998 2048
1999 /* suspend devices */ 2049 /* suspend devices */
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index 4c32d93d44b1..664e1377b54c 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -671,7 +671,7 @@ void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc,
671} 671}
672 672
673/* 673/*
674 * ata_gen_ata_desc_sense - Generate check condition sense block. 674 * ata_gen_passthru_sense - Generate check condition sense block.
675 * @qc: Command that completed. 675 * @qc: Command that completed.
676 * 676 *
677 * This function is specific to the ATA descriptor format sense 677 * This function is specific to the ATA descriptor format sense
@@ -681,9 +681,9 @@ void ata_to_sense_error(unsigned id, u8 drv_stat, u8 drv_err, u8 *sk, u8 *asc,
681 * block. Clear sense key, ASC & ASCQ if there is no error. 681 * block. Clear sense key, ASC & ASCQ if there is no error.
682 * 682 *
683 * LOCKING: 683 * LOCKING:
684 * spin_lock_irqsave(host lock) 684 * None.
685 */ 685 */
686void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc) 686static void ata_gen_passthru_sense(struct ata_queued_cmd *qc)
687{ 687{
688 struct scsi_cmnd *cmd = qc->scsicmd; 688 struct scsi_cmnd *cmd = qc->scsicmd;
689 struct ata_taskfile *tf = &qc->result_tf; 689 struct ata_taskfile *tf = &qc->result_tf;
@@ -713,12 +713,9 @@ void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc)
713 713
714 desc[0] = 0x09; 714 desc[0] = 0x09;
715 715
716 /* 716 /* set length of additional sense data */
717 * Set length of additional sense data. 717 sb[7] = 14;
718 * Since we only populate descriptor 0, the total 718 desc[1] = 12;
719 * length is the same (fixed) length as descriptor 0.
720 */
721 desc[1] = sb[7] = 14;
722 719
723 /* 720 /*
724 * Copy registers into sense buffer. 721 * Copy registers into sense buffer.
@@ -746,56 +743,56 @@ void ata_gen_ata_desc_sense(struct ata_queued_cmd *qc)
746} 743}
747 744
748/** 745/**
749 * ata_gen_fixed_sense - generate a SCSI fixed sense block 746 * ata_gen_ata_sense - generate a SCSI fixed sense block
750 * @qc: Command that we are erroring out 747 * @qc: Command that we are erroring out
751 * 748 *
752 * Leverage ata_to_sense_error() to give us the codes. Fit our 749 * Generate sense block for a failed ATA command @qc. Descriptor
753 * LBA in here if there's room. 750 * format is used to accomodate LBA48 block address.
754 * 751 *
755 * LOCKING: 752 * LOCKING:
756 * inherited from caller 753 * None.
757 */ 754 */
758void ata_gen_fixed_sense(struct ata_queued_cmd *qc) 755static void ata_gen_ata_sense(struct ata_queued_cmd *qc)
759{ 756{
757 struct ata_device *dev = qc->dev;
760 struct scsi_cmnd *cmd = qc->scsicmd; 758 struct scsi_cmnd *cmd = qc->scsicmd;
761 struct ata_taskfile *tf = &qc->result_tf; 759 struct ata_taskfile *tf = &qc->result_tf;
762 unsigned char *sb = cmd->sense_buffer; 760 unsigned char *sb = cmd->sense_buffer;
761 unsigned char *desc = sb + 8;
763 int verbose = qc->ap->ops->error_handler == NULL; 762 int verbose = qc->ap->ops->error_handler == NULL;
763 u64 block;
764 764
765 memset(sb, 0, SCSI_SENSE_BUFFERSIZE); 765 memset(sb, 0, SCSI_SENSE_BUFFERSIZE);
766 766
767 cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION; 767 cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
768 768
769 /* 769 /* sense data is current and format is descriptor */
770 * Use ata_to_sense_error() to map status register bits 770 sb[0] = 0x72;
771
772 /* Use ata_to_sense_error() to map status register bits
771 * onto sense key, asc & ascq. 773 * onto sense key, asc & ascq.
772 */ 774 */
773 if (qc->err_mask || 775 if (qc->err_mask ||
774 tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) { 776 tf->command & (ATA_BUSY | ATA_DF | ATA_ERR | ATA_DRQ)) {
775 ata_to_sense_error(qc->ap->id, tf->command, tf->feature, 777 ata_to_sense_error(qc->ap->id, tf->command, tf->feature,
776 &sb[2], &sb[12], &sb[13], verbose); 778 &sb[1], &sb[2], &sb[3], verbose);
777 sb[2] &= 0x0f; 779 sb[1] &= 0x0f;
778 } 780 }
779 781
780 sb[0] = 0x70; 782 block = ata_tf_read_block(&qc->result_tf, dev);
781 sb[7] = 0x0a;
782
783 if (tf->flags & ATA_TFLAG_LBA48) {
784 /* TODO: find solution for LBA48 descriptors */
785 }
786 783
787 else if (tf->flags & ATA_TFLAG_LBA) { 784 /* information sense data descriptor */
788 /* A small (28b) LBA will fit in the 32b info field */ 785 sb[7] = 12;
789 sb[0] |= 0x80; /* set valid bit */ 786 desc[0] = 0x00;
790 sb[3] = tf->device & 0x0f; 787 desc[1] = 10;
791 sb[4] = tf->lbah;
792 sb[5] = tf->lbam;
793 sb[6] = tf->lbal;
794 }
795 788
796 else { 789 desc[2] |= 0x80; /* valid */
797 /* TODO: C/H/S */ 790 desc[6] = block >> 40;
798 } 791 desc[7] = block >> 32;
792 desc[8] = block >> 24;
793 desc[9] = block >> 16;
794 desc[10] = block >> 8;
795 desc[11] = block;
799} 796}
800 797
801static void ata_scsi_sdev_config(struct scsi_device *sdev) 798static void ata_scsi_sdev_config(struct scsi_device *sdev)
@@ -807,23 +804,10 @@ static void ata_scsi_sdev_config(struct scsi_device *sdev)
807static void ata_scsi_dev_config(struct scsi_device *sdev, 804static void ata_scsi_dev_config(struct scsi_device *sdev,
808 struct ata_device *dev) 805 struct ata_device *dev)
809{ 806{
810 unsigned int max_sectors; 807 /* configure max sectors */
811 808 blk_queue_max_sectors(sdev->request_queue, dev->max_sectors);
812 /* TODO: 2048 is an arbitrary number, not the
813 * hardware maximum. This should be increased to
814 * 65534 when Jens Axboe's patch for dynamically
815 * determining max_sectors is merged.
816 */
817 max_sectors = ATA_MAX_SECTORS;
818 if (dev->flags & ATA_DFLAG_LBA48)
819 max_sectors = ATA_MAX_SECTORS_LBA48;
820 if (dev->max_sectors)
821 max_sectors = dev->max_sectors;
822 809
823 blk_queue_max_sectors(sdev->request_queue, max_sectors); 810 /* SATA DMA transfers must be multiples of 4 byte, so
824
825 /*
826 * SATA DMA transfers must be multiples of 4 byte, so
827 * we need to pad ATAPI transfers using an extra sg. 811 * we need to pad ATAPI transfers using an extra sg.
828 * Decrement max hw segments accordingly. 812 * Decrement max hw segments accordingly.
829 */ 813 */
@@ -1040,8 +1024,7 @@ static unsigned int ata_scsi_flush_xlat(struct ata_queued_cmd *qc, const u8 *scs
1040 tf->flags |= ATA_TFLAG_DEVICE; 1024 tf->flags |= ATA_TFLAG_DEVICE;
1041 tf->protocol = ATA_PROT_NODATA; 1025 tf->protocol = ATA_PROT_NODATA;
1042 1026
1043 if ((qc->dev->flags & ATA_DFLAG_LBA48) && 1027 if (qc->dev->flags & ATA_DFLAG_FLUSH_EXT)
1044 (ata_id_has_flush_ext(qc->dev->id)))
1045 tf->command = ATA_CMD_FLUSH_EXT; 1028 tf->command = ATA_CMD_FLUSH_EXT;
1046 else 1029 else
1047 tf->command = ATA_CMD_FLUSH; 1030 tf->command = ATA_CMD_FLUSH;
@@ -1282,17 +1265,14 @@ nothing_to_do:
1282 1265
1283static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd) 1266static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicmd)
1284{ 1267{
1285 struct ata_taskfile *tf = &qc->tf; 1268 unsigned int tf_flags = 0;
1286 struct ata_device *dev = qc->dev;
1287 u64 block; 1269 u64 block;
1288 u32 n_block; 1270 u32 n_block;
1289 1271 int rc;
1290 qc->flags |= ATA_QCFLAG_IO;
1291 tf->flags |= ATA_TFLAG_ISADDR | ATA_TFLAG_DEVICE;
1292 1272
1293 if (scsicmd[0] == WRITE_10 || scsicmd[0] == WRITE_6 || 1273 if (scsicmd[0] == WRITE_10 || scsicmd[0] == WRITE_6 ||
1294 scsicmd[0] == WRITE_16) 1274 scsicmd[0] == WRITE_16)
1295 tf->flags |= ATA_TFLAG_WRITE; 1275 tf_flags |= ATA_TFLAG_WRITE;
1296 1276
1297 /* Calculate the SCSI LBA, transfer length and FUA. */ 1277 /* Calculate the SCSI LBA, transfer length and FUA. */
1298 switch (scsicmd[0]) { 1278 switch (scsicmd[0]) {
@@ -1300,7 +1280,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
1300 case WRITE_10: 1280 case WRITE_10:
1301 scsi_10_lba_len(scsicmd, &block, &n_block); 1281 scsi_10_lba_len(scsicmd, &block, &n_block);
1302 if (unlikely(scsicmd[1] & (1 << 3))) 1282 if (unlikely(scsicmd[1] & (1 << 3)))
1303 tf->flags |= ATA_TFLAG_FUA; 1283 tf_flags |= ATA_TFLAG_FUA;
1304 break; 1284 break;
1305 case READ_6: 1285 case READ_6:
1306 case WRITE_6: 1286 case WRITE_6:
@@ -1316,7 +1296,7 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
1316 case WRITE_16: 1296 case WRITE_16:
1317 scsi_16_lba_len(scsicmd, &block, &n_block); 1297 scsi_16_lba_len(scsicmd, &block, &n_block);
1318 if (unlikely(scsicmd[1] & (1 << 3))) 1298 if (unlikely(scsicmd[1] & (1 << 3)))
1319 tf->flags |= ATA_TFLAG_FUA; 1299 tf_flags |= ATA_TFLAG_FUA;
1320 break; 1300 break;
1321 default: 1301 default:
1322 DPRINTK("no-byte command\n"); 1302 DPRINTK("no-byte command\n");
@@ -1334,106 +1314,17 @@ static unsigned int ata_scsi_rw_xlat(struct ata_queued_cmd *qc, const u8 *scsicm
1334 */ 1314 */
1335 goto nothing_to_do; 1315 goto nothing_to_do;
1336 1316
1337 if ((dev->flags & (ATA_DFLAG_PIO | ATA_DFLAG_NCQ_OFF | 1317 qc->flags |= ATA_QCFLAG_IO;
1338 ATA_DFLAG_NCQ)) == ATA_DFLAG_NCQ) { 1318 qc->nsect = n_block;
1339 /* yay, NCQ */
1340 if (!lba_48_ok(block, n_block))
1341 goto out_of_range;
1342
1343 tf->protocol = ATA_PROT_NCQ;
1344 tf->flags |= ATA_TFLAG_LBA | ATA_TFLAG_LBA48;
1345
1346 if (tf->flags & ATA_TFLAG_WRITE)
1347 tf->command = ATA_CMD_FPDMA_WRITE;
1348 else
1349 tf->command = ATA_CMD_FPDMA_READ;
1350
1351 qc->nsect = n_block;
1352
1353 tf->nsect = qc->tag << 3;
1354 tf->hob_feature = (n_block >> 8) & 0xff;
1355 tf->feature = n_block & 0xff;
1356
1357 tf->hob_lbah = (block >> 40) & 0xff;
1358 tf->hob_lbam = (block >> 32) & 0xff;
1359 tf->hob_lbal = (block >> 24) & 0xff;
1360 tf->lbah = (block >> 16) & 0xff;
1361 tf->lbam = (block >> 8) & 0xff;
1362 tf->lbal = block & 0xff;
1363
1364 tf->device = 1 << 6;
1365 if (tf->flags & ATA_TFLAG_FUA)
1366 tf->device |= 1 << 7;
1367 } else if (dev->flags & ATA_DFLAG_LBA) {
1368 tf->flags |= ATA_TFLAG_LBA;
1369
1370 if (lba_28_ok(block, n_block)) {
1371 /* use LBA28 */
1372 tf->device |= (block >> 24) & 0xf;
1373 } else if (lba_48_ok(block, n_block)) {
1374 if (!(dev->flags & ATA_DFLAG_LBA48))
1375 goto out_of_range;
1376
1377 /* use LBA48 */
1378 tf->flags |= ATA_TFLAG_LBA48;
1379
1380 tf->hob_nsect = (n_block >> 8) & 0xff;
1381
1382 tf->hob_lbah = (block >> 40) & 0xff;
1383 tf->hob_lbam = (block >> 32) & 0xff;
1384 tf->hob_lbal = (block >> 24) & 0xff;
1385 } else
1386 /* request too large even for LBA48 */
1387 goto out_of_range;
1388
1389 if (unlikely(ata_rwcmd_protocol(qc) < 0))
1390 goto invalid_fld;
1391
1392 qc->nsect = n_block;
1393 tf->nsect = n_block & 0xff;
1394
1395 tf->lbah = (block >> 16) & 0xff;
1396 tf->lbam = (block >> 8) & 0xff;
1397 tf->lbal = block & 0xff;
1398
1399 tf->device |= ATA_LBA;
1400 } else {
1401 /* CHS */
1402 u32 sect, head, cyl, track;
1403
1404 /* The request -may- be too large for CHS addressing. */
1405 if (!lba_28_ok(block, n_block))
1406 goto out_of_range;
1407
1408 if (unlikely(ata_rwcmd_protocol(qc) < 0))
1409 goto invalid_fld;
1410
1411 /* Convert LBA to CHS */
1412 track = (u32)block / dev->sectors;
1413 cyl = track / dev->heads;
1414 head = track % dev->heads;
1415 sect = (u32)block % dev->sectors + 1;
1416
1417 DPRINTK("block %u track %u cyl %u head %u sect %u\n",
1418 (u32)block, track, cyl, head, sect);
1419
1420 /* Check whether the converted CHS can fit.
1421 Cylinder: 0-65535
1422 Head: 0-15
1423 Sector: 1-255*/
1424 if ((cyl >> 16) || (head >> 4) || (sect >> 8) || (!sect))
1425 goto out_of_range;
1426
1427 qc->nsect = n_block;
1428 tf->nsect = n_block & 0xff; /* Sector count 0 means 256 sectors */
1429 tf->lbal = sect;
1430 tf->lbam = cyl;
1431 tf->lbah = cyl >> 8;
1432 tf->device |= head;
1433 }
1434 1319
1435 return 0; 1320 rc = ata_build_rw_tf(&qc->tf, qc->dev, block, n_block, tf_flags,
1321 qc->tag);
1322 if (likely(rc == 0))
1323 return 0;
1436 1324
1325 if (rc == -ERANGE)
1326 goto out_of_range;
1327 /* treat all other errors as -EINVAL, fall through */
1437invalid_fld: 1328invalid_fld:
1438 ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0); 1329 ata_scsi_set_sense(qc->scsicmd, ILLEGAL_REQUEST, 0x24, 0x0);
1439 /* "Invalid field in cbd" */ 1330 /* "Invalid field in cbd" */
@@ -1477,7 +1368,7 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
1477 */ 1368 */
1478 if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) && 1369 if (((cdb[0] == ATA_16) || (cdb[0] == ATA_12)) &&
1479 ((cdb[2] & 0x20) || need_sense)) { 1370 ((cdb[2] & 0x20) || need_sense)) {
1480 ata_gen_ata_desc_sense(qc); 1371 ata_gen_passthru_sense(qc);
1481 } else { 1372 } else {
1482 if (!need_sense) { 1373 if (!need_sense) {
1483 cmd->result = SAM_STAT_GOOD; 1374 cmd->result = SAM_STAT_GOOD;
@@ -1488,7 +1379,7 @@ static void ata_scsi_qc_complete(struct ata_queued_cmd *qc)
1488 * good for smaller LBA (and maybe CHS?) 1379 * good for smaller LBA (and maybe CHS?)
1489 * devices. 1380 * devices.
1490 */ 1381 */
1491 ata_gen_fixed_sense(qc); 1382 ata_gen_ata_sense(qc);
1492 } 1383 }
1493 } 1384 }
1494 1385
@@ -1715,6 +1606,22 @@ void ata_scsi_rbuf_fill(struct ata_scsi_args *args,
1715} 1606}
1716 1607
1717/** 1608/**
1609 * ATA_SCSI_RBUF_SET - helper to set values in SCSI response buffer
1610 * @idx: byte index into SCSI response buffer
1611 * @val: value to set
1612 *
1613 * To be used by SCSI command simulator functions. This macros
1614 * expects two local variables, u8 *rbuf and unsigned int buflen,
1615 * are in scope.
1616 *
1617 * LOCKING:
1618 * None.
1619 */
1620#define ATA_SCSI_RBUF_SET(idx, val) do { \
1621 if ((idx) < buflen) rbuf[(idx)] = (u8)(val); \
1622 } while (0)
1623
1624/**
1718 * ata_scsiop_inq_std - Simulate INQUIRY command 1625 * ata_scsiop_inq_std - Simulate INQUIRY command
1719 * @args: device IDENTIFY data / SCSI command of interest. 1626 * @args: device IDENTIFY data / SCSI command of interest.
1720 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent. 1627 * @rbuf: Response buffer, to which simulated SCSI cmd output is sent.
@@ -2173,67 +2080,42 @@ saving_not_supp:
2173 * Simulate READ CAPACITY commands. 2080 * Simulate READ CAPACITY commands.
2174 * 2081 *
2175 * LOCKING: 2082 * LOCKING:
2176 * spin_lock_irqsave(host lock) 2083 * None.
2177 */ 2084 */
2178
2179unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf, 2085unsigned int ata_scsiop_read_cap(struct ata_scsi_args *args, u8 *rbuf,
2180 unsigned int buflen) 2086 unsigned int buflen)
2181{ 2087{
2182 u64 n_sectors; 2088 u64 last_lba = args->dev->n_sectors - 1; /* LBA of the last block */
2183 u32 tmp;
2184 2089
2185 VPRINTK("ENTER\n"); 2090 VPRINTK("ENTER\n");
2186 2091
2187 if (ata_id_has_lba(args->id)) {
2188 if (ata_id_has_lba48(args->id))
2189 n_sectors = ata_id_u64(args->id, 100);
2190 else
2191 n_sectors = ata_id_u32(args->id, 60);
2192 } else {
2193 /* CHS default translation */
2194 n_sectors = args->id[1] * args->id[3] * args->id[6];
2195
2196 if (ata_id_current_chs_valid(args->id))
2197 /* CHS current translation */
2198 n_sectors = ata_id_u32(args->id, 57);
2199 }
2200
2201 n_sectors--; /* ATA TotalUserSectors - 1 */
2202
2203 if (args->cmd->cmnd[0] == READ_CAPACITY) { 2092 if (args->cmd->cmnd[0] == READ_CAPACITY) {
2204 if( n_sectors >= 0xffffffffULL ) 2093 if (last_lba >= 0xffffffffULL)
2205 tmp = 0xffffffff ; /* Return max count on overflow */ 2094 last_lba = 0xffffffff;
2206 else
2207 tmp = n_sectors ;
2208 2095
2209 /* sector count, 32-bit */ 2096 /* sector count, 32-bit */
2210 rbuf[0] = tmp >> (8 * 3); 2097 ATA_SCSI_RBUF_SET(0, last_lba >> (8 * 3));
2211 rbuf[1] = tmp >> (8 * 2); 2098 ATA_SCSI_RBUF_SET(1, last_lba >> (8 * 2));
2212 rbuf[2] = tmp >> (8 * 1); 2099 ATA_SCSI_RBUF_SET(2, last_lba >> (8 * 1));
2213 rbuf[3] = tmp; 2100 ATA_SCSI_RBUF_SET(3, last_lba);
2214 2101
2215 /* sector size */ 2102 /* sector size */
2216 tmp = ATA_SECT_SIZE; 2103 ATA_SCSI_RBUF_SET(6, ATA_SECT_SIZE >> 8);
2217 rbuf[6] = tmp >> 8; 2104 ATA_SCSI_RBUF_SET(7, ATA_SECT_SIZE);
2218 rbuf[7] = tmp;
2219
2220 } else { 2105 } else {
2221 /* sector count, 64-bit */ 2106 /* sector count, 64-bit */
2222 tmp = n_sectors >> (8 * 4); 2107 ATA_SCSI_RBUF_SET(0, last_lba >> (8 * 7));
2223 rbuf[2] = tmp >> (8 * 3); 2108 ATA_SCSI_RBUF_SET(1, last_lba >> (8 * 6));
2224 rbuf[3] = tmp >> (8 * 2); 2109 ATA_SCSI_RBUF_SET(2, last_lba >> (8 * 5));
2225 rbuf[4] = tmp >> (8 * 1); 2110 ATA_SCSI_RBUF_SET(3, last_lba >> (8 * 4));
2226 rbuf[5] = tmp; 2111 ATA_SCSI_RBUF_SET(4, last_lba >> (8 * 3));
2227 tmp = n_sectors; 2112 ATA_SCSI_RBUF_SET(5, last_lba >> (8 * 2));
2228 rbuf[6] = tmp >> (8 * 3); 2113 ATA_SCSI_RBUF_SET(6, last_lba >> (8 * 1));
2229 rbuf[7] = tmp >> (8 * 2); 2114 ATA_SCSI_RBUF_SET(7, last_lba);
2230 rbuf[8] = tmp >> (8 * 1);
2231 rbuf[9] = tmp;
2232 2115
2233 /* sector size */ 2116 /* sector size */
2234 tmp = ATA_SECT_SIZE; 2117 ATA_SCSI_RBUF_SET(10, ATA_SECT_SIZE >> 8);
2235 rbuf[12] = tmp >> 8; 2118 ATA_SCSI_RBUF_SET(11, ATA_SECT_SIZE);
2236 rbuf[13] = tmp;
2237 } 2119 }
2238 2120
2239 return 0; 2121 return 0;
@@ -2319,7 +2201,7 @@ static void atapi_sense_complete(struct ata_queued_cmd *qc)
2319 * a sense descriptors, since that's only 2201 * a sense descriptors, since that's only
2320 * correct for ATA, not ATAPI 2202 * correct for ATA, not ATAPI
2321 */ 2203 */
2322 ata_gen_ata_desc_sense(qc); 2204 ata_gen_passthru_sense(qc);
2323 } 2205 }
2324 2206
2325 qc->scsidone(qc->scsicmd); 2207 qc->scsidone(qc->scsicmd);
@@ -2394,7 +2276,7 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
2394 * sense descriptors, since that's only 2276 * sense descriptors, since that's only
2395 * correct for ATA, not ATAPI 2277 * correct for ATA, not ATAPI
2396 */ 2278 */
2397 ata_gen_ata_desc_sense(qc); 2279 ata_gen_passthru_sense(qc);
2398 } 2280 }
2399 2281
2400 /* SCSI EH automatically locks door if sdev->locked is 2282 /* SCSI EH automatically locks door if sdev->locked is
@@ -2427,7 +2309,7 @@ static void atapi_qc_complete(struct ata_queued_cmd *qc)
2427 * a sense descriptors, since that's only 2309 * a sense descriptors, since that's only
2428 * correct for ATA, not ATAPI 2310 * correct for ATA, not ATAPI
2429 */ 2311 */
2430 ata_gen_ata_desc_sense(qc); 2312 ata_gen_passthru_sense(qc);
2431 } else { 2313 } else {
2432 u8 *scsicmd = cmd->cmnd; 2314 u8 *scsicmd = cmd->cmnd;
2433 2315
@@ -3183,10 +3065,12 @@ static int ata_scsi_user_scan(struct Scsi_Host *shost, unsigned int channel,
3183 rc = -EINVAL; 3065 rc = -EINVAL;
3184 } 3066 }
3185 3067
3186 if (rc == 0) 3068 if (rc == 0) {
3187 ata_port_schedule_eh(ap); 3069 ata_port_schedule_eh(ap);
3188 3070 spin_unlock_irqrestore(ap->lock, flags);
3189 spin_unlock_irqrestore(ap->lock, flags); 3071 ata_port_wait_eh(ap);
3072 } else
3073 spin_unlock_irqrestore(ap->lock, flags);
3190 3074
3191 return rc; 3075 return rc;
3192} 3076}
@@ -3207,15 +3091,27 @@ void ata_scsi_dev_rescan(struct work_struct *work)
3207{ 3091{
3208 struct ata_port *ap = 3092 struct ata_port *ap =
3209 container_of(work, struct ata_port, scsi_rescan_task); 3093 container_of(work, struct ata_port, scsi_rescan_task);
3210 struct ata_device *dev; 3094 unsigned long flags;
3211 unsigned int i; 3095 unsigned int i;
3212 3096
3097 spin_lock_irqsave(ap->lock, flags);
3098
3213 for (i = 0; i < ATA_MAX_DEVICES; i++) { 3099 for (i = 0; i < ATA_MAX_DEVICES; i++) {
3214 dev = &ap->device[i]; 3100 struct ata_device *dev = &ap->device[i];
3101 struct scsi_device *sdev = dev->sdev;
3215 3102
3216 if (ata_dev_enabled(dev) && dev->sdev) 3103 if (!ata_dev_enabled(dev) || !sdev)
3217 scsi_rescan_device(&(dev->sdev->sdev_gendev)); 3104 continue;
3105 if (scsi_device_get(sdev))
3106 continue;
3107
3108 spin_unlock_irqrestore(ap->lock, flags);
3109 scsi_rescan_device(&(sdev->sdev_gendev));
3110 scsi_device_put(sdev);
3111 spin_lock_irqsave(ap->lock, flags);
3218 } 3112 }
3113
3114 spin_unlock_irqrestore(ap->lock, flags);
3219} 3115}
3220 3116
3221/** 3117/**
diff --git a/drivers/ata/libata-sff.c b/drivers/ata/libata-sff.c
index 7645f2b30ccf..10ee22ae5c15 100644
--- a/drivers/ata/libata-sff.c
+++ b/drivers/ata/libata-sff.c
@@ -39,6 +39,35 @@
39#include "libata.h" 39#include "libata.h"
40 40
41/** 41/**
42 * ata_irq_on - Enable interrupts on a port.
43 * @ap: Port on which interrupts are enabled.
44 *
45 * Enable interrupts on a legacy IDE device using MMIO or PIO,
46 * wait for idle, clear any pending interrupts.
47 *
48 * LOCKING:
49 * Inherited from caller.
50 */
51u8 ata_irq_on(struct ata_port *ap)
52{
53 struct ata_ioports *ioaddr = &ap->ioaddr;
54 u8 tmp;
55
56 ap->ctl &= ~ATA_NIEN;
57 ap->last_ctl = ap->ctl;
58
59 if (ap->flags & ATA_FLAG_MMIO)
60 writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
61 else
62 outb(ap->ctl, ioaddr->ctl_addr);
63 tmp = ata_wait_idle(ap);
64
65 ap->ops->irq_clear(ap);
66
67 return tmp;
68}
69
70/**
42 * ata_tf_load_pio - send taskfile registers to host controller 71 * ata_tf_load_pio - send taskfile registers to host controller
43 * @ap: Port to which output is sent 72 * @ap: Port to which output is sent
44 * @tf: ATA taskfile register set 73 * @tf: ATA taskfile register set
@@ -671,6 +700,14 @@ void ata_bmdma_freeze(struct ata_port *ap)
671 writeb(ap->ctl, (void __iomem *)ioaddr->ctl_addr); 700 writeb(ap->ctl, (void __iomem *)ioaddr->ctl_addr);
672 else 701 else
673 outb(ap->ctl, ioaddr->ctl_addr); 702 outb(ap->ctl, ioaddr->ctl_addr);
703
704 /* Under certain circumstances, some controllers raise IRQ on
705 * ATA_NIEN manipulation. Also, many controllers fail to mask
706 * previously pending IRQ on ATA_NIEN assertion. Clear it.
707 */
708 ata_chk_status(ap);
709
710 ap->ops->irq_clear(ap);
674} 711}
675 712
676/** 713/**
@@ -714,7 +751,6 @@ void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
714 ata_reset_fn_t softreset, ata_reset_fn_t hardreset, 751 ata_reset_fn_t softreset, ata_reset_fn_t hardreset,
715 ata_postreset_fn_t postreset) 752 ata_postreset_fn_t postreset)
716{ 753{
717 struct ata_eh_context *ehc = &ap->eh_context;
718 struct ata_queued_cmd *qc; 754 struct ata_queued_cmd *qc;
719 unsigned long flags; 755 unsigned long flags;
720 int thaw = 0; 756 int thaw = 0;
@@ -732,9 +768,7 @@ void ata_bmdma_drive_eh(struct ata_port *ap, ata_prereset_fn_t prereset,
732 qc->tf.protocol == ATA_PROT_ATAPI_DMA)) { 768 qc->tf.protocol == ATA_PROT_ATAPI_DMA)) {
733 u8 host_stat; 769 u8 host_stat;
734 770
735 host_stat = ata_bmdma_status(ap); 771 host_stat = ap->ops->bmdma_status(ap);
736
737 ata_ehi_push_desc(&ehc->i, "BMDMA stat 0x%x", host_stat);
738 772
739 /* BMDMA controllers indicate host bus error by 773 /* BMDMA controllers indicate host bus error by
740 * setting DMA_ERR bit and timing out. As it wasn't 774 * setting DMA_ERR bit and timing out. As it wasn't
@@ -877,6 +911,7 @@ static struct ata_probe_ent *ata_pci_init_legacy_port(struct pci_dev *pdev,
877 return NULL; 911 return NULL;
878 912
879 probe_ent->n_ports = 2; 913 probe_ent->n_ports = 2;
914 probe_ent->irq_flags = IRQF_SHARED;
880 915
881 if (port_mask & ATA_PORT_PRIMARY) { 916 if (port_mask & ATA_PORT_PRIMARY) {
882 probe_ent->irq = ATA_PRIMARY_IRQ; 917 probe_ent->irq = ATA_PRIMARY_IRQ;
diff --git a/drivers/ata/libata.h b/drivers/ata/libata.h
index 7e0f3aff873d..81ae41d5f23f 100644
--- a/drivers/ata/libata.h
+++ b/drivers/ata/libata.h
@@ -39,26 +39,39 @@ struct ata_scsi_args {
39}; 39};
40 40
41/* libata-core.c */ 41/* libata-core.c */
42enum {
43 /* flags for ata_dev_read_id() */
44 ATA_READID_POSTRESET = (1 << 0), /* reading ID after reset */
45};
46
42extern struct workqueue_struct *ata_aux_wq; 47extern struct workqueue_struct *ata_aux_wq;
43extern int atapi_enabled; 48extern int atapi_enabled;
44extern int atapi_dmadir; 49extern int atapi_dmadir;
45extern int libata_fua; 50extern int libata_fua;
46extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev); 51extern struct ata_queued_cmd *ata_qc_new_init(struct ata_device *dev);
47extern int ata_rwcmd_protocol(struct ata_queued_cmd *qc); 52extern int ata_build_rw_tf(struct ata_taskfile *tf, struct ata_device *dev,
53 u64 block, u32 n_block, unsigned int tf_flags,
54 unsigned int tag);
55extern u64 ata_tf_read_block(struct ata_taskfile *tf, struct ata_device *dev);
48extern void ata_dev_disable(struct ata_device *dev); 56extern void ata_dev_disable(struct ata_device *dev);
49extern void ata_port_flush_task(struct ata_port *ap); 57extern void ata_port_flush_task(struct ata_port *ap);
50extern unsigned ata_exec_internal(struct ata_device *dev, 58extern unsigned ata_exec_internal(struct ata_device *dev,
51 struct ata_taskfile *tf, const u8 *cdb, 59 struct ata_taskfile *tf, const u8 *cdb,
52 int dma_dir, void *buf, unsigned int buflen); 60 int dma_dir, void *buf, unsigned int buflen);
61extern unsigned ata_exec_internal_sg(struct ata_device *dev,
62 struct ata_taskfile *tf, const u8 *cdb,
63 int dma_dir, struct scatterlist *sg,
64 unsigned int n_elem);
53extern unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd); 65extern unsigned int ata_do_simple_cmd(struct ata_device *dev, u8 cmd);
54extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class, 66extern int ata_dev_read_id(struct ata_device *dev, unsigned int *p_class,
55 int post_reset, u16 *id); 67 unsigned int flags, u16 *id);
56extern int ata_dev_revalidate(struct ata_device *dev, int post_reset); 68extern int ata_dev_revalidate(struct ata_device *dev, unsigned int flags);
57extern int ata_dev_configure(struct ata_device *dev, int print_info); 69extern int ata_dev_configure(struct ata_device *dev);
58extern int sata_down_spd_limit(struct ata_port *ap); 70extern int sata_down_spd_limit(struct ata_port *ap);
59extern int sata_set_spd_needed(struct ata_port *ap); 71extern int sata_set_spd_needed(struct ata_port *ap);
60extern int ata_down_xfermask_limit(struct ata_device *dev, int force_pio0); 72extern int ata_down_xfermask_limit(struct ata_device *dev, int force_pio0);
61extern int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev); 73extern int ata_set_mode(struct ata_port *ap, struct ata_device **r_failed_dev);
74extern void ata_sg_clean(struct ata_queued_cmd *qc);
62extern void ata_qc_free(struct ata_queued_cmd *qc); 75extern void ata_qc_free(struct ata_queued_cmd *qc);
63extern void ata_qc_issue(struct ata_queued_cmd *qc); 76extern void ata_qc_issue(struct ata_queued_cmd *qc);
64extern void __ata_qc_complete(struct ata_queued_cmd *qc); 77extern void __ata_qc_complete(struct ata_queued_cmd *qc);
@@ -120,4 +133,7 @@ extern void ata_scsi_error(struct Scsi_Host *host);
120extern void ata_port_wait_eh(struct ata_port *ap); 133extern void ata_port_wait_eh(struct ata_port *ap);
121extern void ata_qc_schedule_eh(struct ata_queued_cmd *qc); 134extern void ata_qc_schedule_eh(struct ata_queued_cmd *qc);
122 135
136/* libata-sff.c */
137extern u8 ata_irq_on(struct ata_port *ap);
138
123#endif /* __LIBATA_H__ */ 139#endif /* __LIBATA_H__ */
diff --git a/drivers/ata/pata_ali.c b/drivers/ata/pata_ali.c
index 64eed99f6814..c5d61d1911a5 100644
--- a/drivers/ata/pata_ali.c
+++ b/drivers/ata/pata_ali.c
@@ -34,7 +34,7 @@
34#include <linux/dmi.h> 34#include <linux/dmi.h>
35 35
36#define DRV_NAME "pata_ali" 36#define DRV_NAME "pata_ali"
37#define DRV_VERSION "0.6.6" 37#define DRV_VERSION "0.7.2"
38 38
39/* 39/*
40 * Cable special cases 40 * Cable special cases
@@ -78,7 +78,7 @@ static int ali_c2_cable_detect(struct ata_port *ap)
78 implement the detect logic */ 78 implement the detect logic */
79 79
80 if (ali_cable_override(pdev)) 80 if (ali_cable_override(pdev))
81 return ATA_CBL_PATA80; 81 return ATA_CBL_PATA40_SHORT;
82 82
83 /* Host view cable detect 0x4A bit 0 primary bit 1 secondary 83 /* Host view cable detect 0x4A bit 0 primary bit 1 secondary
84 Bit set for 40 pin */ 84 Bit set for 40 pin */
@@ -337,9 +337,6 @@ static struct scsi_host_template ali_sht = {
337 .can_queue = ATA_DEF_QUEUE, 337 .can_queue = ATA_DEF_QUEUE,
338 .this_id = ATA_SHT_THIS_ID, 338 .this_id = ATA_SHT_THIS_ID,
339 .sg_tablesize = LIBATA_MAX_PRD, 339 .sg_tablesize = LIBATA_MAX_PRD,
340 /* Keep LBA28 counts so large I/O's don't turn LBA48 and PIO
341 with older controllers. Not locked so will grow on C5 or later */
342 .max_sectors = 255,
343 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 340 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
344 .emulated = ATA_SHT_EMULATED, 341 .emulated = ATA_SHT_EMULATED,
345 .use_clustering = ATA_SHT_USE_CLUSTERING, 342 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -348,6 +345,8 @@ static struct scsi_host_template ali_sht = {
348 .slave_configure = ata_scsi_slave_config, 345 .slave_configure = ata_scsi_slave_config,
349 .slave_destroy = ata_scsi_slave_destroy, 346 .slave_destroy = ata_scsi_slave_destroy,
350 .bios_param = ata_std_bios_param, 347 .bios_param = ata_std_bios_param,
348 .resume = ata_scsi_device_resume,
349 .suspend = ata_scsi_device_suspend,
351}; 350};
352 351
353/* 352/*
@@ -497,6 +496,69 @@ static struct ata_port_operations ali_c5_port_ops = {
497 .host_stop = ata_host_stop 496 .host_stop = ata_host_stop
498}; 497};
499 498
499
500/**
501 * ali_init_chipset - chip setup function
502 * @pdev: PCI device of ATA controller
503 *
504 * Perform the setup on the device that must be done both at boot
505 * and at resume time.
506 */
507
508static void ali_init_chipset(struct pci_dev *pdev)
509{
510 u8 rev, tmp;
511 struct pci_dev *north, *isa_bridge;
512
513 pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
514
515 /*
516 * The chipset revision selects the driver operations and
517 * mode data.
518 */
519
520 if (rev >= 0x20 && rev < 0xC2) {
521 /* 1543-E/F, 1543C-C, 1543C-D, 1543C-E */
522 pci_read_config_byte(pdev, 0x4B, &tmp);
523 /* Clear CD-ROM DMA write bit */
524 tmp &= 0x7F;
525 pci_write_config_byte(pdev, 0x4B, tmp);
526 } else if (rev >= 0xC2) {
527 /* Enable cable detection logic */
528 pci_read_config_byte(pdev, 0x4B, &tmp);
529 pci_write_config_byte(pdev, 0x4B, tmp | 0x08);
530 }
531 north = pci_get_bus_and_slot(0, PCI_DEVFN(0,0));
532 isa_bridge = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
533
534 if (north && north->vendor == PCI_VENDOR_ID_AL && isa_bridge) {
535 /* Configure the ALi bridge logic. For non ALi rely on BIOS.
536 Set the south bridge enable bit */
537 pci_read_config_byte(isa_bridge, 0x79, &tmp);
538 if (rev == 0xC2)
539 pci_write_config_byte(isa_bridge, 0x79, tmp | 0x04);
540 else if (rev > 0xC2 && rev < 0xC5)
541 pci_write_config_byte(isa_bridge, 0x79, tmp | 0x02);
542 }
543 if (rev >= 0x20) {
544 /*
545 * CD_ROM DMA on (0x53 bit 0). Enable this even if we want
546 * to use PIO. 0x53 bit 1 (rev 20 only) - enable FIFO control
547 * via 0x54/55.
548 */
549 pci_read_config_byte(pdev, 0x53, &tmp);
550 if (rev <= 0x20)
551 tmp &= ~0x02;
552 if (rev >= 0xc7)
553 tmp |= 0x03;
554 else
555 tmp |= 0x01; /* CD_ROM enable for DMA */
556 pci_write_config_byte(pdev, 0x53, tmp);
557 }
558 pci_dev_put(isa_bridge);
559 pci_dev_put(north);
560 ata_pci_clear_simplex(pdev);
561}
500/** 562/**
501 * ali_init_one - discovery callback 563 * ali_init_one - discovery callback
502 * @pdev: PCI device ID 564 * @pdev: PCI device ID
@@ -570,7 +632,7 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
570 632
571 static struct ata_port_info *port_info[2]; 633 static struct ata_port_info *port_info[2];
572 u8 rev, tmp; 634 u8 rev, tmp;
573 struct pci_dev *north, *isa_bridge; 635 struct pci_dev *isa_bridge;
574 636
575 pci_read_config_byte(pdev, PCI_REVISION_ID, &rev); 637 pci_read_config_byte(pdev, PCI_REVISION_ID, &rev);
576 638
@@ -582,11 +644,6 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
582 if (rev < 0x20) { 644 if (rev < 0x20) {
583 port_info[0] = port_info[1] = &info_early; 645 port_info[0] = port_info[1] = &info_early;
584 } else if (rev < 0xC2) { 646 } else if (rev < 0xC2) {
585 /* 1543-E/F, 1543C-C, 1543C-D, 1543C-E */
586 pci_read_config_byte(pdev, 0x4B, &tmp);
587 /* Clear CD-ROM DMA write bit */
588 tmp &= 0x7F;
589 pci_write_config_byte(pdev, 0x4B, tmp);
590 port_info[0] = port_info[1] = &info_20; 647 port_info[0] = port_info[1] = &info_20;
591 } else if (rev == 0xC2) { 648 } else if (rev == 0xC2) {
592 port_info[0] = port_info[1] = &info_c2; 649 port_info[0] = port_info[1] = &info_c2;
@@ -597,54 +654,25 @@ static int ali_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
597 } else 654 } else
598 port_info[0] = port_info[1] = &info_c5; 655 port_info[0] = port_info[1] = &info_c5;
599 656
600 if (rev >= 0xC2) { 657 ali_init_chipset(pdev);
601 /* Enable cable detection logic */ 658
602 pci_read_config_byte(pdev, 0x4B, &tmp);
603 pci_write_config_byte(pdev, 0x4B, tmp | 0x08);
604 }
605
606 north = pci_get_slot(pdev->bus, PCI_DEVFN(0,0));
607 isa_bridge = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL); 659 isa_bridge = pci_get_device(PCI_VENDOR_ID_AL, PCI_DEVICE_ID_AL_M1533, NULL);
608 660 if (isa_bridge && rev >= 0x20 && rev < 0xC2) {
609 if (north && north->vendor == PCI_VENDOR_ID_AL) { 661 /* Are we paired with a UDMA capable chip */
610 /* Configure the ALi bridge logic. For non ALi rely on BIOS. 662 pci_read_config_byte(isa_bridge, 0x5E, &tmp);
611 Set the south bridge enable bit */ 663 if ((tmp & 0x1E) == 0x12)
612 pci_read_config_byte(isa_bridge, 0x79, &tmp); 664 port_info[0] = port_info[1] = &info_20_udma;
613 if (rev == 0xC2) 665 pci_dev_put(isa_bridge);
614 pci_write_config_byte(isa_bridge, 0x79, tmp | 0x04);
615 else if (rev > 0xC2)
616 pci_write_config_byte(isa_bridge, 0x79, tmp | 0x02);
617 }
618
619 if (rev >= 0x20) {
620 if (rev < 0xC2) {
621 /* Are we paired with a UDMA capable chip */
622 pci_read_config_byte(isa_bridge, 0x5E, &tmp);
623 if ((tmp & 0x1E) == 0x12)
624 port_info[0] = port_info[1] = &info_20_udma;
625 }
626 /*
627 * CD_ROM DMA on (0x53 bit 0). Enable this even if we want
628 * to use PIO. 0x53 bit 1 (rev 20 only) - enable FIFO control
629 * via 0x54/55.
630 */
631 pci_read_config_byte(pdev, 0x53, &tmp);
632 if (rev <= 0x20)
633 tmp &= ~0x02;
634 if (rev >= 0xc7)
635 tmp |= 0x03;
636 else
637 tmp |= 0x01; /* CD_ROM enable for DMA */
638 pci_write_config_byte(pdev, 0x53, tmp);
639 } 666 }
640
641 pci_dev_put(isa_bridge);
642 pci_dev_put(north);
643
644 ata_pci_clear_simplex(pdev);
645 return ata_pci_init_one(pdev, port_info, 2); 667 return ata_pci_init_one(pdev, port_info, 2);
646} 668}
647 669
670static int ali_reinit_one(struct pci_dev *pdev)
671{
672 ali_init_chipset(pdev);
673 return ata_pci_device_resume(pdev);
674}
675
648static const struct pci_device_id ali[] = { 676static const struct pci_device_id ali[] = {
649 { PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5228), }, 677 { PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5228), },
650 { PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5229), }, 678 { PCI_VDEVICE(AL, PCI_DEVICE_ID_AL_M5229), },
@@ -656,7 +684,9 @@ static struct pci_driver ali_pci_driver = {
656 .name = DRV_NAME, 684 .name = DRV_NAME,
657 .id_table = ali, 685 .id_table = ali,
658 .probe = ali_init_one, 686 .probe = ali_init_one,
659 .remove = ata_pci_remove_one 687 .remove = ata_pci_remove_one,
688 .suspend = ata_pci_device_suspend,
689 .resume = ali_reinit_one,
660}; 690};
661 691
662static int __init ali_init(void) 692static int __init ali_init(void)
diff --git a/drivers/ata/pata_amd.c b/drivers/ata/pata_amd.c
index 8be46a63af74..a6b330089f22 100644
--- a/drivers/ata/pata_amd.c
+++ b/drivers/ata/pata_amd.c
@@ -25,7 +25,7 @@
25#include <linux/libata.h> 25#include <linux/libata.h>
26 26
27#define DRV_NAME "pata_amd" 27#define DRV_NAME "pata_amd"
28#define DRV_VERSION "0.2.4" 28#define DRV_VERSION "0.2.7"
29 29
30/** 30/**
31 * timing_setup - shared timing computation and load 31 * timing_setup - shared timing computation and load
@@ -326,7 +326,6 @@ static struct scsi_host_template amd_sht = {
326 .can_queue = ATA_DEF_QUEUE, 326 .can_queue = ATA_DEF_QUEUE,
327 .this_id = ATA_SHT_THIS_ID, 327 .this_id = ATA_SHT_THIS_ID,
328 .sg_tablesize = LIBATA_MAX_PRD, 328 .sg_tablesize = LIBATA_MAX_PRD,
329 .max_sectors = ATA_MAX_SECTORS,
330 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 329 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
331 .emulated = ATA_SHT_EMULATED, 330 .emulated = ATA_SHT_EMULATED,
332 .use_clustering = ATA_SHT_USE_CLUSTERING, 331 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -335,6 +334,8 @@ static struct scsi_host_template amd_sht = {
335 .slave_configure = ata_scsi_slave_config, 334 .slave_configure = ata_scsi_slave_config,
336 .slave_destroy = ata_scsi_slave_destroy, 335 .slave_destroy = ata_scsi_slave_destroy,
337 .bios_param = ata_std_bios_param, 336 .bios_param = ata_std_bios_param,
337 .resume = ata_scsi_device_resume,
338 .suspend = ata_scsi_device_suspend,
338}; 339};
339 340
340static struct ata_port_operations amd33_port_ops = { 341static struct ata_port_operations amd33_port_ops = {
@@ -662,6 +663,23 @@ static int amd_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
662 return ata_pci_init_one(pdev, port_info, 2); 663 return ata_pci_init_one(pdev, port_info, 2);
663} 664}
664 665
666static int amd_reinit_one(struct pci_dev *pdev)
667{
668 if (pdev->vendor == PCI_VENDOR_ID_AMD) {
669 u8 fifo;
670 pci_read_config_byte(pdev, 0x41, &fifo);
671 if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7411)
672 /* FIFO is broken */
673 pci_write_config_byte(pdev, 0x41, fifo & 0x0F);
674 else
675 pci_write_config_byte(pdev, 0x41, fifo | 0xF0);
676 if (pdev->device == PCI_DEVICE_ID_AMD_VIPER_7409 ||
677 pdev->device == PCI_DEVICE_ID_AMD_COBRA_7401)
678 ata_pci_clear_simplex(pdev);
679 }
680 return ata_pci_device_resume(pdev);
681}
682
665static const struct pci_device_id amd[] = { 683static const struct pci_device_id amd[] = {
666 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_COBRA_7401), 0 }, 684 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_COBRA_7401), 0 },
667 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_VIPER_7409), 1 }, 685 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_VIPER_7409), 1 },
@@ -689,7 +707,9 @@ static struct pci_driver amd_pci_driver = {
689 .name = DRV_NAME, 707 .name = DRV_NAME,
690 .id_table = amd, 708 .id_table = amd,
691 .probe = amd_init_one, 709 .probe = amd_init_one,
692 .remove = ata_pci_remove_one 710 .remove = ata_pci_remove_one,
711 .suspend = ata_pci_device_suspend,
712 .resume = amd_reinit_one,
693}; 713};
694 714
695static int __init amd_init(void) 715static int __init amd_init(void)
diff --git a/drivers/ata/pata_artop.c b/drivers/ata/pata_artop.c
index 2cd30761ca1f..37bc1323bda7 100644
--- a/drivers/ata/pata_artop.c
+++ b/drivers/ata/pata_artop.c
@@ -307,7 +307,6 @@ static struct scsi_host_template artop_sht = {
307 .can_queue = ATA_DEF_QUEUE, 307 .can_queue = ATA_DEF_QUEUE,
308 .this_id = ATA_SHT_THIS_ID, 308 .this_id = ATA_SHT_THIS_ID,
309 .sg_tablesize = LIBATA_MAX_PRD, 309 .sg_tablesize = LIBATA_MAX_PRD,
310 .max_sectors = ATA_MAX_SECTORS,
311 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 310 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
312 .emulated = ATA_SHT_EMULATED, 311 .emulated = ATA_SHT_EMULATED,
313 .use_clustering = ATA_SHT_USE_CLUSTERING, 312 .use_clustering = ATA_SHT_USE_CLUSTERING,
diff --git a/drivers/ata/pata_atiixp.c b/drivers/ata/pata_atiixp.c
index 4e1d3b59adbb..6f6672c55131 100644
--- a/drivers/ata/pata_atiixp.c
+++ b/drivers/ata/pata_atiixp.c
@@ -22,7 +22,7 @@
22#include <linux/libata.h> 22#include <linux/libata.h>
23 23
24#define DRV_NAME "pata_atiixp" 24#define DRV_NAME "pata_atiixp"
25#define DRV_VERSION "0.4.3" 25#define DRV_VERSION "0.4.4"
26 26
27enum { 27enum {
28 ATIIXP_IDE_PIO_TIMING = 0x40, 28 ATIIXP_IDE_PIO_TIMING = 0x40,
@@ -209,7 +209,6 @@ static struct scsi_host_template atiixp_sht = {
209 .can_queue = ATA_DEF_QUEUE, 209 .can_queue = ATA_DEF_QUEUE,
210 .this_id = ATA_SHT_THIS_ID, 210 .this_id = ATA_SHT_THIS_ID,
211 .sg_tablesize = LIBATA_MAX_PRD, 211 .sg_tablesize = LIBATA_MAX_PRD,
212 .max_sectors = ATA_MAX_SECTORS,
213 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 212 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
214 .emulated = ATA_SHT_EMULATED, 213 .emulated = ATA_SHT_EMULATED,
215 .use_clustering = ATA_SHT_USE_CLUSTERING, 214 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -218,6 +217,8 @@ static struct scsi_host_template atiixp_sht = {
218 .slave_configure = ata_scsi_slave_config, 217 .slave_configure = ata_scsi_slave_config,
219 .slave_destroy = ata_scsi_slave_destroy, 218 .slave_destroy = ata_scsi_slave_destroy,
220 .bios_param = ata_std_bios_param, 219 .bios_param = ata_std_bios_param,
220 .resume = ata_scsi_device_resume,
221 .suspend = ata_scsi_device_suspend,
221}; 222};
222 223
223static struct ata_port_operations atiixp_port_ops = { 224static struct ata_port_operations atiixp_port_ops = {
@@ -281,7 +282,9 @@ static struct pci_driver atiixp_pci_driver = {
281 .name = DRV_NAME, 282 .name = DRV_NAME,
282 .id_table = atiixp, 283 .id_table = atiixp,
283 .probe = atiixp_init_one, 284 .probe = atiixp_init_one,
284 .remove = ata_pci_remove_one 285 .remove = ata_pci_remove_one,
286 .resume = ata_pci_device_resume,
287 .suspend = ata_pci_device_suspend,
285}; 288};
286 289
287static int __init atiixp_init(void) 290static int __init atiixp_init(void)
diff --git a/drivers/ata/pata_cmd64x.c b/drivers/ata/pata_cmd64x.c
index 29a60df465da..15841a563694 100644
--- a/drivers/ata/pata_cmd64x.c
+++ b/drivers/ata/pata_cmd64x.c
@@ -31,7 +31,7 @@
31#include <linux/libata.h> 31#include <linux/libata.h>
32 32
33#define DRV_NAME "pata_cmd64x" 33#define DRV_NAME "pata_cmd64x"
34#define DRV_VERSION "0.2.1" 34#define DRV_VERSION "0.2.2"
35 35
36/* 36/*
37 * CMD64x specific registers definition. 37 * CMD64x specific registers definition.
@@ -268,7 +268,6 @@ static struct scsi_host_template cmd64x_sht = {
268 .can_queue = ATA_DEF_QUEUE, 268 .can_queue = ATA_DEF_QUEUE,
269 .this_id = ATA_SHT_THIS_ID, 269 .this_id = ATA_SHT_THIS_ID,
270 .sg_tablesize = LIBATA_MAX_PRD, 270 .sg_tablesize = LIBATA_MAX_PRD,
271 .max_sectors = ATA_MAX_SECTORS,
272 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 271 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
273 .emulated = ATA_SHT_EMULATED, 272 .emulated = ATA_SHT_EMULATED,
274 .use_clustering = ATA_SHT_USE_CLUSTERING, 273 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -277,6 +276,8 @@ static struct scsi_host_template cmd64x_sht = {
277 .slave_configure = ata_scsi_slave_config, 276 .slave_configure = ata_scsi_slave_config,
278 .slave_destroy = ata_scsi_slave_destroy, 277 .slave_destroy = ata_scsi_slave_destroy,
279 .bios_param = ata_std_bios_param, 278 .bios_param = ata_std_bios_param,
279 .resume = ata_scsi_device_resume,
280 .suspend = ata_scsi_device_suspend,
280}; 281};
281 282
282static struct ata_port_operations cmd64x_port_ops = { 283static struct ata_port_operations cmd64x_port_ops = {
@@ -469,6 +470,20 @@ static int cmd64x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
469 return ata_pci_init_one(pdev, port_info, 2); 470 return ata_pci_init_one(pdev, port_info, 2);
470} 471}
471 472
473static int cmd64x_reinit_one(struct pci_dev *pdev)
474{
475 u8 mrdmode;
476 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 64);
477 pci_read_config_byte(pdev, MRDMODE, &mrdmode);
478 mrdmode &= ~ 0x30; /* IRQ set up */
479 mrdmode |= 0x02; /* Memory read line enable */
480 pci_write_config_byte(pdev, MRDMODE, mrdmode);
481#ifdef CONFIG_PPC
482 pci_write_config_byte(pdev, UDIDETCR0, 0xF0);
483#endif
484 return ata_pci_device_resume(pdev);
485}
486
472static const struct pci_device_id cmd64x[] = { 487static const struct pci_device_id cmd64x[] = {
473 { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_643), 0 }, 488 { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_643), 0 },
474 { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_646), 1 }, 489 { PCI_VDEVICE(CMD, PCI_DEVICE_ID_CMD_646), 1 },
@@ -482,7 +497,9 @@ static struct pci_driver cmd64x_pci_driver = {
482 .name = DRV_NAME, 497 .name = DRV_NAME,
483 .id_table = cmd64x, 498 .id_table = cmd64x,
484 .probe = cmd64x_init_one, 499 .probe = cmd64x_init_one,
485 .remove = ata_pci_remove_one 500 .remove = ata_pci_remove_one,
501 .suspend = ata_pci_device_suspend,
502 .resume = cmd64x_reinit_one,
486}; 503};
487 504
488static int __init cmd64x_init(void) 505static int __init cmd64x_init(void)
diff --git a/drivers/ata/pata_cs5520.c b/drivers/ata/pata_cs5520.c
index 33d2b88f9c79..9f165a8e032d 100644
--- a/drivers/ata/pata_cs5520.c
+++ b/drivers/ata/pata_cs5520.c
@@ -41,7 +41,7 @@
41#include <linux/libata.h> 41#include <linux/libata.h>
42 42
43#define DRV_NAME "pata_cs5520" 43#define DRV_NAME "pata_cs5520"
44#define DRV_VERSION "0.6.2" 44#define DRV_VERSION "0.6.3"
45 45
46struct pio_clocks 46struct pio_clocks
47{ 47{
@@ -159,7 +159,6 @@ static struct scsi_host_template cs5520_sht = {
159 .can_queue = ATA_DEF_QUEUE, 159 .can_queue = ATA_DEF_QUEUE,
160 .this_id = ATA_SHT_THIS_ID, 160 .this_id = ATA_SHT_THIS_ID,
161 .sg_tablesize = LIBATA_MAX_PRD, 161 .sg_tablesize = LIBATA_MAX_PRD,
162 .max_sectors = ATA_MAX_SECTORS,
163 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 162 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
164 .emulated = ATA_SHT_EMULATED, 163 .emulated = ATA_SHT_EMULATED,
165 .use_clustering = ATA_SHT_USE_CLUSTERING, 164 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -168,6 +167,8 @@ static struct scsi_host_template cs5520_sht = {
168 .slave_configure = ata_scsi_slave_config, 167 .slave_configure = ata_scsi_slave_config,
169 .slave_destroy = ata_scsi_slave_destroy, 168 .slave_destroy = ata_scsi_slave_destroy,
170 .bios_param = ata_std_bios_param, 169 .bios_param = ata_std_bios_param,
170 .resume = ata_scsi_device_resume,
171 .suspend = ata_scsi_device_suspend,
171}; 172};
172 173
173static struct ata_port_operations cs5520_port_ops = { 174static struct ata_port_operations cs5520_port_ops = {
@@ -297,6 +298,22 @@ static void __devexit cs5520_remove_one(struct pci_dev *pdev)
297 dev_set_drvdata(dev, NULL); 298 dev_set_drvdata(dev, NULL);
298} 299}
299 300
301/**
302 * cs5520_reinit_one - device resume
303 * @pdev: PCI device
304 *
305 * Do any reconfiguration work needed by a resume from RAM. We need
306 * to restore DMA mode support on BIOSen which disabled it
307 */
308
309static int cs5520_reinit_one(struct pci_dev *pdev)
310{
311 u8 pcicfg;
312 pci_read_config_byte(pdev, 0x60, &pcicfg);
313 if ((pcicfg & 0x40) == 0)
314 pci_write_config_byte(pdev, 0x60, pcicfg | 0x40);
315 return ata_pci_device_resume(pdev);
316}
300/* For now keep DMA off. We can set it for all but A rev CS5510 once the 317/* For now keep DMA off. We can set it for all but A rev CS5510 once the
301 core ATA code can handle it */ 318 core ATA code can handle it */
302 319
@@ -311,7 +328,9 @@ static struct pci_driver cs5520_pci_driver = {
311 .name = DRV_NAME, 328 .name = DRV_NAME,
312 .id_table = pata_cs5520, 329 .id_table = pata_cs5520,
313 .probe = cs5520_init_one, 330 .probe = cs5520_init_one,
314 .remove = cs5520_remove_one 331 .remove = cs5520_remove_one,
332 .suspend = ata_pci_device_suspend,
333 .resume = cs5520_reinit_one,
315}; 334};
316 335
317static int __init cs5520_init(void) 336static int __init cs5520_init(void)
diff --git a/drivers/ata/pata_cs5530.c b/drivers/ata/pata_cs5530.c
index 981f49223469..1c628014dae6 100644
--- a/drivers/ata/pata_cs5530.c
+++ b/drivers/ata/pata_cs5530.c
@@ -35,7 +35,7 @@
35#include <linux/dmi.h> 35#include <linux/dmi.h>
36 36
37#define DRV_NAME "pata_cs5530" 37#define DRV_NAME "pata_cs5530"
38#define DRV_VERSION "0.6" 38#define DRV_VERSION "0.7.1"
39 39
40/** 40/**
41 * cs5530_set_piomode - PIO setup 41 * cs5530_set_piomode - PIO setup
@@ -173,7 +173,6 @@ static struct scsi_host_template cs5530_sht = {
173 .can_queue = ATA_DEF_QUEUE, 173 .can_queue = ATA_DEF_QUEUE,
174 .this_id = ATA_SHT_THIS_ID, 174 .this_id = ATA_SHT_THIS_ID,
175 .sg_tablesize = LIBATA_MAX_PRD, 175 .sg_tablesize = LIBATA_MAX_PRD,
176 .max_sectors = ATA_MAX_SECTORS,
177 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 176 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
178 .emulated = ATA_SHT_EMULATED, 177 .emulated = ATA_SHT_EMULATED,
179 .use_clustering = ATA_SHT_USE_CLUSTERING, 178 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -182,6 +181,8 @@ static struct scsi_host_template cs5530_sht = {
182 .slave_configure = ata_scsi_slave_config, 181 .slave_configure = ata_scsi_slave_config,
183 .slave_destroy = ata_scsi_slave_destroy, 182 .slave_destroy = ata_scsi_slave_destroy,
184 .bios_param = ata_std_bios_param, 183 .bios_param = ata_std_bios_param,
184 .resume = ata_scsi_device_resume,
185 .suspend = ata_scsi_device_suspend,
185}; 186};
186 187
187static struct ata_port_operations cs5530_port_ops = { 188static struct ata_port_operations cs5530_port_ops = {
@@ -239,38 +240,18 @@ static int cs5530_is_palmax(void)
239 return 0; 240 return 0;
240} 241}
241 242
243
242/** 244/**
243 * cs5530_init_one - Initialise a CS5530 245 * cs5530_init_chip - Chipset init
244 * @dev: PCI device
245 * @id: Entry in match table
246 * 246 *
247 * Install a driver for the newly found CS5530 companion chip. Most of 247 * Perform the chip initialisation work that is shared between both
248 * this is just housekeeping. We have to set the chip up correctly and 248 * setup and resume paths
249 * turn off various bits of emulation magic.
250 */ 249 */
251 250
252static int cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id) 251static int cs5530_init_chip(void)
253{ 252{
254 int compiler_warning_pointless_fix; 253 struct pci_dev *master_0 = NULL, *cs5530_0 = NULL, *dev = NULL;
255 struct pci_dev *master_0 = NULL, *cs5530_0 = NULL;
256 static struct ata_port_info info = {
257 .sht = &cs5530_sht,
258 .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
259 .pio_mask = 0x1f,
260 .mwdma_mask = 0x07,
261 .udma_mask = 0x07,
262 .port_ops = &cs5530_port_ops
263 };
264 /* The docking connector doesn't do UDMA, and it seems not MWDMA */
265 static struct ata_port_info info_palmax_secondary = {
266 .sht = &cs5530_sht,
267 .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
268 .pio_mask = 0x1f,
269 .port_ops = &cs5530_port_ops
270 };
271 static struct ata_port_info *port_info[2] = { &info, &info };
272 254
273 dev = NULL;
274 while ((dev = pci_get_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) { 255 while ((dev = pci_get_device(PCI_VENDOR_ID_CYRIX, PCI_ANY_ID, dev)) != NULL) {
275 switch (dev->device) { 256 switch (dev->device) {
276 case PCI_DEVICE_ID_CYRIX_PCI_MASTER: 257 case PCI_DEVICE_ID_CYRIX_PCI_MASTER:
@@ -291,7 +272,7 @@ static int cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id)
291 } 272 }
292 273
293 pci_set_master(cs5530_0); 274 pci_set_master(cs5530_0);
294 compiler_warning_pointless_fix = pci_set_mwi(cs5530_0); 275 pci_set_mwi(cs5530_0);
295 276
296 /* 277 /*
297 * Set PCI CacheLineSize to 16-bytes: 278 * Set PCI CacheLineSize to 16-bytes:
@@ -339,13 +320,7 @@ static int cs5530_init_one(struct pci_dev *dev, const struct pci_device_id *id)
339 320
340 pci_dev_put(master_0); 321 pci_dev_put(master_0);
341 pci_dev_put(cs5530_0); 322 pci_dev_put(cs5530_0);
342 323 return 0;
343 if (cs5530_is_palmax())
344 port_info[1] = &info_palmax_secondary;
345
346 /* Now kick off ATA set up */
347 return ata_pci_init_one(dev, port_info, 2);
348
349fail_put: 324fail_put:
350 if (master_0) 325 if (master_0)
351 pci_dev_put(master_0); 326 pci_dev_put(master_0);
@@ -354,6 +329,53 @@ fail_put:
354 return -ENODEV; 329 return -ENODEV;
355} 330}
356 331
332/**
333 * cs5530_init_one - Initialise a CS5530
334 * @dev: PCI device
335 * @id: Entry in match table
336 *
337 * Install a driver for the newly found CS5530 companion chip. Most of
338 * this is just housekeeping. We have to set the chip up correctly and
339 * turn off various bits of emulation magic.
340 */
341
342static int cs5530_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
343{
344 static struct ata_port_info info = {
345 .sht = &cs5530_sht,
346 .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
347 .pio_mask = 0x1f,
348 .mwdma_mask = 0x07,
349 .udma_mask = 0x07,
350 .port_ops = &cs5530_port_ops
351 };
352 /* The docking connector doesn't do UDMA, and it seems not MWDMA */
353 static struct ata_port_info info_palmax_secondary = {
354 .sht = &cs5530_sht,
355 .flags = ATA_FLAG_SLAVE_POSS|ATA_FLAG_SRST,
356 .pio_mask = 0x1f,
357 .port_ops = &cs5530_port_ops
358 };
359 static struct ata_port_info *port_info[2] = { &info, &info };
360
361 /* Chip initialisation */
362 if (cs5530_init_chip())
363 return -ENODEV;
364
365 if (cs5530_is_palmax())
366 port_info[1] = &info_palmax_secondary;
367
368 /* Now kick off ATA set up */
369 return ata_pci_init_one(pdev, port_info, 2);
370}
371
372static int cs5530_reinit_one(struct pci_dev *pdev)
373{
374 /* If we fail on resume we are doomed */
375 BUG_ON(cs5530_init_chip());
376 return ata_pci_device_resume(pdev);
377}
378
357static const struct pci_device_id cs5530[] = { 379static const struct pci_device_id cs5530[] = {
358 { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE), }, 380 { PCI_VDEVICE(CYRIX, PCI_DEVICE_ID_CYRIX_5530_IDE), },
359 381
@@ -364,7 +386,9 @@ static struct pci_driver cs5530_pci_driver = {
364 .name = DRV_NAME, 386 .name = DRV_NAME,
365 .id_table = cs5530, 387 .id_table = cs5530,
366 .probe = cs5530_init_one, 388 .probe = cs5530_init_one,
367 .remove = ata_pci_remove_one 389 .remove = ata_pci_remove_one,
390 .suspend = ata_pci_device_suspend,
391 .resume = cs5530_reinit_one,
368}; 392};
369 393
370static int __init cs5530_init(void) 394static int __init cs5530_init(void)
diff --git a/drivers/ata/pata_cs5535.c b/drivers/ata/pata_cs5535.c
index 8dafa4a49fdc..e3efec4ffc79 100644
--- a/drivers/ata/pata_cs5535.c
+++ b/drivers/ata/pata_cs5535.c
@@ -39,7 +39,7 @@
39#include <asm/msr.h> 39#include <asm/msr.h>
40 40
41#define DRV_NAME "cs5535" 41#define DRV_NAME "cs5535"
42#define DRV_VERSION "0.2.10" 42#define DRV_VERSION "0.2.11"
43 43
44/* 44/*
45 * The Geode (Aka Athlon GX now) uses an internal MSR based 45 * The Geode (Aka Athlon GX now) uses an internal MSR based
@@ -177,7 +177,6 @@ static struct scsi_host_template cs5535_sht = {
177 .can_queue = ATA_DEF_QUEUE, 177 .can_queue = ATA_DEF_QUEUE,
178 .this_id = ATA_SHT_THIS_ID, 178 .this_id = ATA_SHT_THIS_ID,
179 .sg_tablesize = LIBATA_MAX_PRD, 179 .sg_tablesize = LIBATA_MAX_PRD,
180 .max_sectors = ATA_MAX_SECTORS,
181 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 180 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
182 .emulated = ATA_SHT_EMULATED, 181 .emulated = ATA_SHT_EMULATED,
183 .use_clustering = ATA_SHT_USE_CLUSTERING, 182 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -186,6 +185,8 @@ static struct scsi_host_template cs5535_sht = {
186 .slave_configure = ata_scsi_slave_config, 185 .slave_configure = ata_scsi_slave_config,
187 .slave_destroy = ata_scsi_slave_destroy, 186 .slave_destroy = ata_scsi_slave_destroy,
188 .bios_param = ata_std_bios_param, 187 .bios_param = ata_std_bios_param,
188 .resume = ata_scsi_device_resume,
189 .suspend = ata_scsi_device_suspend,
189}; 190};
190 191
191static struct ata_port_operations cs5535_port_ops = { 192static struct ata_port_operations cs5535_port_ops = {
@@ -268,7 +269,9 @@ static struct pci_driver cs5535_pci_driver = {
268 .name = DRV_NAME, 269 .name = DRV_NAME,
269 .id_table = cs5535, 270 .id_table = cs5535,
270 .probe = cs5535_init_one, 271 .probe = cs5535_init_one,
271 .remove = ata_pci_remove_one 272 .remove = ata_pci_remove_one,
273 .suspend = ata_pci_device_suspend,
274 .resume = ata_pci_device_resume,
272}; 275};
273 276
274static int __init cs5535_init(void) 277static int __init cs5535_init(void)
diff --git a/drivers/ata/pata_cypress.c b/drivers/ata/pata_cypress.c
index 5a0b811907ee..e2a95699bae7 100644
--- a/drivers/ata/pata_cypress.c
+++ b/drivers/ata/pata_cypress.c
@@ -18,7 +18,7 @@
18#include <linux/libata.h> 18#include <linux/libata.h>
19 19
20#define DRV_NAME "pata_cypress" 20#define DRV_NAME "pata_cypress"
21#define DRV_VERSION "0.1.2" 21#define DRV_VERSION "0.1.4"
22 22
23/* here are the offset definitions for the registers */ 23/* here are the offset definitions for the registers */
24 24
@@ -128,7 +128,6 @@ static struct scsi_host_template cy82c693_sht = {
128 .can_queue = ATA_DEF_QUEUE, 128 .can_queue = ATA_DEF_QUEUE,
129 .this_id = ATA_SHT_THIS_ID, 129 .this_id = ATA_SHT_THIS_ID,
130 .sg_tablesize = LIBATA_MAX_PRD, 130 .sg_tablesize = LIBATA_MAX_PRD,
131 .max_sectors = ATA_MAX_SECTORS,
132 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 131 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
133 .emulated = ATA_SHT_EMULATED, 132 .emulated = ATA_SHT_EMULATED,
134 .use_clustering = ATA_SHT_USE_CLUSTERING, 133 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -137,6 +136,8 @@ static struct scsi_host_template cy82c693_sht = {
137 .slave_configure = ata_scsi_slave_config, 136 .slave_configure = ata_scsi_slave_config,
138 .slave_destroy = ata_scsi_slave_destroy, 137 .slave_destroy = ata_scsi_slave_destroy,
139 .bios_param = ata_std_bios_param, 138 .bios_param = ata_std_bios_param,
139 .resume = ata_scsi_device_resume,
140 .suspend = ata_scsi_device_suspend,
140}; 141};
141 142
142static struct ata_port_operations cy82c693_port_ops = { 143static struct ata_port_operations cy82c693_port_ops = {
@@ -204,7 +205,9 @@ static struct pci_driver cy82c693_pci_driver = {
204 .name = DRV_NAME, 205 .name = DRV_NAME,
205 .id_table = cy82c693, 206 .id_table = cy82c693,
206 .probe = cy82c693_init_one, 207 .probe = cy82c693_init_one,
207 .remove = ata_pci_remove_one 208 .remove = ata_pci_remove_one,
209 .suspend = ata_pci_device_suspend,
210 .resume = ata_pci_device_resume,
208}; 211};
209 212
210static int __init cy82c693_init(void) 213static int __init cy82c693_init(void)
diff --git a/drivers/ata/pata_efar.c b/drivers/ata/pata_efar.c
index 755f79279de3..edf8a63f50af 100644
--- a/drivers/ata/pata_efar.c
+++ b/drivers/ata/pata_efar.c
@@ -22,7 +22,7 @@
22#include <linux/ata.h> 22#include <linux/ata.h>
23 23
24#define DRV_NAME "pata_efar" 24#define DRV_NAME "pata_efar"
25#define DRV_VERSION "0.4.2" 25#define DRV_VERSION "0.4.3"
26 26
27/** 27/**
28 * efar_pre_reset - check for 40/80 pin 28 * efar_pre_reset - check for 40/80 pin
@@ -226,7 +226,6 @@ static struct scsi_host_template efar_sht = {
226 .can_queue = ATA_DEF_QUEUE, 226 .can_queue = ATA_DEF_QUEUE,
227 .this_id = ATA_SHT_THIS_ID, 227 .this_id = ATA_SHT_THIS_ID,
228 .sg_tablesize = LIBATA_MAX_PRD, 228 .sg_tablesize = LIBATA_MAX_PRD,
229 .max_sectors = ATA_MAX_SECTORS,
230 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 229 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
231 .emulated = ATA_SHT_EMULATED, 230 .emulated = ATA_SHT_EMULATED,
232 .use_clustering = ATA_SHT_USE_CLUSTERING, 231 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -235,6 +234,8 @@ static struct scsi_host_template efar_sht = {
235 .slave_configure = ata_scsi_slave_config, 234 .slave_configure = ata_scsi_slave_config,
236 .slave_destroy = ata_scsi_slave_destroy, 235 .slave_destroy = ata_scsi_slave_destroy,
237 .bios_param = ata_std_bios_param, 236 .bios_param = ata_std_bios_param,
237 .resume = ata_scsi_device_resume,
238 .suspend = ata_scsi_device_suspend,
238}; 239};
239 240
240static const struct ata_port_operations efar_ops = { 241static const struct ata_port_operations efar_ops = {
@@ -316,6 +317,8 @@ static struct pci_driver efar_pci_driver = {
316 .id_table = efar_pci_tbl, 317 .id_table = efar_pci_tbl,
317 .probe = efar_init_one, 318 .probe = efar_init_one,
318 .remove = ata_pci_remove_one, 319 .remove = ata_pci_remove_one,
320 .suspend = ata_pci_device_suspend,
321 .resume = ata_pci_device_resume,
319}; 322};
320 323
321static int __init efar_init(void) 324static int __init efar_init(void)
diff --git a/drivers/ata/pata_hpt366.c b/drivers/ata/pata_hpt366.c
index c0e150a9586b..2663599a7c02 100644
--- a/drivers/ata/pata_hpt366.c
+++ b/drivers/ata/pata_hpt366.c
@@ -27,7 +27,7 @@
27#include <linux/libata.h> 27#include <linux/libata.h>
28 28
29#define DRV_NAME "pata_hpt366" 29#define DRV_NAME "pata_hpt366"
30#define DRV_VERSION "0.5" 30#define DRV_VERSION "0.5.3"
31 31
32struct hpt_clock { 32struct hpt_clock {
33 u8 xfer_speed; 33 u8 xfer_speed;
@@ -222,9 +222,17 @@ static u32 hpt36x_find_mode(struct ata_port *ap, int speed)
222 222
223static int hpt36x_pre_reset(struct ata_port *ap) 223static int hpt36x_pre_reset(struct ata_port *ap)
224{ 224{
225 static const struct pci_bits hpt36x_enable_bits[] = {
226 { 0x50, 1, 0x04, 0x04 },
227 { 0x54, 1, 0x04, 0x04 }
228 };
229
225 u8 ata66; 230 u8 ata66;
226 struct pci_dev *pdev = to_pci_dev(ap->host->dev); 231 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
227 232
233 if (!pci_test_config_bits(pdev, &hpt36x_enable_bits[ap->port_no]))
234 return -ENOENT;
235
228 pci_read_config_byte(pdev, 0x5A, &ata66); 236 pci_read_config_byte(pdev, 0x5A, &ata66);
229 if (ata66 & (1 << ap->port_no)) 237 if (ata66 & (1 << ap->port_no))
230 ap->cbl = ATA_CBL_PATA40; 238 ap->cbl = ATA_CBL_PATA40;
@@ -322,7 +330,6 @@ static struct scsi_host_template hpt36x_sht = {
322 .can_queue = ATA_DEF_QUEUE, 330 .can_queue = ATA_DEF_QUEUE,
323 .this_id = ATA_SHT_THIS_ID, 331 .this_id = ATA_SHT_THIS_ID,
324 .sg_tablesize = LIBATA_MAX_PRD, 332 .sg_tablesize = LIBATA_MAX_PRD,
325 .max_sectors = ATA_MAX_SECTORS,
326 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 333 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
327 .emulated = ATA_SHT_EMULATED, 334 .emulated = ATA_SHT_EMULATED,
328 .use_clustering = ATA_SHT_USE_CLUSTERING, 335 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -331,6 +338,8 @@ static struct scsi_host_template hpt36x_sht = {
331 .slave_configure = ata_scsi_slave_config, 338 .slave_configure = ata_scsi_slave_config,
332 .slave_destroy = ata_scsi_slave_destroy, 339 .slave_destroy = ata_scsi_slave_destroy,
333 .bios_param = ata_std_bios_param, 340 .bios_param = ata_std_bios_param,
341 .resume = ata_scsi_device_resume,
342 .suspend = ata_scsi_device_suspend,
334}; 343};
335 344
336/* 345/*
@@ -373,6 +382,27 @@ static struct ata_port_operations hpt366_port_ops = {
373}; 382};
374 383
375/** 384/**
385 * hpt36x_init_chipset - common chip setup
386 * @dev: PCI device
387 *
388 * Perform the chip setup work that must be done at both init and
389 * resume time
390 */
391
392static void hpt36x_init_chipset(struct pci_dev *dev)
393{
394 u8 drive_fast;
395 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4));
396 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);
397 pci_write_config_byte(dev, PCI_MIN_GNT, 0x08);
398 pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);
399
400 pci_read_config_byte(dev, 0x51, &drive_fast);
401 if (drive_fast & 0x80)
402 pci_write_config_byte(dev, 0x51, drive_fast & ~0x80);
403}
404
405/**
376 * hpt36x_init_one - Initialise an HPT366/368 406 * hpt36x_init_one - Initialise an HPT366/368
377 * @dev: PCI device 407 * @dev: PCI device
378 * @id: Entry in match table 408 * @id: Entry in match table
@@ -407,7 +437,6 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
407 437
408 u32 class_rev; 438 u32 class_rev;
409 u32 reg1; 439 u32 reg1;
410 u8 drive_fast;
411 440
412 pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev); 441 pci_read_config_dword(dev, PCI_CLASS_REVISION, &class_rev);
413 class_rev &= 0xFF; 442 class_rev &= 0xFF;
@@ -417,14 +446,7 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
417 if (class_rev > 2) 446 if (class_rev > 2)
418 return -ENODEV; 447 return -ENODEV;
419 448
420 pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, (L1_CACHE_BYTES / 4)); 449 hpt36x_init_chipset(dev);
421 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x78);
422 pci_write_config_byte(dev, PCI_MIN_GNT, 0x08);
423 pci_write_config_byte(dev, PCI_MAX_LAT, 0x08);
424
425 pci_read_config_byte(dev, 0x51, &drive_fast);
426 if (drive_fast & 0x80)
427 pci_write_config_byte(dev, 0x51, drive_fast & ~0x80);
428 450
429 pci_read_config_dword(dev, 0x40, &reg1); 451 pci_read_config_dword(dev, 0x40, &reg1);
430 452
@@ -445,9 +467,15 @@ static int hpt36x_init_one(struct pci_dev *dev, const struct pci_device_id *id)
445 return ata_pci_init_one(dev, port_info, 2); 467 return ata_pci_init_one(dev, port_info, 2);
446} 468}
447 469
470static int hpt36x_reinit_one(struct pci_dev *dev)
471{
472 hpt36x_init_chipset(dev);
473 return ata_pci_device_resume(dev);
474}
475
476
448static const struct pci_device_id hpt36x[] = { 477static const struct pci_device_id hpt36x[] = {
449 { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), }, 478 { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT366), },
450
451 { }, 479 { },
452}; 480};
453 481
@@ -455,7 +483,9 @@ static struct pci_driver hpt36x_pci_driver = {
455 .name = DRV_NAME, 483 .name = DRV_NAME,
456 .id_table = hpt36x, 484 .id_table = hpt36x,
457 .probe = hpt36x_init_one, 485 .probe = hpt36x_init_one,
458 .remove = ata_pci_remove_one 486 .remove = ata_pci_remove_one,
487 .suspend = ata_pci_device_suspend,
488 .resume = hpt36x_reinit_one,
459}; 489};
460 490
461static int __init hpt36x_init(void) 491static int __init hpt36x_init(void)
@@ -463,13 +493,11 @@ static int __init hpt36x_init(void)
463 return pci_register_driver(&hpt36x_pci_driver); 493 return pci_register_driver(&hpt36x_pci_driver);
464} 494}
465 495
466
467static void __exit hpt36x_exit(void) 496static void __exit hpt36x_exit(void)
468{ 497{
469 pci_unregister_driver(&hpt36x_pci_driver); 498 pci_unregister_driver(&hpt36x_pci_driver);
470} 499}
471 500
472
473MODULE_AUTHOR("Alan Cox"); 501MODULE_AUTHOR("Alan Cox");
474MODULE_DESCRIPTION("low-level driver for the Highpoint HPT366/368"); 502MODULE_DESCRIPTION("low-level driver for the Highpoint HPT366/368");
475MODULE_LICENSE("GPL"); 503MODULE_LICENSE("GPL");
diff --git a/drivers/ata/pata_hpt37x.c b/drivers/ata/pata_hpt37x.c
index 1eeb16f0fb02..47082df7199e 100644
--- a/drivers/ata/pata_hpt37x.c
+++ b/drivers/ata/pata_hpt37x.c
@@ -768,7 +768,6 @@ static struct scsi_host_template hpt37x_sht = {
768 .can_queue = ATA_DEF_QUEUE, 768 .can_queue = ATA_DEF_QUEUE,
769 .this_id = ATA_SHT_THIS_ID, 769 .this_id = ATA_SHT_THIS_ID,
770 .sg_tablesize = LIBATA_MAX_PRD, 770 .sg_tablesize = LIBATA_MAX_PRD,
771 .max_sectors = ATA_MAX_SECTORS,
772 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 771 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
773 .emulated = ATA_SHT_EMULATED, 772 .emulated = ATA_SHT_EMULATED,
774 .use_clustering = ATA_SHT_USE_CLUSTERING, 773 .use_clustering = ATA_SHT_USE_CLUSTERING,
diff --git a/drivers/ata/pata_hpt3x2n.c b/drivers/ata/pata_hpt3x2n.c
index 47d7664e9eee..f6817b4093a4 100644
--- a/drivers/ata/pata_hpt3x2n.c
+++ b/drivers/ata/pata_hpt3x2n.c
@@ -334,7 +334,6 @@ static struct scsi_host_template hpt3x2n_sht = {
334 .can_queue = ATA_DEF_QUEUE, 334 .can_queue = ATA_DEF_QUEUE,
335 .this_id = ATA_SHT_THIS_ID, 335 .this_id = ATA_SHT_THIS_ID,
336 .sg_tablesize = LIBATA_MAX_PRD, 336 .sg_tablesize = LIBATA_MAX_PRD,
337 .max_sectors = ATA_MAX_SECTORS,
338 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 337 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
339 .emulated = ATA_SHT_EMULATED, 338 .emulated = ATA_SHT_EMULATED,
340 .use_clustering = ATA_SHT_USE_CLUSTERING, 339 .use_clustering = ATA_SHT_USE_CLUSTERING,
diff --git a/drivers/ata/pata_hpt3x3.c b/drivers/ata/pata_hpt3x3.c
index d216cc564b56..5f1d385eb592 100644
--- a/drivers/ata/pata_hpt3x3.c
+++ b/drivers/ata/pata_hpt3x3.c
@@ -23,7 +23,7 @@
23#include <linux/libata.h> 23#include <linux/libata.h>
24 24
25#define DRV_NAME "pata_hpt3x3" 25#define DRV_NAME "pata_hpt3x3"
26#define DRV_VERSION "0.4.1" 26#define DRV_VERSION "0.4.2"
27 27
28static int hpt3x3_probe_init(struct ata_port *ap) 28static int hpt3x3_probe_init(struct ata_port *ap)
29{ 29{
@@ -111,7 +111,6 @@ static struct scsi_host_template hpt3x3_sht = {
111 .can_queue = ATA_DEF_QUEUE, 111 .can_queue = ATA_DEF_QUEUE,
112 .this_id = ATA_SHT_THIS_ID, 112 .this_id = ATA_SHT_THIS_ID,
113 .sg_tablesize = LIBATA_MAX_PRD, 113 .sg_tablesize = LIBATA_MAX_PRD,
114 .max_sectors = ATA_MAX_SECTORS,
115 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 114 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
116 .emulated = ATA_SHT_EMULATED, 115 .emulated = ATA_SHT_EMULATED,
117 .use_clustering = ATA_SHT_USE_CLUSTERING, 116 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -120,6 +119,8 @@ static struct scsi_host_template hpt3x3_sht = {
120 .slave_configure = ata_scsi_slave_config, 119 .slave_configure = ata_scsi_slave_config,
121 .slave_destroy = ata_scsi_slave_destroy, 120 .slave_destroy = ata_scsi_slave_destroy,
122 .bios_param = ata_std_bios_param, 121 .bios_param = ata_std_bios_param,
122 .resume = ata_scsi_device_resume,
123 .suspend = ata_scsi_device_suspend,
123}; 124};
124 125
125static struct ata_port_operations hpt3x3_port_ops = { 126static struct ata_port_operations hpt3x3_port_ops = {
@@ -158,6 +159,27 @@ static struct ata_port_operations hpt3x3_port_ops = {
158}; 159};
159 160
160/** 161/**
162 * hpt3x3_init_chipset - chip setup
163 * @dev: PCI device
164 *
165 * Perform the setup required at boot and on resume.
166 */
167
168static void hpt3x3_init_chipset(struct pci_dev *dev)
169{
170 u16 cmd;
171 /* Initialize the board */
172 pci_write_config_word(dev, 0x80, 0x00);
173 /* Check if it is a 343 or a 363. 363 has COMMAND_MEMORY set */
174 pci_read_config_word(dev, PCI_COMMAND, &cmd);
175 if (cmd & PCI_COMMAND_MEMORY)
176 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0);
177 else
178 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
179}
180
181
182/**
161 * hpt3x3_init_one - Initialise an HPT343/363 183 * hpt3x3_init_one - Initialise an HPT343/363
162 * @dev: PCI device 184 * @dev: PCI device
163 * @id: Entry in match table 185 * @id: Entry in match table
@@ -178,21 +200,18 @@ static int hpt3x3_init_one(struct pci_dev *dev, const struct pci_device_id *id)
178 .port_ops = &hpt3x3_port_ops 200 .port_ops = &hpt3x3_port_ops
179 }; 201 };
180 static struct ata_port_info *port_info[2] = { &info, &info }; 202 static struct ata_port_info *port_info[2] = { &info, &info };
181 u16 cmd;
182
183 /* Initialize the board */
184 pci_write_config_word(dev, 0x80, 0x00);
185 /* Check if it is a 343 or a 363. 363 has COMMAND_MEMORY set */
186 pci_read_config_word(dev, PCI_COMMAND, &cmd);
187 if (cmd & PCI_COMMAND_MEMORY)
188 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF0);
189 else
190 pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0x20);
191 203
204 hpt3x3_init_chipset(dev);
192 /* Now kick off ATA set up */ 205 /* Now kick off ATA set up */
193 return ata_pci_init_one(dev, port_info, 2); 206 return ata_pci_init_one(dev, port_info, 2);
194} 207}
195 208
209static int hpt3x3_reinit_one(struct pci_dev *dev)
210{
211 hpt3x3_init_chipset(dev);
212 return ata_pci_device_resume(dev);
213}
214
196static const struct pci_device_id hpt3x3[] = { 215static const struct pci_device_id hpt3x3[] = {
197 { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT343), }, 216 { PCI_VDEVICE(TTI, PCI_DEVICE_ID_TTI_HPT343), },
198 217
@@ -203,7 +222,9 @@ static struct pci_driver hpt3x3_pci_driver = {
203 .name = DRV_NAME, 222 .name = DRV_NAME,
204 .id_table = hpt3x3, 223 .id_table = hpt3x3,
205 .probe = hpt3x3_init_one, 224 .probe = hpt3x3_init_one,
206 .remove = ata_pci_remove_one 225 .remove = ata_pci_remove_one,
226 .suspend = ata_pci_device_suspend,
227 .resume = hpt3x3_reinit_one,
207}; 228};
208 229
209static int __init hpt3x3_init(void) 230static int __init hpt3x3_init(void)
diff --git a/drivers/ata/pata_isapnp.c b/drivers/ata/pata_isapnp.c
index 40ca2b82b7fc..a97d55ae95c9 100644
--- a/drivers/ata/pata_isapnp.c
+++ b/drivers/ata/pata_isapnp.c
@@ -27,7 +27,6 @@ static struct scsi_host_template isapnp_sht = {
27 .can_queue = ATA_DEF_QUEUE, 27 .can_queue = ATA_DEF_QUEUE,
28 .this_id = ATA_SHT_THIS_ID, 28 .this_id = ATA_SHT_THIS_ID,
29 .sg_tablesize = LIBATA_MAX_PRD, 29 .sg_tablesize = LIBATA_MAX_PRD,
30 .max_sectors = ATA_MAX_SECTORS,
31 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 30 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
32 .emulated = ATA_SHT_EMULATED, 31 .emulated = ATA_SHT_EMULATED,
33 .use_clustering = ATA_SHT_USE_CLUSTERING, 32 .use_clustering = ATA_SHT_USE_CLUSTERING,
diff --git a/drivers/ata/pata_it821x.c b/drivers/ata/pata_it821x.c
index 7f68f14be6fd..0b56ff3d1cfe 100644
--- a/drivers/ata/pata_it821x.c
+++ b/drivers/ata/pata_it821x.c
@@ -80,7 +80,7 @@
80 80
81 81
82#define DRV_NAME "pata_it821x" 82#define DRV_NAME "pata_it821x"
83#define DRV_VERSION "0.3.2" 83#define DRV_VERSION "0.3.3"
84 84
85struct it821x_dev 85struct it821x_dev
86{ 86{
@@ -666,9 +666,6 @@ static struct scsi_host_template it821x_sht = {
666 .can_queue = ATA_DEF_QUEUE, 666 .can_queue = ATA_DEF_QUEUE,
667 .this_id = ATA_SHT_THIS_ID, 667 .this_id = ATA_SHT_THIS_ID,
668 .sg_tablesize = LIBATA_MAX_PRD, 668 .sg_tablesize = LIBATA_MAX_PRD,
669 /* 255 sectors to begin with. This is locked in smart mode but not
670 in pass through */
671 .max_sectors = 255,
672 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 669 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
673 .emulated = ATA_SHT_EMULATED, 670 .emulated = ATA_SHT_EMULATED,
674 .use_clustering = ATA_SHT_USE_CLUSTERING, 671 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -677,6 +674,8 @@ static struct scsi_host_template it821x_sht = {
677 .slave_configure = ata_scsi_slave_config, 674 .slave_configure = ata_scsi_slave_config,
678 .slave_destroy = ata_scsi_slave_destroy, 675 .slave_destroy = ata_scsi_slave_destroy,
679 .bios_param = ata_std_bios_param, 676 .bios_param = ata_std_bios_param,
677 .resume = ata_scsi_device_resume,
678 .suspend = ata_scsi_device_suspend,
680}; 679};
681 680
682static struct ata_port_operations it821x_smart_port_ops = { 681static struct ata_port_operations it821x_smart_port_ops = {
@@ -809,6 +808,14 @@ static int it821x_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
809 return ata_pci_init_one(pdev, port_info, 2); 808 return ata_pci_init_one(pdev, port_info, 2);
810} 809}
811 810
811static int it821x_reinit_one(struct pci_dev *pdev)
812{
813 /* Resume - turn raid back off if need be */
814 if (it8212_noraid)
815 it821x_disable_raid(pdev);
816 return ata_pci_device_resume(pdev);
817}
818
812static const struct pci_device_id it821x[] = { 819static const struct pci_device_id it821x[] = {
813 { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8211), }, 820 { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8211), },
814 { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8212), }, 821 { PCI_VDEVICE(ITE, PCI_DEVICE_ID_ITE_8212), },
@@ -820,7 +827,9 @@ static struct pci_driver it821x_pci_driver = {
820 .name = DRV_NAME, 827 .name = DRV_NAME,
821 .id_table = it821x, 828 .id_table = it821x,
822 .probe = it821x_init_one, 829 .probe = it821x_init_one,
823 .remove = ata_pci_remove_one 830 .remove = ata_pci_remove_one,
831 .suspend = ata_pci_device_suspend,
832 .resume = it821x_reinit_one,
824}; 833};
825 834
826static int __init it821x_init(void) 835static int __init it821x_init(void)
diff --git a/drivers/ata/pata_ixp4xx_cf.c b/drivers/ata/pata_ixp4xx_cf.c
new file mode 100644
index 000000000000..cb8924109f59
--- /dev/null
+++ b/drivers/ata/pata_ixp4xx_cf.c
@@ -0,0 +1,271 @@
1/*
2 * ixp4xx PATA/Compact Flash driver
3 * Copyright (c) 2006 Tower Technologies
4 * Author: Alessandro Zummo <a.zummo@towertech.it>
5 *
6 * An ATA driver to handle a Compact Flash connected
7 * to the ixp4xx expansion bus in TrueIDE mode. The CF
8 * must have it chip selects connected to two CS lines
9 * on the ixp4xx. The interrupt line is optional, if not
10 * specified the driver will run in polling mode.
11 *
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License version 2 as
14 * published by the Free Software Foundation.
15 *
16 */
17
18#include <linux/kernel.h>
19#include <linux/module.h>
20#include <linux/libata.h>
21#include <linux/irq.h>
22#include <linux/platform_device.h>
23#include <scsi/scsi_host.h>
24
25#define DRV_NAME "pata_ixp4xx_cf"
26#define DRV_VERSION "0.1.1"
27
28static void ixp4xx_set_mode(struct ata_port *ap)
29{
30 int i;
31
32 for (i = 0; i < ATA_MAX_DEVICES; i++) {
33 struct ata_device *dev = &ap->device[i];
34 if (ata_dev_enabled(dev)) {
35 dev->pio_mode = XFER_PIO_0;
36 dev->xfer_mode = XFER_PIO_0;
37 dev->xfer_shift = ATA_SHIFT_PIO;
38 dev->flags |= ATA_DFLAG_PIO;
39 }
40 }
41}
42
43static void ixp4xx_phy_reset(struct ata_port *ap)
44{
45 ap->cbl = ATA_CBL_PATA40;
46 ata_port_probe(ap);
47 ata_bus_reset(ap);
48}
49
50static void ixp4xx_mmio_data_xfer(struct ata_device *adev, unsigned char *buf,
51 unsigned int buflen, int write_data)
52{
53 unsigned int i;
54 unsigned int words = buflen >> 1;
55 u16 *buf16 = (u16 *) buf;
56 struct ata_port *ap = adev->ap;
57 void __iomem *mmio = (void __iomem *)ap->ioaddr.data_addr;
58 struct ixp4xx_pata_data *data = ap->host->dev->platform_data;
59
60 /* set the expansion bus in 16bit mode and restore
61 * 8 bit mode after the transaction.
62 */
63 *data->cs0_cfg &= ~(0x01);
64 udelay(100);
65
66 /* Transfer multiple of 2 bytes */
67 if (write_data) {
68 for (i = 0; i < words; i++)
69 writew(buf16[i], mmio);
70 } else {
71 for (i = 0; i < words; i++)
72 buf16[i] = readw(mmio);
73 }
74
75 /* Transfer trailing 1 byte, if any. */
76 if (unlikely(buflen & 0x01)) {
77 u16 align_buf[1] = { 0 };
78 unsigned char *trailing_buf = buf + buflen - 1;
79
80 if (write_data) {
81 memcpy(align_buf, trailing_buf, 1);
82 writew(align_buf[0], mmio);
83 } else {
84 align_buf[0] = readw(mmio);
85 memcpy(trailing_buf, align_buf, 1);
86 }
87 }
88
89 udelay(100);
90 *data->cs0_cfg |= 0x01;
91}
92
93static void ixp4xx_irq_clear(struct ata_port *ap)
94{
95}
96
97static void ixp4xx_host_stop (struct ata_host *host)
98{
99 struct ixp4xx_pata_data *data = host->dev->platform_data;
100
101 iounmap(data->cs0);
102 iounmap(data->cs1);
103}
104
105static struct scsi_host_template ixp4xx_sht = {
106 .module = THIS_MODULE,
107 .name = DRV_NAME,
108 .ioctl = ata_scsi_ioctl,
109 .queuecommand = ata_scsi_queuecmd,
110 .can_queue = ATA_DEF_QUEUE,
111 .this_id = ATA_SHT_THIS_ID,
112 .sg_tablesize = LIBATA_MAX_PRD,
113 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
114 .emulated = ATA_SHT_EMULATED,
115 .use_clustering = ATA_SHT_USE_CLUSTERING,
116 .proc_name = DRV_NAME,
117 .dma_boundary = ATA_DMA_BOUNDARY,
118 .slave_configure = ata_scsi_slave_config,
119 .slave_destroy = ata_scsi_slave_destroy,
120 .bios_param = ata_std_bios_param,
121};
122
123static struct ata_port_operations ixp4xx_port_ops = {
124 .set_mode = ixp4xx_set_mode,
125 .mode_filter = ata_pci_default_filter,
126
127 .port_disable = ata_port_disable,
128 .tf_load = ata_tf_load,
129 .tf_read = ata_tf_read,
130 .check_status = ata_check_status,
131 .exec_command = ata_exec_command,
132 .dev_select = ata_std_dev_select,
133
134 .qc_prep = ata_qc_prep,
135 .qc_issue = ata_qc_issue_prot,
136 .eng_timeout = ata_eng_timeout,
137 .data_xfer = ixp4xx_mmio_data_xfer,
138
139 .irq_handler = ata_interrupt,
140 .irq_clear = ixp4xx_irq_clear,
141
142 .port_start = ata_port_start,
143 .port_stop = ata_port_stop,
144 .host_stop = ixp4xx_host_stop,
145
146 .phy_reset = ixp4xx_phy_reset,
147};
148
149static void ixp4xx_setup_port(struct ata_ioports *ioaddr,
150 struct ixp4xx_pata_data *data)
151{
152 ioaddr->cmd_addr = (unsigned long) data->cs0;
153 ioaddr->altstatus_addr = (unsigned long) data->cs1 + 0x06;
154 ioaddr->ctl_addr = (unsigned long) data->cs1 + 0x06;
155
156 ata_std_ports(ioaddr);
157
158#ifndef __ARMEB__
159
160 /* adjust the addresses to handle the address swizzling of the
161 * ixp4xx in little endian mode.
162 */
163
164 ioaddr->data_addr ^= 0x02;
165 ioaddr->cmd_addr ^= 0x03;
166 ioaddr->altstatus_addr ^= 0x03;
167 ioaddr->ctl_addr ^= 0x03;
168 ioaddr->error_addr ^= 0x03;
169 ioaddr->feature_addr ^= 0x03;
170 ioaddr->nsect_addr ^= 0x03;
171 ioaddr->lbal_addr ^= 0x03;
172 ioaddr->lbam_addr ^= 0x03;
173 ioaddr->lbah_addr ^= 0x03;
174 ioaddr->device_addr ^= 0x03;
175 ioaddr->status_addr ^= 0x03;
176 ioaddr->command_addr ^= 0x03;
177#endif
178}
179
180static __devinit int ixp4xx_pata_probe(struct platform_device *pdev)
181{
182 int ret;
183 unsigned int irq;
184 struct resource *cs0, *cs1;
185 struct ata_probe_ent ae;
186
187 struct ixp4xx_pata_data *data = pdev->dev.platform_data;
188
189 cs0 = platform_get_resource(pdev, IORESOURCE_MEM, 0);
190 cs1 = platform_get_resource(pdev, IORESOURCE_MEM, 1);
191
192 if (!cs0 || !cs1)
193 return -EINVAL;
194
195 pdev->dev.coherent_dma_mask = DMA_32BIT_MASK;
196
197 data->cs0 = ioremap(cs0->start, 0x1000);
198 data->cs1 = ioremap(cs1->start, 0x1000);
199
200 irq = platform_get_irq(pdev, 0);
201 if (irq)
202 set_irq_type(irq, IRQT_HIGH);
203
204 /* Setup expansion bus chip selects */
205 *data->cs0_cfg = data->cs0_bits;
206 *data->cs1_cfg = data->cs1_bits;
207
208 memset(&ae, 0, sizeof(struct ata_probe_ent));
209 INIT_LIST_HEAD(&ae.node);
210
211 ae.dev = &pdev->dev;
212 ae.port_ops = &ixp4xx_port_ops;
213 ae.sht = &ixp4xx_sht;
214 ae.n_ports = 1;
215 ae.pio_mask = 0x1f; /* PIO4 */
216 ae.irq = irq;
217 ae.irq_flags = 0;
218 ae.port_flags = ATA_FLAG_MMIO | ATA_FLAG_NO_LEGACY
219 | ATA_FLAG_NO_ATAPI | ATA_FLAG_SRST;
220
221 /* run in polling mode if no irq has been assigned */
222 if (!irq)
223 ae.port_flags |= ATA_FLAG_PIO_POLLING;
224
225 ixp4xx_setup_port(&ae.port[0], data);
226
227 dev_printk(KERN_INFO, &pdev->dev, "version " DRV_VERSION "\n");
228
229 ret = ata_device_add(&ae);
230 if (ret == 0)
231 return -ENODEV;
232
233 return 0;
234}
235
236static __devexit int ixp4xx_pata_remove(struct platform_device *dev)
237{
238 struct ata_host *host = platform_get_drvdata(dev);
239
240 ata_host_remove(host);
241 platform_set_drvdata(dev, NULL);
242
243 return 0;
244}
245
246static struct platform_driver ixp4xx_pata_platform_driver = {
247 .driver = {
248 .name = DRV_NAME,
249 .owner = THIS_MODULE,
250 },
251 .probe = ixp4xx_pata_probe,
252 .remove = __devexit_p(ixp4xx_pata_remove),
253};
254
255static int __init ixp4xx_pata_init(void)
256{
257 return platform_driver_register(&ixp4xx_pata_platform_driver);
258}
259
260static void __exit ixp4xx_pata_exit(void)
261{
262 platform_driver_unregister(&ixp4xx_pata_platform_driver);
263}
264
265MODULE_AUTHOR("Alessandro Zummo <a.zummo@towertech.it>");
266MODULE_DESCRIPTION("low-level driver for ixp4xx Compact Flash PATA");
267MODULE_LICENSE("GPL");
268MODULE_VERSION(DRV_VERSION);
269
270module_init(ixp4xx_pata_init);
271module_exit(ixp4xx_pata_exit);
diff --git a/drivers/ata/pata_jmicron.c b/drivers/ata/pata_jmicron.c
index 0210b10d49cd..2d661cb4df3c 100644
--- a/drivers/ata/pata_jmicron.c
+++ b/drivers/ata/pata_jmicron.c
@@ -19,7 +19,7 @@
19#include <linux/ata.h> 19#include <linux/ata.h>
20 20
21#define DRV_NAME "pata_jmicron" 21#define DRV_NAME "pata_jmicron"
22#define DRV_VERSION "0.1.2" 22#define DRV_VERSION "0.1.4"
23 23
24typedef enum { 24typedef enum {
25 PORT_PATA0 = 0, 25 PORT_PATA0 = 0,
@@ -128,8 +128,6 @@ static struct scsi_host_template jmicron_sht = {
128 .can_queue = ATA_DEF_QUEUE, 128 .can_queue = ATA_DEF_QUEUE,
129 .this_id = ATA_SHT_THIS_ID, 129 .this_id = ATA_SHT_THIS_ID,
130 .sg_tablesize = LIBATA_MAX_PRD, 130 .sg_tablesize = LIBATA_MAX_PRD,
131 /* Special handling needed if you have sector or LBA48 limits */
132 .max_sectors = ATA_MAX_SECTORS,
133 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 131 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
134 .emulated = ATA_SHT_EMULATED, 132 .emulated = ATA_SHT_EMULATED,
135 .use_clustering = ATA_SHT_USE_CLUSTERING, 133 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -213,12 +211,11 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
213 211
214 /* FIXME: We may want a way to override this in future */ 212 /* FIXME: We may want a way to override this in future */
215 pci_write_config_byte(pdev, 0x41, 0xa1); 213 pci_write_config_byte(pdev, 0x41, 0xa1);
216 }
217
218 /* PATA controller is fn 1, AHCI is fn 0 */
219 if (PCI_FUNC(pdev->devfn) != 1)
220 return -ENODEV;
221 214
215 /* PATA controller is fn 1, AHCI is fn 0 */
216 if (PCI_FUNC(pdev->devfn) != 1)
217 return -ENODEV;
218 }
222 if ( id->driver_data == 365 || id->driver_data == 366) { 219 if ( id->driver_data == 365 || id->driver_data == 366) {
223 /* The 365/66 have two PATA channels, redirect the second */ 220 /* The 365/66 have two PATA channels, redirect the second */
224 pci_read_config_dword(pdev, 0x80, &reg); 221 pci_read_config_dword(pdev, 0x80, &reg);
@@ -229,6 +226,27 @@ static int jmicron_init_one (struct pci_dev *pdev, const struct pci_device_id *i
229 return ata_pci_init_one(pdev, port_info, 2); 226 return ata_pci_init_one(pdev, port_info, 2);
230} 227}
231 228
229static int jmicron_reinit_one(struct pci_dev *pdev)
230{
231 u32 reg;
232
233 switch(pdev->device) {
234 case PCI_DEVICE_ID_JMICRON_JMB368:
235 break;
236 case PCI_DEVICE_ID_JMICRON_JMB365:
237 case PCI_DEVICE_ID_JMICRON_JMB366:
238 /* Restore mapping or disks swap and boy does it get ugly */
239 pci_read_config_dword(pdev, 0x80, &reg);
240 reg |= (1 << 24); /* IDE1 to PATA IDE secondary */
241 pci_write_config_dword(pdev, 0x80, reg);
242 /* Fall through */
243 default:
244 /* Make sure AHCI is turned back on */
245 pci_write_config_byte(pdev, 0x41, 0xa1);
246 }
247 return ata_pci_device_resume(pdev);
248}
249
232static const struct pci_device_id jmicron_pci_tbl[] = { 250static const struct pci_device_id jmicron_pci_tbl[] = {
233 { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB361), 361}, 251 { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB361), 361},
234 { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB363), 363}, 252 { PCI_VDEVICE(JMICRON, PCI_DEVICE_ID_JMICRON_JMB363), 363},
@@ -244,6 +262,8 @@ static struct pci_driver jmicron_pci_driver = {
244 .id_table = jmicron_pci_tbl, 262 .id_table = jmicron_pci_tbl,
245 .probe = jmicron_init_one, 263 .probe = jmicron_init_one,
246 .remove = ata_pci_remove_one, 264 .remove = ata_pci_remove_one,
265 .suspend = ata_pci_device_suspend,
266 .resume = jmicron_reinit_one,
247}; 267};
248 268
249static int __init jmicron_init(void) 269static int __init jmicron_init(void)
diff --git a/drivers/ata/pata_legacy.c b/drivers/ata/pata_legacy.c
index b39078b2a47b..c7d1738e4e69 100644
--- a/drivers/ata/pata_legacy.c
+++ b/drivers/ata/pata_legacy.c
@@ -128,7 +128,6 @@ static struct scsi_host_template legacy_sht = {
128 .can_queue = ATA_DEF_QUEUE, 128 .can_queue = ATA_DEF_QUEUE,
129 .this_id = ATA_SHT_THIS_ID, 129 .this_id = ATA_SHT_THIS_ID,
130 .sg_tablesize = LIBATA_MAX_PRD, 130 .sg_tablesize = LIBATA_MAX_PRD,
131 .max_sectors = ATA_MAX_SECTORS,
132 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 131 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
133 .emulated = ATA_SHT_EMULATED, 132 .emulated = ATA_SHT_EMULATED,
134 .use_clustering = ATA_SHT_USE_CLUSTERING, 133 .use_clustering = ATA_SHT_USE_CLUSTERING,
diff --git a/drivers/ata/pata_marvell.c b/drivers/ata/pata_marvell.c
new file mode 100644
index 000000000000..1c810ea00253
--- /dev/null
+++ b/drivers/ata/pata_marvell.c
@@ -0,0 +1,224 @@
1/*
2 * Marvell PATA driver.
3 *
4 * For the moment we drive the PATA port in legacy mode. That
5 * isn't making full use of the device functionality but it is
6 * easy to get working.
7 *
8 * (c) 2006 Red Hat <alan@redhat.com>
9 */
10
11#include <linux/kernel.h>
12#include <linux/module.h>
13#include <linux/pci.h>
14#include <linux/init.h>
15#include <linux/blkdev.h>
16#include <linux/delay.h>
17#include <linux/device.h>
18#include <scsi/scsi_host.h>
19#include <linux/libata.h>
20#include <linux/ata.h>
21
22#define DRV_NAME "pata_marvell"
23#define DRV_VERSION "0.1.1"
24
25/**
26 * marvell_pre_reset - check for 40/80 pin
27 * @ap: Port
28 *
29 * Perform the PATA port setup we need.
30 */
31
32static int marvell_pre_reset(struct ata_port *ap)
33{
34 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
35 u32 devices;
36 void __iomem *barp;
37 int i;
38
39 /* Check if our port is enabled */
40
41 barp = pci_iomap(pdev, 5, 0x10);
42 if (barp == NULL)
43 return -ENOMEM;
44 printk("BAR5:");
45 for(i = 0; i <= 0x0F; i++)
46 printk("%02X:%02X ", i, readb(barp + i));
47 printk("\n");
48
49 devices = readl(barp + 0x0C);
50 pci_iounmap(pdev, barp);
51
52 if ((pdev->device == 0x6145) && (ap->port_no == 0) &&
53 (!(devices & 0x10))) /* PATA enable ? */
54 return -ENOENT;
55
56 /* Cable type */
57 switch(ap->port_no)
58 {
59 case 0:
60 if (inb(ap->ioaddr.bmdma_addr + 1) & 1)
61 ap->cbl = ATA_CBL_PATA40;
62 else
63 ap->cbl = ATA_CBL_PATA80;
64 break;
65
66 case 1: /* Legacy SATA port */
67 ap->cbl = ATA_CBL_SATA;
68 break;
69 }
70 return ata_std_prereset(ap);
71}
72
73/**
74 * marvell_error_handler - Setup and error handler
75 * @ap: Port to handle
76 *
77 * LOCKING:
78 * None (inherited from caller).
79 */
80
81static void marvell_error_handler(struct ata_port *ap)
82{
83 return ata_bmdma_drive_eh(ap, marvell_pre_reset, ata_std_softreset,
84 NULL, ata_std_postreset);
85}
86
87/* No PIO or DMA methods needed for this device */
88
89static struct scsi_host_template marvell_sht = {
90 .module = THIS_MODULE,
91 .name = DRV_NAME,
92 .ioctl = ata_scsi_ioctl,
93 .queuecommand = ata_scsi_queuecmd,
94 .can_queue = ATA_DEF_QUEUE,
95 .this_id = ATA_SHT_THIS_ID,
96 .sg_tablesize = LIBATA_MAX_PRD,
97 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
98 .emulated = ATA_SHT_EMULATED,
99 .use_clustering = ATA_SHT_USE_CLUSTERING,
100 .proc_name = DRV_NAME,
101 .dma_boundary = ATA_DMA_BOUNDARY,
102 .slave_configure = ata_scsi_slave_config,
103 .slave_destroy = ata_scsi_slave_destroy,
104 /* Use standard CHS mapping rules */
105 .bios_param = ata_std_bios_param,
106 .resume = ata_scsi_device_resume,
107 .suspend = ata_scsi_device_suspend,
108};
109
110static const struct ata_port_operations marvell_ops = {
111 .port_disable = ata_port_disable,
112
113 /* Task file is PCI ATA format, use helpers */
114 .tf_load = ata_tf_load,
115 .tf_read = ata_tf_read,
116 .check_status = ata_check_status,
117 .exec_command = ata_exec_command,
118 .dev_select = ata_std_dev_select,
119
120 .freeze = ata_bmdma_freeze,
121 .thaw = ata_bmdma_thaw,
122 .error_handler = marvell_error_handler,
123 .post_internal_cmd = ata_bmdma_post_internal_cmd,
124
125 /* BMDMA handling is PCI ATA format, use helpers */
126 .bmdma_setup = ata_bmdma_setup,
127 .bmdma_start = ata_bmdma_start,
128 .bmdma_stop = ata_bmdma_stop,
129 .bmdma_status = ata_bmdma_status,
130 .qc_prep = ata_qc_prep,
131 .qc_issue = ata_qc_issue_prot,
132 .data_xfer = ata_pio_data_xfer,
133
134 /* Timeout handling */
135 .irq_handler = ata_interrupt,
136 .irq_clear = ata_bmdma_irq_clear,
137
138 /* Generic PATA PCI ATA helpers */
139 .port_start = ata_port_start,
140 .port_stop = ata_port_stop,
141 .host_stop = ata_host_stop,
142};
143
144
145/**
146 * marvell_init_one - Register Marvell ATA PCI device with kernel services
147 * @pdev: PCI device to register
148 * @ent: Entry in marvell_pci_tbl matching with @pdev
149 *
150 * Called from kernel PCI layer.
151 *
152 * LOCKING:
153 * Inherited from PCI layer (may sleep).
154 *
155 * RETURNS:
156 * Zero on success, or -ERRNO value.
157 */
158
159static int marvell_init_one (struct pci_dev *pdev, const struct pci_device_id *id)
160{
161 static struct ata_port_info info = {
162 .sht = &marvell_sht,
163 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
164
165 .pio_mask = 0x1f,
166 .mwdma_mask = 0x07,
167 .udma_mask = 0x3f,
168
169 .port_ops = &marvell_ops,
170 };
171 static struct ata_port_info info_sata = {
172 .sht = &marvell_sht,
173 /* Slave possible as its magically mapped not real */
174 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
175
176 .pio_mask = 0x1f,
177 .mwdma_mask = 0x07,
178 .udma_mask = 0x7f,
179
180 .port_ops = &marvell_ops,
181 };
182 struct ata_port_info *port_info[2] = { &info, &info_sata };
183 int n_port = 2;
184
185 if (pdev->device == 0x6101)
186 n_port = 1;
187
188 return ata_pci_init_one(pdev, port_info, n_port);
189}
190
191static const struct pci_device_id marvell_pci_tbl[] = {
192 { PCI_DEVICE(0x11AB, 0x6101), },
193 { PCI_DEVICE(0x11AB, 0x6145), },
194 { } /* terminate list */
195};
196
197static struct pci_driver marvell_pci_driver = {
198 .name = DRV_NAME,
199 .id_table = marvell_pci_tbl,
200 .probe = marvell_init_one,
201 .remove = ata_pci_remove_one,
202 .suspend = ata_pci_device_suspend,
203 .resume = ata_pci_device_resume,
204};
205
206static int __init marvell_init(void)
207{
208 return pci_register_driver(&marvell_pci_driver);
209}
210
211static void __exit marvell_exit(void)
212{
213 pci_unregister_driver(&marvell_pci_driver);
214}
215
216module_init(marvell_init);
217module_exit(marvell_exit);
218
219MODULE_AUTHOR("Alan Cox");
220MODULE_DESCRIPTION("SCSI low-level driver for Marvell ATA in legacy mode");
221MODULE_LICENSE("GPL");
222MODULE_DEVICE_TABLE(pci, marvell_pci_tbl);
223MODULE_VERSION(DRV_VERSION);
224
diff --git a/drivers/ata/pata_mpiix.c b/drivers/ata/pata_mpiix.c
index e00d406bfdf5..4ccca938675e 100644
--- a/drivers/ata/pata_mpiix.c
+++ b/drivers/ata/pata_mpiix.c
@@ -35,7 +35,7 @@
35#include <linux/libata.h> 35#include <linux/libata.h>
36 36
37#define DRV_NAME "pata_mpiix" 37#define DRV_NAME "pata_mpiix"
38#define DRV_VERSION "0.7.2" 38#define DRV_VERSION "0.7.3"
39 39
40enum { 40enum {
41 IDETIM = 0x6C, /* IDE control register */ 41 IDETIM = 0x6C, /* IDE control register */
@@ -159,7 +159,6 @@ static struct scsi_host_template mpiix_sht = {
159 .can_queue = ATA_DEF_QUEUE, 159 .can_queue = ATA_DEF_QUEUE,
160 .this_id = ATA_SHT_THIS_ID, 160 .this_id = ATA_SHT_THIS_ID,
161 .sg_tablesize = LIBATA_MAX_PRD, 161 .sg_tablesize = LIBATA_MAX_PRD,
162 .max_sectors = ATA_MAX_SECTORS,
163 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 162 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
164 .emulated = ATA_SHT_EMULATED, 163 .emulated = ATA_SHT_EMULATED,
165 .use_clustering = ATA_SHT_USE_CLUSTERING, 164 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -168,6 +167,8 @@ static struct scsi_host_template mpiix_sht = {
168 .slave_configure = ata_scsi_slave_config, 167 .slave_configure = ata_scsi_slave_config,
169 .slave_destroy = ata_scsi_slave_destroy, 168 .slave_destroy = ata_scsi_slave_destroy,
170 .bios_param = ata_std_bios_param, 169 .bios_param = ata_std_bios_param,
170 .resume = ata_scsi_device_resume,
171 .suspend = ata_scsi_device_suspend,
171}; 172};
172 173
173static struct ata_port_operations mpiix_port_ops = { 174static struct ata_port_operations mpiix_port_ops = {
@@ -285,7 +286,9 @@ static struct pci_driver mpiix_pci_driver = {
285 .name = DRV_NAME, 286 .name = DRV_NAME,
286 .id_table = mpiix, 287 .id_table = mpiix,
287 .probe = mpiix_init_one, 288 .probe = mpiix_init_one,
288 .remove = mpiix_remove_one 289 .remove = mpiix_remove_one,
290 .suspend = ata_pci_device_suspend,
291 .resume = ata_pci_device_resume,
289}; 292};
290 293
291static int __init mpiix_init(void) 294static int __init mpiix_init(void)
diff --git a/drivers/ata/pata_netcell.c b/drivers/ata/pata_netcell.c
index 1963a4d35873..cf7fe037471c 100644
--- a/drivers/ata/pata_netcell.c
+++ b/drivers/ata/pata_netcell.c
@@ -16,7 +16,7 @@
16#include <linux/ata.h> 16#include <linux/ata.h>
17 17
18#define DRV_NAME "pata_netcell" 18#define DRV_NAME "pata_netcell"
19#define DRV_VERSION "0.1.5" 19#define DRV_VERSION "0.1.6"
20 20
21/** 21/**
22 * netcell_probe_init - check for 40/80 pin 22 * netcell_probe_init - check for 40/80 pin
@@ -54,8 +54,6 @@ static struct scsi_host_template netcell_sht = {
54 .can_queue = ATA_DEF_QUEUE, 54 .can_queue = ATA_DEF_QUEUE,
55 .this_id = ATA_SHT_THIS_ID, 55 .this_id = ATA_SHT_THIS_ID,
56 .sg_tablesize = LIBATA_MAX_PRD, 56 .sg_tablesize = LIBATA_MAX_PRD,
57 /* Special handling needed if you have sector or LBA48 limits */
58 .max_sectors = ATA_MAX_SECTORS,
59 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 57 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
60 .emulated = ATA_SHT_EMULATED, 58 .emulated = ATA_SHT_EMULATED,
61 .use_clustering = ATA_SHT_USE_CLUSTERING, 59 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -65,6 +63,8 @@ static struct scsi_host_template netcell_sht = {
65 .slave_destroy = ata_scsi_slave_destroy, 63 .slave_destroy = ata_scsi_slave_destroy,
66 /* Use standard CHS mapping rules */ 64 /* Use standard CHS mapping rules */
67 .bios_param = ata_std_bios_param, 65 .bios_param = ata_std_bios_param,
66 .resume = ata_scsi_device_resume,
67 .suspend = ata_scsi_device_suspend,
68}; 68};
69 69
70static const struct ata_port_operations netcell_ops = { 70static const struct ata_port_operations netcell_ops = {
@@ -153,6 +153,8 @@ static struct pci_driver netcell_pci_driver = {
153 .id_table = netcell_pci_tbl, 153 .id_table = netcell_pci_tbl,
154 .probe = netcell_init_one, 154 .probe = netcell_init_one,
155 .remove = ata_pci_remove_one, 155 .remove = ata_pci_remove_one,
156 .suspend = ata_pci_device_suspend,
157 .resume = ata_pci_device_resume,
156}; 158};
157 159
158static int __init netcell_init(void) 160static int __init netcell_init(void)
diff --git a/drivers/ata/pata_ns87410.c b/drivers/ata/pata_ns87410.c
index 7ec800f00ec8..c3032eb9010d 100644
--- a/drivers/ata/pata_ns87410.c
+++ b/drivers/ata/pata_ns87410.c
@@ -28,7 +28,7 @@
28#include <linux/libata.h> 28#include <linux/libata.h>
29 29
30#define DRV_NAME "pata_ns87410" 30#define DRV_NAME "pata_ns87410"
31#define DRV_VERSION "0.4.2" 31#define DRV_VERSION "0.4.3"
32 32
33/** 33/**
34 * ns87410_pre_reset - probe begin 34 * ns87410_pre_reset - probe begin
@@ -149,7 +149,6 @@ static struct scsi_host_template ns87410_sht = {
149 .can_queue = ATA_DEF_QUEUE, 149 .can_queue = ATA_DEF_QUEUE,
150 .this_id = ATA_SHT_THIS_ID, 150 .this_id = ATA_SHT_THIS_ID,
151 .sg_tablesize = LIBATA_MAX_PRD, 151 .sg_tablesize = LIBATA_MAX_PRD,
152 .max_sectors = ATA_MAX_SECTORS,
153 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 152 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
154 .emulated = ATA_SHT_EMULATED, 153 .emulated = ATA_SHT_EMULATED,
155 .use_clustering = ATA_SHT_USE_CLUSTERING, 154 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -158,6 +157,8 @@ static struct scsi_host_template ns87410_sht = {
158 .slave_configure = ata_scsi_slave_config, 157 .slave_configure = ata_scsi_slave_config,
159 .slave_destroy = ata_scsi_slave_destroy, 158 .slave_destroy = ata_scsi_slave_destroy,
160 .bios_param = ata_std_bios_param, 159 .bios_param = ata_std_bios_param,
160 .resume = ata_scsi_device_resume,
161 .suspend = ata_scsi_device_suspend,
161}; 162};
162 163
163static struct ata_port_operations ns87410_port_ops = { 164static struct ata_port_operations ns87410_port_ops = {
@@ -210,7 +211,9 @@ static struct pci_driver ns87410_pci_driver = {
210 .name = DRV_NAME, 211 .name = DRV_NAME,
211 .id_table = ns87410, 212 .id_table = ns87410,
212 .probe = ns87410_init_one, 213 .probe = ns87410_init_one,
213 .remove = ata_pci_remove_one 214 .remove = ata_pci_remove_one,
215 .suspend = ata_pci_device_suspend,
216 .resume = ata_pci_device_resume,
214}; 217};
215 218
216static int __init ns87410_init(void) 219static int __init ns87410_init(void)
diff --git a/drivers/ata/pata_oldpiix.c b/drivers/ata/pata_oldpiix.c
index 8837256632e9..10ac3cc10181 100644
--- a/drivers/ata/pata_oldpiix.c
+++ b/drivers/ata/pata_oldpiix.c
@@ -224,7 +224,6 @@ static struct scsi_host_template oldpiix_sht = {
224 .can_queue = ATA_DEF_QUEUE, 224 .can_queue = ATA_DEF_QUEUE,
225 .this_id = ATA_SHT_THIS_ID, 225 .this_id = ATA_SHT_THIS_ID,
226 .sg_tablesize = LIBATA_MAX_PRD, 226 .sg_tablesize = LIBATA_MAX_PRD,
227 .max_sectors = ATA_MAX_SECTORS,
228 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 227 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
229 .emulated = ATA_SHT_EMULATED, 228 .emulated = ATA_SHT_EMULATED,
230 .use_clustering = ATA_SHT_USE_CLUSTERING, 229 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -233,6 +232,8 @@ static struct scsi_host_template oldpiix_sht = {
233 .slave_configure = ata_scsi_slave_config, 232 .slave_configure = ata_scsi_slave_config,
234 .slave_destroy = ata_scsi_slave_destroy, 233 .slave_destroy = ata_scsi_slave_destroy,
235 .bios_param = ata_std_bios_param, 234 .bios_param = ata_std_bios_param,
235 .resume = ata_scsi_device_resume,
236 .suspend = ata_scsi_device_suspend,
236}; 237};
237 238
238static const struct ata_port_operations oldpiix_pata_ops = { 239static const struct ata_port_operations oldpiix_pata_ops = {
@@ -314,6 +315,8 @@ static struct pci_driver oldpiix_pci_driver = {
314 .id_table = oldpiix_pci_tbl, 315 .id_table = oldpiix_pci_tbl,
315 .probe = oldpiix_init_one, 316 .probe = oldpiix_init_one,
316 .remove = ata_pci_remove_one, 317 .remove = ata_pci_remove_one,
318 .suspend = ata_pci_device_suspend,
319 .resume = ata_pci_device_resume,
317}; 320};
318 321
319static int __init oldpiix_init(void) 322static int __init oldpiix_init(void)
diff --git a/drivers/ata/pata_opti.c b/drivers/ata/pata_opti.c
index c6319cf50de4..c2988b0aa8ea 100644
--- a/drivers/ata/pata_opti.c
+++ b/drivers/ata/pata_opti.c
@@ -34,7 +34,7 @@
34#include <linux/libata.h> 34#include <linux/libata.h>
35 35
36#define DRV_NAME "pata_opti" 36#define DRV_NAME "pata_opti"
37#define DRV_VERSION "0.2.5" 37#define DRV_VERSION "0.2.7"
38 38
39enum { 39enum {
40 READ_REG = 0, /* index of Read cycle timing register */ 40 READ_REG = 0, /* index of Read cycle timing register */
@@ -109,30 +109,6 @@ static void opti_write_reg(struct ata_port *ap, u8 val, int reg)
109 outb(0x83, regio + 2); 109 outb(0x83, regio + 2);
110} 110}
111 111
112#if 0
113/**
114 * opti_read_reg - control register read
115 * @ap: ATA port
116 * @reg: control register number
117 *
118 * The Opti uses magic 'trapdoor' register accesses to do configuration
119 * rather than using PCI space as other controllers do. The double inw
120 * on the error register activates configuration mode. We can then read
121 * the control register
122 */
123
124static u8 opti_read_reg(struct ata_port *ap, int reg)
125{
126 unsigned long regio = ap->ioaddr.cmd_addr;
127 u8 ret;
128 inw(regio + 1);
129 inw(regio + 1);
130 outb(3, regio + 2);
131 ret = inb(regio + reg);
132 outb(0x83, regio + 2);
133}
134#endif
135
136/** 112/**
137 * opti_set_piomode - set initial PIO mode data 113 * opti_set_piomode - set initial PIO mode data
138 * @ap: ATA interface 114 * @ap: ATA interface
@@ -195,7 +171,6 @@ static struct scsi_host_template opti_sht = {
195 .can_queue = ATA_DEF_QUEUE, 171 .can_queue = ATA_DEF_QUEUE,
196 .this_id = ATA_SHT_THIS_ID, 172 .this_id = ATA_SHT_THIS_ID,
197 .sg_tablesize = LIBATA_MAX_PRD, 173 .sg_tablesize = LIBATA_MAX_PRD,
198 .max_sectors = ATA_MAX_SECTORS,
199 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 174 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
200 .emulated = ATA_SHT_EMULATED, 175 .emulated = ATA_SHT_EMULATED,
201 .use_clustering = ATA_SHT_USE_CLUSTERING, 176 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -204,12 +179,13 @@ static struct scsi_host_template opti_sht = {
204 .slave_configure = ata_scsi_slave_config, 179 .slave_configure = ata_scsi_slave_config,
205 .slave_destroy = ata_scsi_slave_destroy, 180 .slave_destroy = ata_scsi_slave_destroy,
206 .bios_param = ata_std_bios_param, 181 .bios_param = ata_std_bios_param,
182 .resume = ata_scsi_device_resume,
183 .suspend = ata_scsi_device_suspend,
207}; 184};
208 185
209static struct ata_port_operations opti_port_ops = { 186static struct ata_port_operations opti_port_ops = {
210 .port_disable = ata_port_disable, 187 .port_disable = ata_port_disable,
211 .set_piomode = opti_set_piomode, 188 .set_piomode = opti_set_piomode,
212/* .set_dmamode = opti_set_dmamode, */
213 .tf_load = ata_tf_load, 189 .tf_load = ata_tf_load,
214 .tf_read = ata_tf_read, 190 .tf_read = ata_tf_read,
215 .check_status = ata_check_status, 191 .check_status = ata_check_status,
@@ -267,7 +243,9 @@ static struct pci_driver opti_pci_driver = {
267 .name = DRV_NAME, 243 .name = DRV_NAME,
268 .id_table = opti, 244 .id_table = opti,
269 .probe = opti_init_one, 245 .probe = opti_init_one,
270 .remove = ata_pci_remove_one 246 .remove = ata_pci_remove_one,
247 .suspend = ata_pci_device_suspend,
248 .resume = ata_pci_device_resume,
271}; 249};
272 250
273static int __init opti_init(void) 251static int __init opti_init(void)
diff --git a/drivers/ata/pata_optidma.c b/drivers/ata/pata_optidma.c
index 2f4770cce04e..80d111c569dc 100644
--- a/drivers/ata/pata_optidma.c
+++ b/drivers/ata/pata_optidma.c
@@ -33,7 +33,7 @@
33#include <linux/libata.h> 33#include <linux/libata.h>
34 34
35#define DRV_NAME "pata_optidma" 35#define DRV_NAME "pata_optidma"
36#define DRV_VERSION "0.2.2" 36#define DRV_VERSION "0.2.3"
37 37
38enum { 38enum {
39 READ_REG = 0, /* index of Read cycle timing register */ 39 READ_REG = 0, /* index of Read cycle timing register */
@@ -352,7 +352,6 @@ static struct scsi_host_template optidma_sht = {
352 .can_queue = ATA_DEF_QUEUE, 352 .can_queue = ATA_DEF_QUEUE,
353 .this_id = ATA_SHT_THIS_ID, 353 .this_id = ATA_SHT_THIS_ID,
354 .sg_tablesize = LIBATA_MAX_PRD, 354 .sg_tablesize = LIBATA_MAX_PRD,
355 .max_sectors = ATA_MAX_SECTORS,
356 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 355 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
357 .emulated = ATA_SHT_EMULATED, 356 .emulated = ATA_SHT_EMULATED,
358 .use_clustering = ATA_SHT_USE_CLUSTERING, 357 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -361,6 +360,8 @@ static struct scsi_host_template optidma_sht = {
361 .slave_configure = ata_scsi_slave_config, 360 .slave_configure = ata_scsi_slave_config,
362 .slave_destroy = ata_scsi_slave_destroy, 361 .slave_destroy = ata_scsi_slave_destroy,
363 .bios_param = ata_std_bios_param, 362 .bios_param = ata_std_bios_param,
363 .resume = ata_scsi_device_resume,
364 .suspend = ata_scsi_device_suspend,
364}; 365};
365 366
366static struct ata_port_operations optidma_port_ops = { 367static struct ata_port_operations optidma_port_ops = {
@@ -522,7 +523,9 @@ static struct pci_driver optidma_pci_driver = {
522 .name = DRV_NAME, 523 .name = DRV_NAME,
523 .id_table = optidma, 524 .id_table = optidma,
524 .probe = optidma_init_one, 525 .probe = optidma_init_one,
525 .remove = ata_pci_remove_one 526 .remove = ata_pci_remove_one,
527 .suspend = ata_pci_device_suspend,
528 .resume = ata_pci_device_resume,
526}; 529};
527 530
528static int __init optidma_init(void) 531static int __init optidma_init(void)
diff --git a/drivers/ata/pata_pcmcia.c b/drivers/ata/pata_pcmcia.c
index 999922de476e..4ca6fa5dcb42 100644
--- a/drivers/ata/pata_pcmcia.c
+++ b/drivers/ata/pata_pcmcia.c
@@ -62,7 +62,6 @@ static struct scsi_host_template pcmcia_sht = {
62 .can_queue = ATA_DEF_QUEUE, 62 .can_queue = ATA_DEF_QUEUE,
63 .this_id = ATA_SHT_THIS_ID, 63 .this_id = ATA_SHT_THIS_ID,
64 .sg_tablesize = LIBATA_MAX_PRD, 64 .sg_tablesize = LIBATA_MAX_PRD,
65 .max_sectors = ATA_MAX_SECTORS,
66 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 65 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
67 .emulated = ATA_SHT_EMULATED, 66 .emulated = ATA_SHT_EMULATED,
68 .use_clustering = ATA_SHT_USE_CLUSTERING, 67 .use_clustering = ATA_SHT_USE_CLUSTERING,
diff --git a/drivers/ata/pata_pdc2027x.c b/drivers/ata/pata_pdc2027x.c
index beb6d10a234b..76dd1c935dbd 100644
--- a/drivers/ata/pata_pdc2027x.c
+++ b/drivers/ata/pata_pdc2027x.c
@@ -134,7 +134,6 @@ static struct scsi_host_template pdc2027x_sht = {
134 .can_queue = ATA_DEF_QUEUE, 134 .can_queue = ATA_DEF_QUEUE,
135 .this_id = ATA_SHT_THIS_ID, 135 .this_id = ATA_SHT_THIS_ID,
136 .sg_tablesize = LIBATA_MAX_PRD, 136 .sg_tablesize = LIBATA_MAX_PRD,
137 .max_sectors = ATA_MAX_SECTORS,
138 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 137 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
139 .emulated = ATA_SHT_EMULATED, 138 .emulated = ATA_SHT_EMULATED,
140 .use_clustering = ATA_SHT_USE_CLUSTERING, 139 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -854,7 +853,7 @@ static void __devexit pdc2027x_remove_one(struct pci_dev *pdev)
854 */ 853 */
855static int __init pdc2027x_init(void) 854static int __init pdc2027x_init(void)
856{ 855{
857 return pci_module_init(&pdc2027x_pci_driver); 856 return pci_register_driver(&pdc2027x_pci_driver);
858} 857}
859 858
860/** 859/**
diff --git a/drivers/ata/pata_pdc202xx_old.c b/drivers/ata/pata_pdc202xx_old.c
index 6baf51b2fda1..ad691b9e7743 100644
--- a/drivers/ata/pata_pdc202xx_old.c
+++ b/drivers/ata/pata_pdc202xx_old.c
@@ -21,7 +21,7 @@
21#include <linux/libata.h> 21#include <linux/libata.h>
22 22
23#define DRV_NAME "pata_pdc202xx_old" 23#define DRV_NAME "pata_pdc202xx_old"
24#define DRV_VERSION "0.2.1" 24#define DRV_VERSION "0.2.3"
25 25
26/** 26/**
27 * pdc2024x_pre_reset - probe begin 27 * pdc2024x_pre_reset - probe begin
@@ -63,7 +63,7 @@ static void pdc2026x_error_handler(struct ata_port *ap)
63} 63}
64 64
65/** 65/**
66 * pdc_configure_piomode - set chip PIO timing 66 * pdc202xx_configure_piomode - set chip PIO timing
67 * @ap: ATA interface 67 * @ap: ATA interface
68 * @adev: ATA device 68 * @adev: ATA device
69 * @pio: PIO mode 69 * @pio: PIO mode
@@ -73,7 +73,7 @@ static void pdc2026x_error_handler(struct ata_port *ap)
73 * versa 73 * versa
74 */ 74 */
75 75
76static void pdc_configure_piomode(struct ata_port *ap, struct ata_device *adev, int pio) 76static void pdc202xx_configure_piomode(struct ata_port *ap, struct ata_device *adev, int pio)
77{ 77{
78 struct pci_dev *pdev = to_pci_dev(ap->host->dev); 78 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
79 int port = 0x60 + 4 * ap->port_no + 2 * adev->devno; 79 int port = 0x60 + 4 * ap->port_no + 2 * adev->devno;
@@ -98,7 +98,7 @@ static void pdc_configure_piomode(struct ata_port *ap, struct ata_device *adev,
98} 98}
99 99
100/** 100/**
101 * pdc_set_piomode - set initial PIO mode data 101 * pdc202xx_set_piomode - set initial PIO mode data
102 * @ap: ATA interface 102 * @ap: ATA interface
103 * @adev: ATA device 103 * @adev: ATA device
104 * 104 *
@@ -106,13 +106,13 @@ static void pdc_configure_piomode(struct ata_port *ap, struct ata_device *adev,
106 * but we want to set the PIO timing by default. 106 * but we want to set the PIO timing by default.
107 */ 107 */
108 108
109static void pdc_set_piomode(struct ata_port *ap, struct ata_device *adev) 109static void pdc202xx_set_piomode(struct ata_port *ap, struct ata_device *adev)
110{ 110{
111 pdc_configure_piomode(ap, adev, adev->pio_mode - XFER_PIO_0); 111 pdc202xx_configure_piomode(ap, adev, adev->pio_mode - XFER_PIO_0);
112} 112}
113 113
114/** 114/**
115 * pdc_configure_dmamode - set DMA mode in chip 115 * pdc202xx_configure_dmamode - set DMA mode in chip
116 * @ap: ATA interface 116 * @ap: ATA interface
117 * @adev: ATA device 117 * @adev: ATA device
118 * 118 *
@@ -120,7 +120,7 @@ static void pdc_set_piomode(struct ata_port *ap, struct ata_device *adev)
120 * to occur. 120 * to occur.
121 */ 121 */
122 122
123static void pdc_set_dmamode(struct ata_port *ap, struct ata_device *adev) 123static void pdc202xx_set_dmamode(struct ata_port *ap, struct ata_device *adev)
124{ 124{
125 struct pci_dev *pdev = to_pci_dev(ap->host->dev); 125 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
126 int port = 0x60 + 4 * ap->port_no + 2 * adev->devno; 126 int port = 0x60 + 4 * ap->port_no + 2 * adev->devno;
@@ -184,7 +184,7 @@ static void pdc2026x_bmdma_start(struct ata_queued_cmd *qc)
184 184
185 /* The DMA clocks may have been trashed by a reset. FIXME: make conditional 185 /* The DMA clocks may have been trashed by a reset. FIXME: make conditional
186 and move to qc_issue ? */ 186 and move to qc_issue ? */
187 pdc_set_dmamode(ap, qc->dev); 187 pdc202xx_set_dmamode(ap, qc->dev);
188 188
189 /* Cases the state machine will not complete correctly without help */ 189 /* Cases the state machine will not complete correctly without help */
190 if ((tf->flags & ATA_TFLAG_LBA48) || tf->protocol == ATA_PROT_ATAPI_DMA) 190 if ((tf->flags & ATA_TFLAG_LBA48) || tf->protocol == ATA_PROT_ATAPI_DMA)
@@ -254,7 +254,7 @@ static void pdc2026x_dev_config(struct ata_port *ap, struct ata_device *adev)
254 adev->max_sectors = 256; 254 adev->max_sectors = 256;
255} 255}
256 256
257static struct scsi_host_template pdc_sht = { 257static struct scsi_host_template pdc202xx_sht = {
258 .module = THIS_MODULE, 258 .module = THIS_MODULE,
259 .name = DRV_NAME, 259 .name = DRV_NAME,
260 .ioctl = ata_scsi_ioctl, 260 .ioctl = ata_scsi_ioctl,
@@ -262,7 +262,6 @@ static struct scsi_host_template pdc_sht = {
262 .can_queue = ATA_DEF_QUEUE, 262 .can_queue = ATA_DEF_QUEUE,
263 .this_id = ATA_SHT_THIS_ID, 263 .this_id = ATA_SHT_THIS_ID,
264 .sg_tablesize = LIBATA_MAX_PRD, 264 .sg_tablesize = LIBATA_MAX_PRD,
265 .max_sectors = ATA_MAX_SECTORS,
266 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 265 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
267 .emulated = ATA_SHT_EMULATED, 266 .emulated = ATA_SHT_EMULATED,
268 .use_clustering = ATA_SHT_USE_CLUSTERING, 267 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -271,12 +270,14 @@ static struct scsi_host_template pdc_sht = {
271 .slave_configure = ata_scsi_slave_config, 270 .slave_configure = ata_scsi_slave_config,
272 .slave_destroy = ata_scsi_slave_destroy, 271 .slave_destroy = ata_scsi_slave_destroy,
273 .bios_param = ata_std_bios_param, 272 .bios_param = ata_std_bios_param,
273 .resume = ata_scsi_device_resume,
274 .suspend = ata_scsi_device_suspend,
274}; 275};
275 276
276static struct ata_port_operations pdc2024x_port_ops = { 277static struct ata_port_operations pdc2024x_port_ops = {
277 .port_disable = ata_port_disable, 278 .port_disable = ata_port_disable,
278 .set_piomode = pdc_set_piomode, 279 .set_piomode = pdc202xx_set_piomode,
279 .set_dmamode = pdc_set_dmamode, 280 .set_dmamode = pdc202xx_set_dmamode,
280 .mode_filter = ata_pci_default_filter, 281 .mode_filter = ata_pci_default_filter,
281 .tf_load = ata_tf_load, 282 .tf_load = ata_tf_load,
282 .tf_read = ata_tf_read, 283 .tf_read = ata_tf_read,
@@ -308,8 +309,8 @@ static struct ata_port_operations pdc2024x_port_ops = {
308 309
309static struct ata_port_operations pdc2026x_port_ops = { 310static struct ata_port_operations pdc2026x_port_ops = {
310 .port_disable = ata_port_disable, 311 .port_disable = ata_port_disable,
311 .set_piomode = pdc_set_piomode, 312 .set_piomode = pdc202xx_set_piomode,
312 .set_dmamode = pdc_set_dmamode, 313 .set_dmamode = pdc202xx_set_dmamode,
313 .mode_filter = ata_pci_default_filter, 314 .mode_filter = ata_pci_default_filter,
314 .tf_load = ata_tf_load, 315 .tf_load = ata_tf_load,
315 .tf_read = ata_tf_read, 316 .tf_read = ata_tf_read,
@@ -340,11 +341,11 @@ static struct ata_port_operations pdc2026x_port_ops = {
340 .host_stop = ata_host_stop 341 .host_stop = ata_host_stop
341}; 342};
342 343
343static int pdc_init_one(struct pci_dev *dev, const struct pci_device_id *id) 344static int pdc202xx_init_one(struct pci_dev *dev, const struct pci_device_id *id)
344{ 345{
345 static struct ata_port_info info[3] = { 346 static struct ata_port_info info[3] = {
346 { 347 {
347 .sht = &pdc_sht, 348 .sht = &pdc202xx_sht,
348 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 349 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
349 .pio_mask = 0x1f, 350 .pio_mask = 0x1f,
350 .mwdma_mask = 0x07, 351 .mwdma_mask = 0x07,
@@ -352,7 +353,7 @@ static int pdc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
352 .port_ops = &pdc2024x_port_ops 353 .port_ops = &pdc2024x_port_ops
353 }, 354 },
354 { 355 {
355 .sht = &pdc_sht, 356 .sht = &pdc202xx_sht,
356 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 357 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
357 .pio_mask = 0x1f, 358 .pio_mask = 0x1f,
358 .mwdma_mask = 0x07, 359 .mwdma_mask = 0x07,
@@ -360,7 +361,7 @@ static int pdc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
360 .port_ops = &pdc2026x_port_ops 361 .port_ops = &pdc2026x_port_ops
361 }, 362 },
362 { 363 {
363 .sht = &pdc_sht, 364 .sht = &pdc202xx_sht,
364 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 365 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
365 .pio_mask = 0x1f, 366 .pio_mask = 0x1f,
366 .mwdma_mask = 0x07, 367 .mwdma_mask = 0x07,
@@ -386,7 +387,7 @@ static int pdc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
386 return ata_pci_init_one(dev, port_info, 2); 387 return ata_pci_init_one(dev, port_info, 2);
387} 388}
388 389
389static const struct pci_device_id pdc[] = { 390static const struct pci_device_id pdc202xx[] = {
390 { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20246), 0 }, 391 { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20246), 0 },
391 { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20262), 1 }, 392 { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20262), 1 },
392 { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20263), 1 }, 393 { PCI_VDEVICE(PROMISE, PCI_DEVICE_ID_PROMISE_20263), 1 },
@@ -396,28 +397,30 @@ static const struct pci_device_id pdc[] = {
396 { }, 397 { },
397}; 398};
398 399
399static struct pci_driver pdc_pci_driver = { 400static struct pci_driver pdc202xx_pci_driver = {
400 .name = DRV_NAME, 401 .name = DRV_NAME,
401 .id_table = pdc, 402 .id_table = pdc202xx,
402 .probe = pdc_init_one, 403 .probe = pdc202xx_init_one,
403 .remove = ata_pci_remove_one 404 .remove = ata_pci_remove_one,
405 .suspend = ata_pci_device_suspend,
406 .resume = ata_pci_device_resume,
404}; 407};
405 408
406static int __init pdc_init(void) 409static int __init pdc202xx_init(void)
407{ 410{
408 return pci_register_driver(&pdc_pci_driver); 411 return pci_register_driver(&pdc202xx_pci_driver);
409} 412}
410 413
411static void __exit pdc_exit(void) 414static void __exit pdc202xx_exit(void)
412{ 415{
413 pci_unregister_driver(&pdc_pci_driver); 416 pci_unregister_driver(&pdc202xx_pci_driver);
414} 417}
415 418
416MODULE_AUTHOR("Alan Cox"); 419MODULE_AUTHOR("Alan Cox");
417MODULE_DESCRIPTION("low-level driver for Promise 2024x and 20262-20267"); 420MODULE_DESCRIPTION("low-level driver for Promise 2024x and 20262-20267");
418MODULE_LICENSE("GPL"); 421MODULE_LICENSE("GPL");
419MODULE_DEVICE_TABLE(pci, pdc); 422MODULE_DEVICE_TABLE(pci, pdc202xx);
420MODULE_VERSION(DRV_VERSION); 423MODULE_VERSION(DRV_VERSION);
421 424
422module_init(pdc_init); 425module_init(pdc202xx_init);
423module_exit(pdc_exit); 426module_exit(pdc202xx_exit);
diff --git a/drivers/ata/pata_platform.c b/drivers/ata/pata_platform.c
new file mode 100644
index 000000000000..443b1d85c6c4
--- /dev/null
+++ b/drivers/ata/pata_platform.c
@@ -0,0 +1,295 @@
1/*
2 * Generic platform device PATA driver
3 *
4 * Copyright (C) 2006 Paul Mundt
5 *
6 * Based on pata_pcmcia:
7 *
8 * Copyright 2005-2006 Red Hat Inc <alan@redhat.com>, all rights reserved.
9 *
10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file "COPYING" in the main directory of this archive
12 * for more details.
13 */
14#include <linux/kernel.h>
15#include <linux/module.h>
16#include <linux/init.h>
17#include <linux/blkdev.h>
18#include <scsi/scsi_host.h>
19#include <linux/ata.h>
20#include <linux/libata.h>
21#include <linux/platform_device.h>
22#include <linux/pata_platform.h>
23
24#define DRV_NAME "pata_platform"
25#define DRV_VERSION "0.1.2"
26
27static int pio_mask = 1;
28
29/*
30 * Provide our own set_mode() as we don't want to change anything that has
31 * already been configured..
32 */
33static void pata_platform_set_mode(struct ata_port *ap)
34{
35 int i;
36
37 for (i = 0; i < ATA_MAX_DEVICES; i++) {
38 struct ata_device *dev = &ap->device[i];
39
40 if (ata_dev_enabled(dev)) {
41 /* We don't really care */
42 dev->pio_mode = dev->xfer_mode = XFER_PIO_0;
43 dev->xfer_shift = ATA_SHIFT_PIO;
44 dev->flags |= ATA_DFLAG_PIO;
45 }
46 }
47}
48
49static void pata_platform_host_stop(struct ata_host *host)
50{
51 int i;
52
53 /*
54 * Unmap the bases for MMIO
55 */
56 for (i = 0; i < host->n_ports; i++) {
57 struct ata_port *ap = host->ports[i];
58
59 if (ap->flags & ATA_FLAG_MMIO) {
60 iounmap((void __iomem *)ap->ioaddr.ctl_addr);
61 iounmap((void __iomem *)ap->ioaddr.cmd_addr);
62 }
63 }
64}
65
66static struct scsi_host_template pata_platform_sht = {
67 .module = THIS_MODULE,
68 .name = DRV_NAME,
69 .ioctl = ata_scsi_ioctl,
70 .queuecommand = ata_scsi_queuecmd,
71 .can_queue = ATA_DEF_QUEUE,
72 .this_id = ATA_SHT_THIS_ID,
73 .sg_tablesize = LIBATA_MAX_PRD,
74 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
75 .emulated = ATA_SHT_EMULATED,
76 .use_clustering = ATA_SHT_USE_CLUSTERING,
77 .proc_name = DRV_NAME,
78 .dma_boundary = ATA_DMA_BOUNDARY,
79 .slave_configure = ata_scsi_slave_config,
80 .slave_destroy = ata_scsi_slave_destroy,
81 .bios_param = ata_std_bios_param,
82};
83
84static struct ata_port_operations pata_platform_port_ops = {
85 .set_mode = pata_platform_set_mode,
86
87 .port_disable = ata_port_disable,
88 .tf_load = ata_tf_load,
89 .tf_read = ata_tf_read,
90 .check_status = ata_check_status,
91 .exec_command = ata_exec_command,
92 .dev_select = ata_std_dev_select,
93
94 .freeze = ata_bmdma_freeze,
95 .thaw = ata_bmdma_thaw,
96 .error_handler = ata_bmdma_error_handler,
97 .post_internal_cmd = ata_bmdma_post_internal_cmd,
98
99 .qc_prep = ata_qc_prep,
100 .qc_issue = ata_qc_issue_prot,
101
102 .data_xfer = ata_pio_data_xfer_noirq,
103
104 .irq_handler = ata_interrupt,
105 .irq_clear = ata_bmdma_irq_clear,
106
107 .port_start = ata_port_start,
108 .port_stop = ata_port_stop,
109 .host_stop = pata_platform_host_stop
110};
111
112static void pata_platform_setup_port(struct ata_ioports *ioaddr,
113 struct pata_platform_info *info)
114{
115 unsigned int shift = 0;
116
117 /* Fixup the port shift for platforms that need it */
118 if (info && info->ioport_shift)
119 shift = info->ioport_shift;
120
121 ioaddr->data_addr = ioaddr->cmd_addr + (ATA_REG_DATA << shift);
122 ioaddr->error_addr = ioaddr->cmd_addr + (ATA_REG_ERR << shift);
123 ioaddr->feature_addr = ioaddr->cmd_addr + (ATA_REG_FEATURE << shift);
124 ioaddr->nsect_addr = ioaddr->cmd_addr + (ATA_REG_NSECT << shift);
125 ioaddr->lbal_addr = ioaddr->cmd_addr + (ATA_REG_LBAL << shift);
126 ioaddr->lbam_addr = ioaddr->cmd_addr + (ATA_REG_LBAM << shift);
127 ioaddr->lbah_addr = ioaddr->cmd_addr + (ATA_REG_LBAH << shift);
128 ioaddr->device_addr = ioaddr->cmd_addr + (ATA_REG_DEVICE << shift);
129 ioaddr->status_addr = ioaddr->cmd_addr + (ATA_REG_STATUS << shift);
130 ioaddr->command_addr = ioaddr->cmd_addr + (ATA_REG_CMD << shift);
131}
132
133/**
134 * pata_platform_probe - attach a platform interface
135 * @pdev: platform device
136 *
137 * Register a platform bus IDE interface. Such interfaces are PIO and we
138 * assume do not support IRQ sharing.
139 *
140 * Platform devices are expected to contain 3 resources per port:
141 *
142 * - I/O Base (IORESOURCE_IO or IORESOURCE_MEM)
143 * - CTL Base (IORESOURCE_IO or IORESOURCE_MEM)
144 * - IRQ (IORESOURCE_IRQ)
145 *
146 * If the base resources are both mem types, the ioremap() is handled
147 * here. For IORESOURCE_IO, it's assumed that there's no remapping
148 * necessary.
149 */
150static int __devinit pata_platform_probe(struct platform_device *pdev)
151{
152 struct resource *io_res, *ctl_res;
153 struct ata_probe_ent ae;
154 unsigned int mmio;
155 int ret;
156
157 /*
158 * Simple resource validation ..
159 */
160 if (unlikely(pdev->num_resources != 3)) {
161 dev_err(&pdev->dev, "invalid number of resources\n");
162 return -EINVAL;
163 }
164
165 /*
166 * Get the I/O base first
167 */
168 io_res = platform_get_resource(pdev, IORESOURCE_IO, 0);
169 if (io_res == NULL) {
170 io_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
171 if (unlikely(io_res == NULL))
172 return -EINVAL;
173 }
174
175 /*
176 * Then the CTL base
177 */
178 ctl_res = platform_get_resource(pdev, IORESOURCE_IO, 1);
179 if (ctl_res == NULL) {
180 ctl_res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
181 if (unlikely(ctl_res == NULL))
182 return -EINVAL;
183 }
184
185 /*
186 * Check for MMIO
187 */
188 mmio = (( io_res->flags == IORESOURCE_MEM) &&
189 (ctl_res->flags == IORESOURCE_MEM));
190
191 /*
192 * Now that that's out of the way, wire up the port..
193 */
194 memset(&ae, 0, sizeof(struct ata_probe_ent));
195 INIT_LIST_HEAD(&ae.node);
196 ae.dev = &pdev->dev;
197 ae.port_ops = &pata_platform_port_ops;
198 ae.sht = &pata_platform_sht;
199 ae.n_ports = 1;
200 ae.pio_mask = pio_mask;
201 ae.irq = platform_get_irq(pdev, 0);
202 ae.irq_flags = 0;
203 ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
204
205 /*
206 * Handle the MMIO case
207 */
208 if (mmio) {
209 ae.port_flags |= ATA_FLAG_MMIO;
210
211 ae.port[0].cmd_addr = (unsigned long)ioremap(io_res->start,
212 io_res->end - io_res->start + 1);
213 if (unlikely(!ae.port[0].cmd_addr)) {
214 dev_err(&pdev->dev, "failed to remap IO base\n");
215 return -ENXIO;
216 }
217
218 ae.port[0].ctl_addr = (unsigned long)ioremap(ctl_res->start,
219 ctl_res->end - ctl_res->start + 1);
220 if (unlikely(!ae.port[0].ctl_addr)) {
221 dev_err(&pdev->dev, "failed to remap CTL base\n");
222 ret = -ENXIO;
223 goto bad_remap;
224 }
225 } else {
226 ae.port[0].cmd_addr = io_res->start;
227 ae.port[0].ctl_addr = ctl_res->start;
228 }
229
230 ae.port[0].altstatus_addr = ae.port[0].ctl_addr;
231
232 pata_platform_setup_port(&ae.port[0], pdev->dev.platform_data);
233
234 if (unlikely(ata_device_add(&ae) == 0)) {
235 ret = -ENODEV;
236 goto add_failed;
237 }
238
239 return 0;
240
241add_failed:
242 if (ae.port[0].ctl_addr && mmio)
243 iounmap((void __iomem *)ae.port[0].ctl_addr);
244bad_remap:
245 if (ae.port[0].cmd_addr && mmio)
246 iounmap((void __iomem *)ae.port[0].cmd_addr);
247
248 return ret;
249}
250
251/**
252 * pata_platform_remove - unplug a platform interface
253 * @pdev: platform device
254 *
255 * A platform bus ATA device has been unplugged. Perform the needed
256 * cleanup. Also called on module unload for any active devices.
257 */
258static int __devexit pata_platform_remove(struct platform_device *pdev)
259{
260 struct device *dev = &pdev->dev;
261 struct ata_host *host = dev_get_drvdata(dev);
262
263 ata_host_remove(host);
264 dev_set_drvdata(dev, NULL);
265
266 return 0;
267}
268
269static struct platform_driver pata_platform_driver = {
270 .probe = pata_platform_probe,
271 .remove = __devexit_p(pata_platform_remove),
272 .driver = {
273 .name = DRV_NAME,
274 .owner = THIS_MODULE,
275 },
276};
277
278static int __init pata_platform_init(void)
279{
280 return platform_driver_register(&pata_platform_driver);
281}
282
283static void __exit pata_platform_exit(void)
284{
285 platform_driver_unregister(&pata_platform_driver);
286}
287module_init(pata_platform_init);
288module_exit(pata_platform_exit);
289
290module_param(pio_mask, int, 0);
291
292MODULE_AUTHOR("Paul Mundt");
293MODULE_DESCRIPTION("low-level driver for platform device ATA");
294MODULE_LICENSE("GPL");
295MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/ata/pata_qdi.c b/drivers/ata/pata_qdi.c
index 314938dea1fc..36f621abc390 100644
--- a/drivers/ata/pata_qdi.c
+++ b/drivers/ata/pata_qdi.c
@@ -157,7 +157,6 @@ static struct scsi_host_template qdi_sht = {
157 .can_queue = ATA_DEF_QUEUE, 157 .can_queue = ATA_DEF_QUEUE,
158 .this_id = ATA_SHT_THIS_ID, 158 .this_id = ATA_SHT_THIS_ID,
159 .sg_tablesize = LIBATA_MAX_PRD, 159 .sg_tablesize = LIBATA_MAX_PRD,
160 .max_sectors = ATA_MAX_SECTORS,
161 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 160 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
162 .emulated = ATA_SHT_EMULATED, 161 .emulated = ATA_SHT_EMULATED,
163 .use_clustering = ATA_SHT_USE_CLUSTERING, 162 .use_clustering = ATA_SHT_USE_CLUSTERING,
diff --git a/drivers/ata/pata_radisys.c b/drivers/ata/pata_radisys.c
index 048c2bb21ef1..065541d034ad 100644
--- a/drivers/ata/pata_radisys.c
+++ b/drivers/ata/pata_radisys.c
@@ -220,7 +220,6 @@ static struct scsi_host_template radisys_sht = {
220 .can_queue = ATA_DEF_QUEUE, 220 .can_queue = ATA_DEF_QUEUE,
221 .this_id = ATA_SHT_THIS_ID, 221 .this_id = ATA_SHT_THIS_ID,
222 .sg_tablesize = LIBATA_MAX_PRD, 222 .sg_tablesize = LIBATA_MAX_PRD,
223 .max_sectors = ATA_MAX_SECTORS,
224 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 223 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
225 .emulated = ATA_SHT_EMULATED, 224 .emulated = ATA_SHT_EMULATED,
226 .use_clustering = ATA_SHT_USE_CLUSTERING, 225 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -229,6 +228,8 @@ static struct scsi_host_template radisys_sht = {
229 .slave_configure = ata_scsi_slave_config, 228 .slave_configure = ata_scsi_slave_config,
230 .slave_destroy = ata_scsi_slave_destroy, 229 .slave_destroy = ata_scsi_slave_destroy,
231 .bios_param = ata_std_bios_param, 230 .bios_param = ata_std_bios_param,
231 .resume = ata_scsi_device_resume,
232 .suspend = ata_scsi_device_suspend,
232}; 233};
233 234
234static const struct ata_port_operations radisys_pata_ops = { 235static const struct ata_port_operations radisys_pata_ops = {
@@ -311,6 +312,8 @@ static struct pci_driver radisys_pci_driver = {
311 .id_table = radisys_pci_tbl, 312 .id_table = radisys_pci_tbl,
312 .probe = radisys_init_one, 313 .probe = radisys_init_one,
313 .remove = ata_pci_remove_one, 314 .remove = ata_pci_remove_one,
315 .suspend = ata_pci_device_suspend,
316 .resume = ata_pci_device_resume,
314}; 317};
315 318
316static int __init radisys_init(void) 319static int __init radisys_init(void)
diff --git a/drivers/ata/pata_rz1000.c b/drivers/ata/pata_rz1000.c
index e4e5ea423fef..3677c642c9f9 100644
--- a/drivers/ata/pata_rz1000.c
+++ b/drivers/ata/pata_rz1000.c
@@ -21,7 +21,7 @@
21#include <linux/libata.h> 21#include <linux/libata.h>
22 22
23#define DRV_NAME "pata_rz1000" 23#define DRV_NAME "pata_rz1000"
24#define DRV_VERSION "0.2.2" 24#define DRV_VERSION "0.2.3"
25 25
26 26
27/** 27/**
@@ -83,7 +83,6 @@ static struct scsi_host_template rz1000_sht = {
83 .can_queue = ATA_DEF_QUEUE, 83 .can_queue = ATA_DEF_QUEUE,
84 .this_id = ATA_SHT_THIS_ID, 84 .this_id = ATA_SHT_THIS_ID,
85 .sg_tablesize = LIBATA_MAX_PRD, 85 .sg_tablesize = LIBATA_MAX_PRD,
86 .max_sectors = ATA_MAX_SECTORS,
87 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 86 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
88 .emulated = ATA_SHT_EMULATED, 87 .emulated = ATA_SHT_EMULATED,
89 .use_clustering = ATA_SHT_USE_CLUSTERING, 88 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -92,6 +91,8 @@ static struct scsi_host_template rz1000_sht = {
92 .slave_configure = ata_scsi_slave_config, 91 .slave_configure = ata_scsi_slave_config,
93 .slave_destroy = ata_scsi_slave_destroy, 92 .slave_destroy = ata_scsi_slave_destroy,
94 .bios_param = ata_std_bios_param, 93 .bios_param = ata_std_bios_param,
94 .resume = ata_scsi_device_resume,
95 .suspend = ata_scsi_device_suspend,
95}; 96};
96 97
97static struct ata_port_operations rz1000_port_ops = { 98static struct ata_port_operations rz1000_port_ops = {
@@ -129,6 +130,19 @@ static struct ata_port_operations rz1000_port_ops = {
129 .host_stop = ata_host_stop 130 .host_stop = ata_host_stop
130}; 131};
131 132
133static int rz1000_fifo_disable(struct pci_dev *pdev)
134{
135 u16 reg;
136 /* Be exceptionally paranoid as we must be sure to apply the fix */
137 if (pci_read_config_word(pdev, 0x40, &reg) != 0)
138 return -1;
139 reg &= 0xDFFF;
140 if (pci_write_config_word(pdev, 0x40, reg) != 0)
141 return -1;
142 printk(KERN_INFO DRV_NAME ": disabled chipset readahead.\n");
143 return 0;
144}
145
132/** 146/**
133 * rz1000_init_one - Register RZ1000 ATA PCI device with kernel services 147 * rz1000_init_one - Register RZ1000 ATA PCI device with kernel services
134 * @pdev: PCI device to register 148 * @pdev: PCI device to register
@@ -143,7 +157,6 @@ static int rz1000_init_one (struct pci_dev *pdev, const struct pci_device_id *en
143{ 157{
144 static int printed_version; 158 static int printed_version;
145 struct ata_port_info *port_info[2]; 159 struct ata_port_info *port_info[2];
146 u16 reg;
147 static struct ata_port_info info = { 160 static struct ata_port_info info = {
148 .sht = &rz1000_sht, 161 .sht = &rz1000_sht,
149 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 162 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
@@ -154,23 +167,25 @@ static int rz1000_init_one (struct pci_dev *pdev, const struct pci_device_id *en
154 if (!printed_version++) 167 if (!printed_version++)
155 printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n"); 168 printk(KERN_DEBUG DRV_NAME " version " DRV_VERSION "\n");
156 169
157 /* Be exceptionally paranoid as we must be sure to apply the fix */ 170 if (rz1000_fifo_disable(pdev) == 0) {
158 if (pci_read_config_word(pdev, 0x40, &reg) != 0) 171 port_info[0] = &info;
159 goto fail; 172 port_info[1] = &info;
160 reg &= 0xDFFF; 173 return ata_pci_init_one(pdev, port_info, 2);
161 if (pci_write_config_word(pdev, 0x40, reg) != 0) 174 }
162 goto fail;
163 printk(KERN_INFO DRV_NAME ": disabled chipset readahead.\n");
164
165 port_info[0] = &info;
166 port_info[1] = &info;
167 return ata_pci_init_one(pdev, port_info, 2);
168fail:
169 printk(KERN_ERR DRV_NAME ": failed to disable read-ahead on chipset..\n"); 175 printk(KERN_ERR DRV_NAME ": failed to disable read-ahead on chipset..\n");
170 /* Not safe to use so skip */ 176 /* Not safe to use so skip */
171 return -ENODEV; 177 return -ENODEV;
172} 178}
173 179
180static int rz1000_reinit_one(struct pci_dev *pdev)
181{
182 /* If this fails on resume (which is a "cant happen" case), we
183 must stop as any progress risks data loss */
184 if (rz1000_fifo_disable(pdev))
185 panic("rz1000 fifo");
186 return ata_pci_device_resume(pdev);
187}
188
174static const struct pci_device_id pata_rz1000[] = { 189static const struct pci_device_id pata_rz1000[] = {
175 { PCI_VDEVICE(PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000), }, 190 { PCI_VDEVICE(PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000), },
176 { PCI_VDEVICE(PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001), }, 191 { PCI_VDEVICE(PCTECH, PCI_DEVICE_ID_PCTECH_RZ1001), },
@@ -182,7 +197,9 @@ static struct pci_driver rz1000_pci_driver = {
182 .name = DRV_NAME, 197 .name = DRV_NAME,
183 .id_table = pata_rz1000, 198 .id_table = pata_rz1000,
184 .probe = rz1000_init_one, 199 .probe = rz1000_init_one,
185 .remove = ata_pci_remove_one 200 .remove = ata_pci_remove_one,
201 .suspend = ata_pci_device_suspend,
202 .resume = rz1000_reinit_one,
186}; 203};
187 204
188static int __init rz1000_init(void) 205static int __init rz1000_init(void)
diff --git a/drivers/ata/pata_sc1200.c b/drivers/ata/pata_sc1200.c
index 0c75dae74764..a3b35bc50394 100644
--- a/drivers/ata/pata_sc1200.c
+++ b/drivers/ata/pata_sc1200.c
@@ -40,7 +40,7 @@
40#include <linux/libata.h> 40#include <linux/libata.h>
41 41
42#define DRV_NAME "sc1200" 42#define DRV_NAME "sc1200"
43#define DRV_VERSION "0.2.3" 43#define DRV_VERSION "0.2.4"
44 44
45#define SC1200_REV_A 0x00 45#define SC1200_REV_A 0x00
46#define SC1200_REV_B1 0x01 46#define SC1200_REV_B1 0x01
@@ -186,7 +186,6 @@ static struct scsi_host_template sc1200_sht = {
186 .can_queue = ATA_DEF_QUEUE, 186 .can_queue = ATA_DEF_QUEUE,
187 .this_id = ATA_SHT_THIS_ID, 187 .this_id = ATA_SHT_THIS_ID,
188 .sg_tablesize = LIBATA_MAX_PRD, 188 .sg_tablesize = LIBATA_MAX_PRD,
189 .max_sectors = ATA_MAX_SECTORS,
190 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 189 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
191 .emulated = ATA_SHT_EMULATED, 190 .emulated = ATA_SHT_EMULATED,
192 .use_clustering = ATA_SHT_USE_CLUSTERING, 191 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -195,6 +194,8 @@ static struct scsi_host_template sc1200_sht = {
195 .slave_configure = ata_scsi_slave_config, 194 .slave_configure = ata_scsi_slave_config,
196 .slave_destroy = ata_scsi_slave_destroy, 195 .slave_destroy = ata_scsi_slave_destroy,
197 .bios_param = ata_std_bios_param, 196 .bios_param = ata_std_bios_param,
197 .resume = ata_scsi_device_resume,
198 .suspend = ata_scsi_device_suspend,
198}; 199};
199 200
200static struct ata_port_operations sc1200_port_ops = { 201static struct ata_port_operations sc1200_port_ops = {
@@ -264,7 +265,9 @@ static struct pci_driver sc1200_pci_driver = {
264 .name = DRV_NAME, 265 .name = DRV_NAME,
265 .id_table = sc1200, 266 .id_table = sc1200,
266 .probe = sc1200_init_one, 267 .probe = sc1200_init_one,
267 .remove = ata_pci_remove_one 268 .remove = ata_pci_remove_one,
269 .suspend = ata_pci_device_suspend,
270 .resume = ata_pci_device_resume,
268}; 271};
269 272
270static int __init sc1200_init(void) 273static int __init sc1200_init(void)
diff --git a/drivers/ata/pata_serverworks.c b/drivers/ata/pata_serverworks.c
index be7f60efcb61..f02b6a3b0f10 100644
--- a/drivers/ata/pata_serverworks.c
+++ b/drivers/ata/pata_serverworks.c
@@ -41,7 +41,7 @@
41#include <linux/libata.h> 41#include <linux/libata.h>
42 42
43#define DRV_NAME "pata_serverworks" 43#define DRV_NAME "pata_serverworks"
44#define DRV_VERSION "0.3.7" 44#define DRV_VERSION "0.3.9"
45 45
46#define SVWKS_CSB5_REVISION_NEW 0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */ 46#define SVWKS_CSB5_REVISION_NEW 0x92 /* min PCI_REVISION_ID for UDMA5 (A2.0) */
47#define SVWKS_CSB6_REVISION 0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */ 47#define SVWKS_CSB6_REVISION 0xa0 /* min PCI_REVISION_ID for UDMA4 (A1.0) */
@@ -318,7 +318,6 @@ static struct scsi_host_template serverworks_sht = {
318 .can_queue = ATA_DEF_QUEUE, 318 .can_queue = ATA_DEF_QUEUE,
319 .this_id = ATA_SHT_THIS_ID, 319 .this_id = ATA_SHT_THIS_ID,
320 .sg_tablesize = LIBATA_MAX_PRD, 320 .sg_tablesize = LIBATA_MAX_PRD,
321 .max_sectors = ATA_MAX_SECTORS,
322 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 321 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
323 .emulated = ATA_SHT_EMULATED, 322 .emulated = ATA_SHT_EMULATED,
324 .use_clustering = ATA_SHT_USE_CLUSTERING, 323 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -327,6 +326,8 @@ static struct scsi_host_template serverworks_sht = {
327 .slave_configure = ata_scsi_slave_config, 326 .slave_configure = ata_scsi_slave_config,
328 .slave_destroy = ata_scsi_slave_destroy, 327 .slave_destroy = ata_scsi_slave_destroy,
329 .bios_param = ata_std_bios_param, 328 .bios_param = ata_std_bios_param,
329 .resume = ata_scsi_device_resume,
330 .suspend = ata_scsi_device_suspend,
330}; 331};
331 332
332static struct ata_port_operations serverworks_osb4_port_ops = { 333static struct ata_port_operations serverworks_osb4_port_ops = {
@@ -554,6 +555,30 @@ static int serverworks_init_one(struct pci_dev *pdev, const struct pci_device_id
554 return ata_pci_init_one(pdev, port_info, ports); 555 return ata_pci_init_one(pdev, port_info, ports);
555} 556}
556 557
558static int serverworks_reinit_one(struct pci_dev *pdev)
559{
560 /* Force master latency timer to 64 PCI clocks */
561 pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x40);
562
563 switch (pdev->device)
564 {
565 case PCI_DEVICE_ID_SERVERWORKS_OSB4IDE:
566 serverworks_fixup_osb4(pdev);
567 break;
568 case PCI_DEVICE_ID_SERVERWORKS_CSB5IDE:
569 ata_pci_clear_simplex(pdev);
570 /* fall through */
571 case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE:
572 case PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2:
573 serverworks_fixup_csb(pdev);
574 break;
575 case PCI_DEVICE_ID_SERVERWORKS_HT1000IDE:
576 serverworks_fixup_ht1000(pdev);
577 break;
578 }
579 return ata_pci_device_resume(pdev);
580}
581
557static const struct pci_device_id serverworks[] = { 582static const struct pci_device_id serverworks[] = {
558 { PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE), 0}, 583 { PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_OSB4IDE), 0},
559 { PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE), 2}, 584 { PCI_VDEVICE(SERVERWORKS, PCI_DEVICE_ID_SERVERWORKS_CSB5IDE), 2},
@@ -568,7 +593,9 @@ static struct pci_driver serverworks_pci_driver = {
568 .name = DRV_NAME, 593 .name = DRV_NAME,
569 .id_table = serverworks, 594 .id_table = serverworks,
570 .probe = serverworks_init_one, 595 .probe = serverworks_init_one,
571 .remove = ata_pci_remove_one 596 .remove = ata_pci_remove_one,
597 .suspend = ata_pci_device_suspend,
598 .resume = serverworks_reinit_one,
572}; 599};
573 600
574static int __init serverworks_init(void) 601static int __init serverworks_init(void)
diff --git a/drivers/ata/pata_sil680.c b/drivers/ata/pata_sil680.c
index 11942fd03b55..32cf0bfa8921 100644
--- a/drivers/ata/pata_sil680.c
+++ b/drivers/ata/pata_sil680.c
@@ -33,7 +33,7 @@
33#include <linux/libata.h> 33#include <linux/libata.h>
34 34
35#define DRV_NAME "pata_sil680" 35#define DRV_NAME "pata_sil680"
36#define DRV_VERSION "0.3.2" 36#define DRV_VERSION "0.4.1"
37 37
38/** 38/**
39 * sil680_selreg - return register base 39 * sil680_selreg - return register base
@@ -218,7 +218,6 @@ static struct scsi_host_template sil680_sht = {
218 .can_queue = ATA_DEF_QUEUE, 218 .can_queue = ATA_DEF_QUEUE,
219 .this_id = ATA_SHT_THIS_ID, 219 .this_id = ATA_SHT_THIS_ID,
220 .sg_tablesize = LIBATA_MAX_PRD, 220 .sg_tablesize = LIBATA_MAX_PRD,
221 .max_sectors = ATA_MAX_SECTORS,
222 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 221 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
223 .emulated = ATA_SHT_EMULATED, 222 .emulated = ATA_SHT_EMULATED,
224 .use_clustering = ATA_SHT_USE_CLUSTERING, 223 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -263,32 +262,20 @@ static struct ata_port_operations sil680_port_ops = {
263 .host_stop = ata_host_stop 262 .host_stop = ata_host_stop
264}; 263};
265 264
266static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id) 265/**
266 * sil680_init_chip - chip setup
267 * @pdev: PCI device
268 *
269 * Perform all the chip setup which must be done both when the device
270 * is powered up on boot and when we resume in case we resumed from RAM.
271 * Returns the final clock settings.
272 */
273
274static u8 sil680_init_chip(struct pci_dev *pdev)
267{ 275{
268 static struct ata_port_info info = {
269 .sht = &sil680_sht,
270 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
271 .pio_mask = 0x1f,
272 .mwdma_mask = 0x07,
273 .udma_mask = 0x7f,
274 .port_ops = &sil680_port_ops
275 };
276 static struct ata_port_info info_slow = {
277 .sht = &sil680_sht,
278 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
279 .pio_mask = 0x1f,
280 .mwdma_mask = 0x07,
281 .udma_mask = 0x3f,
282 .port_ops = &sil680_port_ops
283 };
284 static struct ata_port_info *port_info[2] = {&info, &info};
285 static int printed_version;
286 u32 class_rev = 0; 276 u32 class_rev = 0;
287 u8 tmpbyte = 0; 277 u8 tmpbyte = 0;
288 278
289 if (!printed_version++)
290 dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
291
292 pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev); 279 pci_read_config_dword(pdev, PCI_CLASS_REVISION, &class_rev);
293 class_rev &= 0xff; 280 class_rev &= 0xff;
294 /* FIXME: double check */ 281 /* FIXME: double check */
@@ -323,8 +310,6 @@ static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
323 pci_read_config_byte(pdev, 0x8A, &tmpbyte); 310 pci_read_config_byte(pdev, 0x8A, &tmpbyte);
324 printk(KERN_INFO "sil680: BA5_EN = %d clock = %02X\n", 311 printk(KERN_INFO "sil680: BA5_EN = %d clock = %02X\n",
325 tmpbyte & 1, tmpbyte & 0x30); 312 tmpbyte & 1, tmpbyte & 0x30);
326 if ((tmpbyte & 0x30) == 0)
327 port_info[0] = port_info[1] = &info_slow;
328 313
329 pci_write_config_byte(pdev, 0xA1, 0x72); 314 pci_write_config_byte(pdev, 0xA1, 0x72);
330 pci_write_config_word(pdev, 0xA2, 0x328A); 315 pci_write_config_word(pdev, 0xA2, 0x328A);
@@ -343,11 +328,51 @@ static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
343 case 0x20: printk(KERN_INFO "sil680: Using PCI clock.\n");break; 328 case 0x20: printk(KERN_INFO "sil680: Using PCI clock.\n");break;
344 /* This last case is _NOT_ ok */ 329 /* This last case is _NOT_ ok */
345 case 0x30: printk(KERN_ERR "sil680: Clock disabled ?\n"); 330 case 0x30: printk(KERN_ERR "sil680: Clock disabled ?\n");
346 return -EIO; 331 }
332 return tmpbyte & 0x30;
333}
334
335static int sil680_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
336{
337 static struct ata_port_info info = {
338 .sht = &sil680_sht,
339 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
340 .pio_mask = 0x1f,
341 .mwdma_mask = 0x07,
342 .udma_mask = 0x7f,
343 .port_ops = &sil680_port_ops
344 };
345 static struct ata_port_info info_slow = {
346 .sht = &sil680_sht,
347 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST,
348 .pio_mask = 0x1f,
349 .mwdma_mask = 0x07,
350 .udma_mask = 0x3f,
351 .port_ops = &sil680_port_ops
352 };
353 static struct ata_port_info *port_info[2] = {&info, &info};
354 static int printed_version;
355
356 if (!printed_version++)
357 dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
358
359 switch(sil680_init_chip(pdev))
360 {
361 case 0:
362 port_info[0] = port_info[1] = &info_slow;
363 break;
364 case 0x30:
365 return -ENODEV;
347 } 366 }
348 return ata_pci_init_one(pdev, port_info, 2); 367 return ata_pci_init_one(pdev, port_info, 2);
349} 368}
350 369
370static int sil680_reinit_one(struct pci_dev *pdev)
371{
372 sil680_init_chip(pdev);
373 return ata_pci_device_resume(pdev);
374}
375
351static const struct pci_device_id sil680[] = { 376static const struct pci_device_id sil680[] = {
352 { PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_680), }, 377 { PCI_VDEVICE(CMD, PCI_DEVICE_ID_SII_680), },
353 378
@@ -358,7 +383,9 @@ static struct pci_driver sil680_pci_driver = {
358 .name = DRV_NAME, 383 .name = DRV_NAME,
359 .id_table = sil680, 384 .id_table = sil680,
360 .probe = sil680_init_one, 385 .probe = sil680_init_one,
361 .remove = ata_pci_remove_one 386 .remove = ata_pci_remove_one,
387 .suspend = ata_pci_device_suspend,
388 .resume = sil680_reinit_one,
362}; 389};
363 390
364static int __init sil680_init(void) 391static int __init sil680_init(void)
diff --git a/drivers/ata/pata_sis.c b/drivers/ata/pata_sis.c
index 91e85f90941d..916cedb3d755 100644
--- a/drivers/ata/pata_sis.c
+++ b/drivers/ata/pata_sis.c
@@ -34,7 +34,7 @@
34#include <linux/ata.h> 34#include <linux/ata.h>
35 35
36#define DRV_NAME "pata_sis" 36#define DRV_NAME "pata_sis"
37#define DRV_VERSION "0.4.4" 37#define DRV_VERSION "0.4.5"
38 38
39struct sis_chipset { 39struct sis_chipset {
40 u16 device; /* PCI host ID */ 40 u16 device; /* PCI host ID */
@@ -538,7 +538,6 @@ static struct scsi_host_template sis_sht = {
538 .can_queue = ATA_DEF_QUEUE, 538 .can_queue = ATA_DEF_QUEUE,
539 .this_id = ATA_SHT_THIS_ID, 539 .this_id = ATA_SHT_THIS_ID,
540 .sg_tablesize = LIBATA_MAX_PRD, 540 .sg_tablesize = LIBATA_MAX_PRD,
541 .max_sectors = ATA_MAX_SECTORS,
542 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 541 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
543 .emulated = ATA_SHT_EMULATED, 542 .emulated = ATA_SHT_EMULATED,
544 .use_clustering = ATA_SHT_USE_CLUSTERING, 543 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -547,6 +546,8 @@ static struct scsi_host_template sis_sht = {
547 .slave_configure = ata_scsi_slave_config, 546 .slave_configure = ata_scsi_slave_config,
548 .slave_destroy = ata_scsi_slave_destroy, 547 .slave_destroy = ata_scsi_slave_destroy,
549 .bios_param = ata_std_bios_param, 548 .bios_param = ata_std_bios_param,
549 .resume = ata_scsi_device_resume,
550 .suspend = ata_scsi_device_suspend,
550}; 551};
551 552
552static const struct ata_port_operations sis_133_ops = { 553static const struct ata_port_operations sis_133_ops = {
@@ -1000,6 +1001,8 @@ static struct pci_driver sis_pci_driver = {
1000 .id_table = sis_pci_tbl, 1001 .id_table = sis_pci_tbl,
1001 .probe = sis_init_one, 1002 .probe = sis_init_one,
1002 .remove = ata_pci_remove_one, 1003 .remove = ata_pci_remove_one,
1004 .suspend = ata_pci_device_suspend,
1005 .resume = ata_pci_device_resume,
1003}; 1006};
1004 1007
1005static int __init sis_init(void) 1008static int __init sis_init(void)
diff --git a/drivers/ata/pata_sl82c105.c b/drivers/ata/pata_sl82c105.c
index dc1cfc6d805b..e94f515ef54b 100644
--- a/drivers/ata/pata_sl82c105.c
+++ b/drivers/ata/pata_sl82c105.c
@@ -230,7 +230,6 @@ static struct scsi_host_template sl82c105_sht = {
230 .can_queue = ATA_DEF_QUEUE, 230 .can_queue = ATA_DEF_QUEUE,
231 .this_id = ATA_SHT_THIS_ID, 231 .this_id = ATA_SHT_THIS_ID,
232 .sg_tablesize = LIBATA_MAX_PRD, 232 .sg_tablesize = LIBATA_MAX_PRD,
233 .max_sectors = ATA_MAX_SECTORS,
234 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 233 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
235 .emulated = ATA_SHT_EMULATED, 234 .emulated = ATA_SHT_EMULATED,
236 .use_clustering = ATA_SHT_USE_CLUSTERING, 235 .use_clustering = ATA_SHT_USE_CLUSTERING,
diff --git a/drivers/ata/pata_triflex.c b/drivers/ata/pata_triflex.c
index bfda1f7e760a..a142971f1307 100644
--- a/drivers/ata/pata_triflex.c
+++ b/drivers/ata/pata_triflex.c
@@ -43,7 +43,7 @@
43#include <linux/libata.h> 43#include <linux/libata.h>
44 44
45#define DRV_NAME "pata_triflex" 45#define DRV_NAME "pata_triflex"
46#define DRV_VERSION "0.2.5" 46#define DRV_VERSION "0.2.7"
47 47
48/** 48/**
49 * triflex_prereset - probe begin 49 * triflex_prereset - probe begin
@@ -185,7 +185,6 @@ static struct scsi_host_template triflex_sht = {
185 .can_queue = ATA_DEF_QUEUE, 185 .can_queue = ATA_DEF_QUEUE,
186 .this_id = ATA_SHT_THIS_ID, 186 .this_id = ATA_SHT_THIS_ID,
187 .sg_tablesize = LIBATA_MAX_PRD, 187 .sg_tablesize = LIBATA_MAX_PRD,
188 .max_sectors = ATA_MAX_SECTORS,
189 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 188 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
190 .emulated = ATA_SHT_EMULATED, 189 .emulated = ATA_SHT_EMULATED,
191 .use_clustering = ATA_SHT_USE_CLUSTERING, 190 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -194,6 +193,8 @@ static struct scsi_host_template triflex_sht = {
194 .slave_configure = ata_scsi_slave_config, 193 .slave_configure = ata_scsi_slave_config,
195 .slave_destroy = ata_scsi_slave_destroy, 194 .slave_destroy = ata_scsi_slave_destroy,
196 .bios_param = ata_std_bios_param, 195 .bios_param = ata_std_bios_param,
196 .resume = ata_scsi_device_resume,
197 .suspend = ata_scsi_device_suspend,
197}; 198};
198 199
199static struct ata_port_operations triflex_port_ops = { 200static struct ata_port_operations triflex_port_ops = {
@@ -258,7 +259,9 @@ static struct pci_driver triflex_pci_driver = {
258 .name = DRV_NAME, 259 .name = DRV_NAME,
259 .id_table = triflex, 260 .id_table = triflex,
260 .probe = triflex_init_one, 261 .probe = triflex_init_one,
261 .remove = ata_pci_remove_one 262 .remove = ata_pci_remove_one,
263 .suspend = ata_pci_device_suspend,
264 .resume = ata_pci_device_resume,
262}; 265};
263 266
264static int __init triflex_init(void) 267static int __init triflex_init(void)
diff --git a/drivers/ata/pata_via.c b/drivers/ata/pata_via.c
index c5f1616d224d..cc09d47fb927 100644
--- a/drivers/ata/pata_via.c
+++ b/drivers/ata/pata_via.c
@@ -23,6 +23,7 @@
23 * VIA VT8233c - UDMA100 23 * VIA VT8233c - UDMA100
24 * VIA VT8235 - UDMA133 24 * VIA VT8235 - UDMA133
25 * VIA VT8237 - UDMA133 25 * VIA VT8237 - UDMA133
26 * VIA VT8251 - UDMA133
26 * 27 *
27 * Most registers remain compatible across chips. Others start reserved 28 * Most registers remain compatible across chips. Others start reserved
28 * and acquire sensible semantics if set to 1 (eg cable detect). A few 29 * and acquire sensible semantics if set to 1 (eg cable detect). A few
@@ -60,7 +61,7 @@
60#include <linux/libata.h> 61#include <linux/libata.h>
61 62
62#define DRV_NAME "pata_via" 63#define DRV_NAME "pata_via"
63#define DRV_VERSION "0.1.14" 64#define DRV_VERSION "0.2.0"
64 65
65/* 66/*
66 * The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx 67 * The following comes directly from Vojtech Pavlik's ide/pci/via82cxxx
@@ -94,6 +95,7 @@ static const struct via_isa_bridge {
94 u8 rev_max; 95 u8 rev_max;
95 u16 flags; 96 u16 flags;
96} via_isa_bridges[] = { 97} via_isa_bridges[] = {
98 { "vt8251", PCI_DEVICE_ID_VIA_8251, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
97 { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, 99 { "cx700", PCI_DEVICE_ID_VIA_CX700, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
98 { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES}, 100 { "vt6410", PCI_DEVICE_ID_VIA_6410, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST | VIA_NO_ENABLES},
99 { "vt8237a", PCI_DEVICE_ID_VIA_8237A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST }, 101 { "vt8237a", PCI_DEVICE_ID_VIA_8237A, 0x00, 0x2f, VIA_UDMA_133 | VIA_BAD_AST },
@@ -288,7 +290,6 @@ static struct scsi_host_template via_sht = {
288 .can_queue = ATA_DEF_QUEUE, 290 .can_queue = ATA_DEF_QUEUE,
289 .this_id = ATA_SHT_THIS_ID, 291 .this_id = ATA_SHT_THIS_ID,
290 .sg_tablesize = LIBATA_MAX_PRD, 292 .sg_tablesize = LIBATA_MAX_PRD,
291 .max_sectors = ATA_MAX_SECTORS,
292 .cmd_per_lun = ATA_SHT_CMD_PER_LUN, 293 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
293 .emulated = ATA_SHT_EMULATED, 294 .emulated = ATA_SHT_EMULATED,
294 .use_clustering = ATA_SHT_USE_CLUSTERING, 295 .use_clustering = ATA_SHT_USE_CLUSTERING,
@@ -297,6 +298,8 @@ static struct scsi_host_template via_sht = {
297 .slave_configure = ata_scsi_slave_config, 298 .slave_configure = ata_scsi_slave_config,
298 .slave_destroy = ata_scsi_slave_destroy, 299 .slave_destroy = ata_scsi_slave_destroy,
299 .bios_param = ata_std_bios_param, 300 .bios_param = ata_std_bios_param,
301 .resume = ata_scsi_device_resume,
302 .suspend = ata_scsi_device_suspend,
300}; 303};
301 304
302static struct ata_port_operations via_port_ops = { 305static struct ata_port_operations via_port_ops = {
@@ -370,8 +373,42 @@ static struct ata_port_operations via_port_ops_noirq = {
370}; 373};
371 374
372/** 375/**
376 * via_config_fifo - set up the FIFO
377 * @pdev: PCI device
378 * @flags: configuration flags
379 *
380 * Set the FIFO properties for this device if neccessary. Used both on
381 * set up and on and the resume path
382 */
383
384static void via_config_fifo(struct pci_dev *pdev, unsigned int flags)
385{
386 u8 enable;
387
388 /* 0x40 low bits indicate enabled channels */
389 pci_read_config_byte(pdev, 0x40 , &enable);
390 enable &= 3;
391
392 if (flags & VIA_SET_FIFO) {
393 u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20};
394 u8 fifo;
395
396 pci_read_config_byte(pdev, 0x43, &fifo);
397
398 /* Clear PREQ# until DDACK# for errata */
399 if (flags & VIA_BAD_PREQ)
400 fifo &= 0x7F;
401 else
402 fifo &= 0x9f;
403 /* Turn on FIFO for enabled channels */
404 fifo |= fifo_setting[enable];
405 pci_write_config_byte(pdev, 0x43, fifo);
406 }
407}
408
409/**
373 * via_init_one - discovery callback 410 * via_init_one - discovery callback
374 * @pdev: PCI device ID 411 * @pdev: PCI device
375 * @id: PCI table info 412 * @id: PCI table info
376 * 413 *
377 * A VIA IDE interface has been discovered. Figure out what revision 414 * A VIA IDE interface has been discovered. Figure out what revision
@@ -383,7 +420,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
383 /* Early VIA without UDMA support */ 420 /* Early VIA without UDMA support */
384 static struct ata_port_info via_mwdma_info = { 421 static struct ata_port_info via_mwdma_info = {
385 .sht = &via_sht, 422 .sht = &via_sht,
386 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 423 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
387 .pio_mask = 0x1f, 424 .pio_mask = 0x1f,
388 .mwdma_mask = 0x07, 425 .mwdma_mask = 0x07,
389 .port_ops = &via_port_ops 426 .port_ops = &via_port_ops
@@ -391,7 +428,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
391 /* Ditto with IRQ masking required */ 428 /* Ditto with IRQ masking required */
392 static struct ata_port_info via_mwdma_info_borked = { 429 static struct ata_port_info via_mwdma_info_borked = {
393 .sht = &via_sht, 430 .sht = &via_sht,
394 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 431 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
395 .pio_mask = 0x1f, 432 .pio_mask = 0x1f,
396 .mwdma_mask = 0x07, 433 .mwdma_mask = 0x07,
397 .port_ops = &via_port_ops_noirq, 434 .port_ops = &via_port_ops_noirq,
@@ -399,7 +436,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
399 /* VIA UDMA 33 devices (and borked 66) */ 436 /* VIA UDMA 33 devices (and borked 66) */
400 static struct ata_port_info via_udma33_info = { 437 static struct ata_port_info via_udma33_info = {
401 .sht = &via_sht, 438 .sht = &via_sht,
402 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 439 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
403 .pio_mask = 0x1f, 440 .pio_mask = 0x1f,
404 .mwdma_mask = 0x07, 441 .mwdma_mask = 0x07,
405 .udma_mask = 0x7, 442 .udma_mask = 0x7,
@@ -408,7 +445,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
408 /* VIA UDMA 66 devices */ 445 /* VIA UDMA 66 devices */
409 static struct ata_port_info via_udma66_info = { 446 static struct ata_port_info via_udma66_info = {
410 .sht = &via_sht, 447 .sht = &via_sht,
411 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 448 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
412 .pio_mask = 0x1f, 449 .pio_mask = 0x1f,
413 .mwdma_mask = 0x07, 450 .mwdma_mask = 0x07,
414 .udma_mask = 0x1f, 451 .udma_mask = 0x1f,
@@ -417,7 +454,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
417 /* VIA UDMA 100 devices */ 454 /* VIA UDMA 100 devices */
418 static struct ata_port_info via_udma100_info = { 455 static struct ata_port_info via_udma100_info = {
419 .sht = &via_sht, 456 .sht = &via_sht,
420 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 457 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
421 .pio_mask = 0x1f, 458 .pio_mask = 0x1f,
422 .mwdma_mask = 0x07, 459 .mwdma_mask = 0x07,
423 .udma_mask = 0x3f, 460 .udma_mask = 0x3f,
@@ -426,7 +463,7 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
426 /* UDMA133 with bad AST (All current 133) */ 463 /* UDMA133 with bad AST (All current 133) */
427 static struct ata_port_info via_udma133_info = { 464 static struct ata_port_info via_udma133_info = {
428 .sht = &via_sht, 465 .sht = &via_sht,
429 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST, 466 .flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SETXFER_POLLING,
430 .pio_mask = 0x1f, 467 .pio_mask = 0x1f,
431 .mwdma_mask = 0x07, 468 .mwdma_mask = 0x07,
432 .udma_mask = 0x7f, /* FIXME: should check north bridge */ 469 .udma_mask = 0x7f, /* FIXME: should check north bridge */
@@ -471,21 +508,8 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
471 } 508 }
472 509
473 /* Initialise the FIFO for the enabled channels. */ 510 /* Initialise the FIFO for the enabled channels. */
474 if (config->flags & VIA_SET_FIFO) { 511 via_config_fifo(pdev, config->flags);
475 u8 fifo_setting[4] = {0x00, 0x60, 0x00, 0x20}; 512
476 u8 fifo;
477
478 pci_read_config_byte(pdev, 0x43, &fifo);
479
480 /* Clear PREQ# until DDACK# for errata */
481 if (config->flags & VIA_BAD_PREQ)
482 fifo &= 0x7F;
483 else
484 fifo &= 0x9f;
485 /* Turn on FIFO for enabled channels */
486 fifo |= fifo_setting[enable];
487 pci_write_config_byte(pdev, 0x43, fifo);
488 }
489 /* Clock set up */ 513 /* Clock set up */
490 switch(config->flags & VIA_UDMA) { 514 switch(config->flags & VIA_UDMA) {
491 case VIA_UDMA_NONE: 515 case VIA_UDMA_NONE:
@@ -529,6 +553,39 @@ static int via_init_one(struct pci_dev *pdev, const struct pci_device_id *id)
529 return ata_pci_init_one(pdev, port_info, 2); 553 return ata_pci_init_one(pdev, port_info, 2);
530} 554}
531 555
556/**
557 * via_reinit_one - reinit after resume
558 * @pdev; PCI device
559 *
560 * Called when the VIA PATA device is resumed. We must then
561 * reconfigure the fifo and other setup we may have altered. In
562 * addition the kernel needs to have the resume methods on PCI
563 * quirk supported.
564 */
565
566static int via_reinit_one(struct pci_dev *pdev)
567{
568 u32 timing;
569 struct ata_host *host = dev_get_drvdata(&pdev->dev);
570 const struct via_isa_bridge *config = host->private_data;
571
572 via_config_fifo(pdev, config->flags);
573
574 if ((config->flags & VIA_UDMA) == VIA_UDMA_66) {
575 /* The 66 MHz devices require we enable the clock */
576 pci_read_config_dword(pdev, 0x50, &timing);
577 timing |= 0x80008;
578 pci_write_config_dword(pdev, 0x50, timing);
579 }
580 if (config->flags & VIA_BAD_CLK66) {
581 /* Disable the 66MHz clock on problem devices */
582 pci_read_config_dword(pdev, 0x50, &timing);
583 timing &= ~0x80008;
584 pci_write_config_dword(pdev, 0x50, timing);
585 }
586 return ata_pci_device_resume(pdev);
587}
588
532static const struct pci_device_id via[] = { 589static const struct pci_device_id via[] = {
533 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), }, 590 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C576_1), },
534 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1), }, 591 { PCI_VDEVICE(VIA, PCI_DEVICE_ID_VIA_82C586_1), },
@@ -542,7 +599,9 @@ static struct pci_driver via_pci_driver = {
542 .name = DRV_NAME, 599 .name = DRV_NAME,
543 .id_table = via, 600 .id_table = via,
544 .probe = via_init_one, 601 .probe = via_init_one,
545 .remove = ata_pci_remove_one 602 .remove = ata_pci_remove_one,
603 .suspend = ata_pci_device_suspend,
604 .resume = via_reinit_one,
546}; 605};
547 606
548static int __init via_init(void) 607static int __init via_init(void)
diff --git a/drivers/ata/pata_winbond.c b/drivers/ata/pata_winbond.c
new file mode 100644
index 000000000000..3ea345cde52e
--- /dev/null
+++ b/drivers/ata/pata_winbond.c
@@ -0,0 +1,306 @@
1/*
2 * pata_winbond.c - Winbond VLB ATA controllers
3 * (C) 2006 Red Hat <alan@redhat.com>
4 *
5 * Support for the Winbond 83759A when operating in advanced mode.
6 * Multichip mode is not currently supported.
7 */
8
9#include <linux/kernel.h>
10#include <linux/module.h>
11#include <linux/pci.h>
12#include <linux/init.h>
13#include <linux/blkdev.h>
14#include <linux/delay.h>
15#include <scsi/scsi_host.h>
16#include <linux/libata.h>
17#include <linux/platform_device.h>
18
19#define DRV_NAME "pata_winbond"
20#define DRV_VERSION "0.0.1"
21
22#define NR_HOST 4 /* Two winbond controllers, two channels each */
23
24struct winbond_data {
25 unsigned long config;
26 struct platform_device *platform_dev;
27};
28
29static struct ata_host *winbond_host[NR_HOST];
30static struct winbond_data winbond_data[NR_HOST];
31static int nr_winbond_host;
32
33#ifdef MODULE
34static int probe_winbond = 1;
35#else
36static int probe_winbond;
37#endif
38
39static spinlock_t winbond_lock = SPIN_LOCK_UNLOCKED;
40
41static void winbond_writecfg(unsigned long port, u8 reg, u8 val)
42{
43 unsigned long flags;
44 spin_lock_irqsave(&winbond_lock, flags);
45 outb(reg, port + 0x01);
46 outb(val, port + 0x02);
47 spin_unlock_irqrestore(&winbond_lock, flags);
48}
49
50static u8 winbond_readcfg(unsigned long port, u8 reg)
51{
52 u8 val;
53
54 unsigned long flags;
55 spin_lock_irqsave(&winbond_lock, flags);
56 outb(reg, port + 0x01);
57 val = inb(port + 0x02);
58 spin_unlock_irqrestore(&winbond_lock, flags);
59
60 return val;
61}
62
63static void winbond_set_piomode(struct ata_port *ap, struct ata_device *adev)
64{
65 struct ata_timing t;
66 struct winbond_data *winbond = ap->host->private_data;
67 int active, recovery;
68 u8 reg;
69 int timing = 0x88 + (ap->port_no * 4) + (adev->devno * 2);
70
71 reg = winbond_readcfg(winbond->config, 0x81);
72
73 /* Get the timing data in cycles */
74 if (reg & 0x40) /* Fast VLB bus, assume 50MHz */
75 ata_timing_compute(adev, adev->pio_mode, &t, 20000, 1000);
76 else
77 ata_timing_compute(adev, adev->pio_mode, &t, 30303, 1000);
78
79 active = (FIT(t.active, 3, 17) - 1) & 0x0F;
80 recovery = (FIT(t.recover, 1, 15) + 1) & 0x0F;
81 timing = (active << 4) | recovery;
82 winbond_writecfg(winbond->config, timing, reg);
83
84 /* Load the setup timing */
85
86 reg = 0x35;
87 if (adev->class != ATA_DEV_ATA)
88 reg |= 0x08; /* FIFO off */
89 if (!ata_pio_need_iordy(adev))
90 reg |= 0x02; /* IORDY off */
91 reg |= (FIT(t.setup, 0, 3) << 6);
92 winbond_writecfg(winbond->config, timing + 1, reg);
93}
94
95
96static void winbond_data_xfer(struct ata_device *adev, unsigned char *buf, unsigned int buflen, int write_data)
97{
98 struct ata_port *ap = adev->ap;
99 int slop = buflen & 3;
100
101 if (ata_id_has_dword_io(adev->id)) {
102 if (write_data)
103 outsl(ap->ioaddr.data_addr, buf, buflen >> 2);
104 else
105 insl(ap->ioaddr.data_addr, buf, buflen >> 2);
106
107 if (unlikely(slop)) {
108 u32 pad;
109 if (write_data) {
110 memcpy(&pad, buf + buflen - slop, slop);
111 outl(le32_to_cpu(pad), ap->ioaddr.data_addr);
112 } else {
113 pad = cpu_to_le16(inl(ap->ioaddr.data_addr));
114 memcpy(buf + buflen - slop, &pad, slop);
115 }
116 }
117 } else
118 ata_pio_data_xfer(adev, buf, buflen, write_data);
119}
120
121static struct scsi_host_template winbond_sht = {
122 .module = THIS_MODULE,
123 .name = DRV_NAME,
124 .ioctl = ata_scsi_ioctl,
125 .queuecommand = ata_scsi_queuecmd,
126 .can_queue = ATA_DEF_QUEUE,
127 .this_id = ATA_SHT_THIS_ID,
128 .sg_tablesize = LIBATA_MAX_PRD,
129 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
130 .emulated = ATA_SHT_EMULATED,
131 .use_clustering = ATA_SHT_USE_CLUSTERING,
132 .proc_name = DRV_NAME,
133 .dma_boundary = ATA_DMA_BOUNDARY,
134 .slave_configure = ata_scsi_slave_config,
135 .slave_destroy = ata_scsi_slave_destroy,
136 .bios_param = ata_std_bios_param,
137};
138
139static struct ata_port_operations winbond_port_ops = {
140 .port_disable = ata_port_disable,
141 .set_piomode = winbond_set_piomode,
142
143 .tf_load = ata_tf_load,
144 .tf_read = ata_tf_read,
145 .check_status = ata_check_status,
146 .exec_command = ata_exec_command,
147 .dev_select = ata_std_dev_select,
148
149 .freeze = ata_bmdma_freeze,
150 .thaw = ata_bmdma_thaw,
151 .error_handler = ata_bmdma_error_handler,
152 .post_internal_cmd = ata_bmdma_post_internal_cmd,
153
154 .qc_prep = ata_qc_prep,
155 .qc_issue = ata_qc_issue_prot,
156
157 .data_xfer = winbond_data_xfer,
158
159 .irq_handler = ata_interrupt,
160 .irq_clear = ata_bmdma_irq_clear,
161
162 .port_start = ata_port_start,
163 .port_stop = ata_port_stop,
164 .host_stop = ata_host_stop
165};
166
167/**
168 * winbond_init_one - attach a winbond interface
169 * @type: Type to display
170 * @io: I/O port start
171 * @irq: interrupt line
172 * @fast: True if on a > 33Mhz VLB
173 *
174 * Register a VLB bus IDE interface. Such interfaces are PIO and we
175 * assume do not support IRQ sharing.
176 */
177
178static __init int winbond_init_one(unsigned long port)
179{
180 struct ata_probe_ent ae;
181 struct platform_device *pdev;
182 int ret;
183 u8 reg;
184 int i;
185
186 reg = winbond_readcfg(port, 0x81);
187 reg |= 0x80; /* jumpered mode off */
188 winbond_writecfg(port, 0x81, reg);
189 reg = winbond_readcfg(port, 0x83);
190 reg |= 0xF0; /* local control */
191 winbond_writecfg(port, 0x83, reg);
192 reg = winbond_readcfg(port, 0x85);
193 reg |= 0xF0; /* programmable timing */
194 winbond_writecfg(port, 0x85, reg);
195
196 reg = winbond_readcfg(port, 0x81);
197
198 if (!(reg & 0x03)) /* Disabled */
199 return 0;
200
201 for (i = 0; i < 2 ; i ++) {
202
203 if (reg & (1 << i)) {
204 /*
205 * Fill in a probe structure first of all
206 */
207
208 pdev = platform_device_register_simple(DRV_NAME, nr_winbond_host, NULL, 0);
209 if (pdev == NULL)
210 return -ENOMEM;
211
212 memset(&ae, 0, sizeof(struct ata_probe_ent));
213 INIT_LIST_HEAD(&ae.node);
214 ae.dev = &pdev->dev;
215
216 ae.port_ops = &winbond_port_ops;
217 ae.pio_mask = 0x1F;
218
219 ae.sht = &winbond_sht;
220
221 ae.n_ports = 1;
222 ae.irq = 14 + i;
223 ae.irq_flags = 0;
224 ae.port_flags = ATA_FLAG_SLAVE_POSS | ATA_FLAG_SRST;
225 ae.port[0].cmd_addr = 0x1F0 - (0x80 * i);
226 ae.port[0].altstatus_addr = ae.port[0].cmd_addr + 0x0206;
227 ae.port[0].ctl_addr = ae.port[0].altstatus_addr;
228 ata_std_ports(&ae.port[0]);
229 /*
230 * Hook in a private data structure per channel
231 */
232 ae.private_data = &winbond_data[nr_winbond_host];
233 winbond_data[nr_winbond_host].config = port;
234 winbond_data[nr_winbond_host].platform_dev = pdev;
235
236 ret = ata_device_add(&ae);
237 if (ret == 0) {
238 platform_device_unregister(pdev);
239 return -ENODEV;
240 }
241 winbond_host[nr_winbond_host++] = dev_get_drvdata(&pdev->dev);
242 }
243 }
244
245 return 0;
246}
247
248/**
249 * winbond_init - attach winbond interfaces
250 *
251 * Attach winbond IDE interfaces by scanning the ports it may occupy.
252 */
253
254static __init int winbond_init(void)
255{
256 static const unsigned long config[2] = { 0x130, 0x1B0 };
257
258 int ct = 0;
259 int i;
260
261 if (probe_winbond == 0)
262 return -ENODEV;
263
264 /*
265 * Check both base addresses
266 */
267
268 for (i = 0; i < 2; i++) {
269 if (probe_winbond & (1<<i)) {
270 int ret = 0;
271 unsigned long port = config[i];
272
273 if (request_region(port, 2, "pata_winbond")) {
274 ret = winbond_init_one(port);
275 if(ret <= 0)
276 release_region(port, 2);
277 else ct+= ret;
278 }
279 }
280 }
281 if (ct != 0)
282 return 0;
283 return -ENODEV;
284}
285
286static __exit void winbond_exit(void)
287{
288 int i;
289
290 for (i = 0; i < nr_winbond_host; i++) {
291 ata_host_remove(winbond_host[i]);
292 release_region(winbond_data[i].config, 2);
293 platform_device_unregister(winbond_data[i].platform_dev);
294 }
295}
296
297MODULE_AUTHOR("Alan Cox");
298MODULE_DESCRIPTION("low-level driver for Winbond VL ATA");
299MODULE_LICENSE("GPL");
300MODULE_VERSION(DRV_VERSION);
301
302module_init(winbond_init);
303module_exit(winbond_exit);
304
305module_param(probe_winbond, int, 0);
306
diff --git a/drivers/ata/sata_nv.c b/drivers/ata/sata_nv.c
index d65ebfd7c7b2..0d316eb3c214 100644
--- a/drivers/ata/sata_nv.c
+++ b/drivers/ata/sata_nv.c
@@ -29,6 +29,11 @@
29 * NV-specific details such as register offsets, SATA phy location, 29 * NV-specific details such as register offsets, SATA phy location,
30 * hotplug info, etc. 30 * hotplug info, etc.
31 * 31 *
32 * CK804/MCP04 controllers support an alternate programming interface
33 * similar to the ADMA specification (with some modifications).
34 * This allows the use of NCQ. Non-DMA-mapped ATA commands are still
35 * sent through the legacy interface.
36 *
32 */ 37 */
33 38
34#include <linux/kernel.h> 39#include <linux/kernel.h>
@@ -40,10 +45,13 @@
40#include <linux/interrupt.h> 45#include <linux/interrupt.h>
41#include <linux/device.h> 46#include <linux/device.h>
42#include <scsi/scsi_host.h> 47#include <scsi/scsi_host.h>
48#include <scsi/scsi_device.h>
43#include <linux/libata.h> 49#include <linux/libata.h>
44 50
45#define DRV_NAME "sata_nv" 51#define DRV_NAME "sata_nv"
46#define DRV_VERSION "2.0" 52#define DRV_VERSION "3.2"
53
54#define NV_ADMA_DMA_BOUNDARY 0xffffffffUL
47 55
48enum { 56enum {
49 NV_PORTS = 2, 57 NV_PORTS = 2,
@@ -78,8 +86,138 @@ enum {
78 // For PCI config register 20 86 // For PCI config register 20
79 NV_MCP_SATA_CFG_20 = 0x50, 87 NV_MCP_SATA_CFG_20 = 0x50,
80 NV_MCP_SATA_CFG_20_SATA_SPACE_EN = 0x04, 88 NV_MCP_SATA_CFG_20_SATA_SPACE_EN = 0x04,
89 NV_MCP_SATA_CFG_20_PORT0_EN = (1 << 17),
90 NV_MCP_SATA_CFG_20_PORT1_EN = (1 << 16),
91 NV_MCP_SATA_CFG_20_PORT0_PWB_EN = (1 << 14),
92 NV_MCP_SATA_CFG_20_PORT1_PWB_EN = (1 << 12),
93
94 NV_ADMA_MAX_CPBS = 32,
95 NV_ADMA_CPB_SZ = 128,
96 NV_ADMA_APRD_SZ = 16,
97 NV_ADMA_SGTBL_LEN = (1024 - NV_ADMA_CPB_SZ) /
98 NV_ADMA_APRD_SZ,
99 NV_ADMA_SGTBL_TOTAL_LEN = NV_ADMA_SGTBL_LEN + 5,
100 NV_ADMA_SGTBL_SZ = NV_ADMA_SGTBL_LEN * NV_ADMA_APRD_SZ,
101 NV_ADMA_PORT_PRIV_DMA_SZ = NV_ADMA_MAX_CPBS *
102 (NV_ADMA_CPB_SZ + NV_ADMA_SGTBL_SZ),
103
104 /* BAR5 offset to ADMA general registers */
105 NV_ADMA_GEN = 0x400,
106 NV_ADMA_GEN_CTL = 0x00,
107 NV_ADMA_NOTIFIER_CLEAR = 0x30,
108
109 /* BAR5 offset to ADMA ports */
110 NV_ADMA_PORT = 0x480,
111
112 /* size of ADMA port register space */
113 NV_ADMA_PORT_SIZE = 0x100,
114
115 /* ADMA port registers */
116 NV_ADMA_CTL = 0x40,
117 NV_ADMA_CPB_COUNT = 0x42,
118 NV_ADMA_NEXT_CPB_IDX = 0x43,
119 NV_ADMA_STAT = 0x44,
120 NV_ADMA_CPB_BASE_LOW = 0x48,
121 NV_ADMA_CPB_BASE_HIGH = 0x4C,
122 NV_ADMA_APPEND = 0x50,
123 NV_ADMA_NOTIFIER = 0x68,
124 NV_ADMA_NOTIFIER_ERROR = 0x6C,
125
126 /* NV_ADMA_CTL register bits */
127 NV_ADMA_CTL_HOTPLUG_IEN = (1 << 0),
128 NV_ADMA_CTL_CHANNEL_RESET = (1 << 5),
129 NV_ADMA_CTL_GO = (1 << 7),
130 NV_ADMA_CTL_AIEN = (1 << 8),
131 NV_ADMA_CTL_READ_NON_COHERENT = (1 << 11),
132 NV_ADMA_CTL_WRITE_NON_COHERENT = (1 << 12),
133
134 /* CPB response flag bits */
135 NV_CPB_RESP_DONE = (1 << 0),
136 NV_CPB_RESP_ATA_ERR = (1 << 3),
137 NV_CPB_RESP_CMD_ERR = (1 << 4),
138 NV_CPB_RESP_CPB_ERR = (1 << 7),
139
140 /* CPB control flag bits */
141 NV_CPB_CTL_CPB_VALID = (1 << 0),
142 NV_CPB_CTL_QUEUE = (1 << 1),
143 NV_CPB_CTL_APRD_VALID = (1 << 2),
144 NV_CPB_CTL_IEN = (1 << 3),
145 NV_CPB_CTL_FPDMA = (1 << 4),
146
147 /* APRD flags */
148 NV_APRD_WRITE = (1 << 1),
149 NV_APRD_END = (1 << 2),
150 NV_APRD_CONT = (1 << 3),
151
152 /* NV_ADMA_STAT flags */
153 NV_ADMA_STAT_TIMEOUT = (1 << 0),
154 NV_ADMA_STAT_HOTUNPLUG = (1 << 1),
155 NV_ADMA_STAT_HOTPLUG = (1 << 2),
156 NV_ADMA_STAT_CPBERR = (1 << 4),
157 NV_ADMA_STAT_SERROR = (1 << 5),
158 NV_ADMA_STAT_CMD_COMPLETE = (1 << 6),
159 NV_ADMA_STAT_IDLE = (1 << 8),
160 NV_ADMA_STAT_LEGACY = (1 << 9),
161 NV_ADMA_STAT_STOPPED = (1 << 10),
162 NV_ADMA_STAT_DONE = (1 << 12),
163 NV_ADMA_STAT_ERR = NV_ADMA_STAT_CPBERR |
164 NV_ADMA_STAT_TIMEOUT,
165
166 /* port flags */
167 NV_ADMA_PORT_REGISTER_MODE = (1 << 0),
168 NV_ADMA_ATAPI_SETUP_COMPLETE = (1 << 1),
169
170};
171
172/* ADMA Physical Region Descriptor - one SG segment */
173struct nv_adma_prd {
174 __le64 addr;
175 __le32 len;
176 u8 flags;
177 u8 packet_len;
178 __le16 reserved;
179};
180
181enum nv_adma_regbits {
182 CMDEND = (1 << 15), /* end of command list */
183 WNB = (1 << 14), /* wait-not-BSY */
184 IGN = (1 << 13), /* ignore this entry */
185 CS1n = (1 << (4 + 8)), /* std. PATA signals follow... */
186 DA2 = (1 << (2 + 8)),
187 DA1 = (1 << (1 + 8)),
188 DA0 = (1 << (0 + 8)),
189};
190
191/* ADMA Command Parameter Block
192 The first 5 SG segments are stored inside the Command Parameter Block itself.
193 If there are more than 5 segments the remainder are stored in a separate
194 memory area indicated by next_aprd. */
195struct nv_adma_cpb {
196 u8 resp_flags; /* 0 */
197 u8 reserved1; /* 1 */
198 u8 ctl_flags; /* 2 */
199 /* len is length of taskfile in 64 bit words */
200 u8 len; /* 3 */
201 u8 tag; /* 4 */
202 u8 next_cpb_idx; /* 5 */
203 __le16 reserved2; /* 6-7 */
204 __le16 tf[12]; /* 8-31 */
205 struct nv_adma_prd aprd[5]; /* 32-111 */
206 __le64 next_aprd; /* 112-119 */
207 __le64 reserved3; /* 120-127 */
208};
209
210
211struct nv_adma_port_priv {
212 struct nv_adma_cpb *cpb;
213 dma_addr_t cpb_dma;
214 struct nv_adma_prd *aprd;
215 dma_addr_t aprd_dma;
216 u8 flags;
81}; 217};
82 218
219#define NV_ADMA_CHECK_INTR(GCTL, PORT) ((GCTL) & ( 1 << (19 + (12 * (PORT)))))
220
83static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent); 221static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent);
84static void nv_ck804_host_stop(struct ata_host *host); 222static void nv_ck804_host_stop(struct ata_host *host);
85static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance); 223static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance);
@@ -93,13 +231,28 @@ static void nv_nf2_thaw(struct ata_port *ap);
93static void nv_ck804_freeze(struct ata_port *ap); 231static void nv_ck804_freeze(struct ata_port *ap);
94static void nv_ck804_thaw(struct ata_port *ap); 232static void nv_ck804_thaw(struct ata_port *ap);
95static void nv_error_handler(struct ata_port *ap); 233static void nv_error_handler(struct ata_port *ap);
234static int nv_adma_slave_config(struct scsi_device *sdev);
235static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc);
236static void nv_adma_qc_prep(struct ata_queued_cmd *qc);
237static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc);
238static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance);
239static void nv_adma_irq_clear(struct ata_port *ap);
240static int nv_adma_port_start(struct ata_port *ap);
241static void nv_adma_port_stop(struct ata_port *ap);
242static void nv_adma_error_handler(struct ata_port *ap);
243static void nv_adma_host_stop(struct ata_host *host);
244static void nv_adma_bmdma_setup(struct ata_queued_cmd *qc);
245static void nv_adma_bmdma_start(struct ata_queued_cmd *qc);
246static void nv_adma_bmdma_stop(struct ata_queued_cmd *qc);
247static u8 nv_adma_bmdma_status(struct ata_port *ap);
96 248
97enum nv_host_type 249enum nv_host_type
98{ 250{
99 GENERIC, 251 GENERIC,
100 NFORCE2, 252 NFORCE2,
101 NFORCE3 = NFORCE2, /* NF2 == NF3 as far as sata_nv is concerned */ 253 NFORCE3 = NFORCE2, /* NF2 == NF3 as far as sata_nv is concerned */
102 CK804 254 CK804,
255 ADMA
103}; 256};
104 257
105static const struct pci_device_id nv_pci_tbl[] = { 258static const struct pci_device_id nv_pci_tbl[] = {
@@ -160,6 +313,24 @@ static struct scsi_host_template nv_sht = {
160 .bios_param = ata_std_bios_param, 313 .bios_param = ata_std_bios_param,
161}; 314};
162 315
316static struct scsi_host_template nv_adma_sht = {
317 .module = THIS_MODULE,
318 .name = DRV_NAME,
319 .ioctl = ata_scsi_ioctl,
320 .queuecommand = ata_scsi_queuecmd,
321 .can_queue = NV_ADMA_MAX_CPBS,
322 .this_id = ATA_SHT_THIS_ID,
323 .sg_tablesize = NV_ADMA_SGTBL_TOTAL_LEN,
324 .cmd_per_lun = ATA_SHT_CMD_PER_LUN,
325 .emulated = ATA_SHT_EMULATED,
326 .use_clustering = ATA_SHT_USE_CLUSTERING,
327 .proc_name = DRV_NAME,
328 .dma_boundary = NV_ADMA_DMA_BOUNDARY,
329 .slave_configure = nv_adma_slave_config,
330 .slave_destroy = ata_scsi_slave_destroy,
331 .bios_param = ata_std_bios_param,
332};
333
163static const struct ata_port_operations nv_generic_ops = { 334static const struct ata_port_operations nv_generic_ops = {
164 .port_disable = ata_port_disable, 335 .port_disable = ata_port_disable,
165 .tf_load = ata_tf_load, 336 .tf_load = ata_tf_load,
@@ -241,11 +412,40 @@ static const struct ata_port_operations nv_ck804_ops = {
241 .host_stop = nv_ck804_host_stop, 412 .host_stop = nv_ck804_host_stop,
242}; 413};
243 414
415static const struct ata_port_operations nv_adma_ops = {
416 .port_disable = ata_port_disable,
417 .tf_load = ata_tf_load,
418 .tf_read = ata_tf_read,
419 .check_atapi_dma = nv_adma_check_atapi_dma,
420 .exec_command = ata_exec_command,
421 .check_status = ata_check_status,
422 .dev_select = ata_std_dev_select,
423 .bmdma_setup = nv_adma_bmdma_setup,
424 .bmdma_start = nv_adma_bmdma_start,
425 .bmdma_stop = nv_adma_bmdma_stop,
426 .bmdma_status = nv_adma_bmdma_status,
427 .qc_prep = nv_adma_qc_prep,
428 .qc_issue = nv_adma_qc_issue,
429 .freeze = nv_ck804_freeze,
430 .thaw = nv_ck804_thaw,
431 .error_handler = nv_adma_error_handler,
432 .post_internal_cmd = nv_adma_bmdma_stop,
433 .data_xfer = ata_mmio_data_xfer,
434 .irq_handler = nv_adma_interrupt,
435 .irq_clear = nv_adma_irq_clear,
436 .scr_read = nv_scr_read,
437 .scr_write = nv_scr_write,
438 .port_start = nv_adma_port_start,
439 .port_stop = nv_adma_port_stop,
440 .host_stop = nv_adma_host_stop,
441};
442
244static struct ata_port_info nv_port_info[] = { 443static struct ata_port_info nv_port_info[] = {
245 /* generic */ 444 /* generic */
246 { 445 {
247 .sht = &nv_sht, 446 .sht = &nv_sht,
248 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, 447 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
448 ATA_FLAG_HRST_TO_RESUME,
249 .pio_mask = NV_PIO_MASK, 449 .pio_mask = NV_PIO_MASK,
250 .mwdma_mask = NV_MWDMA_MASK, 450 .mwdma_mask = NV_MWDMA_MASK,
251 .udma_mask = NV_UDMA_MASK, 451 .udma_mask = NV_UDMA_MASK,
@@ -254,7 +454,8 @@ static struct ata_port_info nv_port_info[] = {
254 /* nforce2/3 */ 454 /* nforce2/3 */
255 { 455 {
256 .sht = &nv_sht, 456 .sht = &nv_sht,
257 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, 457 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
458 ATA_FLAG_HRST_TO_RESUME,
258 .pio_mask = NV_PIO_MASK, 459 .pio_mask = NV_PIO_MASK,
259 .mwdma_mask = NV_MWDMA_MASK, 460 .mwdma_mask = NV_MWDMA_MASK,
260 .udma_mask = NV_UDMA_MASK, 461 .udma_mask = NV_UDMA_MASK,
@@ -263,12 +464,23 @@ static struct ata_port_info nv_port_info[] = {
263 /* ck804 */ 464 /* ck804 */
264 { 465 {
265 .sht = &nv_sht, 466 .sht = &nv_sht,
266 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY, 467 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
468 ATA_FLAG_HRST_TO_RESUME,
267 .pio_mask = NV_PIO_MASK, 469 .pio_mask = NV_PIO_MASK,
268 .mwdma_mask = NV_MWDMA_MASK, 470 .mwdma_mask = NV_MWDMA_MASK,
269 .udma_mask = NV_UDMA_MASK, 471 .udma_mask = NV_UDMA_MASK,
270 .port_ops = &nv_ck804_ops, 472 .port_ops = &nv_ck804_ops,
271 }, 473 },
474 /* ADMA */
475 {
476 .sht = &nv_adma_sht,
477 .flags = ATA_FLAG_SATA | ATA_FLAG_NO_LEGACY |
478 ATA_FLAG_MMIO | ATA_FLAG_NCQ,
479 .pio_mask = NV_PIO_MASK,
480 .mwdma_mask = NV_MWDMA_MASK,
481 .udma_mask = NV_UDMA_MASK,
482 .port_ops = &nv_adma_ops,
483 },
272}; 484};
273 485
274MODULE_AUTHOR("NVIDIA"); 486MODULE_AUTHOR("NVIDIA");
@@ -277,37 +489,220 @@ MODULE_LICENSE("GPL");
277MODULE_DEVICE_TABLE(pci, nv_pci_tbl); 489MODULE_DEVICE_TABLE(pci, nv_pci_tbl);
278MODULE_VERSION(DRV_VERSION); 490MODULE_VERSION(DRV_VERSION);
279 491
280static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance) 492static int adma_enabled = 1;
493
494static inline void __iomem *__nv_adma_ctl_block(void __iomem *mmio,
495 unsigned int port_no)
281{ 496{
282 struct ata_host *host = dev_instance; 497 mmio += NV_ADMA_PORT + port_no * NV_ADMA_PORT_SIZE;
283 unsigned int i; 498 return mmio;
284 unsigned int handled = 0; 499}
285 unsigned long flags;
286 500
287 spin_lock_irqsave(&host->lock, flags); 501static inline void __iomem *nv_adma_ctl_block(struct ata_port *ap)
502{
503 return __nv_adma_ctl_block(ap->host->mmio_base, ap->port_no);
504}
288 505
289 for (i = 0; i < host->n_ports; i++) { 506static inline void __iomem *nv_adma_gen_block(struct ata_port *ap)
290 struct ata_port *ap; 507{
508 return (ap->host->mmio_base + NV_ADMA_GEN);
509}
291 510
292 ap = host->ports[i]; 511static inline void __iomem *nv_adma_notifier_clear_block(struct ata_port *ap)
293 if (ap && 512{
294 !(ap->flags & ATA_FLAG_DISABLED)) { 513 return (nv_adma_gen_block(ap) + NV_ADMA_NOTIFIER_CLEAR + (4 * ap->port_no));
295 struct ata_queued_cmd *qc; 514}
296 515
297 qc = ata_qc_from_tag(ap, ap->active_tag); 516static void nv_adma_register_mode(struct ata_port *ap)
298 if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING))) 517{
299 handled += ata_host_intr(ap, qc); 518 void __iomem *mmio = nv_adma_ctl_block(ap);
300 else 519 struct nv_adma_port_priv *pp = ap->private_data;
301 // No request pending? Clear interrupt status 520 u16 tmp;
302 // anyway, in case there's one pending. 521
303 ap->ops->check_status(ap); 522 if (pp->flags & NV_ADMA_PORT_REGISTER_MODE)
304 } 523 return;
524
525 tmp = readw(mmio + NV_ADMA_CTL);
526 writew(tmp & ~NV_ADMA_CTL_GO, mmio + NV_ADMA_CTL);
527
528 pp->flags |= NV_ADMA_PORT_REGISTER_MODE;
529}
530
531static void nv_adma_mode(struct ata_port *ap)
532{
533 void __iomem *mmio = nv_adma_ctl_block(ap);
534 struct nv_adma_port_priv *pp = ap->private_data;
535 u16 tmp;
305 536
537 if (!(pp->flags & NV_ADMA_PORT_REGISTER_MODE))
538 return;
539
540 WARN_ON(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE);
541
542 tmp = readw(mmio + NV_ADMA_CTL);
543 writew(tmp | NV_ADMA_CTL_GO, mmio + NV_ADMA_CTL);
544
545 pp->flags &= ~NV_ADMA_PORT_REGISTER_MODE;
546}
547
548static int nv_adma_slave_config(struct scsi_device *sdev)
549{
550 struct ata_port *ap = ata_shost_to_port(sdev->host);
551 struct nv_adma_port_priv *pp = ap->private_data;
552 struct pci_dev *pdev = to_pci_dev(ap->host->dev);
553 u64 bounce_limit;
554 unsigned long segment_boundary;
555 unsigned short sg_tablesize;
556 int rc;
557 int adma_enable;
558 u32 current_reg, new_reg, config_mask;
559
560 rc = ata_scsi_slave_config(sdev);
561
562 if (sdev->id >= ATA_MAX_DEVICES || sdev->channel || sdev->lun)
563 /* Not a proper libata device, ignore */
564 return rc;
565
566 if (ap->device[sdev->id].class == ATA_DEV_ATAPI) {
567 /*
568 * NVIDIA reports that ADMA mode does not support ATAPI commands.
569 * Therefore ATAPI commands are sent through the legacy interface.
570 * However, the legacy interface only supports 32-bit DMA.
571 * Restrict DMA parameters as required by the legacy interface
572 * when an ATAPI device is connected.
573 */
574 bounce_limit = ATA_DMA_MASK;
575 segment_boundary = ATA_DMA_BOUNDARY;
576 /* Subtract 1 since an extra entry may be needed for padding, see
577 libata-scsi.c */
578 sg_tablesize = LIBATA_MAX_PRD - 1;
579
580 /* Since the legacy DMA engine is in use, we need to disable ADMA
581 on the port. */
582 adma_enable = 0;
583 nv_adma_register_mode(ap);
584 }
585 else {
586 bounce_limit = *ap->dev->dma_mask;
587 segment_boundary = NV_ADMA_DMA_BOUNDARY;
588 sg_tablesize = NV_ADMA_SGTBL_TOTAL_LEN;
589 adma_enable = 1;
590 }
591
592 pci_read_config_dword(pdev, NV_MCP_SATA_CFG_20, &current_reg);
593
594 if(ap->port_no == 1)
595 config_mask = NV_MCP_SATA_CFG_20_PORT1_EN |
596 NV_MCP_SATA_CFG_20_PORT1_PWB_EN;
597 else
598 config_mask = NV_MCP_SATA_CFG_20_PORT0_EN |
599 NV_MCP_SATA_CFG_20_PORT0_PWB_EN;
600
601 if(adma_enable) {
602 new_reg = current_reg | config_mask;
603 pp->flags &= ~NV_ADMA_ATAPI_SETUP_COMPLETE;
604 }
605 else {
606 new_reg = current_reg & ~config_mask;
607 pp->flags |= NV_ADMA_ATAPI_SETUP_COMPLETE;
306 } 608 }
609
610 if(current_reg != new_reg)
611 pci_write_config_dword(pdev, NV_MCP_SATA_CFG_20, new_reg);
612
613 blk_queue_bounce_limit(sdev->request_queue, bounce_limit);
614 blk_queue_segment_boundary(sdev->request_queue, segment_boundary);
615 blk_queue_max_hw_segments(sdev->request_queue, sg_tablesize);
616 ata_port_printk(ap, KERN_INFO,
617 "bounce limit 0x%llX, segment boundary 0x%lX, hw segs %hu\n",
618 (unsigned long long)bounce_limit, segment_boundary, sg_tablesize);
619 return rc;
620}
307 621
308 spin_unlock_irqrestore(&host->lock, flags); 622static int nv_adma_check_atapi_dma(struct ata_queued_cmd *qc)
623{
624 struct nv_adma_port_priv *pp = qc->ap->private_data;
625 return !(pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE);
626}
309 627
310 return IRQ_RETVAL(handled); 628static unsigned int nv_adma_tf_to_cpb(struct ata_taskfile *tf, __le16 *cpb)
629{
630 unsigned int idx = 0;
631
632 cpb[idx++] = cpu_to_le16((ATA_REG_DEVICE << 8) | tf->device | WNB);
633
634 if ((tf->flags & ATA_TFLAG_LBA48) == 0) {
635 cpb[idx++] = cpu_to_le16(IGN);
636 cpb[idx++] = cpu_to_le16(IGN);
637 cpb[idx++] = cpu_to_le16(IGN);
638 cpb[idx++] = cpu_to_le16(IGN);
639 cpb[idx++] = cpu_to_le16(IGN);
640 }
641 else {
642 cpb[idx++] = cpu_to_le16((ATA_REG_ERR << 8) | tf->hob_feature);
643 cpb[idx++] = cpu_to_le16((ATA_REG_NSECT << 8) | tf->hob_nsect);
644 cpb[idx++] = cpu_to_le16((ATA_REG_LBAL << 8) | tf->hob_lbal);
645 cpb[idx++] = cpu_to_le16((ATA_REG_LBAM << 8) | tf->hob_lbam);
646 cpb[idx++] = cpu_to_le16((ATA_REG_LBAH << 8) | tf->hob_lbah);
647 }
648 cpb[idx++] = cpu_to_le16((ATA_REG_ERR << 8) | tf->feature);
649 cpb[idx++] = cpu_to_le16((ATA_REG_NSECT << 8) | tf->nsect);
650 cpb[idx++] = cpu_to_le16((ATA_REG_LBAL << 8) | tf->lbal);
651 cpb[idx++] = cpu_to_le16((ATA_REG_LBAM << 8) | tf->lbam);
652 cpb[idx++] = cpu_to_le16((ATA_REG_LBAH << 8) | tf->lbah);
653
654 cpb[idx++] = cpu_to_le16((ATA_REG_CMD << 8) | tf->command | CMDEND);
655
656 return idx;
657}
658
659static void nv_adma_check_cpb(struct ata_port *ap, int cpb_num, int force_err)
660{
661 struct nv_adma_port_priv *pp = ap->private_data;
662 int complete = 0, have_err = 0;
663 u8 flags = pp->cpb[cpb_num].resp_flags;
664
665 VPRINTK("CPB %d, flags=0x%x\n", cpb_num, flags);
666
667 if (flags & NV_CPB_RESP_DONE) {
668 VPRINTK("CPB flags done, flags=0x%x\n", flags);
669 complete = 1;
670 }
671 if (flags & NV_CPB_RESP_ATA_ERR) {
672 ata_port_printk(ap, KERN_ERR, "CPB flags ATA err, flags=0x%x\n", flags);
673 have_err = 1;
674 complete = 1;
675 }
676 if (flags & NV_CPB_RESP_CMD_ERR) {
677 ata_port_printk(ap, KERN_ERR, "CPB flags CMD err, flags=0x%x\n", flags);
678 have_err = 1;
679 complete = 1;
680 }
681 if (flags & NV_CPB_RESP_CPB_ERR) {
682 ata_port_printk(ap, KERN_ERR, "CPB flags CPB err, flags=0x%x\n", flags);
683 have_err = 1;
684 complete = 1;
685 }
686 if(complete || force_err)
687 {
688 struct ata_queued_cmd *qc = ata_qc_from_tag(ap, cpb_num);
689 if(likely(qc)) {
690 u8 ata_status = 0;
691 /* Only use the ATA port status for non-NCQ commands.
692 For NCQ commands the current status may have nothing to do with
693 the command just completed. */
694 if(qc->tf.protocol != ATA_PROT_NCQ)
695 ata_status = readb(nv_adma_ctl_block(ap) + (ATA_REG_STATUS * 4));
696
697 if(have_err || force_err)
698 ata_status |= ATA_ERR;
699
700 qc->err_mask |= ac_err_mask(ata_status);
701 DPRINTK("Completing qc from tag %d with err_mask %u\n",cpb_num,
702 qc->err_mask);
703 ata_qc_complete(qc);
704 }
705 }
311} 706}
312 707
313static int nv_host_intr(struct ata_port *ap, u8 irq_stat) 708static int nv_host_intr(struct ata_port *ap, u8 irq_stat)
@@ -341,6 +736,486 @@ static int nv_host_intr(struct ata_port *ap, u8 irq_stat)
341 return 1; 736 return 1;
342} 737}
343 738
739static irqreturn_t nv_adma_interrupt(int irq, void *dev_instance)
740{
741 struct ata_host *host = dev_instance;
742 int i, handled = 0;
743 u32 notifier_clears[2];
744
745 spin_lock(&host->lock);
746
747 for (i = 0; i < host->n_ports; i++) {
748 struct ata_port *ap = host->ports[i];
749 notifier_clears[i] = 0;
750
751 if (ap && !(ap->flags & ATA_FLAG_DISABLED)) {
752 struct nv_adma_port_priv *pp = ap->private_data;
753 void __iomem *mmio = nv_adma_ctl_block(ap);
754 u16 status;
755 u32 gen_ctl;
756 int have_global_err = 0;
757 u32 notifier, notifier_error;
758
759 /* if in ATA register mode, use standard ata interrupt handler */
760 if (pp->flags & NV_ADMA_PORT_REGISTER_MODE) {
761 u8 irq_stat = readb(host->mmio_base + NV_INT_STATUS_CK804)
762 >> (NV_INT_PORT_SHIFT * i);
763 handled += nv_host_intr(ap, irq_stat);
764 continue;
765 }
766
767 notifier = readl(mmio + NV_ADMA_NOTIFIER);
768 notifier_error = readl(mmio + NV_ADMA_NOTIFIER_ERROR);
769 notifier_clears[i] = notifier | notifier_error;
770
771 gen_ctl = readl(nv_adma_gen_block(ap) + NV_ADMA_GEN_CTL);
772
773 if( !NV_ADMA_CHECK_INTR(gen_ctl, ap->port_no) && !notifier &&
774 !notifier_error)
775 /* Nothing to do */
776 continue;
777
778 status = readw(mmio + NV_ADMA_STAT);
779
780 /* Clear status. Ensure the controller sees the clearing before we start
781 looking at any of the CPB statuses, so that any CPB completions after
782 this point in the handler will raise another interrupt. */
783 writew(status, mmio + NV_ADMA_STAT);
784 readw(mmio + NV_ADMA_STAT); /* flush posted write */
785 rmb();
786
787 /* freeze if hotplugged */
788 if (unlikely(status & (NV_ADMA_STAT_HOTPLUG | NV_ADMA_STAT_HOTUNPLUG))) {
789 ata_port_printk(ap, KERN_NOTICE, "Hotplug event, freezing\n");
790 ata_port_freeze(ap);
791 handled++;
792 continue;
793 }
794
795 if (status & NV_ADMA_STAT_TIMEOUT) {
796 ata_port_printk(ap, KERN_ERR, "timeout, stat=0x%x\n", status);
797 have_global_err = 1;
798 }
799 if (status & NV_ADMA_STAT_CPBERR) {
800 ata_port_printk(ap, KERN_ERR, "CPB error, stat=0x%x\n", status);
801 have_global_err = 1;
802 }
803 if ((status & NV_ADMA_STAT_DONE) || have_global_err) {
804 /** Check CPBs for completed commands */
805
806 if(ata_tag_valid(ap->active_tag))
807 /* Non-NCQ command */
808 nv_adma_check_cpb(ap, ap->active_tag, have_global_err ||
809 (notifier_error & (1 << ap->active_tag)));
810 else {
811 int pos;
812 u32 active = ap->sactive;
813 while( (pos = ffs(active)) ) {
814 pos--;
815 nv_adma_check_cpb(ap, pos, have_global_err ||
816 (notifier_error & (1 << pos)) );
817 active &= ~(1 << pos );
818 }
819 }
820 }
821
822 handled++; /* irq handled if we got here */
823 }
824 }
825
826 if(notifier_clears[0] || notifier_clears[1]) {
827 /* Note: Both notifier clear registers must be written
828 if either is set, even if one is zero, according to NVIDIA. */
829 writel(notifier_clears[0],
830 nv_adma_notifier_clear_block(host->ports[0]));
831 writel(notifier_clears[1],
832 nv_adma_notifier_clear_block(host->ports[1]));
833 }
834
835 spin_unlock(&host->lock);
836
837 return IRQ_RETVAL(handled);
838}
839
840static void nv_adma_irq_clear(struct ata_port *ap)
841{
842 void __iomem *mmio = nv_adma_ctl_block(ap);
843 u16 status = readw(mmio + NV_ADMA_STAT);
844 u32 notifier = readl(mmio + NV_ADMA_NOTIFIER);
845 u32 notifier_error = readl(mmio + NV_ADMA_NOTIFIER_ERROR);
846 unsigned long dma_stat_addr = ap->ioaddr.bmdma_addr + ATA_DMA_STATUS;
847
848 /* clear ADMA status */
849 writew(status, mmio + NV_ADMA_STAT);
850 writel(notifier | notifier_error,
851 nv_adma_notifier_clear_block(ap));
852
853 /** clear legacy status */
854 outb(inb(dma_stat_addr), dma_stat_addr);
855}
856
857static void nv_adma_bmdma_setup(struct ata_queued_cmd *qc)
858{
859 struct ata_port *ap = qc->ap;
860 unsigned int rw = (qc->tf.flags & ATA_TFLAG_WRITE);
861 struct nv_adma_port_priv *pp = ap->private_data;
862 u8 dmactl;
863
864 if(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)) {
865 WARN_ON(1);
866 return;
867 }
868
869 /* load PRD table addr. */
870 outl(ap->prd_dma, ap->ioaddr.bmdma_addr + ATA_DMA_TABLE_OFS);
871
872 /* specify data direction, triple-check start bit is clear */
873 dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
874 dmactl &= ~(ATA_DMA_WR | ATA_DMA_START);
875 if (!rw)
876 dmactl |= ATA_DMA_WR;
877
878 outb(dmactl, ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
879
880 /* issue r/w command */
881 ata_exec_command(ap, &qc->tf);
882}
883
884static void nv_adma_bmdma_start(struct ata_queued_cmd *qc)
885{
886 struct ata_port *ap = qc->ap;
887 struct nv_adma_port_priv *pp = ap->private_data;
888 u8 dmactl;
889
890 if(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)) {
891 WARN_ON(1);
892 return;
893 }
894
895 /* start host DMA transaction */
896 dmactl = inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
897 outb(dmactl | ATA_DMA_START,
898 ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
899}
900
901static void nv_adma_bmdma_stop(struct ata_queued_cmd *qc)
902{
903 struct ata_port *ap = qc->ap;
904 struct nv_adma_port_priv *pp = ap->private_data;
905
906 if(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE))
907 return;
908
909 /* clear start/stop bit */
910 outb(inb(ap->ioaddr.bmdma_addr + ATA_DMA_CMD) & ~ATA_DMA_START,
911 ap->ioaddr.bmdma_addr + ATA_DMA_CMD);
912
913 /* one-PIO-cycle guaranteed wait, per spec, for HDMA1:0 transition */
914 ata_altstatus(ap); /* dummy read */
915}
916
917static u8 nv_adma_bmdma_status(struct ata_port *ap)
918{
919 struct nv_adma_port_priv *pp = ap->private_data;
920
921 WARN_ON(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE));
922
923 return inb(ap->ioaddr.bmdma_addr + ATA_DMA_STATUS);
924}
925
926static int nv_adma_port_start(struct ata_port *ap)
927{
928 struct device *dev = ap->host->dev;
929 struct nv_adma_port_priv *pp;
930 int rc;
931 void *mem;
932 dma_addr_t mem_dma;
933 void __iomem *mmio = nv_adma_ctl_block(ap);
934 u16 tmp;
935
936 VPRINTK("ENTER\n");
937
938 rc = ata_port_start(ap);
939 if (rc)
940 return rc;
941
942 pp = kzalloc(sizeof(*pp), GFP_KERNEL);
943 if (!pp) {
944 rc = -ENOMEM;
945 goto err_out;
946 }
947
948 mem = dma_alloc_coherent(dev, NV_ADMA_PORT_PRIV_DMA_SZ,
949 &mem_dma, GFP_KERNEL);
950
951 if (!mem) {
952 rc = -ENOMEM;
953 goto err_out_kfree;
954 }
955 memset(mem, 0, NV_ADMA_PORT_PRIV_DMA_SZ);
956
957 /*
958 * First item in chunk of DMA memory:
959 * 128-byte command parameter block (CPB)
960 * one for each command tag
961 */
962 pp->cpb = mem;
963 pp->cpb_dma = mem_dma;
964
965 writel(mem_dma & 0xFFFFFFFF, mmio + NV_ADMA_CPB_BASE_LOW);
966 writel((mem_dma >> 16 ) >> 16, mmio + NV_ADMA_CPB_BASE_HIGH);
967
968 mem += NV_ADMA_MAX_CPBS * NV_ADMA_CPB_SZ;
969 mem_dma += NV_ADMA_MAX_CPBS * NV_ADMA_CPB_SZ;
970
971 /*
972 * Second item: block of ADMA_SGTBL_LEN s/g entries
973 */
974 pp->aprd = mem;
975 pp->aprd_dma = mem_dma;
976
977 ap->private_data = pp;
978
979 /* clear any outstanding interrupt conditions */
980 writew(0xffff, mmio + NV_ADMA_STAT);
981
982 /* initialize port variables */
983 pp->flags = NV_ADMA_PORT_REGISTER_MODE;
984
985 /* clear CPB fetch count */
986 writew(0, mmio + NV_ADMA_CPB_COUNT);
987
988 /* clear GO for register mode */
989 tmp = readw(mmio + NV_ADMA_CTL);
990 writew(tmp & ~NV_ADMA_CTL_GO, mmio + NV_ADMA_CTL);
991
992 tmp = readw(mmio + NV_ADMA_CTL);
993 writew(tmp | NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL);
994 readl( mmio + NV_ADMA_CTL ); /* flush posted write */
995 udelay(1);
996 writew(tmp & ~NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL);
997 readl( mmio + NV_ADMA_CTL ); /* flush posted write */
998
999 return 0;
1000
1001err_out_kfree:
1002 kfree(pp);
1003err_out:
1004 ata_port_stop(ap);
1005 return rc;
1006}
1007
1008static void nv_adma_port_stop(struct ata_port *ap)
1009{
1010 struct device *dev = ap->host->dev;
1011 struct nv_adma_port_priv *pp = ap->private_data;
1012 void __iomem *mmio = nv_adma_ctl_block(ap);
1013
1014 VPRINTK("ENTER\n");
1015
1016 writew(0, mmio + NV_ADMA_CTL);
1017
1018 ap->private_data = NULL;
1019 dma_free_coherent(dev, NV_ADMA_PORT_PRIV_DMA_SZ, pp->cpb, pp->cpb_dma);
1020 kfree(pp);
1021 ata_port_stop(ap);
1022}
1023
1024
1025static void nv_adma_setup_port(struct ata_probe_ent *probe_ent, unsigned int port)
1026{
1027 void __iomem *mmio = probe_ent->mmio_base;
1028 struct ata_ioports *ioport = &probe_ent->port[port];
1029
1030 VPRINTK("ENTER\n");
1031
1032 mmio += NV_ADMA_PORT + port * NV_ADMA_PORT_SIZE;
1033
1034 ioport->cmd_addr = (unsigned long) mmio;
1035 ioport->data_addr = (unsigned long) mmio + (ATA_REG_DATA * 4);
1036 ioport->error_addr =
1037 ioport->feature_addr = (unsigned long) mmio + (ATA_REG_ERR * 4);
1038 ioport->nsect_addr = (unsigned long) mmio + (ATA_REG_NSECT * 4);
1039 ioport->lbal_addr = (unsigned long) mmio + (ATA_REG_LBAL * 4);
1040 ioport->lbam_addr = (unsigned long) mmio + (ATA_REG_LBAM * 4);
1041 ioport->lbah_addr = (unsigned long) mmio + (ATA_REG_LBAH * 4);
1042 ioport->device_addr = (unsigned long) mmio + (ATA_REG_DEVICE * 4);
1043 ioport->status_addr =
1044 ioport->command_addr = (unsigned long) mmio + (ATA_REG_STATUS * 4);
1045 ioport->altstatus_addr =
1046 ioport->ctl_addr = (unsigned long) mmio + 0x20;
1047}
1048
1049static int nv_adma_host_init(struct ata_probe_ent *probe_ent)
1050{
1051 struct pci_dev *pdev = to_pci_dev(probe_ent->dev);
1052 unsigned int i;
1053 u32 tmp32;
1054
1055 VPRINTK("ENTER\n");
1056
1057 /* enable ADMA on the ports */
1058 pci_read_config_dword(pdev, NV_MCP_SATA_CFG_20, &tmp32);
1059 tmp32 |= NV_MCP_SATA_CFG_20_PORT0_EN |
1060 NV_MCP_SATA_CFG_20_PORT0_PWB_EN |
1061 NV_MCP_SATA_CFG_20_PORT1_EN |
1062 NV_MCP_SATA_CFG_20_PORT1_PWB_EN;
1063
1064 pci_write_config_dword(pdev, NV_MCP_SATA_CFG_20, tmp32);
1065
1066 for (i = 0; i < probe_ent->n_ports; i++)
1067 nv_adma_setup_port(probe_ent, i);
1068
1069 for (i = 0; i < probe_ent->n_ports; i++) {
1070 void __iomem *mmio = __nv_adma_ctl_block(probe_ent->mmio_base, i);
1071 u16 tmp;
1072
1073 /* enable interrupt, clear reset if not already clear */
1074 tmp = readw(mmio + NV_ADMA_CTL);
1075 writew(tmp | NV_ADMA_CTL_AIEN, mmio + NV_ADMA_CTL);
1076 }
1077
1078 return 0;
1079}
1080
1081static void nv_adma_fill_aprd(struct ata_queued_cmd *qc,
1082 struct scatterlist *sg,
1083 int idx,
1084 struct nv_adma_prd *aprd)
1085{
1086 u8 flags;
1087
1088 memset(aprd, 0, sizeof(struct nv_adma_prd));
1089
1090 flags = 0;
1091 if (qc->tf.flags & ATA_TFLAG_WRITE)
1092 flags |= NV_APRD_WRITE;
1093 if (idx == qc->n_elem - 1)
1094 flags |= NV_APRD_END;
1095 else if (idx != 4)
1096 flags |= NV_APRD_CONT;
1097
1098 aprd->addr = cpu_to_le64(((u64)sg_dma_address(sg)));
1099 aprd->len = cpu_to_le32(((u32)sg_dma_len(sg))); /* len in bytes */
1100 aprd->flags = flags;
1101}
1102
1103static void nv_adma_fill_sg(struct ata_queued_cmd *qc, struct nv_adma_cpb *cpb)
1104{
1105 struct nv_adma_port_priv *pp = qc->ap->private_data;
1106 unsigned int idx;
1107 struct nv_adma_prd *aprd;
1108 struct scatterlist *sg;
1109
1110 VPRINTK("ENTER\n");
1111
1112 idx = 0;
1113
1114 ata_for_each_sg(sg, qc) {
1115 aprd = (idx < 5) ? &cpb->aprd[idx] : &pp->aprd[NV_ADMA_SGTBL_LEN * qc->tag + (idx-5)];
1116 nv_adma_fill_aprd(qc, sg, idx, aprd);
1117 idx++;
1118 }
1119 if (idx > 5)
1120 cpb->next_aprd = cpu_to_le64(((u64)(pp->aprd_dma + NV_ADMA_SGTBL_SZ * qc->tag)));
1121}
1122
1123static void nv_adma_qc_prep(struct ata_queued_cmd *qc)
1124{
1125 struct nv_adma_port_priv *pp = qc->ap->private_data;
1126 struct nv_adma_cpb *cpb = &pp->cpb[qc->tag];
1127 u8 ctl_flags = NV_CPB_CTL_CPB_VALID |
1128 NV_CPB_CTL_APRD_VALID |
1129 NV_CPB_CTL_IEN;
1130
1131 VPRINTK("qc->flags = 0x%lx\n", qc->flags);
1132
1133 if (!(qc->flags & ATA_QCFLAG_DMAMAP) ||
1134 (pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE)) {
1135 nv_adma_register_mode(qc->ap);
1136 ata_qc_prep(qc);
1137 return;
1138 }
1139
1140 memset(cpb, 0, sizeof(struct nv_adma_cpb));
1141
1142 cpb->len = 3;
1143 cpb->tag = qc->tag;
1144 cpb->next_cpb_idx = 0;
1145
1146 /* turn on NCQ flags for NCQ commands */
1147 if (qc->tf.protocol == ATA_PROT_NCQ)
1148 ctl_flags |= NV_CPB_CTL_QUEUE | NV_CPB_CTL_FPDMA;
1149
1150 nv_adma_tf_to_cpb(&qc->tf, cpb->tf);
1151
1152 nv_adma_fill_sg(qc, cpb);
1153
1154 /* Be paranoid and don't let the device see NV_CPB_CTL_CPB_VALID until we are
1155 finished filling in all of the contents */
1156 wmb();
1157 cpb->ctl_flags = ctl_flags;
1158}
1159
1160static unsigned int nv_adma_qc_issue(struct ata_queued_cmd *qc)
1161{
1162 struct nv_adma_port_priv *pp = qc->ap->private_data;
1163 void __iomem *mmio = nv_adma_ctl_block(qc->ap);
1164
1165 VPRINTK("ENTER\n");
1166
1167 if (!(qc->flags & ATA_QCFLAG_DMAMAP) ||
1168 (pp->flags & NV_ADMA_ATAPI_SETUP_COMPLETE)) {
1169 /* use ATA register mode */
1170 VPRINTK("no dmamap or ATAPI, using ATA register mode: 0x%lx\n", qc->flags);
1171 nv_adma_register_mode(qc->ap);
1172 return ata_qc_issue_prot(qc);
1173 } else
1174 nv_adma_mode(qc->ap);
1175
1176 /* write append register, command tag in lower 8 bits
1177 and (number of cpbs to append -1) in top 8 bits */
1178 wmb();
1179 writew(qc->tag, mmio + NV_ADMA_APPEND);
1180
1181 DPRINTK("Issued tag %u\n",qc->tag);
1182
1183 return 0;
1184}
1185
1186static irqreturn_t nv_generic_interrupt(int irq, void *dev_instance)
1187{
1188 struct ata_host *host = dev_instance;
1189 unsigned int i;
1190 unsigned int handled = 0;
1191 unsigned long flags;
1192
1193 spin_lock_irqsave(&host->lock, flags);
1194
1195 for (i = 0; i < host->n_ports; i++) {
1196 struct ata_port *ap;
1197
1198 ap = host->ports[i];
1199 if (ap &&
1200 !(ap->flags & ATA_FLAG_DISABLED)) {
1201 struct ata_queued_cmd *qc;
1202
1203 qc = ata_qc_from_tag(ap, ap->active_tag);
1204 if (qc && (!(qc->tf.flags & ATA_TFLAG_POLLING)))
1205 handled += ata_host_intr(ap, qc);
1206 else
1207 // No request pending? Clear interrupt status
1208 // anyway, in case there's one pending.
1209 ap->ops->check_status(ap);
1210 }
1211
1212 }
1213
1214 spin_unlock_irqrestore(&host->lock, flags);
1215
1216 return IRQ_RETVAL(handled);
1217}
1218
344static irqreturn_t nv_do_interrupt(struct ata_host *host, u8 irq_stat) 1219static irqreturn_t nv_do_interrupt(struct ata_host *host, u8 irq_stat)
345{ 1220{
346 int i, handled = 0; 1221 int i, handled = 0;
@@ -466,6 +1341,56 @@ static void nv_error_handler(struct ata_port *ap)
466 nv_hardreset, ata_std_postreset); 1341 nv_hardreset, ata_std_postreset);
467} 1342}
468 1343
1344static void nv_adma_error_handler(struct ata_port *ap)
1345{
1346 struct nv_adma_port_priv *pp = ap->private_data;
1347 if(!(pp->flags & NV_ADMA_PORT_REGISTER_MODE)) {
1348 void __iomem *mmio = nv_adma_ctl_block(ap);
1349 int i;
1350 u16 tmp;
1351
1352 u32 notifier = readl(mmio + NV_ADMA_NOTIFIER);
1353 u32 notifier_error = readl(mmio + NV_ADMA_NOTIFIER_ERROR);
1354 u32 gen_ctl = readl(nv_adma_gen_block(ap) + NV_ADMA_GEN_CTL);
1355 u32 status = readw(mmio + NV_ADMA_STAT);
1356
1357 ata_port_printk(ap, KERN_ERR, "EH in ADMA mode, notifier 0x%X "
1358 "notifier_error 0x%X gen_ctl 0x%X status 0x%X\n",
1359 notifier, notifier_error, gen_ctl, status);
1360
1361 for( i=0;i<NV_ADMA_MAX_CPBS;i++) {
1362 struct nv_adma_cpb *cpb = &pp->cpb[i];
1363 if( cpb->ctl_flags || cpb->resp_flags )
1364 ata_port_printk(ap, KERN_ERR,
1365 "CPB %d: ctl_flags 0x%x, resp_flags 0x%x\n",
1366 i, cpb->ctl_flags, cpb->resp_flags);
1367 }
1368
1369 /* Push us back into port register mode for error handling. */
1370 nv_adma_register_mode(ap);
1371
1372 ata_port_printk(ap, KERN_ERR, "Resetting port\n");
1373
1374 /* Mark all of the CPBs as invalid to prevent them from being executed */
1375 for( i=0;i<NV_ADMA_MAX_CPBS;i++)
1376 pp->cpb[i].ctl_flags &= ~NV_CPB_CTL_CPB_VALID;
1377
1378 /* clear CPB fetch count */
1379 writew(0, mmio + NV_ADMA_CPB_COUNT);
1380
1381 /* Reset channel */
1382 tmp = readw(mmio + NV_ADMA_CTL);
1383 writew(tmp | NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL);
1384 readl( mmio + NV_ADMA_CTL ); /* flush posted write */
1385 udelay(1);
1386 writew(tmp & ~NV_ADMA_CTL_CHANNEL_RESET, mmio + NV_ADMA_CTL);
1387 readl( mmio + NV_ADMA_CTL ); /* flush posted write */
1388 }
1389
1390 ata_bmdma_drive_eh(ap, ata_std_prereset, ata_std_softreset,
1391 nv_hardreset, ata_std_postreset);
1392}
1393
469static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent) 1394static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
470{ 1395{
471 static int printed_version = 0; 1396 static int printed_version = 0;
@@ -475,6 +1400,8 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
475 int rc; 1400 int rc;
476 u32 bar; 1401 u32 bar;
477 unsigned long base; 1402 unsigned long base;
1403 unsigned long type = ent->driver_data;
1404 int mask_set = 0;
478 1405
479 // Make sure this is a SATA controller by counting the number of bars 1406 // Make sure this is a SATA controller by counting the number of bars
480 // (NVIDIA SATA controllers will always have six bars). Otherwise, 1407 // (NVIDIA SATA controllers will always have six bars). Otherwise,
@@ -483,7 +1410,7 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
483 if (pci_resource_start(pdev, bar) == 0) 1410 if (pci_resource_start(pdev, bar) == 0)
484 return -ENODEV; 1411 return -ENODEV;
485 1412
486 if (!printed_version++) 1413 if ( !printed_version++)
487 dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n"); 1414 dev_printk(KERN_DEBUG, &pdev->dev, "version " DRV_VERSION "\n");
488 1415
489 rc = pci_enable_device(pdev); 1416 rc = pci_enable_device(pdev);
@@ -496,16 +1423,26 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
496 goto err_out_disable; 1423 goto err_out_disable;
497 } 1424 }
498 1425
499 rc = pci_set_dma_mask(pdev, ATA_DMA_MASK); 1426 if(type >= CK804 && adma_enabled) {
500 if (rc) 1427 dev_printk(KERN_NOTICE, &pdev->dev, "Using ADMA mode\n");
501 goto err_out_regions; 1428 type = ADMA;
502 rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK); 1429 if(!pci_set_dma_mask(pdev, DMA_64BIT_MASK) &&
503 if (rc) 1430 !pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK))
504 goto err_out_regions; 1431 mask_set = 1;
1432 }
1433
1434 if(!mask_set) {
1435 rc = pci_set_dma_mask(pdev, ATA_DMA_MASK);
1436 if (rc)
1437 goto err_out_regions;
1438 rc = pci_set_consistent_dma_mask(pdev, ATA_DMA_MASK);
1439 if (rc)
1440 goto err_out_regions;
1441 }
505 1442
506 rc = -ENOMEM; 1443 rc = -ENOMEM;
507 1444
508 ppi[0] = ppi[1] = &nv_port_info[ent->driver_data]; 1445 ppi[0] = ppi[1] = &nv_port_info[type];
509 probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY); 1446 probe_ent = ata_pci_init_native_mode(pdev, ppi, ATA_PORT_PRIMARY | ATA_PORT_SECONDARY);
510 if (!probe_ent) 1447 if (!probe_ent)
511 goto err_out_regions; 1448 goto err_out_regions;
@@ -522,7 +1459,7 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
522 probe_ent->port[1].scr_addr = base + NV_PORT1_SCR_REG_OFFSET; 1459 probe_ent->port[1].scr_addr = base + NV_PORT1_SCR_REG_OFFSET;
523 1460
524 /* enable SATA space for CK804 */ 1461 /* enable SATA space for CK804 */
525 if (ent->driver_data == CK804) { 1462 if (type >= CK804) {
526 u8 regval; 1463 u8 regval;
527 1464
528 pci_read_config_byte(pdev, NV_MCP_SATA_CFG_20, &regval); 1465 pci_read_config_byte(pdev, NV_MCP_SATA_CFG_20, &regval);
@@ -532,6 +1469,12 @@ static int nv_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
532 1469
533 pci_set_master(pdev); 1470 pci_set_master(pdev);
534 1471
1472 if (type == ADMA) {
1473 rc = nv_adma_host_init(probe_ent);
1474 if (rc)
1475 goto err_out_iounmap;
1476 }
1477
535 rc = ata_device_add(probe_ent); 1478 rc = ata_device_add(probe_ent);
536 if (rc != NV_PORTS) 1479 if (rc != NV_PORTS)
537 goto err_out_iounmap; 1480 goto err_out_iounmap;
@@ -566,6 +1509,33 @@ static void nv_ck804_host_stop(struct ata_host *host)
566 ata_pci_host_stop(host); 1509 ata_pci_host_stop(host);
567} 1510}
568 1511
1512static void nv_adma_host_stop(struct ata_host *host)
1513{
1514 struct pci_dev *pdev = to_pci_dev(host->dev);
1515 int i;
1516 u32 tmp32;
1517
1518 for (i = 0; i < host->n_ports; i++) {
1519 void __iomem *mmio = __nv_adma_ctl_block(host->mmio_base, i);
1520 u16 tmp;
1521
1522 /* disable interrupt */
1523 tmp = readw(mmio + NV_ADMA_CTL);
1524 writew(tmp & ~NV_ADMA_CTL_AIEN, mmio + NV_ADMA_CTL);
1525 }
1526
1527 /* disable ADMA on the ports */
1528 pci_read_config_dword(pdev, NV_MCP_SATA_CFG_20, &tmp32);
1529 tmp32 &= ~(NV_MCP_SATA_CFG_20_PORT0_EN |
1530 NV_MCP_SATA_CFG_20_PORT0_PWB_EN |
1531 NV_MCP_SATA_CFG_20_PORT1_EN |
1532 NV_MCP_SATA_CFG_20_PORT1_PWB_EN);
1533
1534 pci_write_config_dword(pdev, NV_MCP_SATA_CFG_20, tmp32);
1535
1536 nv_ck804_host_stop(host);
1537}
1538
569static int __init nv_init(void) 1539static int __init nv_init(void)
570{ 1540{
571 return pci_register_driver(&nv_pci_driver); 1541 return pci_register_driver(&nv_pci_driver);
@@ -578,3 +1548,5 @@ static void __exit nv_exit(void)
578 1548
579module_init(nv_init); 1549module_init(nv_init);
580module_exit(nv_exit); 1550module_exit(nv_exit);
1551module_param_named(adma, adma_enabled, bool, 0444);
1552MODULE_PARM_DESC(adma, "Enable use of ADMA (Default: true)");
diff --git a/drivers/ata/sata_promise.c b/drivers/ata/sata_promise.c
index 72eda5160fad..a2778cf016bc 100644
--- a/drivers/ata/sata_promise.c
+++ b/drivers/ata/sata_promise.c
@@ -46,20 +46,19 @@
46#include "sata_promise.h" 46#include "sata_promise.h"
47 47
48#define DRV_NAME "sata_promise" 48#define DRV_NAME "sata_promise"
49#define DRV_VERSION "1.04" 49#define DRV_VERSION "1.05"
50 50
51 51
52enum { 52enum {
53 PDC_PKT_SUBMIT = 0x40, /* Command packet pointer addr */ 53 PDC_PKT_SUBMIT = 0x40, /* Command packet pointer addr */
54 PDC_INT_SEQMASK = 0x40, /* Mask of asserted SEQ INTs */ 54 PDC_INT_SEQMASK = 0x40, /* Mask of asserted SEQ INTs */
55 PDC_TBG_MODE = 0x41, /* TBG mode */
56 PDC_FLASH_CTL = 0x44, /* Flash control register */ 55 PDC_FLASH_CTL = 0x44, /* Flash control register */
57 PDC_PCI_CTL = 0x48, /* PCI control and status register */
58 PDC_GLOBAL_CTL = 0x48, /* Global control/status (per port) */ 56 PDC_GLOBAL_CTL = 0x48, /* Global control/status (per port) */
59 PDC_CTLSTAT = 0x60, /* IDE control and status (per port) */ 57 PDC_CTLSTAT = 0x60, /* IDE control and status (per port) */
60 PDC_SATA_PLUG_CSR = 0x6C, /* SATA Plug control/status reg */ 58 PDC_SATA_PLUG_CSR = 0x6C, /* SATA Plug control/status reg */
61 PDC2_SATA_PLUG_CSR = 0x60, /* SATAII Plug control/status reg */ 59 PDC2_SATA_PLUG_CSR = 0x60, /* SATAII Plug control/status reg */
62 PDC_SLEW_CTL = 0x470, /* slew rate control reg */ 60 PDC_TBG_MODE = 0x41C, /* TBG mode (not SATAII) */
61 PDC_SLEW_CTL = 0x470, /* slew rate control reg (not SATAII) */
63 62
64 PDC_ERR_MASK = (1<<19) | (1<<20) | (1<<21) | (1<<22) | 63 PDC_ERR_MASK = (1<<19) | (1<<20) | (1<<21) | (1<<22) |
65 (1<<8) | (1<<9) | (1<<10), 64 (1<<8) | (1<<9) | (1<<10),
@@ -78,6 +77,9 @@ enum {
78 PDC_COMMON_FLAGS = ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST | 77 PDC_COMMON_FLAGS = ATA_FLAG_NO_LEGACY | ATA_FLAG_SRST |
79 ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI | 78 ATA_FLAG_MMIO | ATA_FLAG_NO_ATAPI |
80 ATA_FLAG_PIO_POLLING, 79 ATA_FLAG_PIO_POLLING,
80
81 /* hp->flags bits */
82 PDC_FLAG_GEN_II = (1 << 0),
81}; 83};
82 84
83 85
@@ -87,6 +89,7 @@ struct pdc_port_priv {
87}; 89};
88 90
89struct pdc_host_priv { 91struct pdc_host_priv {
92 unsigned long flags;
90 int hotplug_offset; 93 int hotplug_offset;
91}; 94};
92 95
@@ -235,20 +238,20 @@ static const struct ata_port_info pdc_port_info[] = {
235 238
236static const struct pci_device_id pdc_ata_pci_tbl[] = { 239static const struct pci_device_id pdc_ata_pci_tbl[] = {
237 { PCI_VDEVICE(PROMISE, 0x3371), board_2037x }, 240 { PCI_VDEVICE(PROMISE, 0x3371), board_2037x },
238 { PCI_VDEVICE(PROMISE, 0x3570), board_2037x },
239 { PCI_VDEVICE(PROMISE, 0x3571), board_2037x },
240 { PCI_VDEVICE(PROMISE, 0x3373), board_2037x }, 241 { PCI_VDEVICE(PROMISE, 0x3373), board_2037x },
241 { PCI_VDEVICE(PROMISE, 0x3375), board_2037x }, 242 { PCI_VDEVICE(PROMISE, 0x3375), board_2037x },
242 { PCI_VDEVICE(PROMISE, 0x3376), board_2037x }, 243 { PCI_VDEVICE(PROMISE, 0x3376), board_2037x },
244 { PCI_VDEVICE(PROMISE, 0x3570), board_2057x },
245 { PCI_VDEVICE(PROMISE, 0x3571), board_2057x },
243 { PCI_VDEVICE(PROMISE, 0x3574), board_2057x }, 246 { PCI_VDEVICE(PROMISE, 0x3574), board_2057x },
247 { PCI_VDEVICE(PROMISE, 0x3d73), board_2057x },
244 { PCI_VDEVICE(PROMISE, 0x3d75), board_2057x }, 248 { PCI_VDEVICE(PROMISE, 0x3d75), board_2057x },
245 { PCI_VDEVICE(PROMISE, 0x3d73), board_2037x },
246 249
247 { PCI_VDEVICE(PROMISE, 0x3318), board_20319 }, 250 { PCI_VDEVICE(PROMISE, 0x3318), board_20319 },
248 { PCI_VDEVICE(PROMISE, 0x3319), board_20319 }, 251 { PCI_VDEVICE(PROMISE, 0x3319), board_20319 },
249 { PCI_VDEVICE(PROMISE, 0x3515), board_20319 }, 252 { PCI_VDEVICE(PROMISE, 0x3515), board_20319 },
250 { PCI_VDEVICE(PROMISE, 0x3519), board_20319 }, 253 { PCI_VDEVICE(PROMISE, 0x3519), board_20319 },
251 { PCI_VDEVICE(PROMISE, 0x3d17), board_20319 }, 254 { PCI_VDEVICE(PROMISE, 0x3d17), board_40518 },
252 { PCI_VDEVICE(PROMISE, 0x3d18), board_40518 }, 255 { PCI_VDEVICE(PROMISE, 0x3d18), board_40518 },
253 256
254 { PCI_VDEVICE(PROMISE, 0x6629), board_20619 }, 257 { PCI_VDEVICE(PROMISE, 0x6629), board_20619 },
@@ -277,6 +280,7 @@ static struct pci_driver pdc_ata_pci_driver = {
277static int pdc_port_start(struct ata_port *ap) 280static int pdc_port_start(struct ata_port *ap)
278{ 281{
279 struct device *dev = ap->host->dev; 282 struct device *dev = ap->host->dev;
283 struct pdc_host_priv *hp = ap->host->private_data;
280 struct pdc_port_priv *pp; 284 struct pdc_port_priv *pp;
281 int rc; 285 int rc;
282 286
@@ -298,6 +302,16 @@ static int pdc_port_start(struct ata_port *ap)
298 302
299 ap->private_data = pp; 303 ap->private_data = pp;
300 304
305 /* fix up PHYMODE4 align timing */
306 if ((hp->flags & PDC_FLAG_GEN_II) && sata_scr_valid(ap)) {
307 void __iomem *mmio = (void __iomem *) ap->ioaddr.scr_addr;
308 unsigned int tmp;
309
310 tmp = readl(mmio + 0x014);
311 tmp = (tmp & ~3) | 1; /* set bits 1:0 = 0:1 */
312 writel(tmp, mmio + 0x014);
313 }
314
301 return 0; 315 return 0;
302 316
303err_out_kfree: 317err_out_kfree:
@@ -640,9 +654,11 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
640 * "TODO: figure out why we do this" 654 * "TODO: figure out why we do this"
641 */ 655 */
642 656
643 /* change FIFO_SHD to 8 dwords, enable BMR_BURST */ 657 /* enable BMR_BURST, maybe change FIFO_SHD to 8 dwords */
644 tmp = readl(mmio + PDC_FLASH_CTL); 658 tmp = readl(mmio + PDC_FLASH_CTL);
645 tmp |= 0x12000; /* bit 16 (fifo 8 dw) and 13 (bmr burst?) */ 659 tmp |= 0x02000; /* bit 13 (enable bmr burst) */
660 if (!(hp->flags & PDC_FLAG_GEN_II))
661 tmp |= 0x10000; /* bit 16 (fifo threshold at 8 dw) */
646 writel(tmp, mmio + PDC_FLASH_CTL); 662 writel(tmp, mmio + PDC_FLASH_CTL);
647 663
648 /* clear plug/unplug flags for all ports */ 664 /* clear plug/unplug flags for all ports */
@@ -653,6 +669,10 @@ static void pdc_host_init(unsigned int chip_id, struct ata_probe_ent *pe)
653 tmp = readl(mmio + hotplug_offset); 669 tmp = readl(mmio + hotplug_offset);
654 writel(tmp | 0xff0000, mmio + hotplug_offset); 670 writel(tmp | 0xff0000, mmio + hotplug_offset);
655 671
672 /* don't initialise TBG or SLEW on 2nd generation chips */
673 if (hp->flags & PDC_FLAG_GEN_II)
674 return;
675
656 /* reduce TBG clock to 133 Mhz. */ 676 /* reduce TBG clock to 133 Mhz. */
657 tmp = readl(mmio + PDC_TBG_MODE); 677 tmp = readl(mmio + PDC_TBG_MODE);
658 tmp &= ~0x30000; /* clear bit 17, 16*/ 678 tmp &= ~0x30000; /* clear bit 17, 16*/
@@ -746,6 +766,7 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
746 /* notice 4-port boards */ 766 /* notice 4-port boards */
747 switch (board_idx) { 767 switch (board_idx) {
748 case board_40518: 768 case board_40518:
769 hp->flags |= PDC_FLAG_GEN_II;
749 /* Override hotplug offset for SATAII150 */ 770 /* Override hotplug offset for SATAII150 */
750 hp->hotplug_offset = PDC2_SATA_PLUG_CSR; 771 hp->hotplug_offset = PDC2_SATA_PLUG_CSR;
751 /* Fall through */ 772 /* Fall through */
@@ -759,15 +780,14 @@ static int pdc_ata_init_one (struct pci_dev *pdev, const struct pci_device_id *e
759 probe_ent->port[3].scr_addr = base + 0x700; 780 probe_ent->port[3].scr_addr = base + 0x700;
760 break; 781 break;
761 case board_2057x: 782 case board_2057x:
783 case board_20771:
784 hp->flags |= PDC_FLAG_GEN_II;
762 /* Override hotplug offset for SATAII150 */ 785 /* Override hotplug offset for SATAII150 */
763 hp->hotplug_offset = PDC2_SATA_PLUG_CSR; 786 hp->hotplug_offset = PDC2_SATA_PLUG_CSR;
764 /* Fall through */ 787 /* Fall through */
765 case board_2037x: 788 case board_2037x:
766 probe_ent->n_ports = 2; 789 probe_ent->n_ports = 2;
767 break; 790 break;
768 case board_20771:
769 probe_ent->n_ports = 2;
770 break;
771 case board_20619: 791 case board_20619:
772 probe_ent->n_ports = 4; 792 probe_ent->n_ports = 4;
773 793
diff --git a/drivers/ata/sata_sil.c b/drivers/ata/sata_sil.c
index ca8d99312472..7808d0369d91 100644
--- a/drivers/ata/sata_sil.c
+++ b/drivers/ata/sata_sil.c
@@ -356,6 +356,7 @@ static void sil_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
356 356
357static void sil_host_intr(struct ata_port *ap, u32 bmdma2) 357static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
358{ 358{
359 struct ata_eh_info *ehi = &ap->eh_info;
359 struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag); 360 struct ata_queued_cmd *qc = ata_qc_from_tag(ap, ap->active_tag);
360 u8 status; 361 u8 status;
361 362
@@ -428,6 +429,10 @@ static void sil_host_intr(struct ata_port *ap, u32 bmdma2)
428 /* kick HSM in the ass */ 429 /* kick HSM in the ass */
429 ata_hsm_move(ap, qc, status, 0); 430 ata_hsm_move(ap, qc, status, 0);
430 431
432 if (unlikely(qc->err_mask) && (qc->tf.protocol == ATA_PROT_DMA ||
433 qc->tf.protocol == ATA_PROT_ATAPI_DMA))
434 ata_ehi_push_desc(ehi, "BMDMA2 stat 0x%x", bmdma2);
435
431 return; 436 return;
432 437
433 err_hsm: 438 err_hsm:
@@ -534,6 +539,7 @@ static void sil_thaw(struct ata_port *ap)
534 */ 539 */
535static void sil_dev_config(struct ata_port *ap, struct ata_device *dev) 540static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
536{ 541{
542 int print_info = ap->eh_context.i.flags & ATA_EHI_PRINTINFO;
537 unsigned int n, quirks = 0; 543 unsigned int n, quirks = 0;
538 unsigned char model_num[41]; 544 unsigned char model_num[41];
539 545
@@ -549,16 +555,18 @@ static void sil_dev_config(struct ata_port *ap, struct ata_device *dev)
549 if (slow_down || 555 if (slow_down ||
550 ((ap->flags & SIL_FLAG_MOD15WRITE) && 556 ((ap->flags & SIL_FLAG_MOD15WRITE) &&
551 (quirks & SIL_QUIRK_MOD15WRITE))) { 557 (quirks & SIL_QUIRK_MOD15WRITE))) {
552 ata_dev_printk(dev, KERN_INFO, "applying Seagate errata fix " 558 if (print_info)
553 "(mod15write workaround)\n"); 559 ata_dev_printk(dev, KERN_INFO, "applying Seagate "
560 "errata fix (mod15write workaround)\n");
554 dev->max_sectors = 15; 561 dev->max_sectors = 15;
555 return; 562 return;
556 } 563 }
557 564
558 /* limit to udma5 */ 565 /* limit to udma5 */
559 if (quirks & SIL_QUIRK_UDMA5MAX) { 566 if (quirks & SIL_QUIRK_UDMA5MAX) {
560 ata_dev_printk(dev, KERN_INFO, 567 if (print_info)
561 "applying Maxtor errata fix %s\n", model_num); 568 ata_dev_printk(dev, KERN_INFO, "applying Maxtor "
569 "errata fix %s\n", model_num);
562 dev->udma_mask &= ATA_UDMA5; 570 dev->udma_mask &= ATA_UDMA5;
563 return; 571 return;
564 } 572 }
diff --git a/drivers/ata/sata_sil24.c b/drivers/ata/sata_sil24.c
index 169e200a6a71..5aa288d2fb86 100644
--- a/drivers/ata/sata_sil24.c
+++ b/drivers/ata/sata_sil24.c
@@ -100,10 +100,14 @@ enum {
100 */ 100 */
101 PORT_REGS_SIZE = 0x2000, 101 PORT_REGS_SIZE = 0x2000,
102 102
103 PORT_LRAM = 0x0000, /* 31 LRAM slots and PM regs */ 103 PORT_LRAM = 0x0000, /* 31 LRAM slots and PMP regs */
104 PORT_LRAM_SLOT_SZ = 0x0080, /* 32 bytes PRB + 2 SGE, ACT... */ 104 PORT_LRAM_SLOT_SZ = 0x0080, /* 32 bytes PRB + 2 SGE, ACT... */
105 105
106 PORT_PM = 0x0f80, /* 8 bytes PM * 16 (128 bytes) */ 106 PORT_PMP = 0x0f80, /* 8 bytes PMP * 16 (128 bytes) */
107 PORT_PMP_STATUS = 0x0000, /* port device status offset */
108 PORT_PMP_QACTIVE = 0x0004, /* port device QActive offset */
109 PORT_PMP_SIZE = 0x0008, /* 8 bytes per PMP */
110
107 /* 32 bit regs */ 111 /* 32 bit regs */
108 PORT_CTRL_STAT = 0x1000, /* write: ctrl-set, read: stat */ 112 PORT_CTRL_STAT = 0x1000, /* write: ctrl-set, read: stat */
109 PORT_CTRL_CLR = 0x1004, /* write: ctrl-clear */ 113 PORT_CTRL_CLR = 0x1004, /* write: ctrl-clear */
@@ -126,6 +130,7 @@ enum {
126 PORT_PHY_CFG = 0x1050, 130 PORT_PHY_CFG = 0x1050,
127 PORT_SLOT_STAT = 0x1800, 131 PORT_SLOT_STAT = 0x1800,
128 PORT_CMD_ACTIVATE = 0x1c00, /* 64 bit cmd activate * 31 (248 bytes) */ 132 PORT_CMD_ACTIVATE = 0x1c00, /* 64 bit cmd activate * 31 (248 bytes) */
133 PORT_CONTEXT = 0x1e04,
129 PORT_EXEC_DIAG = 0x1e00, /* 32bit exec diag * 16 (64 bytes, 0-10 used on 3124) */ 134 PORT_EXEC_DIAG = 0x1e00, /* 32bit exec diag * 16 (64 bytes, 0-10 used on 3124) */
130 PORT_PSD_DIAG = 0x1e40, /* 32bit psd diag * 16 (64 bytes, 0-8 used on 3124) */ 135 PORT_PSD_DIAG = 0x1e40, /* 32bit psd diag * 16 (64 bytes, 0-8 used on 3124) */
131 PORT_SCONTROL = 0x1f00, 136 PORT_SCONTROL = 0x1f00,
@@ -139,9 +144,9 @@ enum {
139 PORT_CS_INIT = (1 << 2), /* port initialize */ 144 PORT_CS_INIT = (1 << 2), /* port initialize */
140 PORT_CS_IRQ_WOC = (1 << 3), /* interrupt write one to clear */ 145 PORT_CS_IRQ_WOC = (1 << 3), /* interrupt write one to clear */
141 PORT_CS_CDB16 = (1 << 5), /* 0=12b cdb, 1=16b cdb */ 146 PORT_CS_CDB16 = (1 << 5), /* 0=12b cdb, 1=16b cdb */
142 PORT_CS_RESUME = (1 << 6), /* port resume */ 147 PORT_CS_PMP_RESUME = (1 << 6), /* PMP resume */
143 PORT_CS_32BIT_ACTV = (1 << 10), /* 32-bit activation */ 148 PORT_CS_32BIT_ACTV = (1 << 10), /* 32-bit activation */
144 PORT_CS_PM_EN = (1 << 13), /* port multiplier enable */ 149 PORT_CS_PMP_EN = (1 << 13), /* port multiplier enable */
145 PORT_CS_RDY = (1 << 31), /* port ready to accept commands */ 150 PORT_CS_RDY = (1 << 31), /* port ready to accept commands */
146 151
147 /* PORT_IRQ_STAT/ENABLE_SET/CLR */ 152 /* PORT_IRQ_STAT/ENABLE_SET/CLR */
@@ -562,7 +567,7 @@ static int sil24_softreset(struct ata_port *ap, unsigned int *class)
562 567
563 /* do SRST */ 568 /* do SRST */
564 prb->ctrl = cpu_to_le16(PRB_CTRL_SRST); 569 prb->ctrl = cpu_to_le16(PRB_CTRL_SRST);
565 prb->fis[1] = 0; /* no PM yet */ 570 prb->fis[1] = 0; /* no PMP yet */
566 571
567 writel((u32)paddr, port + PORT_CMD_ACTIVATE); 572 writel((u32)paddr, port + PORT_CMD_ACTIVATE);
568 writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4); 573 writel((u64)paddr >> 32, port + PORT_CMD_ACTIVATE + 4);
@@ -1050,7 +1055,8 @@ static void sil24_init_controller(struct pci_dev *pdev, int n_ports,
1050 writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_CLR); 1055 writel(PORT_CS_32BIT_ACTV, port + PORT_CTRL_CLR);
1051 1056
1052 /* Clear port multiplier enable and resume bits */ 1057 /* Clear port multiplier enable and resume bits */
1053 writel(PORT_CS_PM_EN | PORT_CS_RESUME, port + PORT_CTRL_CLR); 1058 writel(PORT_CS_PMP_EN | PORT_CS_PMP_RESUME,
1059 port + PORT_CTRL_CLR);
1054 } 1060 }
1055 1061
1056 /* Turn on interrupts */ 1062 /* Turn on interrupts */
diff --git a/drivers/ata/sata_sis.c b/drivers/ata/sata_sis.c
index 9d1235ba06b1..9c25a1e91730 100644
--- a/drivers/ata/sata_sis.c
+++ b/drivers/ata/sata_sis.c
@@ -173,7 +173,7 @@ static u32 sis_scr_cfg_read (struct ata_port *ap, unsigned int sc_reg)
173 if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED)) 173 if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED))
174 pci_read_config_dword(pdev, cfg_addr+0x10, &val2); 174 pci_read_config_dword(pdev, cfg_addr+0x10, &val2);
175 175
176 return val|val2; 176 return (val|val2) & 0xfffffffb; /* avoid problems with powerdowned ports */
177} 177}
178 178
179static void sis_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val) 179static void sis_scr_cfg_write (struct ata_port *ap, unsigned int scr, u32 val)
@@ -212,7 +212,7 @@ static u32 sis_scr_read (struct ata_port *ap, unsigned int sc_reg)
212 if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED)) 212 if ((pdev->device == 0x182) || (pmr & SIS_PMR_COMBINED))
213 val2 = inl(ap->ioaddr.scr_addr + (sc_reg * 4) + 0x10); 213 val2 = inl(ap->ioaddr.scr_addr + (sc_reg * 4) + 0x10);
214 214
215 return val | val2; 215 return (val | val2) & 0xfffffffb;
216} 216}
217 217
218static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val) 218static void sis_scr_write (struct ata_port *ap, unsigned int sc_reg, u32 val)
@@ -239,7 +239,7 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
239 static int printed_version; 239 static int printed_version;
240 struct ata_probe_ent *probe_ent = NULL; 240 struct ata_probe_ent *probe_ent = NULL;
241 int rc; 241 int rc;
242 u32 genctl; 242 u32 genctl, val;
243 struct ata_port_info pi = sis_port_info, *ppi[2] = { &pi, &pi }; 243 struct ata_port_info pi = sis_port_info, *ppi[2] = { &pi, &pi };
244 int pci_dev_busy = 0; 244 int pci_dev_busy = 0;
245 u8 pmr; 245 u8 pmr;
@@ -285,17 +285,24 @@ static int sis_init_one (struct pci_dev *pdev, const struct pci_device_id *ent)
285 if (ent->device != 0x182) { 285 if (ent->device != 0x182) {
286 if ((pmr & SIS_PMR_COMBINED) == 0) { 286 if ((pmr & SIS_PMR_COMBINED) == 0) {
287 dev_printk(KERN_INFO, &pdev->dev, 287 dev_printk(KERN_INFO, &pdev->dev,
288 "Detected SiS 180/181 chipset in SATA mode\n"); 288 "Detected SiS 180/181/964 chipset in SATA mode\n");
289 port2_start = 64; 289 port2_start = 64;
290 } 290 }
291 else { 291 else {
292 dev_printk(KERN_INFO, &pdev->dev, 292 dev_printk(KERN_INFO, &pdev->dev,
293 "Detected SiS 180/181 chipset in combined mode\n"); 293 "Detected SiS 180/181 chipset in combined mode\n");
294 port2_start=0; 294 port2_start=0;
295 pi.flags |= ATA_FLAG_SLAVE_POSS;
295 } 296 }
296 } 297 }
297 else { 298 else {
298 dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 182 chipset\n"); 299 pci_read_config_dword ( pdev, 0x6C, &val);
300 if (val & (1L << 31)) {
301 dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 182/965 chipset\n");
302 pi.flags |= ATA_FLAG_SLAVE_POSS;
303 }
304 else
305 dev_printk(KERN_INFO, &pdev->dev, "Detected SiS 182/965L chipset\n");
299 port2_start = 0x20; 306 port2_start = 0x20;
300 } 307 }
301 308
diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c
index 4bef76a2f3f2..1f745f12f94e 100644
--- a/drivers/base/cpu.c
+++ b/drivers/base/cpu.c
@@ -5,6 +5,7 @@
5#include <linux/sysdev.h> 5#include <linux/sysdev.h>
6#include <linux/module.h> 6#include <linux/module.h>
7#include <linux/init.h> 7#include <linux/init.h>
8#include <linux/sched.h>
8#include <linux/cpu.h> 9#include <linux/cpu.h>
9#include <linux/topology.h> 10#include <linux/topology.h>
10#include <linux/device.h> 11#include <linux/device.h>
diff --git a/drivers/block/viodasd.c b/drivers/block/viodasd.c
index ec5a1b90a0a2..e19ba4ebcd4e 100644
--- a/drivers/block/viodasd.c
+++ b/drivers/block/viodasd.c
@@ -759,6 +759,8 @@ static struct vio_driver viodasd_driver = {
759 } 759 }
760}; 760};
761 761
762static int need_delete_probe;
763
762/* 764/*
763 * Initialize the whole device driver. Handle module and non-module 765 * Initialize the whole device driver. Handle module and non-module
764 * versions 766 * versions
@@ -773,46 +775,67 @@ static int __init viodasd_init(void)
773 775
774 if (viopath_hostLp == HvLpIndexInvalid) { 776 if (viopath_hostLp == HvLpIndexInvalid) {
775 printk(VIOD_KERN_WARNING "invalid hosting partition\n"); 777 printk(VIOD_KERN_WARNING "invalid hosting partition\n");
776 return -EIO; 778 rc = -EIO;
779 goto early_fail;
777 } 780 }
778 781
779 printk(VIOD_KERN_INFO "vers " VIOD_VERS ", hosting partition %d\n", 782 printk(VIOD_KERN_INFO "vers " VIOD_VERS ", hosting partition %d\n",
780 viopath_hostLp); 783 viopath_hostLp);
781 784
782 /* register the block device */ 785 /* register the block device */
783 if (register_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME)) { 786 rc = register_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME);
787 if (rc) {
784 printk(VIOD_KERN_WARNING 788 printk(VIOD_KERN_WARNING
785 "Unable to get major number %d for %s\n", 789 "Unable to get major number %d for %s\n",
786 VIODASD_MAJOR, VIOD_GENHD_NAME); 790 VIODASD_MAJOR, VIOD_GENHD_NAME);
787 return -EIO; 791 goto early_fail;
788 } 792 }
789 /* Actually open the path to the hosting partition */ 793 /* Actually open the path to the hosting partition */
790 if (viopath_open(viopath_hostLp, viomajorsubtype_blockio, 794 rc = viopath_open(viopath_hostLp, viomajorsubtype_blockio,
791 VIOMAXREQ + 2)) { 795 VIOMAXREQ + 2);
796 if (rc) {
792 printk(VIOD_KERN_WARNING 797 printk(VIOD_KERN_WARNING
793 "error opening path to host partition %d\n", 798 "error opening path to host partition %d\n",
794 viopath_hostLp); 799 viopath_hostLp);
795 unregister_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME); 800 goto unregister_blk;
796 return -EIO;
797 } 801 }
798 802
799 /* Initialize our request handler */ 803 /* Initialize our request handler */
800 vio_setHandler(viomajorsubtype_blockio, handle_block_event); 804 vio_setHandler(viomajorsubtype_blockio, handle_block_event);
801 805
802 rc = vio_register_driver(&viodasd_driver); 806 rc = vio_register_driver(&viodasd_driver);
803 if (rc == 0) 807 if (rc) {
804 driver_create_file(&viodasd_driver.driver, &driver_attr_probe); 808 printk(VIOD_KERN_WARNING "vio_register_driver failed\n");
809 goto unset_handler;
810 }
811
812 /*
813 * If this call fails, it just means that we cannot dynamically
814 * add virtual disks, but the driver will still work fine for
815 * all existing disk, so ignore the failure.
816 */
817 if (!driver_create_file(&viodasd_driver.driver, &driver_attr_probe))
818 need_delete_probe = 1;
819
820 return 0;
821
822unset_handler:
823 vio_clearHandler(viomajorsubtype_blockio);
824 viopath_close(viopath_hostLp, viomajorsubtype_blockio, VIOMAXREQ + 2);
825unregister_blk:
826 unregister_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME);
827early_fail:
805 return rc; 828 return rc;
806} 829}
807module_init(viodasd_init); 830module_init(viodasd_init);
808 831
809void viodasd_exit(void) 832void __exit viodasd_exit(void)
810{ 833{
811 driver_remove_file(&viodasd_driver.driver, &driver_attr_probe); 834 if (need_delete_probe)
835 driver_remove_file(&viodasd_driver.driver, &driver_attr_probe);
812 vio_unregister_driver(&viodasd_driver); 836 vio_unregister_driver(&viodasd_driver);
813 vio_clearHandler(viomajorsubtype_blockio); 837 vio_clearHandler(viomajorsubtype_blockio);
814 unregister_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME);
815 viopath_close(viopath_hostLp, viomajorsubtype_blockio, VIOMAXREQ + 2); 838 viopath_close(viopath_hostLp, viomajorsubtype_blockio, VIOMAXREQ + 2);
839 unregister_blkdev(VIODASD_MAJOR, VIOD_GENHD_NAME);
816} 840}
817
818module_exit(viodasd_exit); 841module_exit(viodasd_exit);
diff --git a/drivers/char/hpet.c b/drivers/char/hpet.c
index 091a11cd878c..20dc3be5ecfc 100644
--- a/drivers/char/hpet.c
+++ b/drivers/char/hpet.c
@@ -21,6 +21,7 @@
21#include <linux/fcntl.h> 21#include <linux/fcntl.h>
22#include <linux/init.h> 22#include <linux/init.h>
23#include <linux/poll.h> 23#include <linux/poll.h>
24#include <linux/mm.h>
24#include <linux/proc_fs.h> 25#include <linux/proc_fs.h>
25#include <linux/spinlock.h> 26#include <linux/spinlock.h>
26#include <linux/sysctl.h> 27#include <linux/sysctl.h>
diff --git a/drivers/char/hw_random/core.c b/drivers/char/hw_random/core.c
index ebace201bec6..26a860adcb38 100644
--- a/drivers/char/hw_random/core.c
+++ b/drivers/char/hw_random/core.c
@@ -36,6 +36,7 @@
36#include <linux/module.h> 36#include <linux/module.h>
37#include <linux/kernel.h> 37#include <linux/kernel.h>
38#include <linux/fs.h> 38#include <linux/fs.h>
39#include <linux/sched.h>
39#include <linux/init.h> 40#include <linux/init.h>
40#include <linux/miscdevice.h> 41#include <linux/miscdevice.h>
41#include <linux/delay.h> 42#include <linux/delay.h>
diff --git a/drivers/char/tpm/tpm.h b/drivers/char/tpm/tpm.h
index 050ced247f68..bb9a43c6cf3d 100644
--- a/drivers/char/tpm/tpm.h
+++ b/drivers/char/tpm/tpm.h
@@ -22,6 +22,7 @@
22#include <linux/pci.h> 22#include <linux/pci.h>
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/fs.h> 24#include <linux/fs.h>
25#include <linux/sched.h>
25#include <linux/miscdevice.h> 26#include <linux/miscdevice.h>
26#include <linux/platform_device.h> 27#include <linux/platform_device.h>
27#include <linux/io.h> 28#include <linux/io.h>
diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c
index e5cb0fdab9b1..b1dc63e4ac7b 100644
--- a/drivers/hwmon/abituguru.c
+++ b/drivers/hwmon/abituguru.c
@@ -21,6 +21,7 @@
21 etc voltage & frequency control is not supported! 21 etc voltage & frequency control is not supported!
22*/ 22*/
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/sched.h>
24#include <linux/init.h> 25#include <linux/init.h>
25#include <linux/slab.h> 26#include <linux/slab.h>
26#include <linux/jiffies.h> 27#include <linux/jiffies.h>
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index 26be4ea8a38a..e8ef62b83d6b 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -33,6 +33,7 @@
33#include <linux/module.h> 33#include <linux/module.h>
34#include <linux/timer.h> 34#include <linux/timer.h>
35#include <linux/dmi.h> 35#include <linux/dmi.h>
36#include <linux/jiffies.h>
36#include <asm/io.h> 37#include <asm/io.h>
37 38
38#define HDAPS_LOW_PORT 0x1600 /* first port used by hdaps */ 39#define HDAPS_LOW_PORT 0x1600 /* first port used by hdaps */
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index 2af634d7acf4..eb7ab112c050 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -35,7 +35,7 @@
35#include <linux/ide.h> 35#include <linux/ide.h>
36#include <asm/io.h> 36#include <asm/io.h>
37 37
38#ifdef CONFIG_PPC_MULTIPLATFORM 38#ifdef CONFIG_PPC_CHRP
39#include <asm/processor.h> 39#include <asm/processor.h>
40#endif 40#endif
41 41
@@ -442,7 +442,7 @@ static void __devinit init_hwif_via82cxxx(ide_hwif_t *hwif)
442 hwif->speedproc = &via_set_drive; 442 hwif->speedproc = &via_set_drive;
443 443
444 444
445#if defined(CONFIG_PPC_CHRP) && defined(CONFIG_PPC32) 445#ifdef CONFIG_PPC_CHRP
446 if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) { 446 if(machine_is(chrp) && _chrp_type == _CHRP_Pegasos) {
447 hwif->irq = hwif->channel ? 15 : 14; 447 hwif->irq = hwif->channel ? 15 : 14;
448 } 448 }
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index 0606744c3f84..5e122501fd80 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -35,6 +35,7 @@
35#include <linux/kernel.h> 35#include <linux/kernel.h>
36#include <linux/slab.h> 36#include <linux/slab.h>
37#include <linux/mm.h> 37#include <linux/mm.h>
38#include <linux/highmem.h>
38#include <asm/io.h> 39#include <asm/io.h>
39#include <asm/scatterlist.h> 40#include <asm/scatterlist.h>
40#include <linux/scatterlist.h> 41#include <linux/scatterlist.h>
diff --git a/drivers/isdn/divert/isdn_divert.c b/drivers/isdn/divert/isdn_divert.c
index 1f5ebe9ee72c..03319ea5aa0c 100644
--- a/drivers/isdn/divert/isdn_divert.c
+++ b/drivers/isdn/divert/isdn_divert.c
@@ -10,6 +10,8 @@
10 */ 10 */
11 11
12#include <linux/proc_fs.h> 12#include <linux/proc_fs.h>
13#include <linux/timer.h>
14#include <linux/jiffies.h>
13 15
14#include "isdn_divert.h" 16#include "isdn_divert.h"
15 17
diff --git a/drivers/leds/ledtrig-ide-disk.c b/drivers/leds/ledtrig-ide-disk.c
index fa651886ab4f..54b155c7026f 100644
--- a/drivers/leds/ledtrig-ide-disk.c
+++ b/drivers/leds/ledtrig-ide-disk.c
@@ -12,6 +12,7 @@
12 */ 12 */
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/jiffies.h>
15#include <linux/kernel.h> 16#include <linux/kernel.h>
16#include <linux/init.h> 17#include <linux/init.h>
17#include <linux/timer.h> 18#include <linux/timer.h>
diff --git a/drivers/leds/ledtrig-timer.c b/drivers/leds/ledtrig-timer.c
index 29a8818a32ec..d756bdb01c59 100644
--- a/drivers/leds/ledtrig-timer.c
+++ b/drivers/leds/ledtrig-timer.c
@@ -12,6 +12,7 @@
12 */ 12 */
13 13
14#include <linux/module.h> 14#include <linux/module.h>
15#include <linux/jiffies.h>
15#include <linux/kernel.h> 16#include <linux/kernel.h>
16#include <linux/init.h> 17#include <linux/init.h>
17#include <linux/list.h> 18#include <linux/list.h>
diff --git a/drivers/macintosh/Kconfig b/drivers/macintosh/Kconfig
index 7f8477d3a661..92ccee85e2a2 100644
--- a/drivers/macintosh/Kconfig
+++ b/drivers/macintosh/Kconfig
@@ -228,4 +228,11 @@ config ANSLCD
228 tristate "Support for ANS LCD display" 228 tristate "Support for ANS LCD display"
229 depends on ADB_CUDA && PPC_PMAC 229 depends on ADB_CUDA && PPC_PMAC
230 230
231config PMAC_RACKMETER
232 tristate "Support for Apple XServe front panel LEDs"
233 depends on PPC_PMAC
234 help
235 This driver procides some support to control the front panel
236 blue LEDs "vu-meter" of the XServer macs.
237
231endmenu 238endmenu
diff --git a/drivers/macintosh/Makefile b/drivers/macintosh/Makefile
index b53d45f87b0b..2dfc3f4eaf42 100644
--- a/drivers/macintosh/Makefile
+++ b/drivers/macintosh/Makefile
@@ -42,3 +42,4 @@ obj-$(CONFIG_WINDFARM_PM112) += windfarm_pm112.o windfarm_smu_sat.o \
42 windfarm_smu_sensors.o \ 42 windfarm_smu_sensors.o \
43 windfarm_max6690_sensor.o \ 43 windfarm_max6690_sensor.o \
44 windfarm_lm75_sensor.o windfarm_pid.o 44 windfarm_lm75_sensor.o windfarm_pid.o
45obj-$(CONFIG_PMAC_RACKMETER) += rack-meter.o
diff --git a/drivers/macintosh/rack-meter.c b/drivers/macintosh/rack-meter.c
new file mode 100644
index 000000000000..f1b6f563673a
--- /dev/null
+++ b/drivers/macintosh/rack-meter.c
@@ -0,0 +1,612 @@
1/*
2 * RackMac vu-meter driver
3 *
4 * (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp.
5 * <benh@kernel.crashing.org>
6 *
7 * Released under the term of the GNU GPL v2.
8 *
9 * Support the CPU-meter LEDs of the Xserve G5
10 *
11 * TODO: Implement PWM to do variable intensity and provide userland
12 * interface for fun. Also, the CPU-meter could be made nicer by being
13 * a bit less "immediate" but giving instead a more average load over
14 * time. Patches welcome :-)
15 *
16 */
17#undef DEBUG
18
19#include <linux/types.h>
20#include <linux/kernel.h>
21#include <linux/device.h>
22#include <linux/interrupt.h>
23#include <linux/module.h>
24#include <linux/pci.h>
25#include <linux/dma-mapping.h>
26#include <linux/kernel_stat.h>
27
28#include <asm/io.h>
29#include <asm/prom.h>
30#include <asm/machdep.h>
31#include <asm/pmac_feature.h>
32#include <asm/dbdma.h>
33#include <asm/dbdma.h>
34#include <asm/macio.h>
35#include <asm/keylargo.h>
36
37/* Number of samples in a sample buffer */
38#define SAMPLE_COUNT 256
39
40/* CPU meter sampling rate in ms */
41#define CPU_SAMPLING_RATE 250
42
43struct rackmeter_dma {
44 struct dbdma_cmd cmd[4] ____cacheline_aligned;
45 u32 mark ____cacheline_aligned;
46 u32 buf1[SAMPLE_COUNT] ____cacheline_aligned;
47 u32 buf2[SAMPLE_COUNT] ____cacheline_aligned;
48} ____cacheline_aligned;
49
50struct rackmeter_cpu {
51 struct work_struct sniffer;
52 cputime64_t prev_wall;
53 cputime64_t prev_idle;
54 int zero;
55} ____cacheline_aligned;
56
57struct rackmeter {
58 struct macio_dev *mdev;
59 unsigned int irq;
60 struct device_node *i2s;
61 u8 *ubuf;
62 struct dbdma_regs __iomem *dma_regs;
63 void __iomem *i2s_regs;
64 dma_addr_t dma_buf_p;
65 struct rackmeter_dma *dma_buf_v;
66 int stale_irq;
67 struct rackmeter_cpu cpu[2];
68 int paused;
69 struct mutex sem;
70};
71
72/* To be set as a tunable */
73static int rackmeter_ignore_nice;
74
75/* This GPIO is whacked by the OS X driver when initializing */
76#define RACKMETER_MAGIC_GPIO 0x78
77
78/* This is copied from cpufreq_ondemand, maybe we should put it in
79 * a common header somewhere
80 */
81static inline cputime64_t get_cpu_idle_time(unsigned int cpu)
82{
83 cputime64_t retval;
84
85 retval = cputime64_add(kstat_cpu(cpu).cpustat.idle,
86 kstat_cpu(cpu).cpustat.iowait);
87
88 if (rackmeter_ignore_nice)
89 retval = cputime64_add(retval, kstat_cpu(cpu).cpustat.nice);
90
91 return retval;
92}
93
94static void rackmeter_setup_i2s(struct rackmeter *rm)
95{
96 struct macio_chip *macio = rm->mdev->bus->chip;
97
98 /* First whack magic GPIO */
99 pmac_call_feature(PMAC_FTR_WRITE_GPIO, NULL, RACKMETER_MAGIC_GPIO, 5);
100
101
102 /* Call feature code to enable the sound channel and the proper
103 * clock sources
104 */
105 pmac_call_feature(PMAC_FTR_SOUND_CHIP_ENABLE, rm->i2s, 0, 1);
106
107 /* Power i2s and stop i2s clock. We whack MacIO FCRs directly for now.
108 * This is a bit racy, thus we should add new platform functions to
109 * handle that. snd-aoa needs that too
110 */
111 MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_ENABLE);
112 MACIO_BIC(KEYLARGO_FCR1, KL1_I2S0_CLK_ENABLE_BIT);
113 (void)MACIO_IN32(KEYLARGO_FCR1);
114 udelay(10);
115
116 /* Then setup i2s. For now, we use the same magic value that
117 * the OS X driver seems to use. We might want to play around
118 * with the clock divisors later
119 */
120 out_le32(rm->i2s_regs + 0x10, 0x01fa0000);
121 (void)in_le32(rm->i2s_regs + 0x10);
122 udelay(10);
123
124 /* Fully restart i2s*/
125 MACIO_BIS(KEYLARGO_FCR1, KL1_I2S0_CELL_ENABLE |
126 KL1_I2S0_CLK_ENABLE_BIT);
127 (void)MACIO_IN32(KEYLARGO_FCR1);
128 udelay(10);
129}
130
131static void rackmeter_set_default_pattern(struct rackmeter *rm)
132{
133 int i;
134
135 for (i = 0; i < 16; i++) {
136 if (i < 8)
137 rm->ubuf[i] = (i & 1) * 255;
138 else
139 rm->ubuf[i] = ((~i) & 1) * 255;
140 }
141}
142
143static void rackmeter_do_pause(struct rackmeter *rm, int pause)
144{
145 struct rackmeter_dma *rdma = rm->dma_buf_v;
146
147 pr_debug("rackmeter: %s\n", pause ? "paused" : "started");
148
149 rm->paused = pause;
150 if (pause) {
151 DBDMA_DO_STOP(rm->dma_regs);
152 return;
153 }
154 memset(rdma->buf1, 0, SAMPLE_COUNT & sizeof(u32));
155 memset(rdma->buf2, 0, SAMPLE_COUNT & sizeof(u32));
156
157 rm->dma_buf_v->mark = 0;
158
159 mb();
160 out_le32(&rm->dma_regs->cmdptr_hi, 0);
161 out_le32(&rm->dma_regs->cmdptr, rm->dma_buf_p);
162 out_le32(&rm->dma_regs->control, (RUN << 16) | RUN);
163}
164
165static void rackmeter_setup_dbdma(struct rackmeter *rm)
166{
167 struct rackmeter_dma *db = rm->dma_buf_v;
168 struct dbdma_cmd *cmd = db->cmd;
169
170 /* Make sure dbdma is reset */
171 DBDMA_DO_RESET(rm->dma_regs);
172
173 pr_debug("rackmeter: mark offset=0x%lx\n",
174 offsetof(struct rackmeter_dma, mark));
175 pr_debug("rackmeter: buf1 offset=0x%lx\n",
176 offsetof(struct rackmeter_dma, buf1));
177 pr_debug("rackmeter: buf2 offset=0x%lx\n",
178 offsetof(struct rackmeter_dma, buf2));
179
180 /* Prepare 4 dbdma commands for the 2 buffers */
181 memset(cmd, 0, 4 * sizeof(struct dbdma_cmd));
182 st_le16(&cmd->req_count, 4);
183 st_le16(&cmd->command, STORE_WORD | INTR_ALWAYS | KEY_SYSTEM);
184 st_le32(&cmd->phy_addr, rm->dma_buf_p +
185 offsetof(struct rackmeter_dma, mark));
186 st_le32(&cmd->cmd_dep, 0x02000000);
187 cmd++;
188
189 st_le16(&cmd->req_count, SAMPLE_COUNT * 4);
190 st_le16(&cmd->command, OUTPUT_MORE);
191 st_le32(&cmd->phy_addr, rm->dma_buf_p +
192 offsetof(struct rackmeter_dma, buf1));
193 cmd++;
194
195 st_le16(&cmd->req_count, 4);
196 st_le16(&cmd->command, STORE_WORD | INTR_ALWAYS | KEY_SYSTEM);
197 st_le32(&cmd->phy_addr, rm->dma_buf_p +
198 offsetof(struct rackmeter_dma, mark));
199 st_le32(&cmd->cmd_dep, 0x01000000);
200 cmd++;
201
202 st_le16(&cmd->req_count, SAMPLE_COUNT * 4);
203 st_le16(&cmd->command, OUTPUT_MORE | BR_ALWAYS);
204 st_le32(&cmd->phy_addr, rm->dma_buf_p +
205 offsetof(struct rackmeter_dma, buf2));
206 st_le32(&cmd->cmd_dep, rm->dma_buf_p);
207
208 rackmeter_do_pause(rm, 0);
209}
210
211static void rackmeter_do_timer(void *data)
212{
213 struct rackmeter *rm = data;
214 unsigned int cpu = smp_processor_id();
215 struct rackmeter_cpu *rcpu = &rm->cpu[cpu];
216 cputime64_t cur_jiffies, total_idle_ticks;
217 unsigned int total_ticks, idle_ticks;
218 int i, offset, load, cumm, pause;
219
220 cur_jiffies = jiffies64_to_cputime64(get_jiffies_64());
221 total_ticks = (unsigned int)cputime64_sub(cur_jiffies,
222 rcpu->prev_wall);
223 rcpu->prev_wall = cur_jiffies;
224
225 total_idle_ticks = get_cpu_idle_time(cpu);
226 idle_ticks = (unsigned int) cputime64_sub(total_idle_ticks,
227 rcpu->prev_idle);
228 rcpu->prev_idle = total_idle_ticks;
229
230 /* We do a very dumb calculation to update the LEDs for now,
231 * we'll do better once we have actual PWM implemented
232 */
233 load = (9 * (total_ticks - idle_ticks)) / total_ticks;
234
235 offset = cpu << 3;
236 cumm = 0;
237 for (i = 0; i < 8; i++) {
238 u8 ub = (load > i) ? 0xff : 0;
239 rm->ubuf[i + offset] = ub;
240 cumm |= ub;
241 }
242 rcpu->zero = (cumm == 0);
243
244 /* Now check if LEDs are all 0, we can stop DMA */
245 pause = (rm->cpu[0].zero && rm->cpu[1].zero);
246 if (pause != rm->paused) {
247 mutex_lock(&rm->sem);
248 pause = (rm->cpu[0].zero && rm->cpu[1].zero);
249 rackmeter_do_pause(rm, pause);
250 mutex_unlock(&rm->sem);
251 }
252 schedule_delayed_work_on(cpu, &rcpu->sniffer,
253 msecs_to_jiffies(CPU_SAMPLING_RATE));
254}
255
256static void __devinit rackmeter_init_cpu_sniffer(struct rackmeter *rm)
257{
258 unsigned int cpu;
259
260 /* This driver works only with 1 or 2 CPUs numbered 0 and 1,
261 * but that's really all we have on Apple Xserve. It doesn't
262 * play very nice with CPU hotplug neither but we don't do that
263 * on those machines yet
264 */
265
266 INIT_WORK(&rm->cpu[0].sniffer, rackmeter_do_timer, rm);
267 INIT_WORK(&rm->cpu[1].sniffer, rackmeter_do_timer, rm);
268
269 for_each_online_cpu(cpu) {
270 struct rackmeter_cpu *rcpu;
271
272 if (cpu > 1)
273 continue;
274 rcpu = &rm->cpu[cpu];;
275 rcpu->prev_idle = get_cpu_idle_time(cpu);
276 rcpu->prev_wall = jiffies64_to_cputime64(get_jiffies_64());
277 schedule_delayed_work_on(cpu, &rm->cpu[cpu].sniffer,
278 msecs_to_jiffies(CPU_SAMPLING_RATE));
279 }
280}
281
282static void __devexit rackmeter_stop_cpu_sniffer(struct rackmeter *rm)
283{
284 cancel_rearming_delayed_work(&rm->cpu[0].sniffer);
285 cancel_rearming_delayed_work(&rm->cpu[1].sniffer);
286}
287
288static int rackmeter_setup(struct rackmeter *rm)
289{
290 pr_debug("rackmeter: setting up i2s..\n");
291 rackmeter_setup_i2s(rm);
292
293 pr_debug("rackmeter: setting up default pattern..\n");
294 rackmeter_set_default_pattern(rm);
295
296 pr_debug("rackmeter: setting up dbdma..\n");
297 rackmeter_setup_dbdma(rm);
298
299 pr_debug("rackmeter: start CPU measurements..\n");
300 rackmeter_init_cpu_sniffer(rm);
301
302 printk(KERN_INFO "RackMeter initialized\n");
303
304 return 0;
305}
306
307/* XXX FIXME: No PWM yet, this is 0/1 */
308static u32 rackmeter_calc_sample(struct rackmeter *rm, unsigned int index)
309{
310 int led;
311 u32 sample = 0;
312
313 for (led = 0; led < 16; led++) {
314 sample >>= 1;
315 sample |= ((rm->ubuf[led] >= 0x80) << 15);
316 }
317 return (sample << 17) | (sample >> 15);
318}
319
320static irqreturn_t rackmeter_irq(int irq, void *arg)
321{
322 struct rackmeter *rm = arg;
323 struct rackmeter_dma *db = rm->dma_buf_v;
324 unsigned int mark, i;
325 u32 *buf;
326
327 /* Flush PCI buffers with an MMIO read. Maybe we could actually
328 * check the status one day ... in case things go wrong, though
329 * this never happened to me
330 */
331 (void)in_le32(&rm->dma_regs->status);
332
333 /* Make sure the CPU gets us in order */
334 rmb();
335
336 /* Read mark */
337 mark = db->mark;
338 if (mark != 1 && mark != 2) {
339 printk(KERN_WARNING "rackmeter: Incorrect DMA mark 0x%08x\n",
340 mark);
341 /* We allow for 3 errors like that (stale DBDMA irqs) */
342 if (++rm->stale_irq > 3) {
343 printk(KERN_ERR "rackmeter: Too many errors,"
344 " stopping DMA\n");
345 DBDMA_DO_RESET(rm->dma_regs);
346 }
347 return IRQ_HANDLED;
348 }
349
350 /* Next buffer we need to fill is mark value */
351 buf = mark == 1 ? db->buf1 : db->buf2;
352
353 /* Fill it now. This routine converts the 8 bits depth sample array
354 * into the PWM bitmap for each LED.
355 */
356 for (i = 0; i < SAMPLE_COUNT; i++)
357 buf[i] = rackmeter_calc_sample(rm, i);
358
359
360 return IRQ_HANDLED;
361}
362
363static int __devinit rackmeter_probe(struct macio_dev* mdev,
364 const struct of_device_id *match)
365{
366 struct device_node *i2s = NULL, *np = NULL;
367 struct rackmeter *rm = NULL;
368 struct resource ri2s, rdma;
369 int rc = -ENODEV;
370
371 pr_debug("rackmeter_probe()\n");
372
373 /* Get i2s-a node */
374 while ((i2s = of_get_next_child(mdev->ofdev.node, i2s)) != NULL)
375 if (strcmp(i2s->name, "i2s-a") == 0)
376 break;
377 if (i2s == NULL) {
378 pr_debug(" i2s-a child not found\n");
379 goto bail;
380 }
381 /* Get lightshow or virtual sound */
382 while ((np = of_get_next_child(i2s, np)) != NULL) {
383 if (strcmp(np->name, "lightshow") == 0)
384 break;
385 if ((strcmp(np->name, "sound") == 0) &&
386 get_property(np, "virtual", NULL) != NULL)
387 break;
388 }
389 if (np == NULL) {
390 pr_debug(" lightshow or sound+virtual child not found\n");
391 goto bail;
392 }
393
394 /* Create and initialize our instance data */
395 rm = kzalloc(sizeof(struct rackmeter), GFP_KERNEL);
396 if (rm == NULL) {
397 printk(KERN_ERR "rackmeter: failed to allocate memory !\n");
398 rc = -ENOMEM;
399 goto bail_release;
400 }
401 rm->mdev = mdev;
402 rm->i2s = i2s;
403 mutex_init(&rm->sem);
404 dev_set_drvdata(&mdev->ofdev.dev, rm);
405 /* Check resources availability. We need at least resource 0 and 1 */
406#if 0 /* Use that when i2s-a is finally an mdev per-se */
407 if (macio_resource_count(mdev) < 2 || macio_irq_count(mdev) < 2) {
408 printk(KERN_ERR
409 "rackmeter: found match but lacks resources: %s"
410 " (%d resources, %d interrupts)\n",
411 mdev->ofdev.node->full_name);
412 rc = -ENXIO;
413 goto bail_free;
414 }
415 if (macio_request_resources(mdev, "rackmeter")) {
416 printk(KERN_ERR
417 "rackmeter: failed to request resources: %s\n",
418 mdev->ofdev.node->full_name);
419 rc = -EBUSY;
420 goto bail_free;
421 }
422 rm->irq = macio_irq(mdev, 1);
423#else
424 rm->irq = irq_of_parse_and_map(i2s, 1);
425 if (rm->irq == NO_IRQ ||
426 of_address_to_resource(i2s, 0, &ri2s) ||
427 of_address_to_resource(i2s, 1, &rdma)) {
428 printk(KERN_ERR
429 "rackmeter: found match but lacks resources: %s",
430 mdev->ofdev.node->full_name);
431 rc = -ENXIO;
432 goto bail_free;
433 }
434#endif
435
436 pr_debug(" i2s @0x%08x\n", (unsigned int)ri2s.start);
437 pr_debug(" dma @0x%08x\n", (unsigned int)rdma.start);
438 pr_debug(" irq %d\n", rm->irq);
439
440 rm->ubuf = (u8 *)__get_free_page(GFP_KERNEL);
441 if (rm->ubuf == NULL) {
442 printk(KERN_ERR
443 "rackmeter: failed to allocate samples page !\n");
444 rc = -ENOMEM;
445 goto bail_release;
446 }
447
448 rm->dma_buf_v = dma_alloc_coherent(&macio_get_pci_dev(mdev)->dev,
449 sizeof(struct rackmeter_dma),
450 &rm->dma_buf_p, GFP_KERNEL);
451 if (rm->dma_buf_v == NULL) {
452 printk(KERN_ERR
453 "rackmeter: failed to allocate dma buffer !\n");
454 rc = -ENOMEM;
455 goto bail_free_samples;
456 }
457#if 0
458 rm->i2s_regs = ioremap(macio_resource_start(mdev, 0), 0x1000);
459#else
460 rm->i2s_regs = ioremap(ri2s.start, 0x1000);
461#endif
462 if (rm->i2s_regs == NULL) {
463 printk(KERN_ERR
464 "rackmeter: failed to map i2s registers !\n");
465 rc = -ENXIO;
466 goto bail_free_dma;
467 }
468#if 0
469 rm->dma_regs = ioremap(macio_resource_start(mdev, 1), 0x100);
470#else
471 rm->dma_regs = ioremap(rdma.start, 0x100);
472#endif
473 if (rm->dma_regs == NULL) {
474 printk(KERN_ERR
475 "rackmeter: failed to map dma registers !\n");
476 rc = -ENXIO;
477 goto bail_unmap_i2s;
478 }
479
480 rc = rackmeter_setup(rm);
481 if (rc) {
482 printk(KERN_ERR
483 "rackmeter: failed to initialize !\n");
484 rc = -ENXIO;
485 goto bail_unmap_dma;
486 }
487
488 rc = request_irq(rm->irq, rackmeter_irq, 0, "rackmeter", rm);
489 if (rc != 0) {
490 printk(KERN_ERR
491 "rackmeter: failed to request interrupt !\n");
492 goto bail_stop_dma;
493 }
494 of_node_put(np);
495 return 0;
496
497 bail_stop_dma:
498 DBDMA_DO_RESET(rm->dma_regs);
499 bail_unmap_dma:
500 iounmap(rm->dma_regs);
501 bail_unmap_i2s:
502 iounmap(rm->i2s_regs);
503 bail_free_dma:
504 dma_free_coherent(&macio_get_pci_dev(mdev)->dev,
505 sizeof(struct rackmeter_dma),
506 rm->dma_buf_v, rm->dma_buf_p);
507 bail_free_samples:
508 free_page((unsigned long)rm->ubuf);
509 bail_release:
510#if 0
511 macio_release_resources(mdev);
512#endif
513 bail_free:
514 kfree(rm);
515 bail:
516 of_node_put(i2s);
517 of_node_put(np);
518 dev_set_drvdata(&mdev->ofdev.dev, NULL);
519 return rc;
520}
521
522static int __devexit rackmeter_remove(struct macio_dev* mdev)
523{
524 struct rackmeter *rm = dev_get_drvdata(&mdev->ofdev.dev);
525
526 /* Stop CPU sniffer timer & work queues */
527 rackmeter_stop_cpu_sniffer(rm);
528
529 /* Clear reference to private data */
530 dev_set_drvdata(&mdev->ofdev.dev, NULL);
531
532 /* Stop/reset dbdma */
533 DBDMA_DO_RESET(rm->dma_regs);
534
535 /* Release the IRQ */
536 free_irq(rm->irq, rm);
537
538 /* Unmap registers */
539 iounmap(rm->dma_regs);
540 iounmap(rm->i2s_regs);
541
542 /* Free DMA */
543 dma_free_coherent(&macio_get_pci_dev(mdev)->dev,
544 sizeof(struct rackmeter_dma),
545 rm->dma_buf_v, rm->dma_buf_p);
546
547 /* Free samples */
548 free_page((unsigned long)rm->ubuf);
549
550#if 0
551 /* Release resources */
552 macio_release_resources(mdev);
553#endif
554
555 /* Get rid of me */
556 kfree(rm);
557
558 return 0;
559}
560
561static int rackmeter_shutdown(struct macio_dev* mdev)
562{
563 struct rackmeter *rm = dev_get_drvdata(&mdev->ofdev.dev);
564
565 if (rm == NULL)
566 return -ENODEV;
567
568 /* Stop CPU sniffer timer & work queues */
569 rackmeter_stop_cpu_sniffer(rm);
570
571 /* Stop/reset dbdma */
572 DBDMA_DO_RESET(rm->dma_regs);
573
574 return 0;
575}
576
577static struct of_device_id rackmeter_match[] = {
578 { .name = "i2s" },
579 { }
580};
581
582static struct macio_driver rackmeter_drv = {
583 .name = "rackmeter",
584 .owner = THIS_MODULE,
585 .match_table = rackmeter_match,
586 .probe = rackmeter_probe,
587 .remove = rackmeter_remove,
588 .shutdown = rackmeter_shutdown,
589};
590
591
592static int __init rackmeter_init(void)
593{
594 pr_debug("rackmeter_init()\n");
595
596 return macio_register_driver(&rackmeter_drv);
597}
598
599static void __exit rackmeter_exit(void)
600{
601 pr_debug("rackmeter_exit()\n");
602
603 macio_unregister_driver(&rackmeter_drv);
604}
605
606module_init(rackmeter_init);
607module_exit(rackmeter_exit);
608
609
610MODULE_LICENSE("GPL");
611MODULE_AUTHOR("Benjamin Herrenschmidt <benh@kernel.crashing.org>");
612MODULE_DESCRIPTION("RackMeter: Support vu-meter on XServe front panel");
diff --git a/drivers/macintosh/smu.c b/drivers/macintosh/smu.c
index 4871158aca3e..6dde27ab79a8 100644
--- a/drivers/macintosh/smu.c
+++ b/drivers/macintosh/smu.c
@@ -46,6 +46,7 @@
46#include <asm/abs_addr.h> 46#include <asm/abs_addr.h>
47#include <asm/uaccess.h> 47#include <asm/uaccess.h>
48#include <asm/of_device.h> 48#include <asm/of_device.h>
49#include <asm/of_platform.h>
49 50
50#define VERSION "0.7" 51#define VERSION "0.7"
51#define AUTHOR "(c) 2005 Benjamin Herrenschmidt, IBM Corp." 52#define AUTHOR "(c) 2005 Benjamin Herrenschmidt, IBM Corp."
@@ -653,7 +654,7 @@ static int __init smu_init_sysfs(void)
653 * I'm a bit too far from figuring out how that works with those 654 * I'm a bit too far from figuring out how that works with those
654 * new chipsets, but that will come back and bite us 655 * new chipsets, but that will come back and bite us
655 */ 656 */
656 of_register_driver(&smu_of_platform_driver); 657 of_register_platform_driver(&smu_of_platform_driver);
657 return 0; 658 return 0;
658} 659}
659 660
diff --git a/drivers/macintosh/therm_adt746x.c b/drivers/macintosh/therm_adt746x.c
index a0f30d0853ea..13b953ae8ebc 100644
--- a/drivers/macintosh/therm_adt746x.c
+++ b/drivers/macintosh/therm_adt746x.c
@@ -30,7 +30,7 @@
30#include <asm/io.h> 30#include <asm/io.h>
31#include <asm/system.h> 31#include <asm/system.h>
32#include <asm/sections.h> 32#include <asm/sections.h>
33#include <asm/of_device.h> 33#include <asm/of_platform.h>
34 34
35#undef DEBUG 35#undef DEBUG
36 36
diff --git a/drivers/macintosh/therm_pm72.c b/drivers/macintosh/therm_pm72.c
index d00c0c37a12e..2e4ad44a8636 100644
--- a/drivers/macintosh/therm_pm72.c
+++ b/drivers/macintosh/therm_pm72.c
@@ -129,6 +129,7 @@
129#include <asm/sections.h> 129#include <asm/sections.h>
130#include <asm/of_device.h> 130#include <asm/of_device.h>
131#include <asm/macio.h> 131#include <asm/macio.h>
132#include <asm/of_platform.h>
132 133
133#include "therm_pm72.h" 134#include "therm_pm72.h"
134 135
@@ -2236,14 +2237,14 @@ static int __init therm_pm72_init(void)
2236 return -ENODEV; 2237 return -ENODEV;
2237 } 2238 }
2238 2239
2239 of_register_driver(&fcu_of_platform_driver); 2240 of_register_platform_driver(&fcu_of_platform_driver);
2240 2241
2241 return 0; 2242 return 0;
2242} 2243}
2243 2244
2244static void __exit therm_pm72_exit(void) 2245static void __exit therm_pm72_exit(void)
2245{ 2246{
2246 of_unregister_driver(&fcu_of_platform_driver); 2247 of_unregister_platform_driver(&fcu_of_platform_driver);
2247 2248
2248 if (of_dev) 2249 if (of_dev)
2249 of_device_unregister(of_dev); 2250 of_device_unregister(of_dev);
diff --git a/drivers/macintosh/therm_windtunnel.c b/drivers/macintosh/therm_windtunnel.c
index 738faab1b22c..a1d3a987cb3a 100644
--- a/drivers/macintosh/therm_windtunnel.c
+++ b/drivers/macintosh/therm_windtunnel.c
@@ -36,12 +36,13 @@
36#include <linux/i2c.h> 36#include <linux/i2c.h>
37#include <linux/slab.h> 37#include <linux/slab.h>
38#include <linux/init.h> 38#include <linux/init.h>
39
39#include <asm/prom.h> 40#include <asm/prom.h>
40#include <asm/machdep.h> 41#include <asm/machdep.h>
41#include <asm/io.h> 42#include <asm/io.h>
42#include <asm/system.h> 43#include <asm/system.h>
43#include <asm/sections.h> 44#include <asm/sections.h>
44#include <asm/of_device.h> 45#include <asm/of_platform.h>
45#include <asm/macio.h> 46#include <asm/macio.h>
46 47
47#define LOG_TEMP 0 /* continously log temperature */ 48#define LOG_TEMP 0 /* continously log temperature */
@@ -511,14 +512,14 @@ g4fan_init( void )
511 return -ENODEV; 512 return -ENODEV;
512 } 513 }
513 514
514 of_register_driver( &therm_of_driver ); 515 of_register_platform_driver( &therm_of_driver );
515 return 0; 516 return 0;
516} 517}
517 518
518static void __exit 519static void __exit
519g4fan_exit( void ) 520g4fan_exit( void )
520{ 521{
521 of_unregister_driver( &therm_of_driver ); 522 of_unregister_platform_driver( &therm_of_driver );
522 523
523 if( x.of_dev ) 524 if( x.of_dev )
524 of_device_unregister( x.of_dev ); 525 of_device_unregister( x.of_dev );
diff --git a/drivers/media/dvb/cinergyT2/cinergyT2.c b/drivers/media/dvb/cinergyT2/cinergyT2.c
index 8458ff3f351e..206c13e47a06 100644
--- a/drivers/media/dvb/cinergyT2/cinergyT2.c
+++ b/drivers/media/dvb/cinergyT2/cinergyT2.c
@@ -30,6 +30,7 @@
30#include <linux/input.h> 30#include <linux/input.h>
31#include <linux/dvb/frontend.h> 31#include <linux/dvb/frontend.h>
32#include <linux/mutex.h> 32#include <linux/mutex.h>
33#include <linux/mm.h>
33 34
34#include "dmxdev.h" 35#include "dmxdev.h"
35#include "dvb_demux.h" 36#include "dvb_demux.h"
diff --git a/drivers/net/ehea/ehea_qmr.c b/drivers/net/ehea/ehea_qmr.c
index 72ef7bde3346..f143e13b229d 100644
--- a/drivers/net/ehea/ehea_qmr.c
+++ b/drivers/net/ehea/ehea_qmr.c
@@ -26,6 +26,7 @@
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
27 */ 27 */
28 28
29#include <linux/mm.h>
29#include "ehea.h" 30#include "ehea.h"
30#include "ehea_phyp.h" 31#include "ehea_phyp.h"
31#include "ehea_qmr.h" 32#include "ehea_qmr.h"
diff --git a/drivers/net/ibm_emac/ibm_emac_mal.h b/drivers/net/ibm_emac/ibm_emac_mal.h
index f73f10a0a562..407d2acbf7c7 100644
--- a/drivers/net/ibm_emac/ibm_emac_mal.h
+++ b/drivers/net/ibm_emac/ibm_emac_mal.h
@@ -24,6 +24,7 @@
24#include <linux/netdevice.h> 24#include <linux/netdevice.h>
25 25
26#include <asm/io.h> 26#include <asm/io.h>
27#include <asm/dcr.h>
27 28
28/* 29/*
29 * These MAL "versions" probably aren't the real versions IBM uses for these 30 * These MAL "versions" probably aren't the real versions IBM uses for these
@@ -191,6 +192,7 @@ struct mal_commac {
191 192
192struct ibm_ocp_mal { 193struct ibm_ocp_mal {
193 int dcrbase; 194 int dcrbase;
195 dcr_host_t dcrhost;
194 196
195 struct list_head poll_list; 197 struct list_head poll_list;
196 struct net_device poll_dev; 198 struct net_device poll_dev;
@@ -207,12 +209,12 @@ struct ibm_ocp_mal {
207 209
208static inline u32 get_mal_dcrn(struct ibm_ocp_mal *mal, int reg) 210static inline u32 get_mal_dcrn(struct ibm_ocp_mal *mal, int reg)
209{ 211{
210 return mfdcr(mal->dcrbase + reg); 212 return dcr_read(mal->dcrhost, mal->dcrbase + reg);
211} 213}
212 214
213static inline void set_mal_dcrn(struct ibm_ocp_mal *mal, int reg, u32 val) 215static inline void set_mal_dcrn(struct ibm_ocp_mal *mal, int reg, u32 val)
214{ 216{
215 mtdcr(mal->dcrbase + reg, val); 217 dcr_write(mal->dcrhost, mal->dcrbase + reg, val);
216} 218}
217 219
218/* Register MAL devices */ 220/* Register MAL devices */
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 44c9f993dcc4..99343b5836b8 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -50,7 +50,6 @@
50#include <asm/semaphore.h> 50#include <asm/semaphore.h>
51#include <asm/hvcall.h> 51#include <asm/hvcall.h>
52#include <asm/atomic.h> 52#include <asm/atomic.h>
53#include <asm/iommu.h>
54#include <asm/vio.h> 53#include <asm/vio.h>
55#include <asm/uaccess.h> 54#include <asm/uaccess.h>
56#include <linux/seq_file.h> 55#include <linux/seq_file.h>
@@ -1000,8 +999,6 @@ static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_
1000 adapter->mac_addr = 0; 999 adapter->mac_addr = 0;
1001 memcpy(&adapter->mac_addr, mac_addr_p, 6); 1000 memcpy(&adapter->mac_addr, mac_addr_p, 6);
1002 1001
1003 adapter->liobn = dev->iommu_table->it_index;
1004
1005 netdev->irq = dev->irq; 1002 netdev->irq = dev->irq;
1006 netdev->open = ibmveth_open; 1003 netdev->open = ibmveth_open;
1007 netdev->poll = ibmveth_poll; 1004 netdev->poll = ibmveth_poll;
@@ -1115,7 +1112,6 @@ static int ibmveth_seq_show(struct seq_file *seq, void *v)
1115 seq_printf(seq, "%s %s\n\n", ibmveth_driver_string, ibmveth_driver_version); 1112 seq_printf(seq, "%s %s\n\n", ibmveth_driver_string, ibmveth_driver_version);
1116 1113
1117 seq_printf(seq, "Unit Address: 0x%x\n", adapter->vdev->unit_address); 1114 seq_printf(seq, "Unit Address: 0x%x\n", adapter->vdev->unit_address);
1118 seq_printf(seq, "LIOBN: 0x%lx\n", adapter->liobn);
1119 seq_printf(seq, "Current MAC: %02X:%02X:%02X:%02X:%02X:%02X\n", 1115 seq_printf(seq, "Current MAC: %02X:%02X:%02X:%02X:%02X:%02X\n",
1120 current_mac[0], current_mac[1], current_mac[2], 1116 current_mac[0], current_mac[1], current_mac[2],
1121 current_mac[3], current_mac[4], current_mac[5]); 1117 current_mac[3], current_mac[4], current_mac[5]);
diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h
index f5b25bff1540..bb69ccae8ace 100644
--- a/drivers/net/ibmveth.h
+++ b/drivers/net/ibmveth.h
@@ -118,7 +118,6 @@ struct ibmveth_adapter {
118 struct net_device_stats stats; 118 struct net_device_stats stats;
119 unsigned int mcastFilterSize; 119 unsigned int mcastFilterSize;
120 unsigned long mac_addr; 120 unsigned long mac_addr;
121 unsigned long liobn;
122 void * buffer_list_addr; 121 void * buffer_list_addr;
123 void * filter_list_addr; 122 void * filter_list_addr;
124 dma_addr_t buffer_list_dma; 123 dma_addr_t buffer_list_dma;
diff --git a/drivers/net/lance.c b/drivers/net/lance.c
index 6efbd499d752..4256c13c73c2 100644
--- a/drivers/net/lance.c
+++ b/drivers/net/lance.c
@@ -57,6 +57,7 @@ static const char version[] = "lance.c:v1.16 2006/11/09 dplatt@3do.com, becker@c
57#include <linux/netdevice.h> 57#include <linux/netdevice.h>
58#include <linux/etherdevice.h> 58#include <linux/etherdevice.h>
59#include <linux/skbuff.h> 59#include <linux/skbuff.h>
60#include <linux/mm.h>
60#include <linux/bitops.h> 61#include <linux/bitops.h>
61 62
62#include <asm/io.h> 63#include <asm/io.h>
diff --git a/drivers/net/ne3210.c b/drivers/net/ne3210.c
index d66328975425..1a6fed76d4cc 100644
--- a/drivers/net/ne3210.c
+++ b/drivers/net/ne3210.c
@@ -36,6 +36,7 @@
36#include <linux/interrupt.h> 36#include <linux/interrupt.h>
37#include <linux/netdevice.h> 37#include <linux/netdevice.h>
38#include <linux/etherdevice.h> 38#include <linux/etherdevice.h>
39#include <linux/mm.h>
39 40
40#include <asm/io.h> 41#include <asm/io.h>
41#include <asm/system.h> 42#include <asm/system.h>
diff --git a/drivers/net/phy/fixed.c b/drivers/net/phy/fixed.c
index f14e99276dba..096d4a100bf2 100644
--- a/drivers/net/phy/fixed.c
+++ b/drivers/net/phy/fixed.c
@@ -254,7 +254,7 @@ static int fixed_mdio_register_device(int number, int speed, int duplex)
254 goto device_create_fail; 254 goto device_create_fail;
255 } 255 }
256 256
257 phydev->irq = -1; 257 phydev->irq = PHY_IGNORE_INTERRUPT;
258 phydev->dev.bus = &mdio_bus_type; 258 phydev->dev.bus = &mdio_bus_type;
259 259
260 if(number) 260 if(number)
diff --git a/drivers/net/sk98lin/skge.c b/drivers/net/sk98lin/skge.c
index 12cbfd190dd7..92d11b961db8 100644
--- a/drivers/net/sk98lin/skge.c
+++ b/drivers/net/sk98lin/skge.c
@@ -114,6 +114,7 @@
114#include <linux/dma-mapping.h> 114#include <linux/dma-mapping.h>
115#include <linux/ip.h> 115#include <linux/ip.h>
116#include <linux/mii.h> 116#include <linux/mii.h>
117#include <linux/mm.h>
117 118
118#include "h/skdrv1st.h" 119#include "h/skdrv1st.h"
119#include "h/skdrv2nd.h" 120#include "h/skdrv2nd.h"
diff --git a/drivers/net/spider_net.c b/drivers/net/spider_net.c
index f16f696c1ff2..ebb6aa39f9c7 100644
--- a/drivers/net/spider_net.c
+++ b/drivers/net/spider_net.c
@@ -88,12 +88,11 @@ MODULE_DEVICE_TABLE(pci, spider_net_pci_tbl);
88static inline u32 88static inline u32
89spider_net_read_reg(struct spider_net_card *card, u32 reg) 89spider_net_read_reg(struct spider_net_card *card, u32 reg)
90{ 90{
91 u32 value; 91 /* We use the powerpc specific variants instead of readl_be() because
92 92 * we know spidernet is not a real PCI device and we can thus avoid the
93 value = readl(card->regs + reg); 93 * performance hit caused by the PCI workarounds.
94 value = le32_to_cpu(value); 94 */
95 95 return in_be32(card->regs + reg);
96 return value;
97} 96}
98 97
99/** 98/**
@@ -105,8 +104,11 @@ spider_net_read_reg(struct spider_net_card *card, u32 reg)
105static inline void 104static inline void
106spider_net_write_reg(struct spider_net_card *card, u32 reg, u32 value) 105spider_net_write_reg(struct spider_net_card *card, u32 reg, u32 value)
107{ 106{
108 value = cpu_to_le32(value); 107 /* We use the powerpc specific variants instead of writel_be() because
109 writel(value, card->regs + reg); 108 * we know spidernet is not a real PCI device and we can thus avoid the
109 * performance hit caused by the PCI workarounds.
110 */
111 out_be32(card->regs + reg, value);
110} 112}
111 113
112/** spider_net_write_phy - write to phy register 114/** spider_net_write_phy - write to phy register
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index 7a0aee6c869d..bf873ea25797 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -41,6 +41,7 @@
41#include <linux/ethtool.h> 41#include <linux/ethtool.h>
42#include <linux/mii.h> 42#include <linux/mii.h>
43#include <linux/if_vlan.h> 43#include <linux/if_vlan.h>
44#include <linux/mm.h>
44#include <asm/processor.h> /* Processor type for cache alignment. */ 45#include <asm/processor.h> /* Processor type for cache alignment. */
45#include <asm/uaccess.h> 46#include <asm/uaccess.h>
46#include <asm/io.h> 47#include <asm/io.h>
diff --git a/drivers/net/sun3lance.c b/drivers/net/sun3lance.c
index b865db363ba0..47a1c09d19ac 100644
--- a/drivers/net/sun3lance.c
+++ b/drivers/net/sun3lance.c
@@ -38,6 +38,7 @@ static char *version = "sun3lance.c: v1.2 1/12/2001 Sam Creasey (sammy@sammy.ne
38#include <linux/skbuff.h> 38#include <linux/skbuff.h>
39#include <linux/bitops.h> 39#include <linux/bitops.h>
40 40
41#include <asm/cacheflush.h>
41#include <asm/setup.h> 42#include <asm/setup.h>
42#include <asm/irq.h> 43#include <asm/irq.h>
43#include <asm/io.h> 44#include <asm/io.h>
diff --git a/drivers/net/sungem.c b/drivers/net/sungem.c
index d03a9a849c06..785e4a535f9e 100644
--- a/drivers/net/sungem.c
+++ b/drivers/net/sungem.c
@@ -56,6 +56,7 @@
56#include <linux/if_vlan.h> 56#include <linux/if_vlan.h>
57#include <linux/bitops.h> 57#include <linux/bitops.h>
58#include <linux/mutex.h> 58#include <linux/mutex.h>
59#include <linux/mm.h>
59 60
60#include <asm/system.h> 61#include <asm/system.h>
61#include <asm/io.h> 62#include <asm/io.h>
diff --git a/drivers/net/sunhme.c b/drivers/net/sunhme.c
index ec432ea879fb..ef671739cfea 100644
--- a/drivers/net/sunhme.c
+++ b/drivers/net/sunhme.c
@@ -32,6 +32,7 @@
32#include <linux/netdevice.h> 32#include <linux/netdevice.h>
33#include <linux/etherdevice.h> 33#include <linux/etherdevice.h>
34#include <linux/skbuff.h> 34#include <linux/skbuff.h>
35#include <linux/mm.h>
35#include <linux/bitops.h> 36#include <linux/bitops.h>
36 37
37#include <asm/system.h> 38#include <asm/system.h>
@@ -3012,6 +3013,11 @@ static int __devinit happy_meal_pci_probe(struct pci_dev *pdev,
3012#endif 3013#endif
3013 3014
3014 err = -ENODEV; 3015 err = -ENODEV;
3016
3017 if (pci_enable_device(pdev))
3018 goto err_out;
3019 pci_set_master(pdev);
3020
3015 if (!strcmp(prom_name, "SUNW,qfe") || !strcmp(prom_name, "qfe")) { 3021 if (!strcmp(prom_name, "SUNW,qfe") || !strcmp(prom_name, "qfe")) {
3016 qp = quattro_pci_find(pdev); 3022 qp = quattro_pci_find(pdev);
3017 if (qp == NULL) 3023 if (qp == NULL)
diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c
index bfe59865b1dd..0d97e10ccac5 100644
--- a/drivers/net/tokenring/ibmtr.c
+++ b/drivers/net/tokenring/ibmtr.c
@@ -1826,7 +1826,7 @@ static void tr_rx(struct net_device *dev)
1826 skb->protocol = tr_type_trans(skb, dev); 1826 skb->protocol = tr_type_trans(skb, dev);
1827 if (IPv4_p) { 1827 if (IPv4_p) {
1828 skb->csum = chksum; 1828 skb->csum = chksum;
1829 skb->ip_summed = 1; 1829 skb->ip_summed = CHECKSUM_COMPLETE;
1830 } 1830 }
1831 netif_rx(skb); 1831 netif_rx(skb);
1832 dev->last_rx = jiffies; 1832 dev->last_rx = jiffies;
diff --git a/drivers/net/tulip/de4x5.c b/drivers/net/tulip/de4x5.c
index 3f4b6408b755..4b3cd3d8b62a 100644
--- a/drivers/net/tulip/de4x5.c
+++ b/drivers/net/tulip/de4x5.c
@@ -473,9 +473,9 @@
473#include <asm/byteorder.h> 473#include <asm/byteorder.h>
474#include <asm/unaligned.h> 474#include <asm/unaligned.h>
475#include <asm/uaccess.h> 475#include <asm/uaccess.h>
476#ifdef CONFIG_PPC_MULTIPLATFORM 476#ifdef CONFIG_PPC_PMAC
477#include <asm/machdep.h> 477#include <asm/machdep.h>
478#endif /* CONFIG_PPC_MULTIPLATFORM */ 478#endif /* CONFIG_PPC_PMAC */
479 479
480#include "de4x5.h" 480#include "de4x5.h"
481 481
@@ -4151,7 +4151,7 @@ get_hw_addr(struct net_device *dev)
4151 /* If possible, try to fix a broken card - SMC only so far */ 4151 /* If possible, try to fix a broken card - SMC only so far */
4152 srom_repair(dev, broken); 4152 srom_repair(dev, broken);
4153 4153
4154#ifdef CONFIG_PPC_MULTIPLATFORM 4154#ifdef CONFIG_PPC_PMAC
4155 /* 4155 /*
4156 ** If the address starts with 00 a0, we have to bit-reverse 4156 ** If the address starts with 00 a0, we have to bit-reverse
4157 ** each byte of the address. 4157 ** each byte of the address.
@@ -4168,7 +4168,7 @@ get_hw_addr(struct net_device *dev)
4168 dev->dev_addr[i] = ((x & 0x55) << 1) + ((x & 0xaa) >> 1); 4168 dev->dev_addr[i] = ((x & 0x55) << 1) + ((x & 0xaa) >> 1);
4169 } 4169 }
4170 } 4170 }
4171#endif /* CONFIG_PPC_MULTIPLATFORM */ 4171#endif /* CONFIG_PPC_PMAC */
4172 4172
4173 /* Test for a bad enet address */ 4173 /* Test for a bad enet address */
4174 status = test_bad_enet(dev, status); 4174 status = test_bad_enet(dev, status);
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index 8ddea1da7c05..9781b16bb8b6 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -117,6 +117,7 @@ static const int multicast_filter_limit = 32;
117#include <linux/netdevice.h> 117#include <linux/netdevice.h>
118#include <linux/etherdevice.h> 118#include <linux/etherdevice.h>
119#include <linux/skbuff.h> 119#include <linux/skbuff.h>
120#include <linux/mm.h>
120#include <linux/init.h> 121#include <linux/init.h>
121#include <linux/delay.h> 122#include <linux/delay.h>
122#include <linux/ethtool.h> 123#include <linux/ethtool.h>
diff --git a/drivers/pci/access.c b/drivers/pci/access.c
index 73a58c73d526..fc405f0165d9 100644
--- a/drivers/pci/access.c
+++ b/drivers/pci/access.c
@@ -1,5 +1,6 @@
1#include <linux/pci.h> 1#include <linux/pci.h>
2#include <linux/module.h> 2#include <linux/module.h>
3#include <linux/sched.h>
3#include <linux/ioport.h> 4#include <linux/ioport.h>
4#include <linux/wait.h> 5#include <linux/wait.h>
5 6
diff --git a/drivers/ps3/Makefile b/drivers/ps3/Makefile
new file mode 100644
index 000000000000..b52d547b7a78
--- /dev/null
+++ b/drivers/ps3/Makefile
@@ -0,0 +1 @@
obj-y += system-bus.o
diff --git a/drivers/ps3/system-bus.c b/drivers/ps3/system-bus.c
new file mode 100644
index 000000000000..d79f949bcb2a
--- /dev/null
+++ b/drivers/ps3/system-bus.c
@@ -0,0 +1,362 @@
1/*
2 * PS3 system bus driver.
3 *
4 * Copyright (C) 2006 Sony Computer Entertainment Inc.
5 * Copyright 2006 Sony Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#include <linux/kernel.h>
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/dma-mapping.h>
25#include <linux/err.h>
26
27#include <asm/udbg.h>
28#include <asm/ps3.h>
29#include <asm/lv1call.h>
30#include <asm/firmware.h>
31
32#define dump_mmio_region(_a) _dump_mmio_region(_a, __func__, __LINE__)
33static void _dump_mmio_region(const struct ps3_mmio_region* r,
34 const char* func, int line)
35{
36 pr_debug("%s:%d: dev %u:%u\n", func, line, r->did.bus_id,
37 r->did.dev_id);
38 pr_debug("%s:%d: bus_addr %lxh\n", func, line, r->bus_addr);
39 pr_debug("%s:%d: len %lxh\n", func, line, r->len);
40 pr_debug("%s:%d: lpar_addr %lxh\n", func, line, r->lpar_addr);
41}
42
43int ps3_mmio_region_create(struct ps3_mmio_region *r)
44{
45 int result;
46
47 result = lv1_map_device_mmio_region(r->did.bus_id, r->did.dev_id,
48 r->bus_addr, r->len, r->page_size, &r->lpar_addr);
49
50 if (result) {
51 pr_debug("%s:%d: lv1_map_device_mmio_region failed: %s\n",
52 __func__, __LINE__, ps3_result(result));
53 r->lpar_addr = r->len = r->bus_addr = 0;
54 }
55
56 dump_mmio_region(r);
57 return result;
58}
59
60int ps3_free_mmio_region(struct ps3_mmio_region *r)
61{
62 int result;
63
64 result = lv1_unmap_device_mmio_region(r->did.bus_id, r->did.dev_id,
65 r->bus_addr);
66
67 if (result)
68 pr_debug("%s:%d: lv1_unmap_device_mmio_region failed: %s\n",
69 __func__, __LINE__, ps3_result(result));
70
71 r->lpar_addr = r->len = r->bus_addr = 0;
72 return result;
73}
74
75static int ps3_system_bus_match(struct device *_dev,
76 struct device_driver *_drv)
77{
78 int result;
79 struct ps3_system_bus_driver *drv = to_ps3_system_bus_driver(_drv);
80 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
81
82 result = dev->match_id == drv->match_id;
83
84 pr_info("%s:%d: dev=%u(%s), drv=%u(%s): %s\n", __func__, __LINE__,
85 dev->match_id, dev->core.bus_id, drv->match_id, drv->core.name,
86 (result ? "match" : "miss"));
87 return result;
88}
89
90static int ps3_system_bus_probe(struct device *_dev)
91{
92 int result;
93 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
94 struct ps3_system_bus_driver *drv =
95 to_ps3_system_bus_driver(_dev->driver);
96
97 result = lv1_open_device(dev->did.bus_id, dev->did.dev_id, 0);
98
99 if (result) {
100 pr_debug("%s:%d: lv1_open_device failed (%d)\n",
101 __func__, __LINE__, result);
102 result = -EACCES;
103 goto clean_none;
104 }
105
106 if (dev->d_region->did.bus_id) {
107 result = ps3_dma_region_create(dev->d_region);
108
109 if (result) {
110 pr_debug("%s:%d: ps3_dma_region_create failed (%d)\n",
111 __func__, __LINE__, result);
112 BUG_ON("check region type");
113 result = -EINVAL;
114 goto clean_device;
115 }
116 }
117
118 BUG_ON(!drv);
119
120 if (drv->probe)
121 result = drv->probe(dev);
122 else
123 pr_info("%s:%d: %s no probe method\n", __func__, __LINE__,
124 dev->core.bus_id);
125
126 if (result) {
127 pr_debug("%s:%d: drv->probe failed\n", __func__, __LINE__);
128 goto clean_dma;
129 }
130
131 return result;
132
133clean_dma:
134 ps3_dma_region_free(dev->d_region);
135clean_device:
136 lv1_close_device(dev->did.bus_id, dev->did.dev_id);
137clean_none:
138 return result;
139}
140
141static int ps3_system_bus_remove(struct device *_dev)
142{
143 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
144 struct ps3_system_bus_driver *drv =
145 to_ps3_system_bus_driver(_dev->driver);
146
147 if (drv->remove)
148 drv->remove(dev);
149 else
150 pr_info("%s:%d: %s no remove method\n", __func__, __LINE__,
151 dev->core.bus_id);
152
153 ps3_dma_region_free(dev->d_region);
154 ps3_free_mmio_region(dev->m_region);
155 lv1_close_device(dev->did.bus_id, dev->did.dev_id);
156
157 return 0;
158}
159
160struct bus_type ps3_system_bus_type = {
161 .name = "ps3_system_bus",
162 .match = ps3_system_bus_match,
163 .probe = ps3_system_bus_probe,
164 .remove = ps3_system_bus_remove,
165};
166
167int __init ps3_system_bus_init(void)
168{
169 int result;
170
171 if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
172 return 0;
173
174 result = bus_register(&ps3_system_bus_type);
175 BUG_ON(result);
176 return result;
177}
178
179core_initcall(ps3_system_bus_init);
180
181/* Allocates a contiguous real buffer and creates mappings over it.
182 * Returns the virtual address of the buffer and sets dma_handle
183 * to the dma address (mapping) of the first page.
184 */
185
186static void * ps3_alloc_coherent(struct device *_dev, size_t size,
187 dma_addr_t *dma_handle, gfp_t flag)
188{
189 int result;
190 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
191 unsigned long virt_addr;
192
193 BUG_ON(!dev->d_region->bus_addr);
194
195 flag &= ~(__GFP_DMA | __GFP_HIGHMEM);
196 flag |= __GFP_ZERO;
197
198 virt_addr = __get_free_pages(flag, get_order(size));
199
200 if (!virt_addr) {
201 pr_debug("%s:%d: get_free_pages failed\n", __func__, __LINE__);
202 goto clean_none;
203 }
204
205 result = ps3_dma_map(dev->d_region, virt_addr, size, dma_handle);
206
207 if (result) {
208 pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
209 __func__, __LINE__, result);
210 BUG_ON("check region type");
211 goto clean_alloc;
212 }
213
214 return (void*)virt_addr;
215
216clean_alloc:
217 free_pages(virt_addr, get_order(size));
218clean_none:
219 dma_handle = NULL;
220 return NULL;
221}
222
223static void ps3_free_coherent(struct device *_dev, size_t size, void *vaddr,
224 dma_addr_t dma_handle)
225{
226 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
227
228 ps3_dma_unmap(dev->d_region, dma_handle, size);
229 free_pages((unsigned long)vaddr, get_order(size));
230}
231
232/* Creates TCEs for a user provided buffer. The user buffer must be
233 * contiguous real kernel storage (not vmalloc). The address of the buffer
234 * passed here is the kernel (virtual) address of the buffer. The buffer
235 * need not be page aligned, the dma_addr_t returned will point to the same
236 * byte within the page as vaddr.
237 */
238
239static dma_addr_t ps3_map_single(struct device *_dev, void *ptr, size_t size,
240 enum dma_data_direction direction)
241{
242 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
243 int result;
244 unsigned long bus_addr;
245
246 result = ps3_dma_map(dev->d_region, (unsigned long)ptr, size,
247 &bus_addr);
248
249 if (result) {
250 pr_debug("%s:%d: ps3_dma_map failed (%d)\n",
251 __func__, __LINE__, result);
252 }
253
254 return bus_addr;
255}
256
257static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr,
258 size_t size, enum dma_data_direction direction)
259{
260 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
261 int result;
262
263 result = ps3_dma_unmap(dev->d_region, dma_addr, size);
264
265 if (result) {
266 pr_debug("%s:%d: ps3_dma_unmap failed (%d)\n",
267 __func__, __LINE__, result);
268 }
269}
270
271static int ps3_map_sg(struct device *_dev, struct scatterlist *sg, int nents,
272 enum dma_data_direction direction)
273{
274#if defined(CONFIG_PS3_DYNAMIC_DMA)
275 BUG_ON("do");
276#endif
277 return 0;
278}
279
280static void ps3_unmap_sg(struct device *_dev, struct scatterlist *sg,
281 int nents, enum dma_data_direction direction)
282{
283#if defined(CONFIG_PS3_DYNAMIC_DMA)
284 BUG_ON("do");
285#endif
286}
287
288static int ps3_dma_supported(struct device *_dev, u64 mask)
289{
290 return 1;
291}
292
293static struct dma_mapping_ops ps3_dma_ops = {
294 .alloc_coherent = ps3_alloc_coherent,
295 .free_coherent = ps3_free_coherent,
296 .map_single = ps3_map_single,
297 .unmap_single = ps3_unmap_single,
298 .map_sg = ps3_map_sg,
299 .unmap_sg = ps3_unmap_sg,
300 .dma_supported = ps3_dma_supported
301};
302
303/**
304 * ps3_system_bus_release_device - remove a device from the system bus
305 */
306
307static void ps3_system_bus_release_device(struct device *_dev)
308{
309 struct ps3_system_bus_device *dev = to_ps3_system_bus_device(_dev);
310 kfree(dev);
311}
312
313/**
314 * ps3_system_bus_device_register - add a device to the system bus
315 *
316 * ps3_system_bus_device_register() expects the dev object to be allocated
317 * dynamically by the caller. The system bus takes ownership of the dev
318 * object and frees the object in ps3_system_bus_release_device().
319 */
320
321int ps3_system_bus_device_register(struct ps3_system_bus_device *dev)
322{
323 int result;
324 static unsigned int dev_count = 1;
325
326 dev->core.parent = NULL;
327 dev->core.bus = &ps3_system_bus_type;
328 dev->core.release = ps3_system_bus_release_device;
329
330 dev->core.archdata.of_node = NULL;
331 dev->core.archdata.dma_ops = &ps3_dma_ops;
332 dev->core.archdata.numa_node = 0;
333
334 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), "sb_%02x",
335 dev_count++);
336
337 pr_debug("%s:%d add %s\n", __func__, __LINE__, dev->core.bus_id);
338
339 result = device_register(&dev->core);
340 return result;
341}
342
343EXPORT_SYMBOL_GPL(ps3_system_bus_device_register);
344
345int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv)
346{
347 int result;
348
349 drv->core.bus = &ps3_system_bus_type;
350
351 result = driver_register(&drv->core);
352 return result;
353}
354
355EXPORT_SYMBOL_GPL(ps3_system_bus_driver_register);
356
357void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv)
358{
359 driver_unregister(&drv->core);
360}
361
362EXPORT_SYMBOL_GPL(ps3_system_bus_driver_unregister);
diff --git a/drivers/s390/block/dasd.c b/drivers/s390/block/dasd.c
index 79ffef6bfaf8..a2cef57d7bcb 100644
--- a/drivers/s390/block/dasd.c
+++ b/drivers/s390/block/dasd.c
@@ -1264,15 +1264,21 @@ __dasd_check_expire(struct dasd_device * device)
1264 if (list_empty(&device->ccw_queue)) 1264 if (list_empty(&device->ccw_queue))
1265 return; 1265 return;
1266 cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list); 1266 cqr = list_entry(device->ccw_queue.next, struct dasd_ccw_req, list);
1267 if (cqr->status == DASD_CQR_IN_IO && cqr->expires != 0) { 1267 if ((cqr->status == DASD_CQR_IN_IO && cqr->expires != 0) &&
1268 if (time_after_eq(jiffies, cqr->expires + cqr->starttime)) { 1268 (time_after_eq(jiffies, cqr->expires + cqr->starttime))) {
1269 if (device->discipline->term_IO(cqr) != 0) {
1270 /* Hmpf, try again in 5 sec */
1271 dasd_set_timer(device, 5*HZ);
1272 DEV_MESSAGE(KERN_ERR, device,
1273 "internal error - timeout (%is) expired "
1274 "for cqr %p, termination failed, "
1275 "retrying in 5s",
1276 (cqr->expires/HZ), cqr);
1277 } else {
1269 DEV_MESSAGE(KERN_ERR, device, 1278 DEV_MESSAGE(KERN_ERR, device,
1270 "internal error - timeout (%is) expired " 1279 "internal error - timeout (%is) expired "
1271 "for cqr %p (%i retries left)", 1280 "for cqr %p (%i retries left)",
1272 (cqr->expires/HZ), cqr, cqr->retries); 1281 (cqr->expires/HZ), cqr, cqr->retries);
1273 if (device->discipline->term_IO(cqr) != 0)
1274 /* Hmpf, try again in 1/10 sec */
1275 dasd_set_timer(device, 10);
1276 } 1282 }
1277 } 1283 }
1278} 1284}
diff --git a/drivers/s390/block/dasd_devmap.c b/drivers/s390/block/dasd_devmap.c
index 91cf971f0652..17fdd8c9f740 100644
--- a/drivers/s390/block/dasd_devmap.c
+++ b/drivers/s390/block/dasd_devmap.c
@@ -684,21 +684,26 @@ dasd_ro_store(struct device *dev, struct device_attribute *attr,
684 const char *buf, size_t count) 684 const char *buf, size_t count)
685{ 685{
686 struct dasd_devmap *devmap; 686 struct dasd_devmap *devmap;
687 int ro_flag; 687 int val;
688 char *endp;
688 689
689 devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); 690 devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
690 if (IS_ERR(devmap)) 691 if (IS_ERR(devmap))
691 return PTR_ERR(devmap); 692 return PTR_ERR(devmap);
692 ro_flag = buf[0] == '1'; 693
694 val = simple_strtoul(buf, &endp, 0);
695 if (((endp + 1) < (buf + count)) || (val > 1))
696 return -EINVAL;
697
693 spin_lock(&dasd_devmap_lock); 698 spin_lock(&dasd_devmap_lock);
694 if (ro_flag) 699 if (val)
695 devmap->features |= DASD_FEATURE_READONLY; 700 devmap->features |= DASD_FEATURE_READONLY;
696 else 701 else
697 devmap->features &= ~DASD_FEATURE_READONLY; 702 devmap->features &= ~DASD_FEATURE_READONLY;
698 if (devmap->device) 703 if (devmap->device)
699 devmap->device->features = devmap->features; 704 devmap->device->features = devmap->features;
700 if (devmap->device && devmap->device->gdp) 705 if (devmap->device && devmap->device->gdp)
701 set_disk_ro(devmap->device->gdp, ro_flag); 706 set_disk_ro(devmap->device->gdp, val);
702 spin_unlock(&dasd_devmap_lock); 707 spin_unlock(&dasd_devmap_lock);
703 return count; 708 return count;
704} 709}
@@ -729,17 +734,22 @@ dasd_use_diag_store(struct device *dev, struct device_attribute *attr,
729{ 734{
730 struct dasd_devmap *devmap; 735 struct dasd_devmap *devmap;
731 ssize_t rc; 736 ssize_t rc;
732 int use_diag; 737 int val;
738 char *endp;
733 739
734 devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); 740 devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
735 if (IS_ERR(devmap)) 741 if (IS_ERR(devmap))
736 return PTR_ERR(devmap); 742 return PTR_ERR(devmap);
737 use_diag = buf[0] == '1'; 743
744 val = simple_strtoul(buf, &endp, 0);
745 if (((endp + 1) < (buf + count)) || (val > 1))
746 return -EINVAL;
747
738 spin_lock(&dasd_devmap_lock); 748 spin_lock(&dasd_devmap_lock);
739 /* Changing diag discipline flag is only allowed in offline state. */ 749 /* Changing diag discipline flag is only allowed in offline state. */
740 rc = count; 750 rc = count;
741 if (!devmap->device) { 751 if (!devmap->device) {
742 if (use_diag) 752 if (val)
743 devmap->features |= DASD_FEATURE_USEDIAG; 753 devmap->features |= DASD_FEATURE_USEDIAG;
744 else 754 else
745 devmap->features &= ~DASD_FEATURE_USEDIAG; 755 devmap->features &= ~DASD_FEATURE_USEDIAG;
@@ -854,14 +864,20 @@ dasd_eer_store(struct device *dev, struct device_attribute *attr,
854 const char *buf, size_t count) 864 const char *buf, size_t count)
855{ 865{
856 struct dasd_devmap *devmap; 866 struct dasd_devmap *devmap;
857 int rc; 867 int val, rc;
868 char *endp;
858 869
859 devmap = dasd_devmap_from_cdev(to_ccwdev(dev)); 870 devmap = dasd_devmap_from_cdev(to_ccwdev(dev));
860 if (IS_ERR(devmap)) 871 if (IS_ERR(devmap))
861 return PTR_ERR(devmap); 872 return PTR_ERR(devmap);
862 if (!devmap->device) 873 if (!devmap->device)
863 return count; 874 return -ENODEV;
864 if (buf[0] == '1') { 875
876 val = simple_strtoul(buf, &endp, 0);
877 if (((endp + 1) < (buf + count)) || (val > 1))
878 return -EINVAL;
879
880 if (val) {
865 rc = dasd_eer_enable(devmap->device); 881 rc = dasd_eer_enable(devmap->device);
866 if (rc) 882 if (rc)
867 return rc; 883 return rc;
diff --git a/drivers/s390/char/con3215.c b/drivers/s390/char/con3215.c
index d7de175d53f0..c9321b920e90 100644
--- a/drivers/s390/char/con3215.c
+++ b/drivers/s390/char/con3215.c
@@ -299,14 +299,14 @@ raw3215_timeout(unsigned long __data)
299 struct raw3215_info *raw = (struct raw3215_info *) __data; 299 struct raw3215_info *raw = (struct raw3215_info *) __data;
300 unsigned long flags; 300 unsigned long flags;
301 301
302 spin_lock_irqsave(raw->lock, flags); 302 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
303 if (raw->flags & RAW3215_TIMER_RUNS) { 303 if (raw->flags & RAW3215_TIMER_RUNS) {
304 del_timer(&raw->timer); 304 del_timer(&raw->timer);
305 raw->flags &= ~RAW3215_TIMER_RUNS; 305 raw->flags &= ~RAW3215_TIMER_RUNS;
306 raw3215_mk_write_req(raw); 306 raw3215_mk_write_req(raw);
307 raw3215_start_io(raw); 307 raw3215_start_io(raw);
308 } 308 }
309 spin_unlock_irqrestore(raw->lock, flags); 309 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
310} 310}
311 311
312/* 312/*
@@ -355,10 +355,10 @@ raw3215_tasklet(void *data)
355 unsigned long flags; 355 unsigned long flags;
356 356
357 raw = (struct raw3215_info *) data; 357 raw = (struct raw3215_info *) data;
358 spin_lock_irqsave(raw->lock, flags); 358 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
359 raw3215_mk_write_req(raw); 359 raw3215_mk_write_req(raw);
360 raw3215_try_io(raw); 360 raw3215_try_io(raw);
361 spin_unlock_irqrestore(raw->lock, flags); 361 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
362 /* Check for pending message from raw3215_irq */ 362 /* Check for pending message from raw3215_irq */
363 if (raw->message != NULL) { 363 if (raw->message != NULL) {
364 printk(raw->message, raw->msg_dstat, raw->msg_cstat); 364 printk(raw->message, raw->msg_dstat, raw->msg_cstat);
@@ -512,9 +512,9 @@ raw3215_make_room(struct raw3215_info *raw, unsigned int length)
512 if (RAW3215_BUFFER_SIZE - raw->count >= length) 512 if (RAW3215_BUFFER_SIZE - raw->count >= length)
513 break; 513 break;
514 /* there might be another cpu waiting for the lock */ 514 /* there might be another cpu waiting for the lock */
515 spin_unlock(raw->lock); 515 spin_unlock(get_ccwdev_lock(raw->cdev));
516 udelay(100); 516 udelay(100);
517 spin_lock(raw->lock); 517 spin_lock(get_ccwdev_lock(raw->cdev));
518 } 518 }
519} 519}
520 520
@@ -528,7 +528,7 @@ raw3215_write(struct raw3215_info *raw, const char *str, unsigned int length)
528 int c, count; 528 int c, count;
529 529
530 while (length > 0) { 530 while (length > 0) {
531 spin_lock_irqsave(raw->lock, flags); 531 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
532 count = (length > RAW3215_BUFFER_SIZE) ? 532 count = (length > RAW3215_BUFFER_SIZE) ?
533 RAW3215_BUFFER_SIZE : length; 533 RAW3215_BUFFER_SIZE : length;
534 length -= count; 534 length -= count;
@@ -555,7 +555,7 @@ raw3215_write(struct raw3215_info *raw, const char *str, unsigned int length)
555 /* start or queue request */ 555 /* start or queue request */
556 raw3215_try_io(raw); 556 raw3215_try_io(raw);
557 } 557 }
558 spin_unlock_irqrestore(raw->lock, flags); 558 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
559 } 559 }
560} 560}
561 561
@@ -568,7 +568,7 @@ raw3215_putchar(struct raw3215_info *raw, unsigned char ch)
568 unsigned long flags; 568 unsigned long flags;
569 unsigned int length, i; 569 unsigned int length, i;
570 570
571 spin_lock_irqsave(raw->lock, flags); 571 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
572 if (ch == '\t') { 572 if (ch == '\t') {
573 length = TAB_STOP_SIZE - (raw->line_pos%TAB_STOP_SIZE); 573 length = TAB_STOP_SIZE - (raw->line_pos%TAB_STOP_SIZE);
574 raw->line_pos += length; 574 raw->line_pos += length;
@@ -592,7 +592,7 @@ raw3215_putchar(struct raw3215_info *raw, unsigned char ch)
592 /* start or queue request */ 592 /* start or queue request */
593 raw3215_try_io(raw); 593 raw3215_try_io(raw);
594 } 594 }
595 spin_unlock_irqrestore(raw->lock, flags); 595 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
596} 596}
597 597
598/* 598/*
@@ -604,13 +604,13 @@ raw3215_flush_buffer(struct raw3215_info *raw)
604{ 604{
605 unsigned long flags; 605 unsigned long flags;
606 606
607 spin_lock_irqsave(raw->lock, flags); 607 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
608 if (raw->count > 0) { 608 if (raw->count > 0) {
609 raw->flags |= RAW3215_FLUSHING; 609 raw->flags |= RAW3215_FLUSHING;
610 raw3215_try_io(raw); 610 raw3215_try_io(raw);
611 raw->flags &= ~RAW3215_FLUSHING; 611 raw->flags &= ~RAW3215_FLUSHING;
612 } 612 }
613 spin_unlock_irqrestore(raw->lock, flags); 613 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
614} 614}
615 615
616/* 616/*
@@ -625,9 +625,9 @@ raw3215_startup(struct raw3215_info *raw)
625 return 0; 625 return 0;
626 raw->line_pos = 0; 626 raw->line_pos = 0;
627 raw->flags |= RAW3215_ACTIVE; 627 raw->flags |= RAW3215_ACTIVE;
628 spin_lock_irqsave(raw->lock, flags); 628 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
629 raw3215_try_io(raw); 629 raw3215_try_io(raw);
630 spin_unlock_irqrestore(raw->lock, flags); 630 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
631 631
632 return 0; 632 return 0;
633} 633}
@@ -644,21 +644,21 @@ raw3215_shutdown(struct raw3215_info *raw)
644 if (!(raw->flags & RAW3215_ACTIVE) || (raw->flags & RAW3215_FIXED)) 644 if (!(raw->flags & RAW3215_ACTIVE) || (raw->flags & RAW3215_FIXED))
645 return; 645 return;
646 /* Wait for outstanding requests, then free irq */ 646 /* Wait for outstanding requests, then free irq */
647 spin_lock_irqsave(raw->lock, flags); 647 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
648 if ((raw->flags & RAW3215_WORKING) || 648 if ((raw->flags & RAW3215_WORKING) ||
649 raw->queued_write != NULL || 649 raw->queued_write != NULL ||
650 raw->queued_read != NULL) { 650 raw->queued_read != NULL) {
651 raw->flags |= RAW3215_CLOSING; 651 raw->flags |= RAW3215_CLOSING;
652 add_wait_queue(&raw->empty_wait, &wait); 652 add_wait_queue(&raw->empty_wait, &wait);
653 set_current_state(TASK_INTERRUPTIBLE); 653 set_current_state(TASK_INTERRUPTIBLE);
654 spin_unlock_irqrestore(raw->lock, flags); 654 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
655 schedule(); 655 schedule();
656 spin_lock_irqsave(raw->lock, flags); 656 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
657 remove_wait_queue(&raw->empty_wait, &wait); 657 remove_wait_queue(&raw->empty_wait, &wait);
658 set_current_state(TASK_RUNNING); 658 set_current_state(TASK_RUNNING);
659 raw->flags &= ~(RAW3215_ACTIVE | RAW3215_CLOSING); 659 raw->flags &= ~(RAW3215_ACTIVE | RAW3215_CLOSING);
660 } 660 }
661 spin_unlock_irqrestore(raw->lock, flags); 661 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
662} 662}
663 663
664static int 664static int
@@ -686,7 +686,6 @@ raw3215_probe (struct ccw_device *cdev)
686 } 686 }
687 687
688 raw->cdev = cdev; 688 raw->cdev = cdev;
689 raw->lock = get_ccwdev_lock(cdev);
690 raw->inbuf = (char *) raw + sizeof(struct raw3215_info); 689 raw->inbuf = (char *) raw + sizeof(struct raw3215_info);
691 memset(raw, 0, sizeof(struct raw3215_info)); 690 memset(raw, 0, sizeof(struct raw3215_info));
692 raw->buffer = (char *) kmalloc(RAW3215_BUFFER_SIZE, 691 raw->buffer = (char *) kmalloc(RAW3215_BUFFER_SIZE,
@@ -809,9 +808,9 @@ con3215_unblank(void)
809 unsigned long flags; 808 unsigned long flags;
810 809
811 raw = raw3215[0]; /* console 3215 is the first one */ 810 raw = raw3215[0]; /* console 3215 is the first one */
812 spin_lock_irqsave(raw->lock, flags); 811 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
813 raw3215_make_room(raw, RAW3215_BUFFER_SIZE); 812 raw3215_make_room(raw, RAW3215_BUFFER_SIZE);
814 spin_unlock_irqrestore(raw->lock, flags); 813 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
815} 814}
816 815
817static int __init 816static int __init
@@ -873,7 +872,6 @@ con3215_init(void)
873 raw->buffer = (char *) alloc_bootmem_low(RAW3215_BUFFER_SIZE); 872 raw->buffer = (char *) alloc_bootmem_low(RAW3215_BUFFER_SIZE);
874 raw->inbuf = (char *) alloc_bootmem_low(RAW3215_INBUF_SIZE); 873 raw->inbuf = (char *) alloc_bootmem_low(RAW3215_INBUF_SIZE);
875 raw->cdev = cdev; 874 raw->cdev = cdev;
876 raw->lock = get_ccwdev_lock(cdev);
877 cdev->dev.driver_data = raw; 875 cdev->dev.driver_data = raw;
878 cdev->handler = raw3215_irq; 876 cdev->handler = raw3215_irq;
879 877
@@ -1066,10 +1064,10 @@ tty3215_unthrottle(struct tty_struct * tty)
1066 1064
1067 raw = (struct raw3215_info *) tty->driver_data; 1065 raw = (struct raw3215_info *) tty->driver_data;
1068 if (raw->flags & RAW3215_THROTTLED) { 1066 if (raw->flags & RAW3215_THROTTLED) {
1069 spin_lock_irqsave(raw->lock, flags); 1067 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
1070 raw->flags &= ~RAW3215_THROTTLED; 1068 raw->flags &= ~RAW3215_THROTTLED;
1071 raw3215_try_io(raw); 1069 raw3215_try_io(raw);
1072 spin_unlock_irqrestore(raw->lock, flags); 1070 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
1073 } 1071 }
1074} 1072}
1075 1073
@@ -1096,10 +1094,10 @@ tty3215_start(struct tty_struct *tty)
1096 1094
1097 raw = (struct raw3215_info *) tty->driver_data; 1095 raw = (struct raw3215_info *) tty->driver_data;
1098 if (raw->flags & RAW3215_STOPPED) { 1096 if (raw->flags & RAW3215_STOPPED) {
1099 spin_lock_irqsave(raw->lock, flags); 1097 spin_lock_irqsave(get_ccwdev_lock(raw->cdev), flags);
1100 raw->flags &= ~RAW3215_STOPPED; 1098 raw->flags &= ~RAW3215_STOPPED;
1101 raw3215_try_io(raw); 1099 raw3215_try_io(raw);
1102 spin_unlock_irqrestore(raw->lock, flags); 1100 spin_unlock_irqrestore(get_ccwdev_lock(raw->cdev), flags);
1103 } 1101 }
1104} 1102}
1105 1103
diff --git a/drivers/s390/char/sclp_quiesce.c b/drivers/s390/char/sclp_quiesce.c
index 32004aae95c1..ffa9282ce97a 100644
--- a/drivers/s390/char/sclp_quiesce.c
+++ b/drivers/s390/char/sclp_quiesce.c
@@ -19,52 +19,17 @@
19 19
20#include "sclp.h" 20#include "sclp.h"
21 21
22
23#ifdef CONFIG_SMP
24/* Signal completion of shutdown process. All CPUs except the first to enter
25 * this function: go to stopped state. First CPU: wait until all other
26 * CPUs are in stopped or check stop state. Afterwards, load special PSW
27 * to indicate completion. */
28static void
29do_load_quiesce_psw(void * __unused)
30{
31 static atomic_t cpuid = ATOMIC_INIT(-1);
32 psw_t quiesce_psw;
33 int cpu;
34
35 if (atomic_cmpxchg(&cpuid, -1, smp_processor_id()) != -1)
36 signal_processor(smp_processor_id(), sigp_stop);
37 /* Wait for all other cpus to enter stopped state */
38 for_each_online_cpu(cpu) {
39 if (cpu == smp_processor_id())
40 continue;
41 while(!smp_cpu_not_running(cpu))
42 cpu_relax();
43 }
44 /* Quiesce the last cpu with the special psw */
45 quiesce_psw.mask = PSW_BASE_BITS | PSW_MASK_WAIT;
46 quiesce_psw.addr = 0xfff;
47 __load_psw(quiesce_psw);
48}
49
50/* Shutdown handler. Perform shutdown function on all CPUs. */
51static void
52do_machine_quiesce(void)
53{
54 on_each_cpu(do_load_quiesce_psw, NULL, 0, 0);
55}
56#else
57/* Shutdown handler. Signal completion of shutdown by loading special PSW. */ 22/* Shutdown handler. Signal completion of shutdown by loading special PSW. */
58static void 23static void
59do_machine_quiesce(void) 24do_machine_quiesce(void)
60{ 25{
61 psw_t quiesce_psw; 26 psw_t quiesce_psw;
62 27
28 smp_send_stop();
63 quiesce_psw.mask = PSW_BASE_BITS | PSW_MASK_WAIT; 29 quiesce_psw.mask = PSW_BASE_BITS | PSW_MASK_WAIT;
64 quiesce_psw.addr = 0xfff; 30 quiesce_psw.addr = 0xfff;
65 __load_psw(quiesce_psw); 31 __load_psw(quiesce_psw);
66} 32}
67#endif
68 33
69/* Handler for quiesce event. Start shutdown procedure. */ 34/* Handler for quiesce event. Start shutdown procedure. */
70static void 35static void
diff --git a/drivers/s390/cio/chsc.c b/drivers/s390/cio/chsc.c
index 2d78f0f4a40f..dbfb77b03928 100644
--- a/drivers/s390/cio/chsc.c
+++ b/drivers/s390/cio/chsc.c
@@ -251,6 +251,8 @@ s390_subchannel_remove_chpid(struct device *dev, void *data)
251 cc = cio_clear(sch); 251 cc = cio_clear(sch);
252 if (cc == -ENODEV) 252 if (cc == -ENODEV)
253 goto out_unreg; 253 goto out_unreg;
254 /* Request retry of internal operation. */
255 device_set_intretry(sch);
254 /* Call handler. */ 256 /* Call handler. */
255 if (sch->driver && sch->driver->termination) 257 if (sch->driver && sch->driver->termination)
256 sch->driver->termination(&sch->dev); 258 sch->driver->termination(&sch->dev);
@@ -711,9 +713,6 @@ static inline int check_for_io_on_path(struct subchannel *sch, int index)
711{ 713{
712 int cc; 714 int cc;
713 715
714 if (!device_is_online(sch))
715 /* cio could be doing I/O. */
716 return 0;
717 cc = stsch(sch->schid, &sch->schib); 716 cc = stsch(sch->schid, &sch->schib);
718 if (cc) 717 if (cc)
719 return 0; 718 return 0;
@@ -722,6 +721,26 @@ static inline int check_for_io_on_path(struct subchannel *sch, int index)
722 return 0; 721 return 0;
723} 722}
724 723
724static void terminate_internal_io(struct subchannel *sch)
725{
726 if (cio_clear(sch)) {
727 /* Recheck device in case clear failed. */
728 sch->lpm = 0;
729 if (device_trigger_verify(sch) != 0) {
730 if(css_enqueue_subchannel_slow(sch->schid)) {
731 css_clear_subchannel_slow_list();
732 need_rescan = 1;
733 }
734 }
735 return;
736 }
737 /* Request retry of internal operation. */
738 device_set_intretry(sch);
739 /* Call handler. */
740 if (sch->driver && sch->driver->termination)
741 sch->driver->termination(&sch->dev);
742}
743
725static inline void 744static inline void
726__s390_subchannel_vary_chpid(struct subchannel *sch, __u8 chpid, int on) 745__s390_subchannel_vary_chpid(struct subchannel *sch, __u8 chpid, int on)
727{ 746{
@@ -744,20 +763,26 @@ __s390_subchannel_vary_chpid(struct subchannel *sch, __u8 chpid, int on)
744 device_trigger_reprobe(sch); 763 device_trigger_reprobe(sch);
745 else if (sch->driver && sch->driver->verify) 764 else if (sch->driver && sch->driver->verify)
746 sch->driver->verify(&sch->dev); 765 sch->driver->verify(&sch->dev);
747 } else { 766 break;
748 sch->opm &= ~(0x80 >> chp); 767 }
749 sch->lpm &= ~(0x80 >> chp); 768 sch->opm &= ~(0x80 >> chp);
750 if (check_for_io_on_path(sch, chp)) 769 sch->lpm &= ~(0x80 >> chp);
770 if (check_for_io_on_path(sch, chp)) {
771 if (device_is_online(sch))
751 /* Path verification is done after killing. */ 772 /* Path verification is done after killing. */
752 device_kill_io(sch); 773 device_kill_io(sch);
753 else if (!sch->lpm) { 774 else
775 /* Kill and retry internal I/O. */
776 terminate_internal_io(sch);
777 } else if (!sch->lpm) {
778 if (device_trigger_verify(sch) != 0) {
754 if (css_enqueue_subchannel_slow(sch->schid)) { 779 if (css_enqueue_subchannel_slow(sch->schid)) {
755 css_clear_subchannel_slow_list(); 780 css_clear_subchannel_slow_list();
756 need_rescan = 1; 781 need_rescan = 1;
757 } 782 }
758 } else if (sch->driver && sch->driver->verify) 783 }
759 sch->driver->verify(&sch->dev); 784 } else if (sch->driver && sch->driver->verify)
760 } 785 sch->driver->verify(&sch->dev);
761 break; 786 break;
762 } 787 }
763 spin_unlock_irqrestore(&sch->lock, flags); 788 spin_unlock_irqrestore(&sch->lock, flags);
@@ -1465,41 +1490,6 @@ chsc_get_chp_desc(struct subchannel *sch, int chp_no)
1465 return desc; 1490 return desc;
1466} 1491}
1467 1492
1468static int reset_channel_path(struct channel_path *chp)
1469{
1470 int cc;
1471
1472 cc = rchp(chp->id);
1473 switch (cc) {
1474 case 0:
1475 return 0;
1476 case 2:
1477 return -EBUSY;
1478 default:
1479 return -ENODEV;
1480 }
1481}
1482
1483static void reset_channel_paths_css(struct channel_subsystem *css)
1484{
1485 int i;
1486
1487 for (i = 0; i <= __MAX_CHPID; i++) {
1488 if (css->chps[i])
1489 reset_channel_path(css->chps[i]);
1490 }
1491}
1492
1493void cio_reset_channel_paths(void)
1494{
1495 int i;
1496
1497 for (i = 0; i <= __MAX_CSSID; i++) {
1498 if (css[i] && css[i]->valid)
1499 reset_channel_paths_css(css[i]);
1500 }
1501}
1502
1503static int __init 1493static int __init
1504chsc_alloc_sei_area(void) 1494chsc_alloc_sei_area(void)
1505{ 1495{
diff --git a/drivers/s390/cio/cio.c b/drivers/s390/cio/cio.c
index 8936e460a807..20aee2783847 100644
--- a/drivers/s390/cio/cio.c
+++ b/drivers/s390/cio/cio.c
@@ -21,6 +21,7 @@
21#include <asm/irq.h> 21#include <asm/irq.h>
22#include <asm/irq_regs.h> 22#include <asm/irq_regs.h>
23#include <asm/setup.h> 23#include <asm/setup.h>
24#include <asm/reset.h>
24#include "airq.h" 25#include "airq.h"
25#include "cio.h" 26#include "cio.h"
26#include "css.h" 27#include "css.h"
@@ -28,6 +29,7 @@
28#include "ioasm.h" 29#include "ioasm.h"
29#include "blacklist.h" 30#include "blacklist.h"
30#include "cio_debug.h" 31#include "cio_debug.h"
32#include "../s390mach.h"
31 33
32debug_info_t *cio_debug_msg_id; 34debug_info_t *cio_debug_msg_id;
33debug_info_t *cio_debug_trace_id; 35debug_info_t *cio_debug_trace_id;
@@ -841,26 +843,12 @@ __clear_subchannel_easy(struct subchannel_id schid)
841 return -EBUSY; 843 return -EBUSY;
842} 844}
843 845
844struct sch_match_id { 846static int __shutdown_subchannel_easy(struct subchannel_id schid, void *data)
845 struct subchannel_id schid;
846 struct ccw_dev_id devid;
847 int rc;
848};
849
850static int __shutdown_subchannel_easy_and_match(struct subchannel_id schid,
851 void *data)
852{ 847{
853 struct schib schib; 848 struct schib schib;
854 struct sch_match_id *match_id = data;
855 849
856 if (stsch_err(schid, &schib)) 850 if (stsch_err(schid, &schib))
857 return -ENXIO; 851 return -ENXIO;
858 if (match_id && schib.pmcw.dnv &&
859 (schib.pmcw.dev == match_id->devid.devno) &&
860 (schid.ssid == match_id->devid.ssid)) {
861 match_id->schid = schid;
862 match_id->rc = 0;
863 }
864 if (!schib.pmcw.ena) 852 if (!schib.pmcw.ena)
865 return 0; 853 return 0;
866 switch(__disable_subchannel_easy(schid, &schib)) { 854 switch(__disable_subchannel_easy(schid, &schib)) {
@@ -876,27 +864,111 @@ static int __shutdown_subchannel_easy_and_match(struct subchannel_id schid,
876 return 0; 864 return 0;
877} 865}
878 866
879static int clear_all_subchannels_and_match(struct ccw_dev_id *devid, 867static atomic_t chpid_reset_count;
880 struct subchannel_id *schid) 868
869static void s390_reset_chpids_mcck_handler(void)
870{
871 struct crw crw;
872 struct mci *mci;
873
874 /* Check for pending channel report word. */
875 mci = (struct mci *)&S390_lowcore.mcck_interruption_code;
876 if (!mci->cp)
877 return;
878 /* Process channel report words. */
879 while (stcrw(&crw) == 0) {
880 /* Check for responses to RCHP. */
881 if (crw.slct && crw.rsc == CRW_RSC_CPATH)
882 atomic_dec(&chpid_reset_count);
883 }
884}
885
886#define RCHP_TIMEOUT (30 * USEC_PER_SEC)
887static void css_reset(void)
888{
889 int i, ret;
890 unsigned long long timeout;
891
892 /* Reset subchannels. */
893 for_each_subchannel(__shutdown_subchannel_easy, NULL);
894 /* Reset channel paths. */
895 s390_reset_mcck_handler = s390_reset_chpids_mcck_handler;
896 /* Enable channel report machine checks. */
897 __ctl_set_bit(14, 28);
898 /* Temporarily reenable machine checks. */
899 local_mcck_enable();
900 for (i = 0; i <= __MAX_CHPID; i++) {
901 ret = rchp(i);
902 if ((ret == 0) || (ret == 2))
903 /*
904 * rchp either succeeded, or another rchp is already
905 * in progress. In either case, we'll get a crw.
906 */
907 atomic_inc(&chpid_reset_count);
908 }
909 /* Wait for machine check for all channel paths. */
910 timeout = get_clock() + (RCHP_TIMEOUT << 12);
911 while (atomic_read(&chpid_reset_count) != 0) {
912 if (get_clock() > timeout)
913 break;
914 cpu_relax();
915 }
916 /* Disable machine checks again. */
917 local_mcck_disable();
918 /* Disable channel report machine checks. */
919 __ctl_clear_bit(14, 28);
920 s390_reset_mcck_handler = NULL;
921}
922
923static struct reset_call css_reset_call = {
924 .fn = css_reset,
925};
926
927static int __init init_css_reset_call(void)
928{
929 atomic_set(&chpid_reset_count, 0);
930 register_reset_call(&css_reset_call);
931 return 0;
932}
933
934arch_initcall(init_css_reset_call);
935
936struct sch_match_id {
937 struct subchannel_id schid;
938 struct ccw_dev_id devid;
939 int rc;
940};
941
942static int __reipl_subchannel_match(struct subchannel_id schid, void *data)
943{
944 struct schib schib;
945 struct sch_match_id *match_id = data;
946
947 if (stsch_err(schid, &schib))
948 return -ENXIO;
949 if (schib.pmcw.dnv &&
950 (schib.pmcw.dev == match_id->devid.devno) &&
951 (schid.ssid == match_id->devid.ssid)) {
952 match_id->schid = schid;
953 match_id->rc = 0;
954 return 1;
955 }
956 return 0;
957}
958
959static int reipl_find_schid(struct ccw_dev_id *devid,
960 struct subchannel_id *schid)
881{ 961{
882 struct sch_match_id match_id; 962 struct sch_match_id match_id;
883 963
884 match_id.devid = *devid; 964 match_id.devid = *devid;
885 match_id.rc = -ENODEV; 965 match_id.rc = -ENODEV;
886 local_irq_disable(); 966 for_each_subchannel(__reipl_subchannel_match, &match_id);
887 for_each_subchannel(__shutdown_subchannel_easy_and_match, &match_id);
888 if (match_id.rc == 0) 967 if (match_id.rc == 0)
889 *schid = match_id.schid; 968 *schid = match_id.schid;
890 return match_id.rc; 969 return match_id.rc;
891} 970}
892 971
893
894void clear_all_subchannels(void)
895{
896 local_irq_disable();
897 for_each_subchannel(__shutdown_subchannel_easy_and_match, NULL);
898}
899
900extern void do_reipl_asm(__u32 schid); 972extern void do_reipl_asm(__u32 schid);
901 973
902/* Make sure all subchannels are quiet before we re-ipl an lpar. */ 974/* Make sure all subchannels are quiet before we re-ipl an lpar. */
@@ -904,9 +976,9 @@ void reipl_ccw_dev(struct ccw_dev_id *devid)
904{ 976{
905 struct subchannel_id schid; 977 struct subchannel_id schid;
906 978
907 if (clear_all_subchannels_and_match(devid, &schid)) 979 s390_reset_system();
980 if (reipl_find_schid(devid, &schid) != 0)
908 panic("IPL Device not found\n"); 981 panic("IPL Device not found\n");
909 cio_reset_channel_paths();
910 do_reipl_asm(*((__u32*)&schid)); 982 do_reipl_asm(*((__u32*)&schid));
911} 983}
912 984
diff --git a/drivers/s390/cio/css.h b/drivers/s390/cio/css.h
index 4c2ff8336288..9ff064e71767 100644
--- a/drivers/s390/cio/css.h
+++ b/drivers/s390/cio/css.h
@@ -94,6 +94,7 @@ struct ccw_device_private {
94 unsigned int donotify:1; /* call notify function */ 94 unsigned int donotify:1; /* call notify function */
95 unsigned int recog_done:1; /* dev. recog. complete */ 95 unsigned int recog_done:1; /* dev. recog. complete */
96 unsigned int fake_irb:1; /* deliver faked irb */ 96 unsigned int fake_irb:1; /* deliver faked irb */
97 unsigned int intretry:1; /* retry internal operation */
97 } __attribute__((packed)) flags; 98 } __attribute__((packed)) flags;
98 unsigned long intparm; /* user interruption parameter */ 99 unsigned long intparm; /* user interruption parameter */
99 struct qdio_irq *qdio_data; 100 struct qdio_irq *qdio_data;
@@ -171,6 +172,8 @@ void device_trigger_reprobe(struct subchannel *);
171/* Helper functions for vary on/off. */ 172/* Helper functions for vary on/off. */
172int device_is_online(struct subchannel *); 173int device_is_online(struct subchannel *);
173void device_kill_io(struct subchannel *); 174void device_kill_io(struct subchannel *);
175void device_set_intretry(struct subchannel *sch);
176int device_trigger_verify(struct subchannel *sch);
174 177
175/* Machine check helper function. */ 178/* Machine check helper function. */
176void device_kill_pending_timer(struct subchannel *); 179void device_kill_pending_timer(struct subchannel *);
diff --git a/drivers/s390/cio/device.c b/drivers/s390/cio/device.c
index 39c98f940507..d3d3716ff84b 100644
--- a/drivers/s390/cio/device.c
+++ b/drivers/s390/cio/device.c
@@ -687,8 +687,20 @@ io_subchannel_register(void *data)
687 cdev = data; 687 cdev = data;
688 sch = to_subchannel(cdev->dev.parent); 688 sch = to_subchannel(cdev->dev.parent);
689 689
690 /*
691 * io_subchannel_register() will also be called after device
692 * recognition has been done for a boxed device (which will already
693 * be registered). We need to reprobe since we may now have sense id
694 * information.
695 */
690 if (klist_node_attached(&cdev->dev.knode_parent)) { 696 if (klist_node_attached(&cdev->dev.knode_parent)) {
691 bus_rescan_devices(&ccw_bus_type); 697 if (!cdev->drv) {
698 ret = device_reprobe(&cdev->dev);
699 if (ret)
700 /* We can't do much here. */
701 dev_info(&cdev->dev, "device_reprobe() returned"
702 " %d\n", ret);
703 }
692 goto out; 704 goto out;
693 } 705 }
694 /* make it known to the system */ 706 /* make it known to the system */
@@ -948,6 +960,9 @@ io_subchannel_ioterm(struct device *dev)
948 cdev = dev->driver_data; 960 cdev = dev->driver_data;
949 if (!cdev) 961 if (!cdev)
950 return; 962 return;
963 /* Internal I/O will be retried by the interrupt handler. */
964 if (cdev->private->flags.intretry)
965 return;
951 cdev->private->state = DEV_STATE_CLEAR_VERIFY; 966 cdev->private->state = DEV_STATE_CLEAR_VERIFY;
952 if (cdev->handler) 967 if (cdev->handler)
953 cdev->handler(cdev, cdev->private->intparm, 968 cdev->handler(cdev, cdev->private->intparm,
diff --git a/drivers/s390/cio/device_fsm.c b/drivers/s390/cio/device_fsm.c
index de3d0857db9f..09c7672eb3f3 100644
--- a/drivers/s390/cio/device_fsm.c
+++ b/drivers/s390/cio/device_fsm.c
@@ -59,6 +59,27 @@ device_set_disconnected(struct subchannel *sch)
59 cdev->private->state = DEV_STATE_DISCONNECTED; 59 cdev->private->state = DEV_STATE_DISCONNECTED;
60} 60}
61 61
62void device_set_intretry(struct subchannel *sch)
63{
64 struct ccw_device *cdev;
65
66 cdev = sch->dev.driver_data;
67 if (!cdev)
68 return;
69 cdev->private->flags.intretry = 1;
70}
71
72int device_trigger_verify(struct subchannel *sch)
73{
74 struct ccw_device *cdev;
75
76 cdev = sch->dev.driver_data;
77 if (!cdev || !cdev->online)
78 return -EINVAL;
79 dev_fsm_event(cdev, DEV_EVENT_VERIFY);
80 return 0;
81}
82
62/* 83/*
63 * Timeout function. It just triggers a DEV_EVENT_TIMEOUT. 84 * Timeout function. It just triggers a DEV_EVENT_TIMEOUT.
64 */ 85 */
@@ -893,6 +914,12 @@ ccw_device_w4sense(struct ccw_device *cdev, enum dev_event dev_event)
893 * had killed the original request. 914 * had killed the original request.
894 */ 915 */
895 if (irb->scsw.fctl & (SCSW_FCTL_CLEAR_FUNC | SCSW_FCTL_HALT_FUNC)) { 916 if (irb->scsw.fctl & (SCSW_FCTL_CLEAR_FUNC | SCSW_FCTL_HALT_FUNC)) {
917 /* Retry Basic Sense if requested. */
918 if (cdev->private->flags.intretry) {
919 cdev->private->flags.intretry = 0;
920 ccw_device_do_sense(cdev, irb);
921 return;
922 }
896 cdev->private->flags.dosense = 0; 923 cdev->private->flags.dosense = 0;
897 memset(&cdev->private->irb, 0, sizeof(struct irb)); 924 memset(&cdev->private->irb, 0, sizeof(struct irb));
898 ccw_device_accumulate_irb(cdev, irb); 925 ccw_device_accumulate_irb(cdev, irb);
diff --git a/drivers/s390/cio/device_id.c b/drivers/s390/cio/device_id.c
index a74785b9e4eb..f17275917fe5 100644
--- a/drivers/s390/cio/device_id.c
+++ b/drivers/s390/cio/device_id.c
@@ -191,6 +191,8 @@ __ccw_device_sense_id_start(struct ccw_device *cdev)
191 if ((sch->opm & cdev->private->imask) != 0 && 191 if ((sch->opm & cdev->private->imask) != 0 &&
192 cdev->private->iretry > 0) { 192 cdev->private->iretry > 0) {
193 cdev->private->iretry--; 193 cdev->private->iretry--;
194 /* Reset internal retry indication. */
195 cdev->private->flags.intretry = 0;
194 ret = cio_start (sch, cdev->private->iccws, 196 ret = cio_start (sch, cdev->private->iccws,
195 cdev->private->imask); 197 cdev->private->imask);
196 /* ret is 0, -EBUSY, -EACCES or -ENODEV */ 198 /* ret is 0, -EBUSY, -EACCES or -ENODEV */
@@ -237,8 +239,14 @@ ccw_device_check_sense_id(struct ccw_device *cdev)
237 return 0; /* Success */ 239 return 0; /* Success */
238 } 240 }
239 /* Check the error cases. */ 241 /* Check the error cases. */
240 if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) 242 if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
243 /* Retry Sense ID if requested. */
244 if (cdev->private->flags.intretry) {
245 cdev->private->flags.intretry = 0;
246 return -EAGAIN;
247 }
241 return -ETIME; 248 return -ETIME;
249 }
242 if (irb->esw.esw0.erw.cons && (irb->ecw[0] & SNS0_CMD_REJECT)) { 250 if (irb->esw.esw0.erw.cons && (irb->ecw[0] & SNS0_CMD_REJECT)) {
243 /* 251 /*
244 * if the device doesn't support the SenseID 252 * if the device doesn't support the SenseID
diff --git a/drivers/s390/cio/device_pgid.c b/drivers/s390/cio/device_pgid.c
index 2975ce888c19..cb1879a96818 100644
--- a/drivers/s390/cio/device_pgid.c
+++ b/drivers/s390/cio/device_pgid.c
@@ -71,6 +71,8 @@ __ccw_device_sense_pgid_start(struct ccw_device *cdev)
71 ccw->cda = (__u32) __pa (&cdev->private->pgid[i]); 71 ccw->cda = (__u32) __pa (&cdev->private->pgid[i]);
72 if (cdev->private->iretry > 0) { 72 if (cdev->private->iretry > 0) {
73 cdev->private->iretry--; 73 cdev->private->iretry--;
74 /* Reset internal retry indication. */
75 cdev->private->flags.intretry = 0;
74 ret = cio_start (sch, cdev->private->iccws, 76 ret = cio_start (sch, cdev->private->iccws,
75 cdev->private->imask); 77 cdev->private->imask);
76 /* ret is 0, -EBUSY, -EACCES or -ENODEV */ 78 /* ret is 0, -EBUSY, -EACCES or -ENODEV */
@@ -122,8 +124,14 @@ __ccw_device_check_sense_pgid(struct ccw_device *cdev)
122 124
123 sch = to_subchannel(cdev->dev.parent); 125 sch = to_subchannel(cdev->dev.parent);
124 irb = &cdev->private->irb; 126 irb = &cdev->private->irb;
125 if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) 127 if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
128 /* Retry Sense PGID if requested. */
129 if (cdev->private->flags.intretry) {
130 cdev->private->flags.intretry = 0;
131 return -EAGAIN;
132 }
126 return -ETIME; 133 return -ETIME;
134 }
127 if (irb->esw.esw0.erw.cons && 135 if (irb->esw.esw0.erw.cons &&
128 (irb->ecw[0]&(SNS0_CMD_REJECT|SNS0_INTERVENTION_REQ))) { 136 (irb->ecw[0]&(SNS0_CMD_REJECT|SNS0_INTERVENTION_REQ))) {
129 /* 137 /*
@@ -253,6 +261,8 @@ __ccw_device_do_pgid(struct ccw_device *cdev, __u8 func)
253 ret = -EACCES; 261 ret = -EACCES;
254 if (cdev->private->iretry > 0) { 262 if (cdev->private->iretry > 0) {
255 cdev->private->iretry--; 263 cdev->private->iretry--;
264 /* Reset internal retry indication. */
265 cdev->private->flags.intretry = 0;
256 ret = cio_start (sch, cdev->private->iccws, 266 ret = cio_start (sch, cdev->private->iccws,
257 cdev->private->imask); 267 cdev->private->imask);
258 /* We expect an interrupt in case of success or busy 268 /* We expect an interrupt in case of success or busy
@@ -293,6 +303,8 @@ static int __ccw_device_do_nop(struct ccw_device *cdev)
293 ret = -EACCES; 303 ret = -EACCES;
294 if (cdev->private->iretry > 0) { 304 if (cdev->private->iretry > 0) {
295 cdev->private->iretry--; 305 cdev->private->iretry--;
306 /* Reset internal retry indication. */
307 cdev->private->flags.intretry = 0;
296 ret = cio_start (sch, cdev->private->iccws, 308 ret = cio_start (sch, cdev->private->iccws,
297 cdev->private->imask); 309 cdev->private->imask);
298 /* We expect an interrupt in case of success or busy 310 /* We expect an interrupt in case of success or busy
@@ -321,8 +333,14 @@ __ccw_device_check_pgid(struct ccw_device *cdev)
321 333
322 sch = to_subchannel(cdev->dev.parent); 334 sch = to_subchannel(cdev->dev.parent);
323 irb = &cdev->private->irb; 335 irb = &cdev->private->irb;
324 if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) 336 if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
337 /* Retry Set PGID if requested. */
338 if (cdev->private->flags.intretry) {
339 cdev->private->flags.intretry = 0;
340 return -EAGAIN;
341 }
325 return -ETIME; 342 return -ETIME;
343 }
326 if (irb->esw.esw0.erw.cons) { 344 if (irb->esw.esw0.erw.cons) {
327 if (irb->ecw[0] & SNS0_CMD_REJECT) 345 if (irb->ecw[0] & SNS0_CMD_REJECT)
328 return -EOPNOTSUPP; 346 return -EOPNOTSUPP;
@@ -360,8 +378,14 @@ static int __ccw_device_check_nop(struct ccw_device *cdev)
360 378
361 sch = to_subchannel(cdev->dev.parent); 379 sch = to_subchannel(cdev->dev.parent);
362 irb = &cdev->private->irb; 380 irb = &cdev->private->irb;
363 if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) 381 if (irb->scsw.fctl & (SCSW_FCTL_HALT_FUNC | SCSW_FCTL_CLEAR_FUNC)) {
382 /* Retry NOP if requested. */
383 if (cdev->private->flags.intretry) {
384 cdev->private->flags.intretry = 0;
385 return -EAGAIN;
386 }
364 return -ETIME; 387 return -ETIME;
388 }
365 if (irb->scsw.cc == 3) { 389 if (irb->scsw.cc == 3) {
366 CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel 0.%x.%04x," 390 CIO_MSG_EVENT(2, "NOP - Device %04x on Subchannel 0.%x.%04x,"
367 " lpm %02X, became 'not operational'\n", 391 " lpm %02X, became 'not operational'\n",
diff --git a/drivers/s390/cio/device_status.c b/drivers/s390/cio/device_status.c
index 3f7cbce4cd87..bdcf930f7beb 100644
--- a/drivers/s390/cio/device_status.c
+++ b/drivers/s390/cio/device_status.c
@@ -319,6 +319,9 @@ ccw_device_do_sense(struct ccw_device *cdev, struct irb *irb)
319 sch->sense_ccw.count = SENSE_MAX_COUNT; 319 sch->sense_ccw.count = SENSE_MAX_COUNT;
320 sch->sense_ccw.flags = CCW_FLAG_SLI; 320 sch->sense_ccw.flags = CCW_FLAG_SLI;
321 321
322 /* Reset internal retry indication. */
323 cdev->private->flags.intretry = 0;
324
322 return cio_start (sch, &sch->sense_ccw, 0xff); 325 return cio_start (sch, &sch->sense_ccw, 0xff);
323} 326}
324 327
diff --git a/drivers/s390/cio/qdio.c b/drivers/s390/cio/qdio.c
index 476aa1da5cbc..8d5fa1b4d11f 100644
--- a/drivers/s390/cio/qdio.c
+++ b/drivers/s390/cio/qdio.c
@@ -481,7 +481,7 @@ qdio_stop_polling(struct qdio_q *q)
481 unsigned char state = 0; 481 unsigned char state = 0;
482 struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr; 482 struct qdio_irq *irq = (struct qdio_irq *) q->irq_ptr;
483 483
484 if (!atomic_swap(&q->polling,0)) 484 if (!atomic_xchg(&q->polling,0))
485 return 1; 485 return 1;
486 486
487 QDIO_DBF_TEXT4(0,trace,"stoppoll"); 487 QDIO_DBF_TEXT4(0,trace,"stoppoll");
@@ -1964,8 +1964,8 @@ qdio_irq_check_sense(struct subchannel_id schid, struct irb *irb)
1964 QDIO_DBF_HEX0(0,sense,irb,QDIO_DBF_SENSE_LEN); 1964 QDIO_DBF_HEX0(0,sense,irb,QDIO_DBF_SENSE_LEN);
1965 1965
1966 QDIO_PRINT_WARN("sense data available on qdio channel.\n"); 1966 QDIO_PRINT_WARN("sense data available on qdio channel.\n");
1967 HEXDUMP16(WARN,"irb: ",irb); 1967 QDIO_HEXDUMP16(WARN,"irb: ",irb);
1968 HEXDUMP16(WARN,"sense data: ",irb->ecw); 1968 QDIO_HEXDUMP16(WARN,"sense data: ",irb->ecw);
1969 } 1969 }
1970 1970
1971} 1971}
@@ -3425,7 +3425,7 @@ do_qdio_handle_inbound(struct qdio_q *q, unsigned int callflags,
3425 3425
3426 if ((used_elements+count==QDIO_MAX_BUFFERS_PER_Q)&& 3426 if ((used_elements+count==QDIO_MAX_BUFFERS_PER_Q)&&
3427 (callflags&QDIO_FLAG_UNDER_INTERRUPT)) 3427 (callflags&QDIO_FLAG_UNDER_INTERRUPT))
3428 atomic_swap(&q->polling,0); 3428 atomic_xchg(&q->polling,0);
3429 3429
3430 if (used_elements) 3430 if (used_elements)
3431 return; 3431 return;
diff --git a/drivers/s390/cio/qdio.h b/drivers/s390/cio/qdio.h
index 49bb9e371c32..42927c1b7451 100644
--- a/drivers/s390/cio/qdio.h
+++ b/drivers/s390/cio/qdio.h
@@ -236,7 +236,7 @@ enum qdio_irq_states {
236#define QDIO_PRINT_EMERG(x...) do { } while (0) 236#define QDIO_PRINT_EMERG(x...) do { } while (0)
237#endif 237#endif
238 238
239#define HEXDUMP16(importance,header,ptr) \ 239#define QDIO_HEXDUMP16(importance,header,ptr) \
240QDIO_PRINT_##importance(header "%02x %02x %02x %02x " \ 240QDIO_PRINT_##importance(header "%02x %02x %02x %02x " \
241 "%02x %02x %02x %02x %02x %02x %02x %02x " \ 241 "%02x %02x %02x %02x %02x %02x %02x %02x " \
242 "%02x %02x %02x %02x\n",*(((char*)ptr)), \ 242 "%02x %02x %02x %02x\n",*(((char*)ptr)), \
@@ -429,8 +429,6 @@ struct qdio_perf_stats {
429}; 429};
430#endif /* QDIO_PERFORMANCE_STATS */ 430#endif /* QDIO_PERFORMANCE_STATS */
431 431
432#define atomic_swap(a,b) xchg((int*)a.counter,b)
433
434/* unlikely as the later the better */ 432/* unlikely as the later the better */
435#define SYNC_MEMORY if (unlikely(q->siga_sync)) qdio_siga_sync_q(q) 433#define SYNC_MEMORY if (unlikely(q->siga_sync)) qdio_siga_sync_q(q)
436#define SYNC_MEMORY_ALL if (unlikely(q->siga_sync)) \ 434#define SYNC_MEMORY_ALL if (unlikely(q->siga_sync)) \
diff --git a/drivers/s390/crypto/ap_bus.c b/drivers/s390/crypto/ap_bus.c
index 79d89c368919..6a54334ffe09 100644
--- a/drivers/s390/crypto/ap_bus.c
+++ b/drivers/s390/crypto/ap_bus.c
@@ -431,7 +431,15 @@ static int ap_uevent (struct device *dev, char **envp, int num_envp,
431 ap_dev->device_type); 431 ap_dev->device_type);
432 if (buffer_size - length <= 0) 432 if (buffer_size - length <= 0)
433 return -ENOMEM; 433 return -ENOMEM;
434 envp[1] = 0; 434 buffer += length;
435 buffer_size -= length;
436 /* Add MODALIAS= */
437 envp[1] = buffer;
438 length = scnprintf(buffer, buffer_size, "MODALIAS=ap:t%02X",
439 ap_dev->device_type);
440 if (buffer_size - length <= 0)
441 return -ENOMEM;
442 envp[2] = NULL;
435 return 0; 443 return 0;
436} 444}
437 445
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index 66a8aec6efa6..08d4e47070bd 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -54,6 +54,8 @@
54#error Cannot compile lcs.c without some net devices switched on. 54#error Cannot compile lcs.c without some net devices switched on.
55#endif 55#endif
56 56
57#define PRINTK_HEADER " lcs: "
58
57/** 59/**
58 * initialization string for output 60 * initialization string for output
59 */ 61 */
@@ -120,7 +122,7 @@ lcs_alloc_channel(struct lcs_channel *channel)
120 kzalloc(LCS_IOBUFFERSIZE, GFP_DMA | GFP_KERNEL); 122 kzalloc(LCS_IOBUFFERSIZE, GFP_DMA | GFP_KERNEL);
121 if (channel->iob[cnt].data == NULL) 123 if (channel->iob[cnt].data == NULL)
122 break; 124 break;
123 channel->iob[cnt].state = BUF_STATE_EMPTY; 125 channel->iob[cnt].state = LCS_BUF_STATE_EMPTY;
124 } 126 }
125 if (cnt < LCS_NUM_BUFFS) { 127 if (cnt < LCS_NUM_BUFFS) {
126 /* Not all io buffers could be allocated. */ 128 /* Not all io buffers could be allocated. */
@@ -236,7 +238,7 @@ lcs_setup_read_ccws(struct lcs_card *card)
236 ((struct lcs_header *) 238 ((struct lcs_header *)
237 card->read.iob[cnt].data)->offset = LCS_ILLEGAL_OFFSET; 239 card->read.iob[cnt].data)->offset = LCS_ILLEGAL_OFFSET;
238 card->read.iob[cnt].callback = lcs_get_frames_cb; 240 card->read.iob[cnt].callback = lcs_get_frames_cb;
239 card->read.iob[cnt].state = BUF_STATE_READY; 241 card->read.iob[cnt].state = LCS_BUF_STATE_READY;
240 card->read.iob[cnt].count = LCS_IOBUFFERSIZE; 242 card->read.iob[cnt].count = LCS_IOBUFFERSIZE;
241 } 243 }
242 card->read.ccws[0].flags &= ~CCW_FLAG_PCI; 244 card->read.ccws[0].flags &= ~CCW_FLAG_PCI;
@@ -247,7 +249,7 @@ lcs_setup_read_ccws(struct lcs_card *card)
247 card->read.ccws[LCS_NUM_BUFFS].cda = 249 card->read.ccws[LCS_NUM_BUFFS].cda =
248 (__u32) __pa(card->read.ccws); 250 (__u32) __pa(card->read.ccws);
249 /* Setg initial state of the read channel. */ 251 /* Setg initial state of the read channel. */
250 card->read.state = CH_STATE_INIT; 252 card->read.state = LCS_CH_STATE_INIT;
251 253
252 card->read.io_idx = 0; 254 card->read.io_idx = 0;
253 card->read.buf_idx = 0; 255 card->read.buf_idx = 0;
@@ -294,7 +296,7 @@ lcs_setup_write_ccws(struct lcs_card *card)
294 card->write.ccws[LCS_NUM_BUFFS].cda = 296 card->write.ccws[LCS_NUM_BUFFS].cda =
295 (__u32) __pa(card->write.ccws); 297 (__u32) __pa(card->write.ccws);
296 /* Set initial state of the write channel. */ 298 /* Set initial state of the write channel. */
297 card->read.state = CH_STATE_INIT; 299 card->read.state = LCS_CH_STATE_INIT;
298 300
299 card->write.io_idx = 0; 301 card->write.io_idx = 0;
300 card->write.buf_idx = 0; 302 card->write.buf_idx = 0;
@@ -496,7 +498,7 @@ lcs_start_channel(struct lcs_channel *channel)
496 channel->ccws + channel->io_idx, 0, 0, 498 channel->ccws + channel->io_idx, 0, 0,
497 DOIO_DENY_PREFETCH | DOIO_ALLOW_SUSPEND); 499 DOIO_DENY_PREFETCH | DOIO_ALLOW_SUSPEND);
498 if (rc == 0) 500 if (rc == 0)
499 channel->state = CH_STATE_RUNNING; 501 channel->state = LCS_CH_STATE_RUNNING;
500 spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); 502 spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
501 if (rc) { 503 if (rc) {
502 LCS_DBF_TEXT_(4,trace,"essh%s", channel->ccwdev->dev.bus_id); 504 LCS_DBF_TEXT_(4,trace,"essh%s", channel->ccwdev->dev.bus_id);
@@ -520,8 +522,8 @@ lcs_clear_channel(struct lcs_channel *channel)
520 LCS_DBF_TEXT_(4,trace,"ecsc%s", channel->ccwdev->dev.bus_id); 522 LCS_DBF_TEXT_(4,trace,"ecsc%s", channel->ccwdev->dev.bus_id);
521 return rc; 523 return rc;
522 } 524 }
523 wait_event(channel->wait_q, (channel->state == CH_STATE_CLEARED)); 525 wait_event(channel->wait_q, (channel->state == LCS_CH_STATE_CLEARED));
524 channel->state = CH_STATE_STOPPED; 526 channel->state = LCS_CH_STATE_STOPPED;
525 return rc; 527 return rc;
526} 528}
527 529
@@ -535,11 +537,11 @@ lcs_stop_channel(struct lcs_channel *channel)
535 unsigned long flags; 537 unsigned long flags;
536 int rc; 538 int rc;
537 539
538 if (channel->state == CH_STATE_STOPPED) 540 if (channel->state == LCS_CH_STATE_STOPPED)
539 return 0; 541 return 0;
540 LCS_DBF_TEXT(4,trace,"haltsch"); 542 LCS_DBF_TEXT(4,trace,"haltsch");
541 LCS_DBF_TEXT_(4,trace,"%s", channel->ccwdev->dev.bus_id); 543 LCS_DBF_TEXT_(4,trace,"%s", channel->ccwdev->dev.bus_id);
542 channel->state = CH_STATE_INIT; 544 channel->state = LCS_CH_STATE_INIT;
543 spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); 545 spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
544 rc = ccw_device_halt(channel->ccwdev, (addr_t) channel); 546 rc = ccw_device_halt(channel->ccwdev, (addr_t) channel);
545 spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); 547 spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
@@ -548,7 +550,7 @@ lcs_stop_channel(struct lcs_channel *channel)
548 return rc; 550 return rc;
549 } 551 }
550 /* Asynchronous halt initialted. Wait for its completion. */ 552 /* Asynchronous halt initialted. Wait for its completion. */
551 wait_event(channel->wait_q, (channel->state == CH_STATE_HALTED)); 553 wait_event(channel->wait_q, (channel->state == LCS_CH_STATE_HALTED));
552 lcs_clear_channel(channel); 554 lcs_clear_channel(channel);
553 return 0; 555 return 0;
554} 556}
@@ -596,8 +598,8 @@ __lcs_get_buffer(struct lcs_channel *channel)
596 LCS_DBF_TEXT(5, trace, "_getbuff"); 598 LCS_DBF_TEXT(5, trace, "_getbuff");
597 index = channel->io_idx; 599 index = channel->io_idx;
598 do { 600 do {
599 if (channel->iob[index].state == BUF_STATE_EMPTY) { 601 if (channel->iob[index].state == LCS_BUF_STATE_EMPTY) {
600 channel->iob[index].state = BUF_STATE_LOCKED; 602 channel->iob[index].state = LCS_BUF_STATE_LOCKED;
601 return channel->iob + index; 603 return channel->iob + index;
602 } 604 }
603 index = (index + 1) & (LCS_NUM_BUFFS - 1); 605 index = (index + 1) & (LCS_NUM_BUFFS - 1);
@@ -626,7 +628,7 @@ __lcs_resume_channel(struct lcs_channel *channel)
626{ 628{
627 int rc; 629 int rc;
628 630
629 if (channel->state != CH_STATE_SUSPENDED) 631 if (channel->state != LCS_CH_STATE_SUSPENDED)
630 return 0; 632 return 0;
631 if (channel->ccws[channel->io_idx].flags & CCW_FLAG_SUSPEND) 633 if (channel->ccws[channel->io_idx].flags & CCW_FLAG_SUSPEND)
632 return 0; 634 return 0;
@@ -636,7 +638,7 @@ __lcs_resume_channel(struct lcs_channel *channel)
636 LCS_DBF_TEXT_(4, trace, "ersc%s", channel->ccwdev->dev.bus_id); 638 LCS_DBF_TEXT_(4, trace, "ersc%s", channel->ccwdev->dev.bus_id);
637 PRINT_ERR("Error in lcs_resume_channel: rc=%d\n",rc); 639 PRINT_ERR("Error in lcs_resume_channel: rc=%d\n",rc);
638 } else 640 } else
639 channel->state = CH_STATE_RUNNING; 641 channel->state = LCS_CH_STATE_RUNNING;
640 return rc; 642 return rc;
641 643
642} 644}
@@ -670,10 +672,10 @@ lcs_ready_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer)
670 int index, rc; 672 int index, rc;
671 673
672 LCS_DBF_TEXT(5, trace, "rdybuff"); 674 LCS_DBF_TEXT(5, trace, "rdybuff");
673 BUG_ON(buffer->state != BUF_STATE_LOCKED && 675 BUG_ON(buffer->state != LCS_BUF_STATE_LOCKED &&
674 buffer->state != BUF_STATE_PROCESSED); 676 buffer->state != LCS_BUF_STATE_PROCESSED);
675 spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); 677 spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
676 buffer->state = BUF_STATE_READY; 678 buffer->state = LCS_BUF_STATE_READY;
677 index = buffer - channel->iob; 679 index = buffer - channel->iob;
678 /* Set length. */ 680 /* Set length. */
679 channel->ccws[index].count = buffer->count; 681 channel->ccws[index].count = buffer->count;
@@ -695,8 +697,8 @@ __lcs_processed_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer)
695 int index, prev, next; 697 int index, prev, next;
696 698
697 LCS_DBF_TEXT(5, trace, "prcsbuff"); 699 LCS_DBF_TEXT(5, trace, "prcsbuff");
698 BUG_ON(buffer->state != BUF_STATE_READY); 700 BUG_ON(buffer->state != LCS_BUF_STATE_READY);
699 buffer->state = BUF_STATE_PROCESSED; 701 buffer->state = LCS_BUF_STATE_PROCESSED;
700 index = buffer - channel->iob; 702 index = buffer - channel->iob;
701 prev = (index - 1) & (LCS_NUM_BUFFS - 1); 703 prev = (index - 1) & (LCS_NUM_BUFFS - 1);
702 next = (index + 1) & (LCS_NUM_BUFFS - 1); 704 next = (index + 1) & (LCS_NUM_BUFFS - 1);
@@ -704,7 +706,7 @@ __lcs_processed_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer)
704 channel->ccws[index].flags |= CCW_FLAG_SUSPEND; 706 channel->ccws[index].flags |= CCW_FLAG_SUSPEND;
705 channel->ccws[index].flags &= ~CCW_FLAG_PCI; 707 channel->ccws[index].flags &= ~CCW_FLAG_PCI;
706 /* Check the suspend bit of the previous buffer. */ 708 /* Check the suspend bit of the previous buffer. */
707 if (channel->iob[prev].state == BUF_STATE_READY) { 709 if (channel->iob[prev].state == LCS_BUF_STATE_READY) {
708 /* 710 /*
709 * Previous buffer is in state ready. It might have 711 * Previous buffer is in state ready. It might have
710 * happened in lcs_ready_buffer that the suspend bit 712 * happened in lcs_ready_buffer that the suspend bit
@@ -727,10 +729,10 @@ lcs_release_buffer(struct lcs_channel *channel, struct lcs_buffer *buffer)
727 unsigned long flags; 729 unsigned long flags;
728 730
729 LCS_DBF_TEXT(5, trace, "relbuff"); 731 LCS_DBF_TEXT(5, trace, "relbuff");
730 BUG_ON(buffer->state != BUF_STATE_LOCKED && 732 BUG_ON(buffer->state != LCS_BUF_STATE_LOCKED &&
731 buffer->state != BUF_STATE_PROCESSED); 733 buffer->state != LCS_BUF_STATE_PROCESSED);
732 spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); 734 spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
733 buffer->state = BUF_STATE_EMPTY; 735 buffer->state = LCS_BUF_STATE_EMPTY;
734 spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags); 736 spin_unlock_irqrestore(get_ccwdev_lock(channel->ccwdev), flags);
735} 737}
736 738
@@ -1264,7 +1266,7 @@ lcs_register_mc_addresses(void *data)
1264 netif_carrier_off(card->dev); 1266 netif_carrier_off(card->dev);
1265 netif_tx_disable(card->dev); 1267 netif_tx_disable(card->dev);
1266 wait_event(card->write.wait_q, 1268 wait_event(card->write.wait_q,
1267 (card->write.state != CH_STATE_RUNNING)); 1269 (card->write.state != LCS_CH_STATE_RUNNING));
1268 lcs_fix_multicast_list(card); 1270 lcs_fix_multicast_list(card);
1269 if (card->state == DEV_STATE_UP) { 1271 if (card->state == DEV_STATE_UP) {
1270 netif_carrier_on(card->dev); 1272 netif_carrier_on(card->dev);
@@ -1404,7 +1406,7 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
1404 } 1406 }
1405 } 1407 }
1406 /* How far in the ccw chain have we processed? */ 1408 /* How far in the ccw chain have we processed? */
1407 if ((channel->state != CH_STATE_INIT) && 1409 if ((channel->state != LCS_CH_STATE_INIT) &&
1408 (irb->scsw.fctl & SCSW_FCTL_START_FUNC)) { 1410 (irb->scsw.fctl & SCSW_FCTL_START_FUNC)) {
1409 index = (struct ccw1 *) __va((addr_t) irb->scsw.cpa) 1411 index = (struct ccw1 *) __va((addr_t) irb->scsw.cpa)
1410 - channel->ccws; 1412 - channel->ccws;
@@ -1424,20 +1426,20 @@ lcs_irq(struct ccw_device *cdev, unsigned long intparm, struct irb *irb)
1424 (irb->scsw.dstat & DEV_STAT_CHN_END) || 1426 (irb->scsw.dstat & DEV_STAT_CHN_END) ||
1425 (irb->scsw.dstat & DEV_STAT_UNIT_CHECK)) 1427 (irb->scsw.dstat & DEV_STAT_UNIT_CHECK))
1426 /* Mark channel as stopped. */ 1428 /* Mark channel as stopped. */
1427 channel->state = CH_STATE_STOPPED; 1429 channel->state = LCS_CH_STATE_STOPPED;
1428 else if (irb->scsw.actl & SCSW_ACTL_SUSPENDED) 1430 else if (irb->scsw.actl & SCSW_ACTL_SUSPENDED)
1429 /* CCW execution stopped on a suspend bit. */ 1431 /* CCW execution stopped on a suspend bit. */
1430 channel->state = CH_STATE_SUSPENDED; 1432 channel->state = LCS_CH_STATE_SUSPENDED;
1431 if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC) { 1433 if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC) {
1432 if (irb->scsw.cc != 0) { 1434 if (irb->scsw.cc != 0) {
1433 ccw_device_halt(channel->ccwdev, (addr_t) channel); 1435 ccw_device_halt(channel->ccwdev, (addr_t) channel);
1434 return; 1436 return;
1435 } 1437 }
1436 /* The channel has been stopped by halt_IO. */ 1438 /* The channel has been stopped by halt_IO. */
1437 channel->state = CH_STATE_HALTED; 1439 channel->state = LCS_CH_STATE_HALTED;
1438 } 1440 }
1439 if (irb->scsw.fctl & SCSW_FCTL_CLEAR_FUNC) { 1441 if (irb->scsw.fctl & SCSW_FCTL_CLEAR_FUNC) {
1440 channel->state = CH_STATE_CLEARED; 1442 channel->state = LCS_CH_STATE_CLEARED;
1441 } 1443 }
1442 /* Do the rest in the tasklet. */ 1444 /* Do the rest in the tasklet. */
1443 tasklet_schedule(&channel->irq_tasklet); 1445 tasklet_schedule(&channel->irq_tasklet);
@@ -1461,7 +1463,7 @@ lcs_tasklet(unsigned long data)
1461 /* Check for processed buffers. */ 1463 /* Check for processed buffers. */
1462 iob = channel->iob; 1464 iob = channel->iob;
1463 buf_idx = channel->buf_idx; 1465 buf_idx = channel->buf_idx;
1464 while (iob[buf_idx].state == BUF_STATE_PROCESSED) { 1466 while (iob[buf_idx].state == LCS_BUF_STATE_PROCESSED) {
1465 /* Do the callback thing. */ 1467 /* Do the callback thing. */
1466 if (iob[buf_idx].callback != NULL) 1468 if (iob[buf_idx].callback != NULL)
1467 iob[buf_idx].callback(channel, iob + buf_idx); 1469 iob[buf_idx].callback(channel, iob + buf_idx);
@@ -1469,12 +1471,12 @@ lcs_tasklet(unsigned long data)
1469 } 1471 }
1470 channel->buf_idx = buf_idx; 1472 channel->buf_idx = buf_idx;
1471 1473
1472 if (channel->state == CH_STATE_STOPPED) 1474 if (channel->state == LCS_CH_STATE_STOPPED)
1473 // FIXME: what if rc != 0 ?? 1475 // FIXME: what if rc != 0 ??
1474 rc = lcs_start_channel(channel); 1476 rc = lcs_start_channel(channel);
1475 spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags); 1477 spin_lock_irqsave(get_ccwdev_lock(channel->ccwdev), flags);
1476 if (channel->state == CH_STATE_SUSPENDED && 1478 if (channel->state == LCS_CH_STATE_SUSPENDED &&
1477 channel->iob[channel->io_idx].state == BUF_STATE_READY) { 1479 channel->iob[channel->io_idx].state == LCS_BUF_STATE_READY) {
1478 // FIXME: what if rc != 0 ?? 1480 // FIXME: what if rc != 0 ??
1479 rc = __lcs_resume_channel(channel); 1481 rc = __lcs_resume_channel(channel);
1480 } 1482 }
@@ -1689,8 +1691,8 @@ lcs_detect(struct lcs_card *card)
1689 card->state = DEV_STATE_UP; 1691 card->state = DEV_STATE_UP;
1690 } else { 1692 } else {
1691 card->state = DEV_STATE_DOWN; 1693 card->state = DEV_STATE_DOWN;
1692 card->write.state = CH_STATE_INIT; 1694 card->write.state = LCS_CH_STATE_INIT;
1693 card->read.state = CH_STATE_INIT; 1695 card->read.state = LCS_CH_STATE_INIT;
1694 } 1696 }
1695 return rc; 1697 return rc;
1696} 1698}
@@ -1705,8 +1707,8 @@ lcs_stopcard(struct lcs_card *card)
1705 1707
1706 LCS_DBF_TEXT(3, setup, "stopcard"); 1708 LCS_DBF_TEXT(3, setup, "stopcard");
1707 1709
1708 if (card->read.state != CH_STATE_STOPPED && 1710 if (card->read.state != LCS_CH_STATE_STOPPED &&
1709 card->write.state != CH_STATE_STOPPED && 1711 card->write.state != LCS_CH_STATE_STOPPED &&
1710 card->state == DEV_STATE_UP) { 1712 card->state == DEV_STATE_UP) {
1711 lcs_clear_multicast_list(card); 1713 lcs_clear_multicast_list(card);
1712 rc = lcs_send_stoplan(card,LCS_INITIATOR_TCPIP); 1714 rc = lcs_send_stoplan(card,LCS_INITIATOR_TCPIP);
@@ -1871,7 +1873,7 @@ lcs_stop_device(struct net_device *dev)
1871 netif_tx_disable(dev); 1873 netif_tx_disable(dev);
1872 dev->flags &= ~IFF_UP; 1874 dev->flags &= ~IFF_UP;
1873 wait_event(card->write.wait_q, 1875 wait_event(card->write.wait_q,
1874 (card->write.state != CH_STATE_RUNNING)); 1876 (card->write.state != LCS_CH_STATE_RUNNING));
1875 rc = lcs_stopcard(card); 1877 rc = lcs_stopcard(card);
1876 if (rc) 1878 if (rc)
1877 PRINT_ERR("Try it again!\n "); 1879 PRINT_ERR("Try it again!\n ");
diff --git a/drivers/s390/net/lcs.h b/drivers/s390/net/lcs.h
index b5247dc08b57..0e1e4a0a88f0 100644
--- a/drivers/s390/net/lcs.h
+++ b/drivers/s390/net/lcs.h
@@ -23,11 +23,6 @@ do { \
23} while (0) 23} while (0)
24 24
25/** 25/**
26 * some more definitions for debug or output stuff
27 */
28#define PRINTK_HEADER " lcs: "
29
30/**
31 * sysfs related stuff 26 * sysfs related stuff
32 */ 27 */
33#define CARD_FROM_DEV(cdev) \ 28#define CARD_FROM_DEV(cdev) \
@@ -127,22 +122,22 @@ do { \
127 * LCS Buffer states 122 * LCS Buffer states
128 */ 123 */
129enum lcs_buffer_states { 124enum lcs_buffer_states {
130 BUF_STATE_EMPTY, /* buffer is empty */ 125 LCS_BUF_STATE_EMPTY, /* buffer is empty */
131 BUF_STATE_LOCKED, /* buffer is locked, don't touch */ 126 LCS_BUF_STATE_LOCKED, /* buffer is locked, don't touch */
132 BUF_STATE_READY, /* buffer is ready for read/write */ 127 LCS_BUF_STATE_READY, /* buffer is ready for read/write */
133 BUF_STATE_PROCESSED, 128 LCS_BUF_STATE_PROCESSED,
134}; 129};
135 130
136/** 131/**
137 * LCS Channel State Machine declarations 132 * LCS Channel State Machine declarations
138 */ 133 */
139enum lcs_channel_states { 134enum lcs_channel_states {
140 CH_STATE_INIT, 135 LCS_CH_STATE_INIT,
141 CH_STATE_HALTED, 136 LCS_CH_STATE_HALTED,
142 CH_STATE_STOPPED, 137 LCS_CH_STATE_STOPPED,
143 CH_STATE_RUNNING, 138 LCS_CH_STATE_RUNNING,
144 CH_STATE_SUSPENDED, 139 LCS_CH_STATE_SUSPENDED,
145 CH_STATE_CLEARED, 140 LCS_CH_STATE_CLEARED,
146}; 141};
147 142
148/** 143/**
diff --git a/drivers/s390/net/qeth.h b/drivers/s390/net/qeth.h
index 821383d8cbe7..53c358c7d368 100644
--- a/drivers/s390/net/qeth.h
+++ b/drivers/s390/net/qeth.h
@@ -151,8 +151,6 @@ qeth_hex_dump(unsigned char *buf, size_t len)
151#define SENSE_RESETTING_EVENT_BYTE 1 151#define SENSE_RESETTING_EVENT_BYTE 1
152#define SENSE_RESETTING_EVENT_FLAG 0x80 152#define SENSE_RESETTING_EVENT_FLAG 0x80
153 153
154#define atomic_swap(a,b) xchg((int *)a.counter, b)
155
156/* 154/*
157 * Common IO related definitions 155 * Common IO related definitions
158 */ 156 */
diff --git a/drivers/s390/net/qeth_main.c b/drivers/s390/net/qeth_main.c
index 8364d5475ac7..7fdc5272c446 100644
--- a/drivers/s390/net/qeth_main.c
+++ b/drivers/s390/net/qeth_main.c
@@ -2982,7 +2982,7 @@ qeth_check_outbound_queue(struct qeth_qdio_out_q *queue)
2982 */ 2982 */
2983 if ((atomic_read(&queue->used_buffers) <= QETH_LOW_WATERMARK_PACK) || 2983 if ((atomic_read(&queue->used_buffers) <= QETH_LOW_WATERMARK_PACK) ||
2984 !atomic_read(&queue->set_pci_flags_count)){ 2984 !atomic_read(&queue->set_pci_flags_count)){
2985 if (atomic_swap(&queue->state, QETH_OUT_Q_LOCKED_FLUSH) == 2985 if (atomic_xchg(&queue->state, QETH_OUT_Q_LOCKED_FLUSH) ==
2986 QETH_OUT_Q_UNLOCKED) { 2986 QETH_OUT_Q_UNLOCKED) {
2987 /* 2987 /*
2988 * If we get in here, there was no action in 2988 * If we get in here, there was no action in
@@ -3245,7 +3245,7 @@ qeth_free_qdio_buffers(struct qeth_card *card)
3245 int i, j; 3245 int i, j;
3246 3246
3247 QETH_DBF_TEXT(trace, 2, "freeqdbf"); 3247 QETH_DBF_TEXT(trace, 2, "freeqdbf");
3248 if (atomic_swap(&card->qdio.state, QETH_QDIO_UNINITIALIZED) == 3248 if (atomic_xchg(&card->qdio.state, QETH_QDIO_UNINITIALIZED) ==
3249 QETH_QDIO_UNINITIALIZED) 3249 QETH_QDIO_UNINITIALIZED)
3250 return; 3250 return;
3251 kfree(card->qdio.in_q); 3251 kfree(card->qdio.in_q);
@@ -4366,7 +4366,7 @@ out:
4366 if (flush_count) 4366 if (flush_count)
4367 qeth_flush_buffers(queue, 0, start_index, flush_count); 4367 qeth_flush_buffers(queue, 0, start_index, flush_count);
4368 else if (!atomic_read(&queue->set_pci_flags_count)) 4368 else if (!atomic_read(&queue->set_pci_flags_count))
4369 atomic_swap(&queue->state, QETH_OUT_Q_LOCKED_FLUSH); 4369 atomic_xchg(&queue->state, QETH_OUT_Q_LOCKED_FLUSH);
4370 /* 4370 /*
4371 * queue->state will go from LOCKED -> UNLOCKED or from 4371 * queue->state will go from LOCKED -> UNLOCKED or from
4372 * LOCKED_FLUSH -> LOCKED if output_handler wanted to 'notify' us 4372 * LOCKED_FLUSH -> LOCKED if output_handler wanted to 'notify' us
diff --git a/drivers/scsi/scsi_transport_sas.c b/drivers/scsi/scsi_transport_sas.c
index b5b0c2cba96b..5c0b75bbfa10 100644
--- a/drivers/scsi/scsi_transport_sas.c
+++ b/drivers/scsi/scsi_transport_sas.c
@@ -25,6 +25,7 @@
25 25
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/jiffies.h>
28#include <linux/err.h> 29#include <linux/err.h>
29#include <linux/slab.h> 30#include <linux/slab.h>
30#include <linux/string.h> 31#include <linux/string.h>
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
index b691d3e14754..787a8f134677 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -282,7 +282,7 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo)
282} 282}
283 283
284/* Setup any dynamic params in the uart desc */ 284/* Setup any dynamic params in the uart desc */
285int cpm_uart_init_portdesc(void) 285int __init cpm_uart_init_portdesc(void)
286{ 286{
287#if defined(CONFIG_SERIAL_CPM_SMC1) || defined(CONFIG_SERIAL_CPM_SMC2) 287#if defined(CONFIG_SERIAL_CPM_SMC1) || defined(CONFIG_SERIAL_CPM_SMC2)
288 u32 addr; 288 u32 addr;
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 4f80c5b4a753..6dd579ed9777 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -1,6 +1,4 @@
1/* 1/*
2 * drivers/serial/mpc52xx_uart.c
3 *
4 * Driver for the PSC of the Freescale MPC52xx PSCs configured as UARTs. 2 * Driver for the PSC of the Freescale MPC52xx PSCs configured as UARTs.
5 * 3 *
6 * FIXME According to the usermanual the status bits in the status register 4 * FIXME According to the usermanual the status bits in the status register
@@ -14,18 +12,20 @@
14 * 12 *
15 * 13 *
16 * Maintainer : Sylvain Munaut <tnt@246tNt.com> 14 * Maintainer : Sylvain Munaut <tnt@246tNt.com>
17 * 15 *
18 * Some of the code has been inspired/copied from the 2.4 code written 16 * Some of the code has been inspired/copied from the 2.4 code written
19 * by Dale Farnsworth <dfarnsworth@mvista.com>. 17 * by Dale Farnsworth <dfarnsworth@mvista.com>.
20 * 18 *
21 * Copyright (C) 2004-2005 Sylvain Munaut <tnt@246tNt.com> 19 * Copyright (C) 2006 Secret Lab Technologies Ltd.
20 * Grant Likely <grant.likely@secretlab.ca>
21 * Copyright (C) 2004-2006 Sylvain Munaut <tnt@246tNt.com>
22 * Copyright (C) 2003 MontaVista, Software, Inc. 22 * Copyright (C) 2003 MontaVista, Software, Inc.
23 * 23 *
24 * This file is licensed under the terms of the GNU General Public License 24 * This file is licensed under the terms of the GNU General Public License
25 * version 2. This program is licensed "as is" without any warranty of any 25 * version 2. This program is licensed "as is" without any warranty of any
26 * kind, whether express or implied. 26 * kind, whether express or implied.
27 */ 27 */
28 28
29/* Platform device Usage : 29/* Platform device Usage :
30 * 30 *
31 * Since PSCs can have multiple function, the correct driver for each one 31 * Since PSCs can have multiple function, the correct driver for each one
@@ -44,7 +44,24 @@
44 * will be mapped to. 44 * will be mapped to.
45 */ 45 */
46 46
47#include <linux/platform_device.h> 47/* OF Platform device Usage :
48 *
49 * This driver is only used for PSCs configured in uart mode. The device
50 * tree will have a node for each PSC in uart mode w/ device_type = "serial"
51 * and "mpc52xx-psc-uart" in the compatible string
52 *
53 * By default, PSC devices are enumerated in the order they are found. However
54 * a particular PSC number can be forces by adding 'device_no = <port#>'
55 * to the device node.
56 *
57 * The driver init all necessary registers to place the PSC in uart mode without
58 * DCD. However, the pin multiplexing aren't changed and should be set either
59 * by the bootloader or in the platform init code.
60 */
61
62#undef DEBUG
63
64#include <linux/device.h>
48#include <linux/module.h> 65#include <linux/module.h>
49#include <linux/tty.h> 66#include <linux/tty.h>
50#include <linux/serial.h> 67#include <linux/serial.h>
@@ -54,6 +71,12 @@
54#include <asm/delay.h> 71#include <asm/delay.h>
55#include <asm/io.h> 72#include <asm/io.h>
56 73
74#if defined(CONFIG_PPC_MERGE)
75#include <asm/of_platform.h>
76#else
77#include <linux/platform_device.h>
78#endif
79
57#include <asm/mpc52xx.h> 80#include <asm/mpc52xx.h>
58#include <asm/mpc52xx_psc.h> 81#include <asm/mpc52xx_psc.h>
59 82
@@ -80,6 +103,12 @@ static struct uart_port mpc52xx_uart_ports[MPC52xx_PSC_MAXNUM];
80 * it's cleared, then a memset(...,0,...) should be added to 103 * it's cleared, then a memset(...,0,...) should be added to
81 * the console_init 104 * the console_init
82 */ 105 */
106#if defined(CONFIG_PPC_MERGE)
107/* lookup table for matching device nodes to index numbers */
108static struct device_node *mpc52xx_uart_nodes[MPC52xx_PSC_MAXNUM];
109
110static void mpc52xx_uart_of_enumerate(void);
111#endif
83 112
84#define PSC(port) ((struct mpc52xx_psc __iomem *)((port)->membase)) 113#define PSC(port) ((struct mpc52xx_psc __iomem *)((port)->membase))
85 114
@@ -96,32 +125,40 @@ static irqreturn_t mpc52xx_uart_int(int irq,void *dev_id);
96#define uart_console(port) (0) 125#define uart_console(port) (0)
97#endif 126#endif
98 127
128#if defined(CONFIG_PPC_MERGE)
129static struct of_device_id mpc52xx_uart_of_match[] = {
130 { .type = "serial", .compatible = "mpc52xx-psc-uart", },
131 { .type = "serial", .compatible = "mpc5200-psc", }, /* Efika only! */
132 {},
133};
134#endif
135
99 136
100/* ======================================================================== */ 137/* ======================================================================== */
101/* UART operations */ 138/* UART operations */
102/* ======================================================================== */ 139/* ======================================================================== */
103 140
104static unsigned int 141static unsigned int
105mpc52xx_uart_tx_empty(struct uart_port *port) 142mpc52xx_uart_tx_empty(struct uart_port *port)
106{ 143{
107 int status = in_be16(&PSC(port)->mpc52xx_psc_status); 144 int status = in_be16(&PSC(port)->mpc52xx_psc_status);
108 return (status & MPC52xx_PSC_SR_TXEMP) ? TIOCSER_TEMT : 0; 145 return (status & MPC52xx_PSC_SR_TXEMP) ? TIOCSER_TEMT : 0;
109} 146}
110 147
111static void 148static void
112mpc52xx_uart_set_mctrl(struct uart_port *port, unsigned int mctrl) 149mpc52xx_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
113{ 150{
114 /* Not implemented */ 151 /* Not implemented */
115} 152}
116 153
117static unsigned int 154static unsigned int
118mpc52xx_uart_get_mctrl(struct uart_port *port) 155mpc52xx_uart_get_mctrl(struct uart_port *port)
119{ 156{
120 /* Not implemented */ 157 /* Not implemented */
121 return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR; 158 return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
122} 159}
123 160
124static void 161static void
125mpc52xx_uart_stop_tx(struct uart_port *port) 162mpc52xx_uart_stop_tx(struct uart_port *port)
126{ 163{
127 /* port->lock taken by caller */ 164 /* port->lock taken by caller */
@@ -129,7 +166,7 @@ mpc52xx_uart_stop_tx(struct uart_port *port)
129 out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask); 166 out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask);
130} 167}
131 168
132static void 169static void
133mpc52xx_uart_start_tx(struct uart_port *port) 170mpc52xx_uart_start_tx(struct uart_port *port)
134{ 171{
135 /* port->lock taken by caller */ 172 /* port->lock taken by caller */
@@ -137,12 +174,12 @@ mpc52xx_uart_start_tx(struct uart_port *port)
137 out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask); 174 out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask);
138} 175}
139 176
140static void 177static void
141mpc52xx_uart_send_xchar(struct uart_port *port, char ch) 178mpc52xx_uart_send_xchar(struct uart_port *port, char ch)
142{ 179{
143 unsigned long flags; 180 unsigned long flags;
144 spin_lock_irqsave(&port->lock, flags); 181 spin_lock_irqsave(&port->lock, flags);
145 182
146 port->x_char = ch; 183 port->x_char = ch;
147 if (ch) { 184 if (ch) {
148 /* Make sure tx interrupts are on */ 185 /* Make sure tx interrupts are on */
@@ -150,7 +187,7 @@ mpc52xx_uart_send_xchar(struct uart_port *port, char ch)
150 port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY; 187 port->read_status_mask |= MPC52xx_PSC_IMR_TXRDY;
151 out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask); 188 out_be16(&PSC(port)->mpc52xx_psc_imr,port->read_status_mask);
152 } 189 }
153 190
154 spin_unlock_irqrestore(&port->lock, flags); 191 spin_unlock_irqrestore(&port->lock, flags);
155} 192}
156 193
@@ -178,7 +215,7 @@ mpc52xx_uart_break_ctl(struct uart_port *port, int ctl)
178 out_8(&PSC(port)->command,MPC52xx_PSC_START_BRK); 215 out_8(&PSC(port)->command,MPC52xx_PSC_START_BRK);
179 else 216 else
180 out_8(&PSC(port)->command,MPC52xx_PSC_STOP_BRK); 217 out_8(&PSC(port)->command,MPC52xx_PSC_STOP_BRK);
181 218
182 spin_unlock_irqrestore(&port->lock, flags); 219 spin_unlock_irqrestore(&port->lock, flags);
183} 220}
184 221
@@ -197,11 +234,11 @@ mpc52xx_uart_startup(struct uart_port *port)
197 /* Reset/activate the port, clear and enable interrupts */ 234 /* Reset/activate the port, clear and enable interrupts */
198 out_8(&psc->command,MPC52xx_PSC_RST_RX); 235 out_8(&psc->command,MPC52xx_PSC_RST_RX);
199 out_8(&psc->command,MPC52xx_PSC_RST_TX); 236 out_8(&psc->command,MPC52xx_PSC_RST_TX);
200 237
201 out_be32(&psc->sicr,0); /* UART mode DCD ignored */ 238 out_be32(&psc->sicr,0); /* UART mode DCD ignored */
202 239
203 out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /16 prescaler on */ 240 out_be16(&psc->mpc52xx_psc_clock_select, 0xdd00); /* /16 prescaler on */
204 241
205 out_8(&psc->rfcntl, 0x00); 242 out_8(&psc->rfcntl, 0x00);
206 out_be16(&psc->rfalarm, 0x1ff); 243 out_be16(&psc->rfalarm, 0x1ff);
207 out_8(&psc->tfcntl, 0x07); 244 out_8(&psc->tfcntl, 0x07);
@@ -209,10 +246,10 @@ mpc52xx_uart_startup(struct uart_port *port)
209 246
210 port->read_status_mask |= MPC52xx_PSC_IMR_RXRDY | MPC52xx_PSC_IMR_TXRDY; 247 port->read_status_mask |= MPC52xx_PSC_IMR_RXRDY | MPC52xx_PSC_IMR_TXRDY;
211 out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask); 248 out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask);
212 249
213 out_8(&psc->command,MPC52xx_PSC_TX_ENABLE); 250 out_8(&psc->command,MPC52xx_PSC_TX_ENABLE);
214 out_8(&psc->command,MPC52xx_PSC_RX_ENABLE); 251 out_8(&psc->command,MPC52xx_PSC_RX_ENABLE);
215 252
216 return 0; 253 return 0;
217} 254}
218 255
@@ -220,19 +257,19 @@ static void
220mpc52xx_uart_shutdown(struct uart_port *port) 257mpc52xx_uart_shutdown(struct uart_port *port)
221{ 258{
222 struct mpc52xx_psc __iomem *psc = PSC(port); 259 struct mpc52xx_psc __iomem *psc = PSC(port);
223 260
224 /* Shut down the port, interrupt and all */ 261 /* Shut down the port, interrupt and all */
225 out_8(&psc->command,MPC52xx_PSC_RST_RX); 262 out_8(&psc->command,MPC52xx_PSC_RST_RX);
226 out_8(&psc->command,MPC52xx_PSC_RST_TX); 263 out_8(&psc->command,MPC52xx_PSC_RST_TX);
227 264
228 port->read_status_mask = 0; 265 port->read_status_mask = 0;
229 out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask); 266 out_be16(&psc->mpc52xx_psc_imr,port->read_status_mask);
230 267
231 /* Release interrupt */ 268 /* Release interrupt */
232 free_irq(port->irq, port); 269 free_irq(port->irq, port);
233} 270}
234 271
235static void 272static void
236mpc52xx_uart_set_termios(struct uart_port *port, struct termios *new, 273mpc52xx_uart_set_termios(struct uart_port *port, struct termios *new,
237 struct termios *old) 274 struct termios *old)
238{ 275{
@@ -241,10 +278,10 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct termios *new,
241 unsigned char mr1, mr2; 278 unsigned char mr1, mr2;
242 unsigned short ctr; 279 unsigned short ctr;
243 unsigned int j, baud, quot; 280 unsigned int j, baud, quot;
244 281
245 /* Prepare what we're gonna write */ 282 /* Prepare what we're gonna write */
246 mr1 = 0; 283 mr1 = 0;
247 284
248 switch (new->c_cflag & CSIZE) { 285 switch (new->c_cflag & CSIZE) {
249 case CS5: mr1 |= MPC52xx_PSC_MODE_5_BITS; 286 case CS5: mr1 |= MPC52xx_PSC_MODE_5_BITS;
250 break; 287 break;
@@ -261,8 +298,8 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct termios *new,
261 MPC52xx_PSC_MODE_PARODD : MPC52xx_PSC_MODE_PAREVEN; 298 MPC52xx_PSC_MODE_PARODD : MPC52xx_PSC_MODE_PAREVEN;
262 } else 299 } else
263 mr1 |= MPC52xx_PSC_MODE_PARNONE; 300 mr1 |= MPC52xx_PSC_MODE_PARNONE;
264 301
265 302
266 mr2 = 0; 303 mr2 = 0;
267 304
268 if (new->c_cflag & CSTOPB) 305 if (new->c_cflag & CSTOPB)
@@ -276,7 +313,7 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct termios *new,
276 baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16); 313 baud = uart_get_baud_rate(port, new, old, 0, port->uartclk/16);
277 quot = uart_get_divisor(port, baud); 314 quot = uart_get_divisor(port, baud);
278 ctr = quot & 0xffff; 315 ctr = quot & 0xffff;
279 316
280 /* Get the lock */ 317 /* Get the lock */
281 spin_lock_irqsave(&port->lock, flags); 318 spin_lock_irqsave(&port->lock, flags);
282 319
@@ -290,14 +327,14 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct termios *new,
290 * boot for the console, all stuff is not yet ready to receive at that 327 * boot for the console, all stuff is not yet ready to receive at that
291 * time and that just makes the kernel oops */ 328 * time and that just makes the kernel oops */
292 /* while (j-- && mpc52xx_uart_int_rx_chars(port)); */ 329 /* while (j-- && mpc52xx_uart_int_rx_chars(port)); */
293 while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP) && 330 while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP) &&
294 --j) 331 --j)
295 udelay(1); 332 udelay(1);
296 333
297 if (!j) 334 if (!j)
298 printk( KERN_ERR "mpc52xx_uart.c: " 335 printk( KERN_ERR "mpc52xx_uart.c: "
299 "Unable to flush RX & TX fifos in-time in set_termios." 336 "Unable to flush RX & TX fifos in-time in set_termios."
300 "Some chars may have been lost.\n" ); 337 "Some chars may have been lost.\n" );
301 338
302 /* Reset the TX & RX */ 339 /* Reset the TX & RX */
303 out_8(&psc->command,MPC52xx_PSC_RST_RX); 340 out_8(&psc->command,MPC52xx_PSC_RST_RX);
@@ -309,7 +346,7 @@ mpc52xx_uart_set_termios(struct uart_port *port, struct termios *new,
309 out_8(&psc->mode,mr2); 346 out_8(&psc->mode,mr2);
310 out_8(&psc->ctur,ctr >> 8); 347 out_8(&psc->ctur,ctr >> 8);
311 out_8(&psc->ctlr,ctr & 0xff); 348 out_8(&psc->ctlr,ctr & 0xff);
312 349
313 /* Reenable TX & RX */ 350 /* Reenable TX & RX */
314 out_8(&psc->command,MPC52xx_PSC_TX_ENABLE); 351 out_8(&psc->command,MPC52xx_PSC_TX_ENABLE);
315 out_8(&psc->command,MPC52xx_PSC_RX_ENABLE); 352 out_8(&psc->command,MPC52xx_PSC_RX_ENABLE);
@@ -332,7 +369,7 @@ mpc52xx_uart_release_port(struct uart_port *port)
332 port->membase = NULL; 369 port->membase = NULL;
333 } 370 }
334 371
335 release_mem_region(port->mapbase, MPC52xx_PSC_SIZE); 372 release_mem_region(port->mapbase, sizeof(struct mpc52xx_psc));
336} 373}
337 374
338static int 375static int
@@ -341,12 +378,13 @@ mpc52xx_uart_request_port(struct uart_port *port)
341 int err; 378 int err;
342 379
343 if (port->flags & UPF_IOREMAP) /* Need to remap ? */ 380 if (port->flags & UPF_IOREMAP) /* Need to remap ? */
344 port->membase = ioremap(port->mapbase, MPC52xx_PSC_SIZE); 381 port->membase = ioremap(port->mapbase,
382 sizeof(struct mpc52xx_psc));
345 383
346 if (!port->membase) 384 if (!port->membase)
347 return -EINVAL; 385 return -EINVAL;
348 386
349 err = request_mem_region(port->mapbase, MPC52xx_PSC_SIZE, 387 err = request_mem_region(port->mapbase, sizeof(struct mpc52xx_psc),
350 "mpc52xx_psc_uart") != NULL ? 0 : -EBUSY; 388 "mpc52xx_psc_uart") != NULL ? 0 : -EBUSY;
351 389
352 if (err && (port->flags & UPF_IOREMAP)) { 390 if (err && (port->flags & UPF_IOREMAP)) {
@@ -373,7 +411,7 @@ mpc52xx_uart_verify_port(struct uart_port *port, struct serial_struct *ser)
373 411
374 if ( (ser->irq != port->irq) || 412 if ( (ser->irq != port->irq) ||
375 (ser->io_type != SERIAL_IO_MEM) || 413 (ser->io_type != SERIAL_IO_MEM) ||
376 (ser->baud_base != port->uartclk) || 414 (ser->baud_base != port->uartclk) ||
377 (ser->iomem_base != (void*)port->mapbase) || 415 (ser->iomem_base != (void*)port->mapbase) ||
378 (ser->hub6 != 0 ) ) 416 (ser->hub6 != 0 ) )
379 return -EINVAL; 417 return -EINVAL;
@@ -404,11 +442,11 @@ static struct uart_ops mpc52xx_uart_ops = {
404 .verify_port = mpc52xx_uart_verify_port 442 .verify_port = mpc52xx_uart_verify_port
405}; 443};
406 444
407 445
408/* ======================================================================== */ 446/* ======================================================================== */
409/* Interrupt handling */ 447/* Interrupt handling */
410/* ======================================================================== */ 448/* ======================================================================== */
411 449
412static inline int 450static inline int
413mpc52xx_uart_int_rx_chars(struct uart_port *port) 451mpc52xx_uart_int_rx_chars(struct uart_port *port)
414{ 452{
@@ -435,11 +473,11 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
435 473
436 flag = TTY_NORMAL; 474 flag = TTY_NORMAL;
437 port->icount.rx++; 475 port->icount.rx++;
438 476
439 if ( status & (MPC52xx_PSC_SR_PE | 477 if ( status & (MPC52xx_PSC_SR_PE |
440 MPC52xx_PSC_SR_FE | 478 MPC52xx_PSC_SR_FE |
441 MPC52xx_PSC_SR_RB) ) { 479 MPC52xx_PSC_SR_RB) ) {
442 480
443 if (status & MPC52xx_PSC_SR_RB) { 481 if (status & MPC52xx_PSC_SR_RB) {
444 flag = TTY_BREAK; 482 flag = TTY_BREAK;
445 uart_handle_break(port); 483 uart_handle_break(port);
@@ -464,7 +502,7 @@ mpc52xx_uart_int_rx_chars(struct uart_port *port)
464 } 502 }
465 503
466 tty_flip_buffer_push(tty); 504 tty_flip_buffer_push(tty);
467 505
468 return in_be16(&PSC(port)->mpc52xx_psc_status) & MPC52xx_PSC_SR_RXRDY; 506 return in_be16(&PSC(port)->mpc52xx_psc_status) & MPC52xx_PSC_SR_RXRDY;
469} 507}
470 508
@@ -509,25 +547,25 @@ mpc52xx_uart_int_tx_chars(struct uart_port *port)
509 return 1; 547 return 1;
510} 548}
511 549
512static irqreturn_t 550static irqreturn_t
513mpc52xx_uart_int(int irq, void *dev_id) 551mpc52xx_uart_int(int irq, void *dev_id)
514{ 552{
515 struct uart_port *port = dev_id; 553 struct uart_port *port = dev_id;
516 unsigned long pass = ISR_PASS_LIMIT; 554 unsigned long pass = ISR_PASS_LIMIT;
517 unsigned int keepgoing; 555 unsigned int keepgoing;
518 unsigned short status; 556 unsigned short status;
519 557
520 spin_lock(&port->lock); 558 spin_lock(&port->lock);
521 559
522 /* While we have stuff to do, we continue */ 560 /* While we have stuff to do, we continue */
523 do { 561 do {
524 /* If we don't find anything to do, we stop */ 562 /* If we don't find anything to do, we stop */
525 keepgoing = 0; 563 keepgoing = 0;
526 564
527 /* Read status */ 565 /* Read status */
528 status = in_be16(&PSC(port)->mpc52xx_psc_isr); 566 status = in_be16(&PSC(port)->mpc52xx_psc_isr);
529 status &= port->read_status_mask; 567 status &= port->read_status_mask;
530 568
531 /* Do we need to receive chars ? */ 569 /* Do we need to receive chars ? */
532 /* For this RX interrupts must be on and some chars waiting */ 570 /* For this RX interrupts must be on and some chars waiting */
533 if ( status & MPC52xx_PSC_IMR_RXRDY ) 571 if ( status & MPC52xx_PSC_IMR_RXRDY )
@@ -537,15 +575,15 @@ mpc52xx_uart_int(int irq, void *dev_id)
537 /* For this, TX must be ready and TX interrupt enabled */ 575 /* For this, TX must be ready and TX interrupt enabled */
538 if ( status & MPC52xx_PSC_IMR_TXRDY ) 576 if ( status & MPC52xx_PSC_IMR_TXRDY )
539 keepgoing |= mpc52xx_uart_int_tx_chars(port); 577 keepgoing |= mpc52xx_uart_int_tx_chars(port);
540 578
541 /* Limit number of iteration */ 579 /* Limit number of iteration */
542 if ( !(--pass) ) 580 if ( !(--pass) )
543 keepgoing = 0; 581 keepgoing = 0;
544 582
545 } while (keepgoing); 583 } while (keepgoing);
546 584
547 spin_unlock(&port->lock); 585 spin_unlock(&port->lock);
548 586
549 return IRQ_HANDLED; 587 return IRQ_HANDLED;
550} 588}
551 589
@@ -563,13 +601,18 @@ mpc52xx_console_get_options(struct uart_port *port,
563 struct mpc52xx_psc __iomem *psc = PSC(port); 601 struct mpc52xx_psc __iomem *psc = PSC(port);
564 unsigned char mr1; 602 unsigned char mr1;
565 603
604 pr_debug("mpc52xx_console_get_options(port=%p)\n", port);
605
566 /* Read the mode registers */ 606 /* Read the mode registers */
567 out_8(&psc->command,MPC52xx_PSC_SEL_MODE_REG_1); 607 out_8(&psc->command,MPC52xx_PSC_SEL_MODE_REG_1);
568 mr1 = in_8(&psc->mode); 608 mr1 = in_8(&psc->mode);
569 609
570 /* CT{U,L}R are write-only ! */ 610 /* CT{U,L}R are write-only ! */
571 *baud = __res.bi_baudrate ? 611 *baud = CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD;
572 __res.bi_baudrate : CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD; 612#if !defined(CONFIG_PPC_MERGE)
613 if (__res.bi_baudrate)
614 *baud = __res.bi_baudrate;
615#endif
573 616
574 /* Parse them */ 617 /* Parse them */
575 switch (mr1 & MPC52xx_PSC_MODE_BITS_MASK) { 618 switch (mr1 & MPC52xx_PSC_MODE_BITS_MASK) {
@@ -579,26 +622,26 @@ mpc52xx_console_get_options(struct uart_port *port,
579 case MPC52xx_PSC_MODE_8_BITS: 622 case MPC52xx_PSC_MODE_8_BITS:
580 default: *bits = 8; 623 default: *bits = 8;
581 } 624 }
582 625
583 if (mr1 & MPC52xx_PSC_MODE_PARNONE) 626 if (mr1 & MPC52xx_PSC_MODE_PARNONE)
584 *parity = 'n'; 627 *parity = 'n';
585 else 628 else
586 *parity = mr1 & MPC52xx_PSC_MODE_PARODD ? 'o' : 'e'; 629 *parity = mr1 & MPC52xx_PSC_MODE_PARODD ? 'o' : 'e';
587} 630}
588 631
589static void 632static void
590mpc52xx_console_write(struct console *co, const char *s, unsigned int count) 633mpc52xx_console_write(struct console *co, const char *s, unsigned int count)
591{ 634{
592 struct uart_port *port = &mpc52xx_uart_ports[co->index]; 635 struct uart_port *port = &mpc52xx_uart_ports[co->index];
593 struct mpc52xx_psc __iomem *psc = PSC(port); 636 struct mpc52xx_psc __iomem *psc = PSC(port);
594 unsigned int i, j; 637 unsigned int i, j;
595 638
596 /* Disable interrupts */ 639 /* Disable interrupts */
597 out_be16(&psc->mpc52xx_psc_imr, 0); 640 out_be16(&psc->mpc52xx_psc_imr, 0);
598 641
599 /* Wait the TX buffer to be empty */ 642 /* Wait the TX buffer to be empty */
600 j = 5000000; /* Maximum wait */ 643 j = 5000000; /* Maximum wait */
601 while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP) && 644 while (!(in_be16(&psc->mpc52xx_psc_status) & MPC52xx_PSC_SR_TXEMP) &&
602 --j) 645 --j)
603 udelay(1); 646 udelay(1);
604 647
@@ -607,13 +650,13 @@ mpc52xx_console_write(struct console *co, const char *s, unsigned int count)
607 /* Line return handling */ 650 /* Line return handling */
608 if (*s == '\n') 651 if (*s == '\n')
609 out_8(&psc->mpc52xx_psc_buffer_8, '\r'); 652 out_8(&psc->mpc52xx_psc_buffer_8, '\r');
610 653
611 /* Send the char */ 654 /* Send the char */
612 out_8(&psc->mpc52xx_psc_buffer_8, *s); 655 out_8(&psc->mpc52xx_psc_buffer_8, *s);
613 656
614 /* Wait the TX buffer to be empty */ 657 /* Wait the TX buffer to be empty */
615 j = 20000; /* Maximum wait */ 658 j = 20000; /* Maximum wait */
616 while (!(in_be16(&psc->mpc52xx_psc_status) & 659 while (!(in_be16(&psc->mpc52xx_psc_status) &
617 MPC52xx_PSC_SR_TXEMP) && --j) 660 MPC52xx_PSC_SR_TXEMP) && --j)
618 udelay(1); 661 udelay(1);
619 } 662 }
@@ -622,6 +665,7 @@ mpc52xx_console_write(struct console *co, const char *s, unsigned int count)
622 out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask); 665 out_be16(&psc->mpc52xx_psc_imr, port->read_status_mask);
623} 666}
624 667
668#if !defined(CONFIG_PPC_MERGE)
625static int __init 669static int __init
626mpc52xx_console_setup(struct console *co, char *options) 670mpc52xx_console_setup(struct console *co, char *options)
627{ 671{
@@ -634,7 +678,7 @@ mpc52xx_console_setup(struct console *co, char *options)
634 678
635 if (co->index < 0 || co->index >= MPC52xx_PSC_MAXNUM) 679 if (co->index < 0 || co->index >= MPC52xx_PSC_MAXNUM)
636 return -EINVAL; 680 return -EINVAL;
637 681
638 /* Basic port init. Needed since we use some uart_??? func before 682 /* Basic port init. Needed since we use some uart_??? func before
639 * real init for early access */ 683 * real init for early access */
640 spin_lock_init(&port->lock); 684 spin_lock_init(&port->lock);
@@ -656,6 +700,78 @@ mpc52xx_console_setup(struct console *co, char *options)
656 return uart_set_options(port, co, baud, parity, bits, flow); 700 return uart_set_options(port, co, baud, parity, bits, flow);
657} 701}
658 702
703#else
704
705static int __init
706mpc52xx_console_setup(struct console *co, char *options)
707{
708 struct uart_port *port = &mpc52xx_uart_ports[co->index];
709 struct device_node *np = mpc52xx_uart_nodes[co->index];
710 unsigned int ipb_freq;
711 struct resource res;
712 int ret;
713
714 int baud = CONFIG_SERIAL_MPC52xx_CONSOLE_BAUD;
715 int bits = 8;
716 int parity = 'n';
717 int flow = 'n';
718
719 pr_debug("mpc52xx_console_setup co=%p, co->index=%i, options=%s\n",
720 co, co->index, options);
721
722 if ((co->index < 0) || (co->index > MPC52xx_PSC_MAXNUM)) {
723 pr_debug("PSC%x out of range\n", co->index);
724 return -EINVAL;
725 }
726
727 if (!np) {
728 pr_debug("PSC%x not found in device tree\n", co->index);
729 return -EINVAL;
730 }
731
732 pr_debug("Console on ttyPSC%x is %s\n",
733 co->index, mpc52xx_uart_nodes[co->index]->full_name);
734
735 /* Fetch register locations */
736 if ((ret = of_address_to_resource(np, 0, &res)) != 0) {
737 pr_debug("Could not get resources for PSC%x\n", co->index);
738 return ret;
739 }
740
741 /* Search for bus-frequency property in this node or a parent */
742 if ((ipb_freq = mpc52xx_find_ipb_freq(np)) == 0) {
743 pr_debug("Could not find IPB bus frequency!\n");
744 return -EINVAL;
745 }
746
747 /* Basic port init. Needed since we use some uart_??? func before
748 * real init for early access */
749 spin_lock_init(&port->lock);
750 port->uartclk = ipb_freq / 2;
751 port->ops = &mpc52xx_uart_ops;
752 port->mapbase = res.start;
753 port->membase = ioremap(res.start, sizeof(struct mpc52xx_psc));
754 port->irq = irq_of_parse_and_map(np, 0);
755
756 if (port->membase == NULL)
757 return -EINVAL;
758
759 pr_debug("mpc52xx-psc uart at %lx, mapped to %p, irq=%x, freq=%i\n",
760 port->mapbase, port->membase, port->irq, port->uartclk);
761
762 /* Setup the port parameters accoding to options */
763 if (options)
764 uart_parse_options(options, &baud, &parity, &bits, &flow);
765 else
766 mpc52xx_console_get_options(port, &baud, &parity, &bits, &flow);
767
768 pr_debug("Setting console parameters: %i %i%c1 flow=%c\n",
769 baud, bits, parity, flow);
770
771 return uart_set_options(port, co, baud, parity, bits, flow);
772}
773#endif /* defined(CONFIG_PPC_MERGE) */
774
659 775
660static struct uart_driver mpc52xx_uart_driver; 776static struct uart_driver mpc52xx_uart_driver;
661 777
@@ -669,10 +785,11 @@ static struct console mpc52xx_console = {
669 .data = &mpc52xx_uart_driver, 785 .data = &mpc52xx_uart_driver,
670}; 786};
671 787
672 788
673static int __init 789static int __init
674mpc52xx_console_init(void) 790mpc52xx_console_init(void)
675{ 791{
792 mpc52xx_uart_of_enumerate();
676 register_console(&mpc52xx_console); 793 register_console(&mpc52xx_console);
677 return 0; 794 return 0;
678} 795}
@@ -700,6 +817,7 @@ static struct uart_driver mpc52xx_uart_driver = {
700}; 817};
701 818
702 819
820#if !defined(CONFIG_PPC_MERGE)
703/* ======================================================================== */ 821/* ======================================================================== */
704/* Platform Driver */ 822/* Platform Driver */
705/* ======================================================================== */ 823/* ======================================================================== */
@@ -723,8 +841,6 @@ mpc52xx_uart_probe(struct platform_device *dev)
723 /* Init the port structure */ 841 /* Init the port structure */
724 port = &mpc52xx_uart_ports[idx]; 842 port = &mpc52xx_uart_ports[idx];
725 843
726 memset(port, 0x00, sizeof(struct uart_port));
727
728 spin_lock_init(&port->lock); 844 spin_lock_init(&port->lock);
729 port->uartclk = __res.bi_ipbfreq / 2; /* Look at CTLR doc */ 845 port->uartclk = __res.bi_ipbfreq / 2; /* Look at CTLR doc */
730 port->fifosize = 512; 846 port->fifosize = 512;
@@ -733,6 +849,7 @@ mpc52xx_uart_probe(struct platform_device *dev)
733 ( uart_console(port) ? 0 : UPF_IOREMAP ); 849 ( uart_console(port) ? 0 : UPF_IOREMAP );
734 port->line = idx; 850 port->line = idx;
735 port->ops = &mpc52xx_uart_ops; 851 port->ops = &mpc52xx_uart_ops;
852 port->dev = &dev->dev;
736 853
737 /* Search for IRQ and mapbase */ 854 /* Search for IRQ and mapbase */
738 for (i=0 ; i<dev->num_resources ; i++, res++) { 855 for (i=0 ; i<dev->num_resources ; i++, res++) {
@@ -771,7 +888,7 @@ mpc52xx_uart_suspend(struct platform_device *dev, pm_message_t state)
771{ 888{
772 struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev); 889 struct uart_port *port = (struct uart_port *) platform_get_drvdata(dev);
773 890
774 if (sport) 891 if (port)
775 uart_suspend_port(&mpc52xx_uart_driver, port); 892 uart_suspend_port(&mpc52xx_uart_driver, port);
776 893
777 return 0; 894 return 0;
@@ -789,6 +906,7 @@ mpc52xx_uart_resume(struct platform_device *dev)
789} 906}
790#endif 907#endif
791 908
909
792static struct platform_driver mpc52xx_uart_platform_driver = { 910static struct platform_driver mpc52xx_uart_platform_driver = {
793 .probe = mpc52xx_uart_probe, 911 .probe = mpc52xx_uart_probe,
794 .remove = mpc52xx_uart_remove, 912 .remove = mpc52xx_uart_remove,
@@ -800,6 +918,184 @@ static struct platform_driver mpc52xx_uart_platform_driver = {
800 .name = "mpc52xx-psc", 918 .name = "mpc52xx-psc",
801 }, 919 },
802}; 920};
921#endif /* !defined(CONFIG_PPC_MERGE) */
922
923
924#if defined(CONFIG_PPC_MERGE)
925/* ======================================================================== */
926/* OF Platform Driver */
927/* ======================================================================== */
928
929static int __devinit
930mpc52xx_uart_of_probe(struct of_device *op, const struct of_device_id *match)
931{
932 int idx = -1;
933 unsigned int ipb_freq;
934 struct uart_port *port = NULL;
935 struct resource res;
936 int ret;
937
938 dev_dbg(&op->dev, "mpc52xx_uart_probe(op=%p, match=%p)\n", op, match);
939
940 /* Check validity & presence */
941 for (idx = 0; idx < MPC52xx_PSC_MAXNUM; idx++)
942 if (mpc52xx_uart_nodes[idx] == op->node)
943 break;
944 if (idx >= MPC52xx_PSC_MAXNUM)
945 return -EINVAL;
946 pr_debug("Found %s assigned to ttyPSC%x\n",
947 mpc52xx_uart_nodes[idx]->full_name, idx);
948
949 /* Search for bus-frequency property in this node or a parent */
950 if ((ipb_freq = mpc52xx_find_ipb_freq(op->node)) == 0) {
951 dev_dbg(&op->dev, "Could not find IPB bus frequency!\n");
952 return -EINVAL;
953 }
954
955 /* Init the port structure */
956 port = &mpc52xx_uart_ports[idx];
957
958 spin_lock_init(&port->lock);
959 port->uartclk = ipb_freq / 2;
960 port->fifosize = 512;
961 port->iotype = UPIO_MEM;
962 port->flags = UPF_BOOT_AUTOCONF |
963 ( uart_console(port) ? 0 : UPF_IOREMAP );
964 port->line = idx;
965 port->ops = &mpc52xx_uart_ops;
966 port->dev = &op->dev;
967
968 /* Search for IRQ and mapbase */
969 if ((ret = of_address_to_resource(op->node, 0, &res)) != 0)
970 return ret;
971
972 port->mapbase = res.start;
973 port->irq = irq_of_parse_and_map(op->node, 0);
974
975 dev_dbg(&op->dev, "mpc52xx-psc uart at %lx, irq=%x, freq=%i\n",
976 port->mapbase, port->irq, port->uartclk);
977
978 if ((port->irq==NO_IRQ) || !port->mapbase) {
979 printk(KERN_ERR "Could not allocate resources for PSC\n");
980 return -EINVAL;
981 }
982
983 /* Add the port to the uart sub-system */
984 ret = uart_add_one_port(&mpc52xx_uart_driver, port);
985 if (!ret)
986 dev_set_drvdata(&op->dev, (void*)port);
987
988 return ret;
989}
990
991static int
992mpc52xx_uart_of_remove(struct of_device *op)
993{
994 struct uart_port *port = dev_get_drvdata(&op->dev);
995 dev_set_drvdata(&op->dev, NULL);
996
997 if (port)
998 uart_remove_one_port(&mpc52xx_uart_driver, port);
999
1000 return 0;
1001}
1002
1003#ifdef CONFIG_PM
1004static int
1005mpc52xx_uart_of_suspend(struct of_device *op, pm_message_t state)
1006{
1007 struct uart_port *port = (struct uart_port *) dev_get_drvdata(&op->dev);
1008
1009 if (port)
1010 uart_suspend_port(&mpc52xx_uart_driver, port);
1011
1012 return 0;
1013}
1014
1015static int
1016mpc52xx_uart_of_resume(struct of_device *op)
1017{
1018 struct uart_port *port = (struct uart_port *) dev_get_drvdata(&op->dev);
1019
1020 if (port)
1021 uart_resume_port(&mpc52xx_uart_driver, port);
1022
1023 return 0;
1024}
1025#endif
1026
1027static void
1028mpc52xx_uart_of_assign(struct device_node *np, int idx)
1029{
1030 int free_idx = -1;
1031 int i;
1032
1033 /* Find the first free node */
1034 for (i = 0; i < MPC52xx_PSC_MAXNUM; i++) {
1035 if (mpc52xx_uart_nodes[i] == NULL) {
1036 free_idx = i;
1037 break;
1038 }
1039 }
1040
1041 if ((idx < 0) || (idx >= MPC52xx_PSC_MAXNUM))
1042 idx = free_idx;
1043
1044 if (idx < 0)
1045 return; /* No free slot; abort */
1046
1047 /* If the slot is already occupied, then swap slots */
1048 if (mpc52xx_uart_nodes[idx] && (free_idx != -1))
1049 mpc52xx_uart_nodes[free_idx] = mpc52xx_uart_nodes[idx];
1050 mpc52xx_uart_nodes[i] = np;
1051}
1052
1053static void
1054mpc52xx_uart_of_enumerate(void)
1055{
1056 static int enum_done = 0;
1057 struct device_node *np;
1058 const unsigned int *devno;
1059 int i;
1060
1061 if (enum_done)
1062 return;
1063
1064 for_each_node_by_type(np, "serial") {
1065 if (!of_match_node(mpc52xx_uart_of_match, np))
1066 continue;
1067
1068 /* Is a particular device number requested? */
1069 devno = get_property(np, "device_no", NULL);
1070 mpc52xx_uart_of_assign(of_node_get(np), devno ? *devno : -1);
1071 }
1072
1073 enum_done = 1;
1074
1075 for (i = 0; i < MPC52xx_PSC_MAXNUM; i++) {
1076 if (mpc52xx_uart_nodes[i])
1077 pr_debug("%s assigned to ttyPSC%x\n",
1078 mpc52xx_uart_nodes[i]->full_name, i);
1079 }
1080}
1081
1082MODULE_DEVICE_TABLE(of, mpc52xx_uart_of_match);
1083
1084static struct of_platform_driver mpc52xx_uart_of_driver = {
1085 .owner = THIS_MODULE,
1086 .name = "mpc52xx-psc-uart",
1087 .match_table = mpc52xx_uart_of_match,
1088 .probe = mpc52xx_uart_of_probe,
1089 .remove = mpc52xx_uart_of_remove,
1090#ifdef CONFIG_PM
1091 .suspend = mpc52xx_uart_of_suspend,
1092 .resume = mpc52xx_uart_of_resume,
1093#endif
1094 .driver = {
1095 .name = "mpc52xx-psc-uart",
1096 },
1097};
1098#endif /* defined(CONFIG_PPC_MERGE) */
803 1099
804 1100
805/* ======================================================================== */ 1101/* ======================================================================== */
@@ -811,22 +1107,45 @@ mpc52xx_uart_init(void)
811{ 1107{
812 int ret; 1108 int ret;
813 1109
814 printk(KERN_INFO "Serial: MPC52xx PSC driver\n"); 1110 printk(KERN_INFO "Serial: MPC52xx PSC UART driver\n");
815 1111
816 ret = uart_register_driver(&mpc52xx_uart_driver); 1112 if ((ret = uart_register_driver(&mpc52xx_uart_driver)) != 0) {
817 if (ret == 0) { 1113 printk(KERN_ERR "%s: uart_register_driver failed (%i)\n",
818 ret = platform_driver_register(&mpc52xx_uart_platform_driver); 1114 __FILE__, ret);
819 if (ret) 1115 return ret;
820 uart_unregister_driver(&mpc52xx_uart_driver);
821 } 1116 }
822 1117
823 return ret; 1118#if defined(CONFIG_PPC_MERGE)
1119 mpc52xx_uart_of_enumerate();
1120
1121 ret = of_register_platform_driver(&mpc52xx_uart_of_driver);
1122 if (ret) {
1123 printk(KERN_ERR "%s: of_register_platform_driver failed (%i)\n",
1124 __FILE__, ret);
1125 uart_unregister_driver(&mpc52xx_uart_driver);
1126 return ret;
1127 }
1128#else
1129 ret = platform_driver_register(&mpc52xx_uart_platform_driver);
1130 if (ret) {
1131 printk(KERN_ERR "%s: platform_driver_register failed (%i)\n",
1132 __FILE__, ret);
1133 uart_unregister_driver(&mpc52xx_uart_driver);
1134 return ret;
1135 }
1136#endif
1137
1138 return 0;
824} 1139}
825 1140
826static void __exit 1141static void __exit
827mpc52xx_uart_exit(void) 1142mpc52xx_uart_exit(void)
828{ 1143{
1144#if defined(CONFIG_PPC_MERGE)
1145 of_unregister_platform_driver(&mpc52xx_uart_of_driver);
1146#else
829 platform_driver_unregister(&mpc52xx_uart_platform_driver); 1147 platform_driver_unregister(&mpc52xx_uart_platform_driver);
1148#endif
830 uart_unregister_driver(&mpc52xx_uart_driver); 1149 uart_unregister_driver(&mpc52xx_uart_driver);
831} 1150}
832 1151
diff --git a/drivers/spi/spi_butterfly.c b/drivers/spi/spi_butterfly.c
index 39d9b20f2038..c2f601f8e4f2 100644
--- a/drivers/spi/spi_butterfly.c
+++ b/drivers/spi/spi_butterfly.c
@@ -23,6 +23,7 @@
23#include <linux/platform_device.h> 23#include <linux/platform_device.h>
24#include <linux/parport.h> 24#include <linux/parport.h>
25 25
26#include <linux/sched.h>
26#include <linux/spi/spi.h> 27#include <linux/spi/spi.h>
27#include <linux/spi/spi_bitbang.h> 28#include <linux/spi/spi_bitbang.h>
28#include <linux/spi/flash.h> 29#include <linux/spi/flash.h>
diff --git a/drivers/video/platinumfb.c b/drivers/video/platinumfb.c
index fdb33cd21a27..cb26c6df0583 100644
--- a/drivers/video/platinumfb.c
+++ b/drivers/video/platinumfb.c
@@ -34,6 +34,7 @@
34#include <asm/prom.h> 34#include <asm/prom.h>
35#include <asm/pgtable.h> 35#include <asm/pgtable.h>
36#include <asm/of_device.h> 36#include <asm/of_device.h>
37#include <asm/of_platform.h>
37 38
38#include "macmodes.h" 39#include "macmodes.h"
39#include "platinumfb.h" 40#include "platinumfb.h"
@@ -682,14 +683,14 @@ static int __init platinumfb_init(void)
682 return -ENODEV; 683 return -ENODEV;
683 platinumfb_setup(option); 684 platinumfb_setup(option);
684#endif 685#endif
685 of_register_driver(&platinum_driver); 686 of_register_platform_driver(&platinum_driver);
686 687
687 return 0; 688 return 0;
688} 689}
689 690
690static void __exit platinumfb_exit(void) 691static void __exit platinumfb_exit(void)
691{ 692{
692 of_unregister_driver(&platinum_driver); 693 of_unregister_platform_driver(&platinum_driver);
693} 694}
694 695
695MODULE_LICENSE("GPL"); 696MODULE_LICENSE("GPL");
diff --git a/drivers/w1/slaves/w1_therm.c b/drivers/w1/slaves/w1_therm.c
index 5372cfcbd054..b022fffd8c51 100644
--- a/drivers/w1/slaves/w1_therm.c
+++ b/drivers/w1/slaves/w1_therm.c
@@ -24,6 +24,7 @@
24#include <linux/kernel.h> 24#include <linux/kernel.h>
25#include <linux/module.h> 25#include <linux/module.h>
26#include <linux/moduleparam.h> 26#include <linux/moduleparam.h>
27#include <linux/sched.h>
27#include <linux/device.h> 28#include <linux/device.h>
28#include <linux/types.h> 29#include <linux/types.h>
29#include <linux/delay.h> 30#include <linux/delay.h>
diff --git a/fs/9p/conv.c b/fs/9p/conv.c
index 56d88c1a09c5..a3ed571eee31 100644
--- a/fs/9p/conv.c
+++ b/fs/9p/conv.c
@@ -27,6 +27,7 @@
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/errno.h> 28#include <linux/errno.h>
29#include <linux/fs.h> 29#include <linux/fs.h>
30#include <linux/sched.h>
30#include <linux/idr.h> 31#include <linux/idr.h>
31#include <asm/uaccess.h> 32#include <asm/uaccess.h>
32#include "debug.h" 33#include "debug.h"
diff --git a/fs/9p/fcall.c b/fs/9p/fcall.c
index 8556097fcda8..dc336a67592f 100644
--- a/fs/9p/fcall.c
+++ b/fs/9p/fcall.c
@@ -27,6 +27,7 @@
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/errno.h> 28#include <linux/errno.h>
29#include <linux/fs.h> 29#include <linux/fs.h>
30#include <linux/sched.h>
30#include <linux/idr.h> 31#include <linux/idr.h>
31 32
32#include "debug.h" 33#include "debug.h"
diff --git a/fs/9p/fid.c b/fs/9p/fid.c
index 70492ccb4385..27507201f9e7 100644
--- a/fs/9p/fid.c
+++ b/fs/9p/fid.c
@@ -23,6 +23,7 @@
23#include <linux/module.h> 23#include <linux/module.h>
24#include <linux/errno.h> 24#include <linux/errno.h>
25#include <linux/fs.h> 25#include <linux/fs.h>
26#include <linux/sched.h>
26#include <linux/idr.h> 27#include <linux/idr.h>
27 28
28#include "debug.h" 29#include "debug.h"
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index 0f628041e3f7..0b96fae8b479 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -26,6 +26,7 @@
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/errno.h> 27#include <linux/errno.h>
28#include <linux/fs.h> 28#include <linux/fs.h>
29#include <linux/sched.h>
29#include <linux/parser.h> 30#include <linux/parser.h>
30#include <linux/idr.h> 31#include <linux/idr.h>
31 32
diff --git a/fs/9p/vfs_dir.c b/fs/9p/vfs_dir.c
index e32d5971039b..905c882f4e2f 100644
--- a/fs/9p/vfs_dir.c
+++ b/fs/9p/vfs_dir.c
@@ -30,6 +30,7 @@
30#include <linux/stat.h> 30#include <linux/stat.h>
31#include <linux/string.h> 31#include <linux/string.h>
32#include <linux/smp_lock.h> 32#include <linux/smp_lock.h>
33#include <linux/sched.h>
33#include <linux/inet.h> 34#include <linux/inet.h>
34#include <linux/idr.h> 35#include <linux/idr.h>
35 36
diff --git a/fs/9p/vfs_file.c b/fs/9p/vfs_file.c
index c3c47eda7574..79e6f9cd7340 100644
--- a/fs/9p/vfs_file.c
+++ b/fs/9p/vfs_file.c
@@ -26,6 +26,7 @@
26#include <linux/module.h> 26#include <linux/module.h>
27#include <linux/errno.h> 27#include <linux/errno.h>
28#include <linux/fs.h> 28#include <linux/fs.h>
29#include <linux/sched.h>
29#include <linux/file.h> 30#include <linux/file.h>
30#include <linux/stat.h> 31#include <linux/stat.h>
31#include <linux/string.h> 32#include <linux/string.h>
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index 79b05a1a4365..cc72bb43061d 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1582,6 +1582,10 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
1582 1582
1583 sz += thread_status_size; 1583 sz += thread_status_size;
1584 1584
1585#ifdef ELF_CORE_WRITE_EXTRA_NOTES
1586 sz += ELF_CORE_EXTRA_NOTES_SIZE;
1587#endif
1588
1585 fill_elf_note_phdr(&phdr, sz, offset); 1589 fill_elf_note_phdr(&phdr, sz, offset);
1586 offset += sz; 1590 offset += sz;
1587 DUMP_WRITE(&phdr, sizeof(phdr)); 1591 DUMP_WRITE(&phdr, sizeof(phdr));
@@ -1622,6 +1626,10 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
1622 if (!writenote(notes + i, file, &foffset)) 1626 if (!writenote(notes + i, file, &foffset))
1623 goto end_coredump; 1627 goto end_coredump;
1624 1628
1629#ifdef ELF_CORE_WRITE_EXTRA_NOTES
1630 ELF_CORE_WRITE_EXTRA_NOTES;
1631#endif
1632
1625 /* write out the thread status notes section */ 1633 /* write out the thread status notes section */
1626 list_for_each(t, &thread_list) { 1634 list_for_each(t, &thread_list) {
1627 struct elf_thread_status *tmp = 1635 struct elf_thread_status *tmp =
diff --git a/fs/compat.c b/fs/compat.c
index 8d0a0018a7d2..06dad665b88f 100644
--- a/fs/compat.c
+++ b/fs/compat.c
@@ -45,6 +45,8 @@
45#include <linux/personality.h> 45#include <linux/personality.h>
46#include <linux/rwsem.h> 46#include <linux/rwsem.h>
47#include <linux/tsacct_kern.h> 47#include <linux/tsacct_kern.h>
48#include <linux/highmem.h>
49#include <linux/poll.h>
48#include <linux/mm.h> 50#include <linux/mm.h>
49 51
50#include <net/sock.h> /* siocdevprivate_ioctl */ 52#include <net/sock.h> /* siocdevprivate_ioctl */
diff --git a/fs/configfs/dir.c b/fs/configfs/dir.c
index 8a3b6a1a6ad1..c398861f78a5 100644
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -93,8 +93,8 @@ static struct configfs_dirent *configfs_new_dirent(struct configfs_dirent * pare
93 * 93 *
94 * called with parent inode's i_mutex held 94 * called with parent inode's i_mutex held
95 */ 95 */
96int configfs_dirent_exists(struct configfs_dirent *parent_sd, 96static int configfs_dirent_exists(struct configfs_dirent *parent_sd,
97 const unsigned char *new) 97 const unsigned char *new)
98{ 98{
99 struct configfs_dirent * sd; 99 struct configfs_dirent * sd;
100 100
@@ -1176,8 +1176,9 @@ void configfs_unregister_subsystem(struct configfs_subsystem *subsys)
1176 return; 1176 return;
1177 } 1177 }
1178 1178
1179 mutex_lock(&configfs_sb->s_root->d_inode->i_mutex); 1179 mutex_lock_nested(&configfs_sb->s_root->d_inode->i_mutex,
1180 mutex_lock(&dentry->d_inode->i_mutex); 1180 I_MUTEX_PARENT);
1181 mutex_lock_nested(&dentry->d_inode->i_mutex, I_MUTEX_CHILD);
1181 if (configfs_detach_prep(dentry)) { 1182 if (configfs_detach_prep(dentry)) {
1182 printk(KERN_ERR "configfs: Tried to unregister non-empty subsystem!\n"); 1183 printk(KERN_ERR "configfs: Tried to unregister non-empty subsystem!\n");
1183 } 1184 }
diff --git a/fs/gfs2/locking/dlm/plock.c b/fs/gfs2/locking/dlm/plock.c
index 7365aec9511b..3799f19b282f 100644
--- a/fs/gfs2/locking/dlm/plock.c
+++ b/fs/gfs2/locking/dlm/plock.c
@@ -8,6 +8,7 @@
8 8
9#include <linux/miscdevice.h> 9#include <linux/miscdevice.h>
10#include <linux/lock_dlm_plock.h> 10#include <linux/lock_dlm_plock.h>
11#include <linux/poll.h>
11 12
12#include "lock_dlm.h" 13#include "lock_dlm.h"
13 14
diff --git a/fs/inotify.c b/fs/inotify.c
index 723836a1f718..f5099d86fd91 100644
--- a/fs/inotify.c
+++ b/fs/inotify.c
@@ -27,6 +27,7 @@
27#include <linux/idr.h> 27#include <linux/idr.h>
28#include <linux/slab.h> 28#include <linux/slab.h>
29#include <linux/fs.h> 29#include <linux/fs.h>
30#include <linux/sched.h>
30#include <linux/init.h> 31#include <linux/init.h>
31#include <linux/list.h> 32#include <linux/list.h>
32#include <linux/writeback.h> 33#include <linux/writeback.h>
diff --git a/fs/jffs2/acl.c b/fs/jffs2/acl.c
index 0ae3cd10702c..73f0d60f73a5 100644
--- a/fs/jffs2/acl.c
+++ b/fs/jffs2/acl.c
@@ -11,6 +11,7 @@
11#include <linux/kernel.h> 11#include <linux/kernel.h>
12#include <linux/slab.h> 12#include <linux/slab.h>
13#include <linux/fs.h> 13#include <linux/fs.h>
14#include <linux/sched.h>
14#include <linux/time.h> 15#include <linux/time.h>
15#include <linux/crc32.h> 16#include <linux/crc32.h>
16#include <linux/jffs2.h> 17#include <linux/jffs2.h>
diff --git a/fs/jffs2/wbuf.c b/fs/jffs2/wbuf.c
index b9b700730dfe..70707309dfa1 100644
--- a/fs/jffs2/wbuf.c
+++ b/fs/jffs2/wbuf.c
@@ -19,6 +19,7 @@
19#include <linux/crc32.h> 19#include <linux/crc32.h>
20#include <linux/mtd/nand.h> 20#include <linux/mtd/nand.h>
21#include <linux/jiffies.h> 21#include <linux/jiffies.h>
22#include <linux/sched.h>
22 23
23#include "nodelist.h" 24#include "nodelist.h"
24 25
diff --git a/fs/jfs/ioctl.c b/fs/jfs/ioctl.c
index 37db52488262..ed814b1ff4d9 100644
--- a/fs/jfs/ioctl.c
+++ b/fs/jfs/ioctl.c
@@ -9,6 +9,7 @@
9#include <linux/ctype.h> 9#include <linux/ctype.h>
10#include <linux/capability.h> 10#include <linux/capability.h>
11#include <linux/time.h> 11#include <linux/time.h>
12#include <linux/sched.h>
12#include <asm/current.h> 13#include <asm/current.h>
13#include <asm/uaccess.h> 14#include <asm/uaccess.h>
14 15
diff --git a/fs/ocfs2/alloc.c b/fs/ocfs2/alloc.c
index 0b2ad163005e..edc91ca3792a 100644
--- a/fs/ocfs2/alloc.c
+++ b/fs/ocfs2/alloc.c
@@ -52,14 +52,14 @@ static int ocfs2_extent_contig(struct inode *inode,
52 u64 blkno); 52 u64 blkno);
53 53
54static int ocfs2_create_new_meta_bhs(struct ocfs2_super *osb, 54static int ocfs2_create_new_meta_bhs(struct ocfs2_super *osb,
55 struct ocfs2_journal_handle *handle, 55 handle_t *handle,
56 struct inode *inode, 56 struct inode *inode,
57 int wanted, 57 int wanted,
58 struct ocfs2_alloc_context *meta_ac, 58 struct ocfs2_alloc_context *meta_ac,
59 struct buffer_head *bhs[]); 59 struct buffer_head *bhs[]);
60 60
61static int ocfs2_add_branch(struct ocfs2_super *osb, 61static int ocfs2_add_branch(struct ocfs2_super *osb,
62 struct ocfs2_journal_handle *handle, 62 handle_t *handle,
63 struct inode *inode, 63 struct inode *inode,
64 struct buffer_head *fe_bh, 64 struct buffer_head *fe_bh,
65 struct buffer_head *eb_bh, 65 struct buffer_head *eb_bh,
@@ -67,14 +67,14 @@ static int ocfs2_add_branch(struct ocfs2_super *osb,
67 struct ocfs2_alloc_context *meta_ac); 67 struct ocfs2_alloc_context *meta_ac);
68 68
69static int ocfs2_shift_tree_depth(struct ocfs2_super *osb, 69static int ocfs2_shift_tree_depth(struct ocfs2_super *osb,
70 struct ocfs2_journal_handle *handle, 70 handle_t *handle,
71 struct inode *inode, 71 struct inode *inode,
72 struct buffer_head *fe_bh, 72 struct buffer_head *fe_bh,
73 struct ocfs2_alloc_context *meta_ac, 73 struct ocfs2_alloc_context *meta_ac,
74 struct buffer_head **ret_new_eb_bh); 74 struct buffer_head **ret_new_eb_bh);
75 75
76static int ocfs2_do_insert_extent(struct ocfs2_super *osb, 76static int ocfs2_do_insert_extent(struct ocfs2_super *osb,
77 struct ocfs2_journal_handle *handle, 77 handle_t *handle,
78 struct inode *inode, 78 struct inode *inode,
79 struct buffer_head *fe_bh, 79 struct buffer_head *fe_bh,
80 u64 blkno, 80 u64 blkno,
@@ -152,7 +152,7 @@ bail:
152 * l_count for you 152 * l_count for you
153 */ 153 */
154static int ocfs2_create_new_meta_bhs(struct ocfs2_super *osb, 154static int ocfs2_create_new_meta_bhs(struct ocfs2_super *osb,
155 struct ocfs2_journal_handle *handle, 155 handle_t *handle,
156 struct inode *inode, 156 struct inode *inode,
157 int wanted, 157 int wanted,
158 struct ocfs2_alloc_context *meta_ac, 158 struct ocfs2_alloc_context *meta_ac,
@@ -253,7 +253,7 @@ bail:
253 * contain a single record with e_clusters == 0. 253 * contain a single record with e_clusters == 0.
254 */ 254 */
255static int ocfs2_add_branch(struct ocfs2_super *osb, 255static int ocfs2_add_branch(struct ocfs2_super *osb,
256 struct ocfs2_journal_handle *handle, 256 handle_t *handle,
257 struct inode *inode, 257 struct inode *inode,
258 struct buffer_head *fe_bh, 258 struct buffer_head *fe_bh,
259 struct buffer_head *eb_bh, 259 struct buffer_head *eb_bh,
@@ -418,7 +418,7 @@ bail:
418 * after this call. 418 * after this call.
419 */ 419 */
420static int ocfs2_shift_tree_depth(struct ocfs2_super *osb, 420static int ocfs2_shift_tree_depth(struct ocfs2_super *osb,
421 struct ocfs2_journal_handle *handle, 421 handle_t *handle,
422 struct inode *inode, 422 struct inode *inode,
423 struct buffer_head *fe_bh, 423 struct buffer_head *fe_bh,
424 struct ocfs2_alloc_context *meta_ac, 424 struct ocfs2_alloc_context *meta_ac,
@@ -520,7 +520,7 @@ bail:
520 * down. 520 * down.
521 */ 521 */
522static int ocfs2_do_insert_extent(struct ocfs2_super *osb, 522static int ocfs2_do_insert_extent(struct ocfs2_super *osb,
523 struct ocfs2_journal_handle *handle, 523 handle_t *handle,
524 struct inode *inode, 524 struct inode *inode,
525 struct buffer_head *fe_bh, 525 struct buffer_head *fe_bh,
526 u64 start_blk, 526 u64 start_blk,
@@ -809,7 +809,7 @@ bail:
809 809
810/* the caller needs to update fe->i_clusters */ 810/* the caller needs to update fe->i_clusters */
811int ocfs2_insert_extent(struct ocfs2_super *osb, 811int ocfs2_insert_extent(struct ocfs2_super *osb,
812 struct ocfs2_journal_handle *handle, 812 handle_t *handle,
813 struct inode *inode, 813 struct inode *inode,
814 struct buffer_head *fe_bh, 814 struct buffer_head *fe_bh,
815 u64 start_blk, 815 u64 start_blk,
@@ -951,7 +951,7 @@ static int ocfs2_truncate_log_can_coalesce(struct ocfs2_truncate_log *tl,
951} 951}
952 952
953static int ocfs2_truncate_log_append(struct ocfs2_super *osb, 953static int ocfs2_truncate_log_append(struct ocfs2_super *osb,
954 struct ocfs2_journal_handle *handle, 954 handle_t *handle,
955 u64 start_blk, 955 u64 start_blk,
956 unsigned int num_clusters) 956 unsigned int num_clusters)
957{ 957{
@@ -1034,7 +1034,7 @@ bail:
1034} 1034}
1035 1035
1036static int ocfs2_replay_truncate_records(struct ocfs2_super *osb, 1036static int ocfs2_replay_truncate_records(struct ocfs2_super *osb,
1037 struct ocfs2_journal_handle *handle, 1037 handle_t *handle,
1038 struct inode *data_alloc_inode, 1038 struct inode *data_alloc_inode,
1039 struct buffer_head *data_alloc_bh) 1039 struct buffer_head *data_alloc_bh)
1040{ 1040{
@@ -1113,7 +1113,7 @@ static int __ocfs2_flush_truncate_log(struct ocfs2_super *osb)
1113{ 1113{
1114 int status; 1114 int status;
1115 unsigned int num_to_flush; 1115 unsigned int num_to_flush;
1116 struct ocfs2_journal_handle *handle = NULL; 1116 handle_t *handle;
1117 struct inode *tl_inode = osb->osb_tl_inode; 1117 struct inode *tl_inode = osb->osb_tl_inode;
1118 struct inode *data_alloc_inode = NULL; 1118 struct inode *data_alloc_inode = NULL;
1119 struct buffer_head *tl_bh = osb->osb_tl_bh; 1119 struct buffer_head *tl_bh = osb->osb_tl_bh;
@@ -1130,7 +1130,7 @@ static int __ocfs2_flush_truncate_log(struct ocfs2_super *osb)
1130 if (!OCFS2_IS_VALID_DINODE(di)) { 1130 if (!OCFS2_IS_VALID_DINODE(di)) {
1131 OCFS2_RO_ON_INVALID_DINODE(osb->sb, di); 1131 OCFS2_RO_ON_INVALID_DINODE(osb->sb, di);
1132 status = -EIO; 1132 status = -EIO;
1133 goto bail; 1133 goto out;
1134 } 1134 }
1135 1135
1136 num_to_flush = le16_to_cpu(tl->tl_used); 1136 num_to_flush = le16_to_cpu(tl->tl_used);
@@ -1138,14 +1138,7 @@ static int __ocfs2_flush_truncate_log(struct ocfs2_super *osb)
1138 num_to_flush, (unsigned long long)OCFS2_I(tl_inode)->ip_blkno); 1138 num_to_flush, (unsigned long long)OCFS2_I(tl_inode)->ip_blkno);
1139 if (!num_to_flush) { 1139 if (!num_to_flush) {
1140 status = 0; 1140 status = 0;
1141 goto bail; 1141 goto out;
1142 }
1143
1144 handle = ocfs2_alloc_handle(osb);
1145 if (!handle) {
1146 status = -ENOMEM;
1147 mlog_errno(status);
1148 goto bail;
1149 } 1142 }
1150 1143
1151 data_alloc_inode = ocfs2_get_system_file_inode(osb, 1144 data_alloc_inode = ocfs2_get_system_file_inode(osb,
@@ -1154,41 +1147,40 @@ static int __ocfs2_flush_truncate_log(struct ocfs2_super *osb)
1154 if (!data_alloc_inode) { 1147 if (!data_alloc_inode) {
1155 status = -EINVAL; 1148 status = -EINVAL;
1156 mlog(ML_ERROR, "Could not get bitmap inode!\n"); 1149 mlog(ML_ERROR, "Could not get bitmap inode!\n");
1157 goto bail; 1150 goto out;
1158 } 1151 }
1159 1152
1160 ocfs2_handle_add_inode(handle, data_alloc_inode); 1153 mutex_lock(&data_alloc_inode->i_mutex);
1161 status = ocfs2_meta_lock(data_alloc_inode, handle, &data_alloc_bh, 1); 1154
1155 status = ocfs2_meta_lock(data_alloc_inode, &data_alloc_bh, 1);
1162 if (status < 0) { 1156 if (status < 0) {
1163 mlog_errno(status); 1157 mlog_errno(status);
1164 goto bail; 1158 goto out_mutex;
1165 } 1159 }
1166 1160
1167 handle = ocfs2_start_trans(osb, handle, OCFS2_TRUNCATE_LOG_UPDATE); 1161 handle = ocfs2_start_trans(osb, OCFS2_TRUNCATE_LOG_UPDATE);
1168 if (IS_ERR(handle)) { 1162 if (IS_ERR(handle)) {
1169 status = PTR_ERR(handle); 1163 status = PTR_ERR(handle);
1170 handle = NULL;
1171 mlog_errno(status); 1164 mlog_errno(status);
1172 goto bail; 1165 goto out_unlock;
1173 } 1166 }
1174 1167
1175 status = ocfs2_replay_truncate_records(osb, handle, data_alloc_inode, 1168 status = ocfs2_replay_truncate_records(osb, handle, data_alloc_inode,
1176 data_alloc_bh); 1169 data_alloc_bh);
1177 if (status < 0) { 1170 if (status < 0)
1178 mlog_errno(status); 1171 mlog_errno(status);
1179 goto bail;
1180 }
1181 1172
1182bail: 1173 ocfs2_commit_trans(osb, handle);
1183 if (handle)
1184 ocfs2_commit_trans(handle);
1185 1174
1186 if (data_alloc_inode) 1175out_unlock:
1187 iput(data_alloc_inode); 1176 brelse(data_alloc_bh);
1177 ocfs2_meta_unlock(data_alloc_inode, 1);
1188 1178
1189 if (data_alloc_bh) 1179out_mutex:
1190 brelse(data_alloc_bh); 1180 mutex_unlock(&data_alloc_inode->i_mutex);
1181 iput(data_alloc_inode);
1191 1182
1183out:
1192 mlog_exit(status); 1184 mlog_exit(status);
1193 return status; 1185 return status;
1194} 1186}
@@ -1349,7 +1341,7 @@ int ocfs2_complete_truncate_log_recovery(struct ocfs2_super *osb,
1349 int i; 1341 int i;
1350 unsigned int clusters, num_recs, start_cluster; 1342 unsigned int clusters, num_recs, start_cluster;
1351 u64 start_blk; 1343 u64 start_blk;
1352 struct ocfs2_journal_handle *handle; 1344 handle_t *handle;
1353 struct inode *tl_inode = osb->osb_tl_inode; 1345 struct inode *tl_inode = osb->osb_tl_inode;
1354 struct ocfs2_truncate_log *tl; 1346 struct ocfs2_truncate_log *tl;
1355 1347
@@ -1375,8 +1367,7 @@ int ocfs2_complete_truncate_log_recovery(struct ocfs2_super *osb,
1375 } 1367 }
1376 } 1368 }
1377 1369
1378 handle = ocfs2_start_trans(osb, NULL, 1370 handle = ocfs2_start_trans(osb, OCFS2_TRUNCATE_LOG_UPDATE);
1379 OCFS2_TRUNCATE_LOG_UPDATE);
1380 if (IS_ERR(handle)) { 1371 if (IS_ERR(handle)) {
1381 status = PTR_ERR(handle); 1372 status = PTR_ERR(handle);
1382 mlog_errno(status); 1373 mlog_errno(status);
@@ -1389,7 +1380,7 @@ int ocfs2_complete_truncate_log_recovery(struct ocfs2_super *osb,
1389 1380
1390 status = ocfs2_truncate_log_append(osb, handle, 1381 status = ocfs2_truncate_log_append(osb, handle,
1391 start_blk, clusters); 1382 start_blk, clusters);
1392 ocfs2_commit_trans(handle); 1383 ocfs2_commit_trans(osb, handle);
1393 if (status < 0) { 1384 if (status < 0) {
1394 mlog_errno(status); 1385 mlog_errno(status);
1395 goto bail_up; 1386 goto bail_up;
@@ -1546,7 +1537,7 @@ static int ocfs2_do_truncate(struct ocfs2_super *osb,
1546 struct inode *inode, 1537 struct inode *inode,
1547 struct buffer_head *fe_bh, 1538 struct buffer_head *fe_bh,
1548 struct buffer_head *old_last_eb_bh, 1539 struct buffer_head *old_last_eb_bh,
1549 struct ocfs2_journal_handle *handle, 1540 handle_t *handle,
1550 struct ocfs2_truncate_context *tc) 1541 struct ocfs2_truncate_context *tc)
1551{ 1542{
1552 int status, i, depth; 1543 int status, i, depth;
@@ -1785,7 +1776,7 @@ int ocfs2_commit_truncate(struct ocfs2_super *osb,
1785 struct ocfs2_extent_block *eb; 1776 struct ocfs2_extent_block *eb;
1786 struct ocfs2_extent_list *el; 1777 struct ocfs2_extent_list *el;
1787 struct buffer_head *last_eb_bh; 1778 struct buffer_head *last_eb_bh;
1788 struct ocfs2_journal_handle *handle = NULL; 1779 handle_t *handle = NULL;
1789 struct inode *tl_inode = osb->osb_tl_inode; 1780 struct inode *tl_inode = osb->osb_tl_inode;
1790 1781
1791 mlog_entry_void(); 1782 mlog_entry_void();
@@ -1871,7 +1862,7 @@ start:
1871 1862
1872 credits = ocfs2_calc_tree_trunc_credits(osb->sb, clusters_to_del, 1863 credits = ocfs2_calc_tree_trunc_credits(osb->sb, clusters_to_del,
1873 fe, el); 1864 fe, el);
1874 handle = ocfs2_start_trans(osb, NULL, credits); 1865 handle = ocfs2_start_trans(osb, credits);
1875 if (IS_ERR(handle)) { 1866 if (IS_ERR(handle)) {
1876 status = PTR_ERR(handle); 1867 status = PTR_ERR(handle);
1877 handle = NULL; 1868 handle = NULL;
@@ -1894,7 +1885,7 @@ start:
1894 mutex_unlock(&tl_inode->i_mutex); 1885 mutex_unlock(&tl_inode->i_mutex);
1895 tl_sem = 0; 1886 tl_sem = 0;
1896 1887
1897 ocfs2_commit_trans(handle); 1888 ocfs2_commit_trans(osb, handle);
1898 handle = NULL; 1889 handle = NULL;
1899 1890
1900 BUG_ON(le32_to_cpu(fe->i_clusters) < target_i_clusters); 1891 BUG_ON(le32_to_cpu(fe->i_clusters) < target_i_clusters);
@@ -1909,7 +1900,7 @@ bail:
1909 mutex_unlock(&tl_inode->i_mutex); 1900 mutex_unlock(&tl_inode->i_mutex);
1910 1901
1911 if (handle) 1902 if (handle)
1912 ocfs2_commit_trans(handle); 1903 ocfs2_commit_trans(osb, handle);
1913 1904
1914 if (last_eb_bh) 1905 if (last_eb_bh)
1915 brelse(last_eb_bh); 1906 brelse(last_eb_bh);
@@ -2014,10 +2005,7 @@ int ocfs2_prepare_truncate(struct ocfs2_super *osb,
2014 mutex_lock(&ext_alloc_inode->i_mutex); 2005 mutex_lock(&ext_alloc_inode->i_mutex);
2015 (*tc)->tc_ext_alloc_inode = ext_alloc_inode; 2006 (*tc)->tc_ext_alloc_inode = ext_alloc_inode;
2016 2007
2017 status = ocfs2_meta_lock(ext_alloc_inode, 2008 status = ocfs2_meta_lock(ext_alloc_inode, &ext_alloc_bh, 1);
2018 NULL,
2019 &ext_alloc_bh,
2020 1);
2021 if (status < 0) { 2009 if (status < 0) {
2022 mlog_errno(status); 2010 mlog_errno(status);
2023 goto bail; 2011 goto bail;
diff --git a/fs/ocfs2/alloc.h b/fs/ocfs2/alloc.h
index 12ba897743f4..0b82e8044325 100644
--- a/fs/ocfs2/alloc.h
+++ b/fs/ocfs2/alloc.h
@@ -28,7 +28,7 @@
28 28
29struct ocfs2_alloc_context; 29struct ocfs2_alloc_context;
30int ocfs2_insert_extent(struct ocfs2_super *osb, 30int ocfs2_insert_extent(struct ocfs2_super *osb,
31 struct ocfs2_journal_handle *handle, 31 handle_t *handle,
32 struct inode *inode, 32 struct inode *inode,
33 struct buffer_head *fe_bh, 33 struct buffer_head *fe_bh,
34 u64 blkno, 34 u64 blkno,
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 3d7c082a8f58..2f7268e81520 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -200,7 +200,7 @@ static int ocfs2_readpage(struct file *file, struct page *page)
200 200
201 mlog_entry("(0x%p, %lu)\n", file, (page ? page->index : 0)); 201 mlog_entry("(0x%p, %lu)\n", file, (page ? page->index : 0));
202 202
203 ret = ocfs2_meta_lock_with_page(inode, NULL, NULL, 0, page); 203 ret = ocfs2_meta_lock_with_page(inode, NULL, 0, page);
204 if (ret != 0) { 204 if (ret != 0) {
205 if (ret == AOP_TRUNCATED_PAGE) 205 if (ret == AOP_TRUNCATED_PAGE)
206 unlock = 0; 206 unlock = 0;
@@ -305,7 +305,7 @@ static int ocfs2_prepare_write(struct file *file, struct page *page,
305 305
306 mlog_entry("(0x%p, 0x%p, %u, %u)\n", file, page, from, to); 306 mlog_entry("(0x%p, 0x%p, %u, %u)\n", file, page, from, to);
307 307
308 ret = ocfs2_meta_lock_with_page(inode, NULL, NULL, 0, page); 308 ret = ocfs2_meta_lock_with_page(inode, NULL, 0, page);
309 if (ret != 0) { 309 if (ret != 0) {
310 mlog_errno(ret); 310 mlog_errno(ret);
311 goto out; 311 goto out;
@@ -355,16 +355,16 @@ static int walk_page_buffers( handle_t *handle,
355 return ret; 355 return ret;
356} 356}
357 357
358struct ocfs2_journal_handle *ocfs2_start_walk_page_trans(struct inode *inode, 358handle_t *ocfs2_start_walk_page_trans(struct inode *inode,
359 struct page *page, 359 struct page *page,
360 unsigned from, 360 unsigned from,
361 unsigned to) 361 unsigned to)
362{ 362{
363 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 363 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
364 struct ocfs2_journal_handle *handle = NULL; 364 handle_t *handle = NULL;
365 int ret = 0; 365 int ret = 0;
366 366
367 handle = ocfs2_start_trans(osb, NULL, OCFS2_INODE_UPDATE_CREDITS); 367 handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
368 if (!handle) { 368 if (!handle) {
369 ret = -ENOMEM; 369 ret = -ENOMEM;
370 mlog_errno(ret); 370 mlog_errno(ret);
@@ -372,7 +372,7 @@ struct ocfs2_journal_handle *ocfs2_start_walk_page_trans(struct inode *inode,
372 } 372 }
373 373
374 if (ocfs2_should_order_data(inode)) { 374 if (ocfs2_should_order_data(inode)) {
375 ret = walk_page_buffers(handle->k_handle, 375 ret = walk_page_buffers(handle,
376 page_buffers(page), 376 page_buffers(page),
377 from, to, NULL, 377 from, to, NULL,
378 ocfs2_journal_dirty_data); 378 ocfs2_journal_dirty_data);
@@ -382,7 +382,7 @@ struct ocfs2_journal_handle *ocfs2_start_walk_page_trans(struct inode *inode,
382out: 382out:
383 if (ret) { 383 if (ret) {
384 if (handle) 384 if (handle)
385 ocfs2_commit_trans(handle); 385 ocfs2_commit_trans(osb, handle);
386 handle = ERR_PTR(ret); 386 handle = ERR_PTR(ret);
387 } 387 }
388 return handle; 388 return handle;
@@ -394,7 +394,7 @@ static int ocfs2_commit_write(struct file *file, struct page *page,
394 int ret; 394 int ret;
395 struct buffer_head *di_bh = NULL; 395 struct buffer_head *di_bh = NULL;
396 struct inode *inode = page->mapping->host; 396 struct inode *inode = page->mapping->host;
397 struct ocfs2_journal_handle *handle = NULL; 397 handle_t *handle = NULL;
398 struct ocfs2_dinode *di; 398 struct ocfs2_dinode *di;
399 399
400 mlog_entry("(0x%p, 0x%p, %u, %u)\n", file, page, from, to); 400 mlog_entry("(0x%p, 0x%p, %u, %u)\n", file, page, from, to);
@@ -412,7 +412,7 @@ static int ocfs2_commit_write(struct file *file, struct page *page,
412 * stale inode allocation image (i_size, i_clusters, etc). 412 * stale inode allocation image (i_size, i_clusters, etc).
413 */ 413 */
414 414
415 ret = ocfs2_meta_lock_with_page(inode, NULL, &di_bh, 1, page); 415 ret = ocfs2_meta_lock_with_page(inode, &di_bh, 1, page);
416 if (ret != 0) { 416 if (ret != 0) {
417 mlog_errno(ret); 417 mlog_errno(ret);
418 goto out; 418 goto out;
@@ -464,7 +464,7 @@ static int ocfs2_commit_write(struct file *file, struct page *page,
464 } 464 }
465 465
466out_commit: 466out_commit:
467 ocfs2_commit_trans(handle); 467 ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
468out_unlock_data: 468out_unlock_data:
469 ocfs2_data_unlock(inode, 1); 469 ocfs2_data_unlock(inode, 1);
470out_unlock_meta: 470out_unlock_meta:
@@ -490,7 +490,7 @@ static sector_t ocfs2_bmap(struct address_space *mapping, sector_t block)
490 * accessed concurrently from multiple nodes. 490 * accessed concurrently from multiple nodes.
491 */ 491 */
492 if (!INODE_JOURNAL(inode)) { 492 if (!INODE_JOURNAL(inode)) {
493 err = ocfs2_meta_lock(inode, NULL, NULL, 0); 493 err = ocfs2_meta_lock(inode, NULL, 0);
494 if (err) { 494 if (err) {
495 if (err != -ENOENT) 495 if (err != -ENOENT)
496 mlog_errno(err); 496 mlog_errno(err);
diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h
index e88c3f0b8fa9..f446a15eab88 100644
--- a/fs/ocfs2/aops.h
+++ b/fs/ocfs2/aops.h
@@ -25,7 +25,7 @@
25int ocfs2_prepare_write_nolock(struct inode *inode, struct page *page, 25int ocfs2_prepare_write_nolock(struct inode *inode, struct page *page,
26 unsigned from, unsigned to); 26 unsigned from, unsigned to);
27 27
28struct ocfs2_journal_handle *ocfs2_start_walk_page_trans(struct inode *inode, 28handle_t *ocfs2_start_walk_page_trans(struct inode *inode,
29 struct page *page, 29 struct page *page,
30 unsigned from, 30 unsigned from,
31 unsigned to); 31 unsigned to);
diff --git a/fs/ocfs2/dir.c b/fs/ocfs2/dir.c
index 04e01915b86e..baad2aa27c14 100644
--- a/fs/ocfs2/dir.c
+++ b/fs/ocfs2/dir.c
@@ -82,6 +82,7 @@ int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir)
82 struct inode *inode = filp->f_dentry->d_inode; 82 struct inode *inode = filp->f_dentry->d_inode;
83 struct super_block * sb = inode->i_sb; 83 struct super_block * sb = inode->i_sb;
84 unsigned int ra_sectors = 16; 84 unsigned int ra_sectors = 16;
85 int lock_level = 0;
85 86
86 mlog_entry("dirino=%llu\n", 87 mlog_entry("dirino=%llu\n",
87 (unsigned long long)OCFS2_I(inode)->ip_blkno); 88 (unsigned long long)OCFS2_I(inode)->ip_blkno);
@@ -89,7 +90,15 @@ int ocfs2_readdir(struct file * filp, void * dirent, filldir_t filldir)
89 stored = 0; 90 stored = 0;
90 bh = NULL; 91 bh = NULL;
91 92
92 error = ocfs2_meta_lock(inode, NULL, NULL, 0); 93 error = ocfs2_meta_lock_atime(inode, filp->f_vfsmnt, &lock_level);
94 if (lock_level && error >= 0) {
95 /* We release EX lock which used to update atime
96 * and get PR lock again to reduce contention
97 * on commonly accessed directories. */
98 ocfs2_meta_unlock(inode, 1);
99 lock_level = 0;
100 error = ocfs2_meta_lock(inode, NULL, 0);
101 }
93 if (error < 0) { 102 if (error < 0) {
94 if (error != -ENOENT) 103 if (error != -ENOENT)
95 mlog_errno(error); 104 mlog_errno(error);
@@ -198,7 +207,7 @@ revalidate:
198 207
199 stored = 0; 208 stored = 0;
200bail: 209bail:
201 ocfs2_meta_unlock(inode, 0); 210 ocfs2_meta_unlock(inode, lock_level);
202 211
203bail_nolock: 212bail_nolock:
204 mlog_exit(stored); 213 mlog_exit(stored);
@@ -340,7 +349,7 @@ int ocfs2_empty_dir(struct inode *inode)
340 349
341/* returns a bh of the 1st new block in the allocation. */ 350/* returns a bh of the 1st new block in the allocation. */
342int ocfs2_do_extend_dir(struct super_block *sb, 351int ocfs2_do_extend_dir(struct super_block *sb,
343 struct ocfs2_journal_handle *handle, 352 handle_t *handle,
344 struct inode *dir, 353 struct inode *dir,
345 struct buffer_head *parent_fe_bh, 354 struct buffer_head *parent_fe_bh,
346 struct ocfs2_alloc_context *data_ac, 355 struct ocfs2_alloc_context *data_ac,
@@ -398,7 +407,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
398 struct ocfs2_dinode *fe = (struct ocfs2_dinode *) parent_fe_bh->b_data; 407 struct ocfs2_dinode *fe = (struct ocfs2_dinode *) parent_fe_bh->b_data;
399 struct ocfs2_alloc_context *data_ac = NULL; 408 struct ocfs2_alloc_context *data_ac = NULL;
400 struct ocfs2_alloc_context *meta_ac = NULL; 409 struct ocfs2_alloc_context *meta_ac = NULL;
401 struct ocfs2_journal_handle *handle = NULL; 410 handle_t *handle = NULL;
402 struct buffer_head *new_bh = NULL; 411 struct buffer_head *new_bh = NULL;
403 struct ocfs2_dir_entry * de; 412 struct ocfs2_dir_entry * de;
404 struct super_block *sb = osb->sb; 413 struct super_block *sb = osb->sb;
@@ -409,13 +418,6 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
409 mlog(0, "extending dir %llu (i_size = %lld)\n", 418 mlog(0, "extending dir %llu (i_size = %lld)\n",
410 (unsigned long long)OCFS2_I(dir)->ip_blkno, dir_i_size); 419 (unsigned long long)OCFS2_I(dir)->ip_blkno, dir_i_size);
411 420
412 handle = ocfs2_alloc_handle(osb);
413 if (handle == NULL) {
414 status = -ENOMEM;
415 mlog_errno(status);
416 goto bail;
417 }
418
419 /* dir->i_size is always block aligned. */ 421 /* dir->i_size is always block aligned. */
420 spin_lock(&OCFS2_I(dir)->ip_lock); 422 spin_lock(&OCFS2_I(dir)->ip_lock);
421 if (dir_i_size == ocfs2_clusters_to_bytes(sb, OCFS2_I(dir)->ip_clusters)) { 423 if (dir_i_size == ocfs2_clusters_to_bytes(sb, OCFS2_I(dir)->ip_clusters)) {
@@ -428,8 +430,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
428 } 430 }
429 431
430 if (!num_free_extents) { 432 if (!num_free_extents) {
431 status = ocfs2_reserve_new_metadata(osb, handle, 433 status = ocfs2_reserve_new_metadata(osb, fe, &meta_ac);
432 fe, &meta_ac);
433 if (status < 0) { 434 if (status < 0) {
434 if (status != -ENOSPC) 435 if (status != -ENOSPC)
435 mlog_errno(status); 436 mlog_errno(status);
@@ -437,7 +438,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
437 } 438 }
438 } 439 }
439 440
440 status = ocfs2_reserve_clusters(osb, handle, 1, &data_ac); 441 status = ocfs2_reserve_clusters(osb, 1, &data_ac);
441 if (status < 0) { 442 if (status < 0) {
442 if (status != -ENOSPC) 443 if (status != -ENOSPC)
443 mlog_errno(status); 444 mlog_errno(status);
@@ -450,7 +451,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
450 credits = OCFS2_SIMPLE_DIR_EXTEND_CREDITS; 451 credits = OCFS2_SIMPLE_DIR_EXTEND_CREDITS;
451 } 452 }
452 453
453 handle = ocfs2_start_trans(osb, handle, credits); 454 handle = ocfs2_start_trans(osb, credits);
454 if (IS_ERR(handle)) { 455 if (IS_ERR(handle)) {
455 status = PTR_ERR(handle); 456 status = PTR_ERR(handle);
456 handle = NULL; 457 handle = NULL;
@@ -496,7 +497,7 @@ static int ocfs2_extend_dir(struct ocfs2_super *osb,
496 get_bh(*new_de_bh); 497 get_bh(*new_de_bh);
497bail: 498bail:
498 if (handle) 499 if (handle)
499 ocfs2_commit_trans(handle); 500 ocfs2_commit_trans(osb, handle);
500 501
501 if (data_ac) 502 if (data_ac)
502 ocfs2_free_alloc_context(data_ac); 503 ocfs2_free_alloc_context(data_ac);
diff --git a/fs/ocfs2/dir.h b/fs/ocfs2/dir.h
index 5f614ec9649c..3f67e146864a 100644
--- a/fs/ocfs2/dir.h
+++ b/fs/ocfs2/dir.h
@@ -45,7 +45,7 @@ int ocfs2_prepare_dir_for_insert(struct ocfs2_super *osb,
45 struct buffer_head **ret_de_bh); 45 struct buffer_head **ret_de_bh);
46struct ocfs2_alloc_context; 46struct ocfs2_alloc_context;
47int ocfs2_do_extend_dir(struct super_block *sb, 47int ocfs2_do_extend_dir(struct super_block *sb,
48 struct ocfs2_journal_handle *handle, 48 handle_t *handle,
49 struct inode *dir, 49 struct inode *dir,
50 struct buffer_head *parent_fe_bh, 50 struct buffer_head *parent_fe_bh,
51 struct ocfs2_alloc_context *data_ac, 51 struct ocfs2_alloc_context *data_ac,
diff --git a/fs/ocfs2/dlm/dlmdomain.c b/fs/ocfs2/dlm/dlmdomain.c
index 637646e6922e..420a375a3949 100644
--- a/fs/ocfs2/dlm/dlmdomain.c
+++ b/fs/ocfs2/dlm/dlmdomain.c
@@ -68,7 +68,8 @@ static void **dlm_alloc_pagevec(int pages)
68 goto out_free; 68 goto out_free;
69 69
70 mlog(0, "Allocated DLM hash pagevec; %d pages (%lu expected), %lu buckets per page\n", 70 mlog(0, "Allocated DLM hash pagevec; %d pages (%lu expected), %lu buckets per page\n",
71 pages, DLM_HASH_PAGES, (unsigned long)DLM_BUCKETS_PER_PAGE); 71 pages, (unsigned long)DLM_HASH_PAGES,
72 (unsigned long)DLM_BUCKETS_PER_PAGE);
72 return vec; 73 return vec;
73out_free: 74out_free:
74 dlm_free_pagevec(vec, i); 75 dlm_free_pagevec(vec, i);
diff --git a/fs/ocfs2/dlmglue.c b/fs/ocfs2/dlmglue.c
index 8801e41afe80..69fba16efbd1 100644
--- a/fs/ocfs2/dlmglue.c
+++ b/fs/ocfs2/dlmglue.c
@@ -49,6 +49,7 @@
49#include "dcache.h" 49#include "dcache.h"
50#include "dlmglue.h" 50#include "dlmglue.h"
51#include "extent_map.h" 51#include "extent_map.h"
52#include "file.h"
52#include "heartbeat.h" 53#include "heartbeat.h"
53#include "inode.h" 54#include "inode.h"
54#include "journal.h" 55#include "journal.h"
@@ -1063,10 +1064,10 @@ static void ocfs2_cluster_unlock(struct ocfs2_super *osb,
1063 mlog_exit_void(); 1064 mlog_exit_void();
1064} 1065}
1065 1066
1066int ocfs2_create_new_lock(struct ocfs2_super *osb, 1067static int ocfs2_create_new_lock(struct ocfs2_super *osb,
1067 struct ocfs2_lock_res *lockres, 1068 struct ocfs2_lock_res *lockres,
1068 int ex, 1069 int ex,
1069 int local) 1070 int local)
1070{ 1071{
1071 int level = ex ? LKM_EXMODE : LKM_PRMODE; 1072 int level = ex ? LKM_EXMODE : LKM_PRMODE;
1072 unsigned long flags; 1073 unsigned long flags;
@@ -1579,7 +1580,6 @@ static int ocfs2_assign_bh(struct inode *inode,
1579 * the result of the lock will be communicated via the callback. 1580 * the result of the lock will be communicated via the callback.
1580 */ 1581 */
1581int ocfs2_meta_lock_full(struct inode *inode, 1582int ocfs2_meta_lock_full(struct inode *inode,
1582 struct ocfs2_journal_handle *handle,
1583 struct buffer_head **ret_bh, 1583 struct buffer_head **ret_bh,
1584 int ex, 1584 int ex,
1585 int arg_flags) 1585 int arg_flags)
@@ -1668,12 +1668,6 @@ int ocfs2_meta_lock_full(struct inode *inode,
1668 } 1668 }
1669 } 1669 }
1670 1670
1671 if (handle) {
1672 status = ocfs2_handle_add_lock(handle, inode);
1673 if (status < 0)
1674 mlog_errno(status);
1675 }
1676
1677bail: 1671bail:
1678 if (status < 0) { 1672 if (status < 0) {
1679 if (ret_bh && (*ret_bh)) { 1673 if (ret_bh && (*ret_bh)) {
@@ -1713,18 +1707,16 @@ bail:
1713 * the lock inversion simply. 1707 * the lock inversion simply.
1714 */ 1708 */
1715int ocfs2_meta_lock_with_page(struct inode *inode, 1709int ocfs2_meta_lock_with_page(struct inode *inode,
1716 struct ocfs2_journal_handle *handle,
1717 struct buffer_head **ret_bh, 1710 struct buffer_head **ret_bh,
1718 int ex, 1711 int ex,
1719 struct page *page) 1712 struct page *page)
1720{ 1713{
1721 int ret; 1714 int ret;
1722 1715
1723 ret = ocfs2_meta_lock_full(inode, handle, ret_bh, ex, 1716 ret = ocfs2_meta_lock_full(inode, ret_bh, ex, OCFS2_LOCK_NONBLOCK);
1724 OCFS2_LOCK_NONBLOCK);
1725 if (ret == -EAGAIN) { 1717 if (ret == -EAGAIN) {
1726 unlock_page(page); 1718 unlock_page(page);
1727 if (ocfs2_meta_lock(inode, handle, ret_bh, ex) == 0) 1719 if (ocfs2_meta_lock(inode, ret_bh, ex) == 0)
1728 ocfs2_meta_unlock(inode, ex); 1720 ocfs2_meta_unlock(inode, ex);
1729 ret = AOP_TRUNCATED_PAGE; 1721 ret = AOP_TRUNCATED_PAGE;
1730 } 1722 }
@@ -1732,6 +1724,44 @@ int ocfs2_meta_lock_with_page(struct inode *inode,
1732 return ret; 1724 return ret;
1733} 1725}
1734 1726
1727int ocfs2_meta_lock_atime(struct inode *inode,
1728 struct vfsmount *vfsmnt,
1729 int *level)
1730{
1731 int ret;
1732
1733 mlog_entry_void();
1734 ret = ocfs2_meta_lock(inode, NULL, 0);
1735 if (ret < 0) {
1736 mlog_errno(ret);
1737 return ret;
1738 }
1739
1740 /*
1741 * If we should update atime, we will get EX lock,
1742 * otherwise we just get PR lock.
1743 */
1744 if (ocfs2_should_update_atime(inode, vfsmnt)) {
1745 struct buffer_head *bh = NULL;
1746
1747 ocfs2_meta_unlock(inode, 0);
1748 ret = ocfs2_meta_lock(inode, &bh, 1);
1749 if (ret < 0) {
1750 mlog_errno(ret);
1751 return ret;
1752 }
1753 *level = 1;
1754 if (ocfs2_should_update_atime(inode, vfsmnt))
1755 ocfs2_update_inode_atime(inode, bh);
1756 if (bh)
1757 brelse(bh);
1758 } else
1759 *level = 0;
1760
1761 mlog_exit(ret);
1762 return ret;
1763}
1764
1735void ocfs2_meta_unlock(struct inode *inode, 1765void ocfs2_meta_unlock(struct inode *inode,
1736 int ex) 1766 int ex)
1737{ 1767{
diff --git a/fs/ocfs2/dlmglue.h b/fs/ocfs2/dlmglue.h
index 4a2769387229..c343fca68cf1 100644
--- a/fs/ocfs2/dlmglue.h
+++ b/fs/ocfs2/dlmglue.h
@@ -68,8 +68,6 @@ void ocfs2_dentry_lock_res_init(struct ocfs2_dentry_lock *dl,
68 u64 parent, struct inode *inode); 68 u64 parent, struct inode *inode);
69void ocfs2_lock_res_free(struct ocfs2_lock_res *res); 69void ocfs2_lock_res_free(struct ocfs2_lock_res *res);
70int ocfs2_create_new_inode_locks(struct inode *inode); 70int ocfs2_create_new_inode_locks(struct inode *inode);
71int ocfs2_create_new_lock(struct ocfs2_super *osb,
72 struct ocfs2_lock_res *lockres, int ex, int local);
73int ocfs2_drop_inode_locks(struct inode *inode); 71int ocfs2_drop_inode_locks(struct inode *inode);
74int ocfs2_data_lock_full(struct inode *inode, 72int ocfs2_data_lock_full(struct inode *inode,
75 int write, 73 int write,
@@ -82,19 +80,20 @@ void ocfs2_data_unlock(struct inode *inode,
82 int write); 80 int write);
83int ocfs2_rw_lock(struct inode *inode, int write); 81int ocfs2_rw_lock(struct inode *inode, int write);
84void ocfs2_rw_unlock(struct inode *inode, int write); 82void ocfs2_rw_unlock(struct inode *inode, int write);
83int ocfs2_meta_lock_atime(struct inode *inode,
84 struct vfsmount *vfsmnt,
85 int *level);
85int ocfs2_meta_lock_full(struct inode *inode, 86int ocfs2_meta_lock_full(struct inode *inode,
86 struct ocfs2_journal_handle *handle,
87 struct buffer_head **ret_bh, 87 struct buffer_head **ret_bh,
88 int ex, 88 int ex,
89 int arg_flags); 89 int arg_flags);
90int ocfs2_meta_lock_with_page(struct inode *inode, 90int ocfs2_meta_lock_with_page(struct inode *inode,
91 struct ocfs2_journal_handle *handle,
92 struct buffer_head **ret_bh, 91 struct buffer_head **ret_bh,
93 int ex, 92 int ex,
94 struct page *page); 93 struct page *page);
95/* 99% of the time we don't want to supply any additional flags -- 94/* 99% of the time we don't want to supply any additional flags --
96 * those are for very specific cases only. */ 95 * those are for very specific cases only. */
97#define ocfs2_meta_lock(i, h, b, e) ocfs2_meta_lock_full(i, h, b, e, 0) 96#define ocfs2_meta_lock(i, b, e) ocfs2_meta_lock_full(i, b, e, 0)
98void ocfs2_meta_unlock(struct inode *inode, 97void ocfs2_meta_unlock(struct inode *inode,
99 int ex); 98 int ex);
100int ocfs2_super_lock(struct ocfs2_super *osb, 99int ocfs2_super_lock(struct ocfs2_super *osb,
diff --git a/fs/ocfs2/export.c b/fs/ocfs2/export.c
index fb91089a60a7..06be6e774cf9 100644
--- a/fs/ocfs2/export.c
+++ b/fs/ocfs2/export.c
@@ -100,7 +100,7 @@ static struct dentry *ocfs2_get_parent(struct dentry *child)
100 mlog(0, "find parent of directory %llu\n", 100 mlog(0, "find parent of directory %llu\n",
101 (unsigned long long)OCFS2_I(dir)->ip_blkno); 101 (unsigned long long)OCFS2_I(dir)->ip_blkno);
102 102
103 status = ocfs2_meta_lock(dir, NULL, NULL, 0); 103 status = ocfs2_meta_lock(dir, NULL, 0);
104 if (status < 0) { 104 if (status < 0) {
105 if (status != -ENOENT) 105 if (status != -ENOENT)
106 mlog_errno(status); 106 mlog_errno(status);
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index 1be74c4e7814..8786b3c490aa 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -31,6 +31,8 @@
31#include <linux/pagemap.h> 31#include <linux/pagemap.h>
32#include <linux/uio.h> 32#include <linux/uio.h>
33#include <linux/sched.h> 33#include <linux/sched.h>
34#include <linux/pipe_fs_i.h>
35#include <linux/mount.h>
34 36
35#define MLOG_MASK_PREFIX ML_INODE 37#define MLOG_MASK_PREFIX ML_INODE
36#include <cluster/masklog.h> 38#include <cluster/masklog.h>
@@ -134,7 +136,58 @@ bail:
134 return (err < 0) ? -EIO : 0; 136 return (err < 0) ? -EIO : 0;
135} 137}
136 138
137int ocfs2_set_inode_size(struct ocfs2_journal_handle *handle, 139int ocfs2_should_update_atime(struct inode *inode,
140 struct vfsmount *vfsmnt)
141{
142 struct timespec now;
143 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
144
145 if (ocfs2_is_hard_readonly(osb) || ocfs2_is_soft_readonly(osb))
146 return 0;
147
148 if ((inode->i_flags & S_NOATIME) ||
149 ((inode->i_sb->s_flags & MS_NODIRATIME) && S_ISDIR(inode->i_mode)))
150 return 0;
151
152 if ((vfsmnt->mnt_flags & MNT_NOATIME) ||
153 ((vfsmnt->mnt_flags & MNT_NODIRATIME) && S_ISDIR(inode->i_mode)))
154 return 0;
155
156 now = CURRENT_TIME;
157 if ((now.tv_sec - inode->i_atime.tv_sec <= osb->s_atime_quantum))
158 return 0;
159 else
160 return 1;
161}
162
163int ocfs2_update_inode_atime(struct inode *inode,
164 struct buffer_head *bh)
165{
166 int ret;
167 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
168 handle_t *handle;
169
170 mlog_entry_void();
171
172 handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
173 if (handle == NULL) {
174 ret = -ENOMEM;
175 mlog_errno(ret);
176 goto out;
177 }
178
179 inode->i_atime = CURRENT_TIME;
180 ret = ocfs2_mark_inode_dirty(handle, inode, bh);
181 if (ret < 0)
182 mlog_errno(ret);
183
184 ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
185out:
186 mlog_exit(ret);
187 return ret;
188}
189
190int ocfs2_set_inode_size(handle_t *handle,
138 struct inode *inode, 191 struct inode *inode,
139 struct buffer_head *fe_bh, 192 struct buffer_head *fe_bh,
140 u64 new_i_size) 193 u64 new_i_size)
@@ -163,10 +216,9 @@ static int ocfs2_simple_size_update(struct inode *inode,
163{ 216{
164 int ret; 217 int ret;
165 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 218 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
166 struct ocfs2_journal_handle *handle = NULL; 219 handle_t *handle = NULL;
167 220
168 handle = ocfs2_start_trans(osb, NULL, 221 handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
169 OCFS2_INODE_UPDATE_CREDITS);
170 if (handle == NULL) { 222 if (handle == NULL) {
171 ret = -ENOMEM; 223 ret = -ENOMEM;
172 mlog_errno(ret); 224 mlog_errno(ret);
@@ -178,7 +230,7 @@ static int ocfs2_simple_size_update(struct inode *inode,
178 if (ret < 0) 230 if (ret < 0)
179 mlog_errno(ret); 231 mlog_errno(ret);
180 232
181 ocfs2_commit_trans(handle); 233 ocfs2_commit_trans(osb, handle);
182out: 234out:
183 return ret; 235 return ret;
184} 236}
@@ -189,14 +241,14 @@ static int ocfs2_orphan_for_truncate(struct ocfs2_super *osb,
189 u64 new_i_size) 241 u64 new_i_size)
190{ 242{
191 int status; 243 int status;
192 struct ocfs2_journal_handle *handle; 244 handle_t *handle;
193 245
194 mlog_entry_void(); 246 mlog_entry_void();
195 247
196 /* TODO: This needs to actually orphan the inode in this 248 /* TODO: This needs to actually orphan the inode in this
197 * transaction. */ 249 * transaction. */
198 250
199 handle = ocfs2_start_trans(osb, NULL, OCFS2_INODE_UPDATE_CREDITS); 251 handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
200 if (IS_ERR(handle)) { 252 if (IS_ERR(handle)) {
201 status = PTR_ERR(handle); 253 status = PTR_ERR(handle);
202 mlog_errno(status); 254 mlog_errno(status);
@@ -207,7 +259,7 @@ static int ocfs2_orphan_for_truncate(struct ocfs2_super *osb,
207 if (status < 0) 259 if (status < 0)
208 mlog_errno(status); 260 mlog_errno(status);
209 261
210 ocfs2_commit_trans(handle); 262 ocfs2_commit_trans(osb, handle);
211out: 263out:
212 mlog_exit(status); 264 mlog_exit(status);
213 return status; 265 return status;
@@ -328,7 +380,7 @@ int ocfs2_do_extend_allocation(struct ocfs2_super *osb,
328 struct inode *inode, 380 struct inode *inode,
329 u32 clusters_to_add, 381 u32 clusters_to_add,
330 struct buffer_head *fe_bh, 382 struct buffer_head *fe_bh,
331 struct ocfs2_journal_handle *handle, 383 handle_t *handle,
332 struct ocfs2_alloc_context *data_ac, 384 struct ocfs2_alloc_context *data_ac,
333 struct ocfs2_alloc_context *meta_ac, 385 struct ocfs2_alloc_context *meta_ac,
334 enum ocfs2_alloc_restarted *reason_ret) 386 enum ocfs2_alloc_restarted *reason_ret)
@@ -433,7 +485,7 @@ static int ocfs2_extend_allocation(struct inode *inode,
433 u32 prev_clusters; 485 u32 prev_clusters;
434 struct buffer_head *bh = NULL; 486 struct buffer_head *bh = NULL;
435 struct ocfs2_dinode *fe = NULL; 487 struct ocfs2_dinode *fe = NULL;
436 struct ocfs2_journal_handle *handle = NULL; 488 handle_t *handle = NULL;
437 struct ocfs2_alloc_context *data_ac = NULL; 489 struct ocfs2_alloc_context *data_ac = NULL;
438 struct ocfs2_alloc_context *meta_ac = NULL; 490 struct ocfs2_alloc_context *meta_ac = NULL;
439 enum ocfs2_alloc_restarted why; 491 enum ocfs2_alloc_restarted why;
@@ -463,13 +515,6 @@ restart_all:
463 (unsigned long long)OCFS2_I(inode)->ip_blkno, i_size_read(inode), 515 (unsigned long long)OCFS2_I(inode)->ip_blkno, i_size_read(inode),
464 fe->i_clusters, clusters_to_add); 516 fe->i_clusters, clusters_to_add);
465 517
466 handle = ocfs2_alloc_handle(osb);
467 if (handle == NULL) {
468 status = -ENOMEM;
469 mlog_errno(status);
470 goto leave;
471 }
472
473 num_free_extents = ocfs2_num_free_extents(osb, 518 num_free_extents = ocfs2_num_free_extents(osb,
474 inode, 519 inode,
475 fe); 520 fe);
@@ -480,10 +525,7 @@ restart_all:
480 } 525 }
481 526
482 if (!num_free_extents) { 527 if (!num_free_extents) {
483 status = ocfs2_reserve_new_metadata(osb, 528 status = ocfs2_reserve_new_metadata(osb, fe, &meta_ac);
484 handle,
485 fe,
486 &meta_ac);
487 if (status < 0) { 529 if (status < 0) {
488 if (status != -ENOSPC) 530 if (status != -ENOSPC)
489 mlog_errno(status); 531 mlog_errno(status);
@@ -491,10 +533,7 @@ restart_all:
491 } 533 }
492 } 534 }
493 535
494 status = ocfs2_reserve_clusters(osb, 536 status = ocfs2_reserve_clusters(osb, clusters_to_add, &data_ac);
495 handle,
496 clusters_to_add,
497 &data_ac);
498 if (status < 0) { 537 if (status < 0) {
499 if (status != -ENOSPC) 538 if (status != -ENOSPC)
500 mlog_errno(status); 539 mlog_errno(status);
@@ -509,7 +548,7 @@ restart_all:
509 drop_alloc_sem = 1; 548 drop_alloc_sem = 1;
510 549
511 credits = ocfs2_calc_extend_credits(osb->sb, fe, clusters_to_add); 550 credits = ocfs2_calc_extend_credits(osb->sb, fe, clusters_to_add);
512 handle = ocfs2_start_trans(osb, handle, credits); 551 handle = ocfs2_start_trans(osb, credits);
513 if (IS_ERR(handle)) { 552 if (IS_ERR(handle)) {
514 status = PTR_ERR(handle); 553 status = PTR_ERR(handle);
515 handle = NULL; 554 handle = NULL;
@@ -589,7 +628,7 @@ leave:
589 drop_alloc_sem = 0; 628 drop_alloc_sem = 0;
590 } 629 }
591 if (handle) { 630 if (handle) {
592 ocfs2_commit_trans(handle); 631 ocfs2_commit_trans(osb, handle);
593 handle = NULL; 632 handle = NULL;
594 } 633 }
595 if (data_ac) { 634 if (data_ac) {
@@ -624,7 +663,7 @@ static int ocfs2_write_zero_page(struct inode *inode,
624 struct page *page; 663 struct page *page;
625 unsigned long index; 664 unsigned long index;
626 unsigned int offset; 665 unsigned int offset;
627 struct ocfs2_journal_handle *handle = NULL; 666 handle_t *handle = NULL;
628 int ret; 667 int ret;
629 668
630 offset = (size & (PAGE_CACHE_SIZE-1)); /* Within page */ 669 offset = (size & (PAGE_CACHE_SIZE-1)); /* Within page */
@@ -668,7 +707,7 @@ static int ocfs2_write_zero_page(struct inode *inode,
668 ret = 0; 707 ret = 0;
669 708
670 if (handle) 709 if (handle)
671 ocfs2_commit_trans(handle); 710 ocfs2_commit_trans(OCFS2_SB(inode->i_sb), handle);
672out_unlock: 711out_unlock:
673 unlock_page(page); 712 unlock_page(page);
674 page_cache_release(page); 713 page_cache_release(page);
@@ -789,7 +828,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
789 struct super_block *sb = inode->i_sb; 828 struct super_block *sb = inode->i_sb;
790 struct ocfs2_super *osb = OCFS2_SB(sb); 829 struct ocfs2_super *osb = OCFS2_SB(sb);
791 struct buffer_head *bh = NULL; 830 struct buffer_head *bh = NULL;
792 struct ocfs2_journal_handle *handle = NULL; 831 handle_t *handle = NULL;
793 832
794 mlog_entry("(0x%p, '%.*s')\n", dentry, 833 mlog_entry("(0x%p, '%.*s')\n", dentry,
795 dentry->d_name.len, dentry->d_name.name); 834 dentry->d_name.len, dentry->d_name.name);
@@ -825,7 +864,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
825 } 864 }
826 } 865 }
827 866
828 status = ocfs2_meta_lock(inode, NULL, &bh, 1); 867 status = ocfs2_meta_lock(inode, &bh, 1);
829 if (status < 0) { 868 if (status < 0) {
830 if (status != -ENOENT) 869 if (status != -ENOENT)
831 mlog_errno(status); 870 mlog_errno(status);
@@ -845,7 +884,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
845 } 884 }
846 } 885 }
847 886
848 handle = ocfs2_start_trans(osb, NULL, OCFS2_INODE_UPDATE_CREDITS); 887 handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
849 if (IS_ERR(handle)) { 888 if (IS_ERR(handle)) {
850 status = PTR_ERR(handle); 889 status = PTR_ERR(handle);
851 mlog_errno(status); 890 mlog_errno(status);
@@ -863,7 +902,7 @@ int ocfs2_setattr(struct dentry *dentry, struct iattr *attr)
863 mlog_errno(status); 902 mlog_errno(status);
864 903
865bail_commit: 904bail_commit:
866 ocfs2_commit_trans(handle); 905 ocfs2_commit_trans(osb, handle);
867bail_unlock: 906bail_unlock:
868 ocfs2_meta_unlock(inode, 1); 907 ocfs2_meta_unlock(inode, 1);
869bail_unlock_rw: 908bail_unlock_rw:
@@ -906,19 +945,41 @@ bail:
906 return err; 945 return err;
907} 946}
908 947
948int ocfs2_permission(struct inode *inode, int mask, struct nameidata *nd)
949{
950 int ret;
951
952 mlog_entry_void();
953
954 ret = ocfs2_meta_lock(inode, NULL, 0);
955 if (ret) {
956 mlog_errno(ret);
957 goto out;
958 }
959
960 ret = generic_permission(inode, mask, NULL);
961 if (ret)
962 mlog_errno(ret);
963
964 ocfs2_meta_unlock(inode, 0);
965out:
966 mlog_exit(ret);
967 return ret;
968}
969
909static int ocfs2_write_remove_suid(struct inode *inode) 970static int ocfs2_write_remove_suid(struct inode *inode)
910{ 971{
911 int ret; 972 int ret;
912 struct buffer_head *bh = NULL; 973 struct buffer_head *bh = NULL;
913 struct ocfs2_inode_info *oi = OCFS2_I(inode); 974 struct ocfs2_inode_info *oi = OCFS2_I(inode);
914 struct ocfs2_journal_handle *handle; 975 handle_t *handle;
915 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 976 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
916 struct ocfs2_dinode *di; 977 struct ocfs2_dinode *di;
917 978
918 mlog_entry("(Inode %llu, mode 0%o)\n", 979 mlog_entry("(Inode %llu, mode 0%o)\n",
919 (unsigned long long)oi->ip_blkno, inode->i_mode); 980 (unsigned long long)oi->ip_blkno, inode->i_mode);
920 981
921 handle = ocfs2_start_trans(osb, NULL, OCFS2_INODE_UPDATE_CREDITS); 982 handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
922 if (handle == NULL) { 983 if (handle == NULL) {
923 ret = -ENOMEM; 984 ret = -ENOMEM;
924 mlog_errno(ret); 985 mlog_errno(ret);
@@ -951,75 +1012,29 @@ static int ocfs2_write_remove_suid(struct inode *inode)
951out_bh: 1012out_bh:
952 brelse(bh); 1013 brelse(bh);
953out_trans: 1014out_trans:
954 ocfs2_commit_trans(handle); 1015 ocfs2_commit_trans(osb, handle);
955out: 1016out:
956 mlog_exit(ret); 1017 mlog_exit(ret);
957 return ret; 1018 return ret;
958} 1019}
959 1020
960static inline int ocfs2_write_should_remove_suid(struct inode *inode) 1021static int ocfs2_prepare_inode_for_write(struct dentry *dentry,
961{ 1022 loff_t *ppos,
962 mode_t mode = inode->i_mode; 1023 size_t count,
963 1024 int appending)
964 if (!capable(CAP_FSETID)) {
965 if (unlikely(mode & S_ISUID))
966 return 1;
967
968 if (unlikely((mode & S_ISGID) && (mode & S_IXGRP)))
969 return 1;
970 }
971 return 0;
972}
973
974static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
975 const struct iovec *iov,
976 unsigned long nr_segs,
977 loff_t pos)
978{ 1025{
979 int ret, rw_level = -1, meta_level = -1, have_alloc_sem = 0; 1026 int ret = 0, meta_level = appending;
1027 struct inode *inode = dentry->d_inode;
980 u32 clusters; 1028 u32 clusters;
981 struct file *filp = iocb->ki_filp;
982 struct inode *inode = filp->f_dentry->d_inode;
983 loff_t newsize, saved_pos; 1029 loff_t newsize, saved_pos;
984 1030
985 mlog_entry("(0x%p, %u, '%.*s')\n", filp,
986 (unsigned int)nr_segs,
987 filp->f_dentry->d_name.len,
988 filp->f_dentry->d_name.name);
989
990 /* happy write of zero bytes */
991 if (iocb->ki_left == 0)
992 return 0;
993
994 if (!inode) {
995 mlog(0, "bad inode\n");
996 return -EIO;
997 }
998
999 mutex_lock(&inode->i_mutex);
1000 /* to match setattr's i_mutex -> i_alloc_sem -> rw_lock ordering */
1001 if (filp->f_flags & O_DIRECT) {
1002 have_alloc_sem = 1;
1003 down_read(&inode->i_alloc_sem);
1004 }
1005
1006 /* concurrent O_DIRECT writes are allowed */
1007 rw_level = (filp->f_flags & O_DIRECT) ? 0 : 1;
1008 ret = ocfs2_rw_lock(inode, rw_level);
1009 if (ret < 0) {
1010 rw_level = -1;
1011 mlog_errno(ret);
1012 goto out;
1013 }
1014
1015 /* 1031 /*
1016 * We sample i_size under a read level meta lock to see if our write 1032 * We sample i_size under a read level meta lock to see if our write
1017 * is extending the file, if it is we back off and get a write level 1033 * is extending the file, if it is we back off and get a write level
1018 * meta lock. 1034 * meta lock.
1019 */ 1035 */
1020 meta_level = (filp->f_flags & O_APPEND) ? 1 : 0;
1021 for(;;) { 1036 for(;;) {
1022 ret = ocfs2_meta_lock(inode, NULL, NULL, meta_level); 1037 ret = ocfs2_meta_lock(inode, NULL, meta_level);
1023 if (ret < 0) { 1038 if (ret < 0) {
1024 meta_level = -1; 1039 meta_level = -1;
1025 mlog_errno(ret); 1040 mlog_errno(ret);
@@ -1035,7 +1050,7 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
1035 * inode. There's also the dinode i_size state which 1050 * inode. There's also the dinode i_size state which
1036 * can be lost via setattr during extending writes (we 1051 * can be lost via setattr during extending writes (we
1037 * set inode->i_size at the end of a write. */ 1052 * set inode->i_size at the end of a write. */
1038 if (ocfs2_write_should_remove_suid(inode)) { 1053 if (should_remove_suid(dentry)) {
1039 if (meta_level == 0) { 1054 if (meta_level == 0) {
1040 ocfs2_meta_unlock(inode, meta_level); 1055 ocfs2_meta_unlock(inode, meta_level);
1041 meta_level = 1; 1056 meta_level = 1;
@@ -1045,19 +1060,19 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
1045 ret = ocfs2_write_remove_suid(inode); 1060 ret = ocfs2_write_remove_suid(inode);
1046 if (ret < 0) { 1061 if (ret < 0) {
1047 mlog_errno(ret); 1062 mlog_errno(ret);
1048 goto out; 1063 goto out_unlock;
1049 } 1064 }
1050 } 1065 }
1051 1066
1052 /* work on a copy of ppos until we're sure that we won't have 1067 /* work on a copy of ppos until we're sure that we won't have
1053 * to recalculate it due to relocking. */ 1068 * to recalculate it due to relocking. */
1054 if (filp->f_flags & O_APPEND) { 1069 if (appending) {
1055 saved_pos = i_size_read(inode); 1070 saved_pos = i_size_read(inode);
1056 mlog(0, "O_APPEND: inode->i_size=%llu\n", saved_pos); 1071 mlog(0, "O_APPEND: inode->i_size=%llu\n", saved_pos);
1057 } else { 1072 } else {
1058 saved_pos = iocb->ki_pos; 1073 saved_pos = *ppos;
1059 } 1074 }
1060 newsize = iocb->ki_left + saved_pos; 1075 newsize = count + saved_pos;
1061 1076
1062 mlog(0, "pos=%lld newsize=%lld cursize=%lld\n", 1077 mlog(0, "pos=%lld newsize=%lld cursize=%lld\n",
1063 (long long) saved_pos, (long long) newsize, 1078 (long long) saved_pos, (long long) newsize,
@@ -1090,19 +1105,66 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
1090 if (!clusters) 1105 if (!clusters)
1091 break; 1106 break;
1092 1107
1093 ret = ocfs2_extend_file(inode, NULL, newsize, iocb->ki_left); 1108 ret = ocfs2_extend_file(inode, NULL, newsize, count);
1094 if (ret < 0) { 1109 if (ret < 0) {
1095 if (ret != -ENOSPC) 1110 if (ret != -ENOSPC)
1096 mlog_errno(ret); 1111 mlog_errno(ret);
1097 goto out; 1112 goto out_unlock;
1098 } 1113 }
1099 break; 1114 break;
1100 } 1115 }
1101 1116
1102 /* ok, we're done with i_size and alloc work */ 1117 if (appending)
1103 iocb->ki_pos = saved_pos; 1118 *ppos = saved_pos;
1119
1120out_unlock:
1104 ocfs2_meta_unlock(inode, meta_level); 1121 ocfs2_meta_unlock(inode, meta_level);
1105 meta_level = -1; 1122
1123out:
1124 return ret;
1125}
1126
1127static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
1128 const struct iovec *iov,
1129 unsigned long nr_segs,
1130 loff_t pos)
1131{
1132 int ret, rw_level, have_alloc_sem = 0;
1133 struct file *filp = iocb->ki_filp;
1134 struct inode *inode = filp->f_dentry->d_inode;
1135 int appending = filp->f_flags & O_APPEND ? 1 : 0;
1136
1137 mlog_entry("(0x%p, %u, '%.*s')\n", filp,
1138 (unsigned int)nr_segs,
1139 filp->f_dentry->d_name.len,
1140 filp->f_dentry->d_name.name);
1141
1142 /* happy write of zero bytes */
1143 if (iocb->ki_left == 0)
1144 return 0;
1145
1146 mutex_lock(&inode->i_mutex);
1147 /* to match setattr's i_mutex -> i_alloc_sem -> rw_lock ordering */
1148 if (filp->f_flags & O_DIRECT) {
1149 have_alloc_sem = 1;
1150 down_read(&inode->i_alloc_sem);
1151 }
1152
1153 /* concurrent O_DIRECT writes are allowed */
1154 rw_level = (filp->f_flags & O_DIRECT) ? 0 : 1;
1155 ret = ocfs2_rw_lock(inode, rw_level);
1156 if (ret < 0) {
1157 rw_level = -1;
1158 mlog_errno(ret);
1159 goto out;
1160 }
1161
1162 ret = ocfs2_prepare_inode_for_write(filp->f_dentry, &iocb->ki_pos,
1163 iocb->ki_left, appending);
1164 if (ret < 0) {
1165 mlog_errno(ret);
1166 goto out;
1167 }
1106 1168
1107 /* communicate with ocfs2_dio_end_io */ 1169 /* communicate with ocfs2_dio_end_io */
1108 ocfs2_iocb_set_rw_locked(iocb); 1170 ocfs2_iocb_set_rw_locked(iocb);
@@ -1128,8 +1190,6 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
1128 } 1190 }
1129 1191
1130out: 1192out:
1131 if (meta_level != -1)
1132 ocfs2_meta_unlock(inode, meta_level);
1133 if (have_alloc_sem) 1193 if (have_alloc_sem)
1134 up_read(&inode->i_alloc_sem); 1194 up_read(&inode->i_alloc_sem);
1135 if (rw_level != -1) 1195 if (rw_level != -1)
@@ -1140,12 +1200,83 @@ out:
1140 return ret; 1200 return ret;
1141} 1201}
1142 1202
1203static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe,
1204 struct file *out,
1205 loff_t *ppos,
1206 size_t len,
1207 unsigned int flags)
1208{
1209 int ret;
1210 struct inode *inode = out->f_dentry->d_inode;
1211
1212 mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", out, pipe,
1213 (unsigned int)len,
1214 out->f_dentry->d_name.len,
1215 out->f_dentry->d_name.name);
1216
1217 inode_double_lock(inode, pipe->inode);
1218
1219 ret = ocfs2_rw_lock(inode, 1);
1220 if (ret < 0) {
1221 mlog_errno(ret);
1222 goto out;
1223 }
1224
1225 ret = ocfs2_prepare_inode_for_write(out->f_dentry, ppos, len, 0);
1226 if (ret < 0) {
1227 mlog_errno(ret);
1228 goto out_unlock;
1229 }
1230
1231 /* ok, we're done with i_size and alloc work */
1232 ret = generic_file_splice_write_nolock(pipe, out, ppos, len, flags);
1233
1234out_unlock:
1235 ocfs2_rw_unlock(inode, 1);
1236out:
1237 inode_double_unlock(inode, pipe->inode);
1238
1239 mlog_exit(ret);
1240 return ret;
1241}
1242
1243static ssize_t ocfs2_file_splice_read(struct file *in,
1244 loff_t *ppos,
1245 struct pipe_inode_info *pipe,
1246 size_t len,
1247 unsigned int flags)
1248{
1249 int ret = 0;
1250 struct inode *inode = in->f_dentry->d_inode;
1251
1252 mlog_entry("(0x%p, 0x%p, %u, '%.*s')\n", in, pipe,
1253 (unsigned int)len,
1254 in->f_dentry->d_name.len,
1255 in->f_dentry->d_name.name);
1256
1257 /*
1258 * See the comment in ocfs2_file_aio_read()
1259 */
1260 ret = ocfs2_meta_lock(inode, NULL, 0);
1261 if (ret < 0) {
1262 mlog_errno(ret);
1263 goto bail;
1264 }
1265 ocfs2_meta_unlock(inode, 0);
1266
1267 ret = generic_file_splice_read(in, ppos, pipe, len, flags);
1268
1269bail:
1270 mlog_exit(ret);
1271 return ret;
1272}
1273
1143static ssize_t ocfs2_file_aio_read(struct kiocb *iocb, 1274static ssize_t ocfs2_file_aio_read(struct kiocb *iocb,
1144 const struct iovec *iov, 1275 const struct iovec *iov,
1145 unsigned long nr_segs, 1276 unsigned long nr_segs,
1146 loff_t pos) 1277 loff_t pos)
1147{ 1278{
1148 int ret = 0, rw_level = -1, have_alloc_sem = 0; 1279 int ret = 0, rw_level = -1, have_alloc_sem = 0, lock_level = 0;
1149 struct file *filp = iocb->ki_filp; 1280 struct file *filp = iocb->ki_filp;
1150 struct inode *inode = filp->f_dentry->d_inode; 1281 struct inode *inode = filp->f_dentry->d_inode;
1151 1282
@@ -1187,12 +1318,12 @@ static ssize_t ocfs2_file_aio_read(struct kiocb *iocb,
1187 * like i_size. This allows the checks down below 1318 * like i_size. This allows the checks down below
1188 * generic_file_aio_read() a chance of actually working. 1319 * generic_file_aio_read() a chance of actually working.
1189 */ 1320 */
1190 ret = ocfs2_meta_lock(inode, NULL, NULL, 0); 1321 ret = ocfs2_meta_lock_atime(inode, filp->f_vfsmnt, &lock_level);
1191 if (ret < 0) { 1322 if (ret < 0) {
1192 mlog_errno(ret); 1323 mlog_errno(ret);
1193 goto bail; 1324 goto bail;
1194 } 1325 }
1195 ocfs2_meta_unlock(inode, 0); 1326 ocfs2_meta_unlock(inode, lock_level);
1196 1327
1197 ret = generic_file_aio_read(iocb, iov, nr_segs, iocb->ki_pos); 1328 ret = generic_file_aio_read(iocb, iov, nr_segs, iocb->ki_pos);
1198 if (ret == -EINVAL) 1329 if (ret == -EINVAL)
@@ -1220,11 +1351,13 @@ bail:
1220struct inode_operations ocfs2_file_iops = { 1351struct inode_operations ocfs2_file_iops = {
1221 .setattr = ocfs2_setattr, 1352 .setattr = ocfs2_setattr,
1222 .getattr = ocfs2_getattr, 1353 .getattr = ocfs2_getattr,
1354 .permission = ocfs2_permission,
1223}; 1355};
1224 1356
1225struct inode_operations ocfs2_special_file_iops = { 1357struct inode_operations ocfs2_special_file_iops = {
1226 .setattr = ocfs2_setattr, 1358 .setattr = ocfs2_setattr,
1227 .getattr = ocfs2_getattr, 1359 .getattr = ocfs2_getattr,
1360 .permission = ocfs2_permission,
1228}; 1361};
1229 1362
1230const struct file_operations ocfs2_fops = { 1363const struct file_operations ocfs2_fops = {
@@ -1238,6 +1371,8 @@ const struct file_operations ocfs2_fops = {
1238 .aio_read = ocfs2_file_aio_read, 1371 .aio_read = ocfs2_file_aio_read,
1239 .aio_write = ocfs2_file_aio_write, 1372 .aio_write = ocfs2_file_aio_write,
1240 .ioctl = ocfs2_ioctl, 1373 .ioctl = ocfs2_ioctl,
1374 .splice_read = ocfs2_file_splice_read,
1375 .splice_write = ocfs2_file_splice_write,
1241}; 1376};
1242 1377
1243const struct file_operations ocfs2_dops = { 1378const struct file_operations ocfs2_dops = {
diff --git a/fs/ocfs2/file.h b/fs/ocfs2/file.h
index 740c9e7ca599..601a453f18a8 100644
--- a/fs/ocfs2/file.h
+++ b/fs/ocfs2/file.h
@@ -41,17 +41,24 @@ int ocfs2_do_extend_allocation(struct ocfs2_super *osb,
41 struct inode *inode, 41 struct inode *inode,
42 u32 clusters_to_add, 42 u32 clusters_to_add,
43 struct buffer_head *fe_bh, 43 struct buffer_head *fe_bh,
44 struct ocfs2_journal_handle *handle, 44 handle_t *handle,
45 struct ocfs2_alloc_context *data_ac, 45 struct ocfs2_alloc_context *data_ac,
46 struct ocfs2_alloc_context *meta_ac, 46 struct ocfs2_alloc_context *meta_ac,
47 enum ocfs2_alloc_restarted *reason); 47 enum ocfs2_alloc_restarted *reason);
48int ocfs2_setattr(struct dentry *dentry, struct iattr *attr); 48int ocfs2_setattr(struct dentry *dentry, struct iattr *attr);
49int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry, 49int ocfs2_getattr(struct vfsmount *mnt, struct dentry *dentry,
50 struct kstat *stat); 50 struct kstat *stat);
51int ocfs2_permission(struct inode *inode, int mask,
52 struct nameidata *nd);
51 53
52int ocfs2_set_inode_size(struct ocfs2_journal_handle *handle, 54int ocfs2_set_inode_size(handle_t *handle,
53 struct inode *inode, 55 struct inode *inode,
54 struct buffer_head *fe_bh, 56 struct buffer_head *fe_bh,
55 u64 new_i_size); 57 u64 new_i_size);
56 58
59int ocfs2_should_update_atime(struct inode *inode,
60 struct vfsmount *vfsmnt);
61int ocfs2_update_inode_atime(struct inode *inode,
62 struct buffer_head *bh);
63
57#endif /* OCFS2_FILE_H */ 64#endif /* OCFS2_FILE_H */
diff --git a/fs/ocfs2/inode.c b/fs/ocfs2/inode.c
index 16e8e74dc966..42e361f3054f 100644
--- a/fs/ocfs2/inode.c
+++ b/fs/ocfs2/inode.c
@@ -360,7 +360,6 @@ int ocfs2_populate_inode(struct inode *inode, struct ocfs2_dinode *fe,
360 inode); 360 inode);
361 361
362 ocfs2_set_inode_flags(inode); 362 ocfs2_set_inode_flags(inode);
363 inode->i_flags |= S_NOATIME;
364 363
365 status = 0; 364 status = 0;
366bail: 365bail:
@@ -441,7 +440,7 @@ static int ocfs2_read_locked_inode(struct inode *inode,
441 generation, inode); 440 generation, inode);
442 441
443 if (can_lock) { 442 if (can_lock) {
444 status = ocfs2_meta_lock(inode, NULL, NULL, 0); 443 status = ocfs2_meta_lock(inode, NULL, 0);
445 if (status) { 444 if (status) {
446 make_bad_inode(inode); 445 make_bad_inode(inode);
447 mlog_errno(status); 446 mlog_errno(status);
@@ -512,7 +511,7 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb,
512 struct buffer_head *fe_bh) 511 struct buffer_head *fe_bh)
513{ 512{
514 int status = 0; 513 int status = 0;
515 struct ocfs2_journal_handle *handle = NULL; 514 handle_t *handle = NULL;
516 struct ocfs2_truncate_context *tc = NULL; 515 struct ocfs2_truncate_context *tc = NULL;
517 struct ocfs2_dinode *fe; 516 struct ocfs2_dinode *fe;
518 517
@@ -524,7 +523,7 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb,
524 if (!fe->i_clusters) 523 if (!fe->i_clusters)
525 goto bail; 524 goto bail;
526 525
527 handle = ocfs2_start_trans(osb, handle, OCFS2_INODE_UPDATE_CREDITS); 526 handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
528 if (IS_ERR(handle)) { 527 if (IS_ERR(handle)) {
529 status = PTR_ERR(handle); 528 status = PTR_ERR(handle);
530 handle = NULL; 529 handle = NULL;
@@ -538,7 +537,7 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb,
538 goto bail; 537 goto bail;
539 } 538 }
540 539
541 ocfs2_commit_trans(handle); 540 ocfs2_commit_trans(osb, handle);
542 handle = NULL; 541 handle = NULL;
543 542
544 status = ocfs2_prepare_truncate(osb, inode, fe_bh, &tc); 543 status = ocfs2_prepare_truncate(osb, inode, fe_bh, &tc);
@@ -554,7 +553,7 @@ static int ocfs2_truncate_for_delete(struct ocfs2_super *osb,
554 } 553 }
555bail: 554bail:
556 if (handle) 555 if (handle)
557 ocfs2_commit_trans(handle); 556 ocfs2_commit_trans(osb, handle);
558 557
559 mlog_exit(status); 558 mlog_exit(status);
560 return status; 559 return status;
@@ -568,7 +567,7 @@ static int ocfs2_remove_inode(struct inode *inode,
568 int status; 567 int status;
569 struct inode *inode_alloc_inode = NULL; 568 struct inode *inode_alloc_inode = NULL;
570 struct buffer_head *inode_alloc_bh = NULL; 569 struct buffer_head *inode_alloc_bh = NULL;
571 struct ocfs2_journal_handle *handle; 570 handle_t *handle;
572 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 571 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
573 struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data; 572 struct ocfs2_dinode *di = (struct ocfs2_dinode *) di_bh->b_data;
574 573
@@ -582,7 +581,7 @@ static int ocfs2_remove_inode(struct inode *inode,
582 } 581 }
583 582
584 mutex_lock(&inode_alloc_inode->i_mutex); 583 mutex_lock(&inode_alloc_inode->i_mutex);
585 status = ocfs2_meta_lock(inode_alloc_inode, NULL, &inode_alloc_bh, 1); 584 status = ocfs2_meta_lock(inode_alloc_inode, &inode_alloc_bh, 1);
586 if (status < 0) { 585 if (status < 0) {
587 mutex_unlock(&inode_alloc_inode->i_mutex); 586 mutex_unlock(&inode_alloc_inode->i_mutex);
588 587
@@ -590,7 +589,7 @@ static int ocfs2_remove_inode(struct inode *inode,
590 goto bail; 589 goto bail;
591 } 590 }
592 591
593 handle = ocfs2_start_trans(osb, NULL, OCFS2_DELETE_INODE_CREDITS); 592 handle = ocfs2_start_trans(osb, OCFS2_DELETE_INODE_CREDITS);
594 if (IS_ERR(handle)) { 593 if (IS_ERR(handle)) {
595 status = PTR_ERR(handle); 594 status = PTR_ERR(handle);
596 mlog_errno(status); 595 mlog_errno(status);
@@ -629,7 +628,7 @@ static int ocfs2_remove_inode(struct inode *inode,
629 mlog_errno(status); 628 mlog_errno(status);
630 629
631bail_commit: 630bail_commit:
632 ocfs2_commit_trans(handle); 631 ocfs2_commit_trans(osb, handle);
633bail_unlock: 632bail_unlock:
634 ocfs2_meta_unlock(inode_alloc_inode, 1); 633 ocfs2_meta_unlock(inode_alloc_inode, 1);
635 mutex_unlock(&inode_alloc_inode->i_mutex); 634 mutex_unlock(&inode_alloc_inode->i_mutex);
@@ -705,7 +704,7 @@ static int ocfs2_wipe_inode(struct inode *inode,
705 * delete_inode operation. We do this now to avoid races with 704 * delete_inode operation. We do this now to avoid races with
706 * recovery completion on other nodes. */ 705 * recovery completion on other nodes. */
707 mutex_lock(&orphan_dir_inode->i_mutex); 706 mutex_lock(&orphan_dir_inode->i_mutex);
708 status = ocfs2_meta_lock(orphan_dir_inode, NULL, &orphan_dir_bh, 1); 707 status = ocfs2_meta_lock(orphan_dir_inode, &orphan_dir_bh, 1);
709 if (status < 0) { 708 if (status < 0) {
710 mutex_unlock(&orphan_dir_inode->i_mutex); 709 mutex_unlock(&orphan_dir_inode->i_mutex);
711 710
@@ -933,7 +932,7 @@ void ocfs2_delete_inode(struct inode *inode)
933 * allocation lock here as it won't be needed - nobody will 932 * allocation lock here as it won't be needed - nobody will
934 * have the file open. 933 * have the file open.
935 */ 934 */
936 status = ocfs2_meta_lock(inode, NULL, &di_bh, 1); 935 status = ocfs2_meta_lock(inode, &di_bh, 1);
937 if (status < 0) { 936 if (status < 0) {
938 if (status != -ENOENT) 937 if (status != -ENOENT)
939 mlog_errno(status); 938 mlog_errno(status);
@@ -1067,12 +1066,6 @@ void ocfs2_clear_inode(struct inode *inode)
1067 mlog_bug_on_msg(oi->ip_open_count, 1066 mlog_bug_on_msg(oi->ip_open_count,
1068 "Clear inode of %llu has open count %d\n", 1067 "Clear inode of %llu has open count %d\n",
1069 (unsigned long long)oi->ip_blkno, oi->ip_open_count); 1068 (unsigned long long)oi->ip_blkno, oi->ip_open_count);
1070 mlog_bug_on_msg(!list_empty(&oi->ip_handle_list),
1071 "Clear inode of %llu has non empty handle list\n",
1072 (unsigned long long)oi->ip_blkno);
1073 mlog_bug_on_msg(oi->ip_handle,
1074 "Clear inode of %llu has non empty handle pointer\n",
1075 (unsigned long long)oi->ip_blkno);
1076 1069
1077 /* Clear all other flags. */ 1070 /* Clear all other flags. */
1078 oi->ip_flags = OCFS2_INODE_CACHE_INLINE; 1071 oi->ip_flags = OCFS2_INODE_CACHE_INLINE;
@@ -1186,7 +1179,7 @@ int ocfs2_inode_revalidate(struct dentry *dentry)
1186 1179
1187 /* Let ocfs2_meta_lock do the work of updating our struct 1180 /* Let ocfs2_meta_lock do the work of updating our struct
1188 * inode for us. */ 1181 * inode for us. */
1189 status = ocfs2_meta_lock(inode, NULL, NULL, 0); 1182 status = ocfs2_meta_lock(inode, NULL, 0);
1190 if (status < 0) { 1183 if (status < 0) {
1191 if (status != -ENOENT) 1184 if (status != -ENOENT)
1192 mlog_errno(status); 1185 mlog_errno(status);
@@ -1204,7 +1197,7 @@ bail:
1204 * struct inode. 1197 * struct inode.
1205 * Only takes ip_lock. 1198 * Only takes ip_lock.
1206 */ 1199 */
1207int ocfs2_mark_inode_dirty(struct ocfs2_journal_handle *handle, 1200int ocfs2_mark_inode_dirty(handle_t *handle,
1208 struct inode *inode, 1201 struct inode *inode,
1209 struct buffer_head *bh) 1202 struct buffer_head *bh)
1210{ 1203{
diff --git a/fs/ocfs2/inode.h b/fs/ocfs2/inode.h
index 9957810fdf85..46a378fbc40b 100644
--- a/fs/ocfs2/inode.h
+++ b/fs/ocfs2/inode.h
@@ -48,13 +48,6 @@ struct ocfs2_inode_info
48 48
49 struct mutex ip_io_mutex; 49 struct mutex ip_io_mutex;
50 50
51 /* Used by the journalling code to attach an inode to a
52 * handle. These are protected by ip_io_mutex in order to lock
53 * out other I/O to the inode until we either commit or
54 * abort. */
55 struct list_head ip_handle_list;
56 struct ocfs2_journal_handle *ip_handle;
57
58 u32 ip_flags; /* see below */ 51 u32 ip_flags; /* see below */
59 u32 ip_attr; /* inode attributes */ 52 u32 ip_attr; /* inode attributes */
60 53
@@ -143,7 +136,7 @@ ssize_t ocfs2_rw_direct(int rw, struct file *filp, char *buf,
143void ocfs2_sync_blockdev(struct super_block *sb); 136void ocfs2_sync_blockdev(struct super_block *sb);
144void ocfs2_refresh_inode(struct inode *inode, 137void ocfs2_refresh_inode(struct inode *inode,
145 struct ocfs2_dinode *fe); 138 struct ocfs2_dinode *fe);
146int ocfs2_mark_inode_dirty(struct ocfs2_journal_handle *handle, 139int ocfs2_mark_inode_dirty(handle_t *handle,
147 struct inode *inode, 140 struct inode *inode,
148 struct buffer_head *bh); 141 struct buffer_head *bh);
149int ocfs2_aio_read(struct file *file, struct kiocb *req, struct iocb *iocb); 142int ocfs2_aio_read(struct file *file, struct kiocb *req, struct iocb *iocb);
diff --git a/fs/ocfs2/ioctl.c b/fs/ocfs2/ioctl.c
index 3663cef80689..4768be5f3086 100644
--- a/fs/ocfs2/ioctl.c
+++ b/fs/ocfs2/ioctl.c
@@ -26,7 +26,7 @@ static int ocfs2_get_inode_attr(struct inode *inode, unsigned *flags)
26{ 26{
27 int status; 27 int status;
28 28
29 status = ocfs2_meta_lock(inode, NULL, NULL, 0); 29 status = ocfs2_meta_lock(inode, NULL, 0);
30 if (status < 0) { 30 if (status < 0) {
31 mlog_errno(status); 31 mlog_errno(status);
32 return status; 32 return status;
@@ -43,14 +43,14 @@ static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
43{ 43{
44 struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode); 44 struct ocfs2_inode_info *ocfs2_inode = OCFS2_I(inode);
45 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb); 45 struct ocfs2_super *osb = OCFS2_SB(inode->i_sb);
46 struct ocfs2_journal_handle *handle = NULL; 46 handle_t *handle = NULL;
47 struct buffer_head *bh = NULL; 47 struct buffer_head *bh = NULL;
48 unsigned oldflags; 48 unsigned oldflags;
49 int status; 49 int status;
50 50
51 mutex_lock(&inode->i_mutex); 51 mutex_lock(&inode->i_mutex);
52 52
53 status = ocfs2_meta_lock(inode, NULL, &bh, 1); 53 status = ocfs2_meta_lock(inode, &bh, 1);
54 if (status < 0) { 54 if (status < 0) {
55 mlog_errno(status); 55 mlog_errno(status);
56 goto bail; 56 goto bail;
@@ -67,7 +67,7 @@ static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
67 if (!S_ISDIR(inode->i_mode)) 67 if (!S_ISDIR(inode->i_mode))
68 flags &= ~OCFS2_DIRSYNC_FL; 68 flags &= ~OCFS2_DIRSYNC_FL;
69 69
70 handle = ocfs2_start_trans(osb, NULL, OCFS2_INODE_UPDATE_CREDITS); 70 handle = ocfs2_start_trans(osb, OCFS2_INODE_UPDATE_CREDITS);
71 if (IS_ERR(handle)) { 71 if (IS_ERR(handle)) {
72 status = PTR_ERR(handle); 72 status = PTR_ERR(handle);
73 mlog_errno(status); 73 mlog_errno(status);
@@ -96,7 +96,7 @@ static int ocfs2_set_inode_attr(struct inode *inode, unsigned flags,
96 if (status < 0) 96 if (status < 0)
97 mlog_errno(status); 97 mlog_errno(status);
98 98
99 ocfs2_commit_trans(handle); 99 ocfs2_commit_trans(osb, handle);
100bail_unlock: 100bail_unlock:
101 ocfs2_meta_unlock(inode, 1); 101 ocfs2_meta_unlock(inode, 1);
102bail: 102bail:
diff --git a/fs/ocfs2/journal.c b/fs/ocfs2/journal.c
index d95ee2720e6e..1d7f4ab1e5ed 100644
--- a/fs/ocfs2/journal.c
+++ b/fs/ocfs2/journal.c
@@ -57,9 +57,6 @@ static int ocfs2_recover_node(struct ocfs2_super *osb,
57static int __ocfs2_recovery_thread(void *arg); 57static int __ocfs2_recovery_thread(void *arg);
58static int ocfs2_commit_cache(struct ocfs2_super *osb); 58static int ocfs2_commit_cache(struct ocfs2_super *osb);
59static int ocfs2_wait_on_mount(struct ocfs2_super *osb); 59static int ocfs2_wait_on_mount(struct ocfs2_super *osb);
60static void ocfs2_handle_cleanup_locks(struct ocfs2_journal *journal,
61 struct ocfs2_journal_handle *handle);
62static void ocfs2_commit_unstarted_handle(struct ocfs2_journal_handle *handle);
63static int ocfs2_journal_toggle_dirty(struct ocfs2_super *osb, 60static int ocfs2_journal_toggle_dirty(struct ocfs2_super *osb,
64 int dirty); 61 int dirty);
65static int ocfs2_trylock_journal(struct ocfs2_super *osb, 62static int ocfs2_trylock_journal(struct ocfs2_super *osb,
@@ -113,46 +110,18 @@ finally:
113 return status; 110 return status;
114} 111}
115 112
116struct ocfs2_journal_handle *ocfs2_alloc_handle(struct ocfs2_super *osb)
117{
118 struct ocfs2_journal_handle *retval = NULL;
119
120 retval = kcalloc(1, sizeof(*retval), GFP_NOFS);
121 if (!retval) {
122 mlog(ML_ERROR, "Failed to allocate memory for journal "
123 "handle!\n");
124 return NULL;
125 }
126
127 retval->max_buffs = 0;
128 retval->num_locks = 0;
129 retval->k_handle = NULL;
130
131 INIT_LIST_HEAD(&retval->locks);
132 INIT_LIST_HEAD(&retval->inode_list);
133 retval->journal = osb->journal;
134
135 return retval;
136}
137
138/* pass it NULL and it will allocate a new handle object for you. If 113/* pass it NULL and it will allocate a new handle object for you. If
139 * you pass it a handle however, it may still return error, in which 114 * you pass it a handle however, it may still return error, in which
140 * case it has free'd the passed handle for you. */ 115 * case it has free'd the passed handle for you. */
141struct ocfs2_journal_handle *ocfs2_start_trans(struct ocfs2_super *osb, 116handle_t *ocfs2_start_trans(struct ocfs2_super *osb, int max_buffs)
142 struct ocfs2_journal_handle *handle,
143 int max_buffs)
144{ 117{
145 int ret;
146 journal_t *journal = osb->journal->j_journal; 118 journal_t *journal = osb->journal->j_journal;
147 119 handle_t *handle;
148 mlog_entry("(max_buffs = %d)\n", max_buffs);
149 120
150 BUG_ON(!osb || !osb->journal->j_journal); 121 BUG_ON(!osb || !osb->journal->j_journal);
151 122
152 if (ocfs2_is_hard_readonly(osb)) { 123 if (ocfs2_is_hard_readonly(osb))
153 ret = -EROFS; 124 return ERR_PTR(-EROFS);
154 goto done_free;
155 }
156 125
157 BUG_ON(osb->journal->j_state == OCFS2_JOURNAL_FREE); 126 BUG_ON(osb->journal->j_state == OCFS2_JOURNAL_FREE);
158 BUG_ON(max_buffs <= 0); 127 BUG_ON(max_buffs <= 0);
@@ -163,154 +132,39 @@ struct ocfs2_journal_handle *ocfs2_start_trans(struct ocfs2_super *osb,
163 BUG(); 132 BUG();
164 } 133 }
165 134
166 if (!handle)
167 handle = ocfs2_alloc_handle(osb);
168 if (!handle) {
169 ret = -ENOMEM;
170 mlog(ML_ERROR, "Failed to allocate memory for journal "
171 "handle!\n");
172 goto done_free;
173 }
174
175 handle->max_buffs = max_buffs;
176
177 down_read(&osb->journal->j_trans_barrier); 135 down_read(&osb->journal->j_trans_barrier);
178 136
179 /* actually start the transaction now */ 137 handle = journal_start(journal, max_buffs);
180 handle->k_handle = journal_start(journal, max_buffs); 138 if (IS_ERR(handle)) {
181 if (IS_ERR(handle->k_handle)) {
182 up_read(&osb->journal->j_trans_barrier); 139 up_read(&osb->journal->j_trans_barrier);
183 140
184 ret = PTR_ERR(handle->k_handle); 141 mlog_errno(PTR_ERR(handle));
185 handle->k_handle = NULL;
186 mlog_errno(ret);
187 142
188 if (is_journal_aborted(journal)) { 143 if (is_journal_aborted(journal)) {
189 ocfs2_abort(osb->sb, "Detected aborted journal"); 144 ocfs2_abort(osb->sb, "Detected aborted journal");
190 ret = -EROFS; 145 handle = ERR_PTR(-EROFS);
191 } 146 }
192 goto done_free; 147 } else
193 } 148 atomic_inc(&(osb->journal->j_num_trans));
194
195 atomic_inc(&(osb->journal->j_num_trans));
196 handle->flags |= OCFS2_HANDLE_STARTED;
197 149
198 mlog_exit_ptr(handle);
199 return handle; 150 return handle;
200
201done_free:
202 if (handle)
203 ocfs2_commit_unstarted_handle(handle); /* will kfree handle */
204
205 mlog_exit(ret);
206 return ERR_PTR(ret);
207}
208
209void ocfs2_handle_add_inode(struct ocfs2_journal_handle *handle,
210 struct inode *inode)
211{
212 BUG_ON(!handle);
213 BUG_ON(!inode);
214
215 atomic_inc(&inode->i_count);
216
217 /* we're obviously changing it... */
218 mutex_lock(&inode->i_mutex);
219
220 /* sanity check */
221 BUG_ON(OCFS2_I(inode)->ip_handle);
222 BUG_ON(!list_empty(&OCFS2_I(inode)->ip_handle_list));
223
224 OCFS2_I(inode)->ip_handle = handle;
225 list_move_tail(&(OCFS2_I(inode)->ip_handle_list), &(handle->inode_list));
226}
227
228static void ocfs2_handle_unlock_inodes(struct ocfs2_journal_handle *handle)
229{
230 struct list_head *p, *n;
231 struct inode *inode;
232 struct ocfs2_inode_info *oi;
233
234 list_for_each_safe(p, n, &handle->inode_list) {
235 oi = list_entry(p, struct ocfs2_inode_info,
236 ip_handle_list);
237 inode = &oi->vfs_inode;
238
239 OCFS2_I(inode)->ip_handle = NULL;
240 list_del_init(&OCFS2_I(inode)->ip_handle_list);
241
242 mutex_unlock(&inode->i_mutex);
243 iput(inode);
244 }
245}
246
247/* This is trivial so we do it out of the main commit
248 * paths. Beware, it can be called from start_trans too! */
249static void ocfs2_commit_unstarted_handle(struct ocfs2_journal_handle *handle)
250{
251 mlog_entry_void();
252
253 BUG_ON(handle->flags & OCFS2_HANDLE_STARTED);
254
255 ocfs2_handle_unlock_inodes(handle);
256 /* You are allowed to add journal locks before the transaction
257 * has started. */
258 ocfs2_handle_cleanup_locks(handle->journal, handle);
259
260 kfree(handle);
261
262 mlog_exit_void();
263} 151}
264 152
265void ocfs2_commit_trans(struct ocfs2_journal_handle *handle) 153int ocfs2_commit_trans(struct ocfs2_super *osb,
154 handle_t *handle)
266{ 155{
267 handle_t *jbd_handle; 156 int ret;
268 int retval; 157 struct ocfs2_journal *journal = osb->journal;
269 struct ocfs2_journal *journal = handle->journal;
270
271 mlog_entry_void();
272 158
273 BUG_ON(!handle); 159 BUG_ON(!handle);
274 160
275 if (!(handle->flags & OCFS2_HANDLE_STARTED)) { 161 ret = journal_stop(handle);
276 ocfs2_commit_unstarted_handle(handle); 162 if (ret < 0)
277 mlog_exit_void(); 163 mlog_errno(ret);
278 return;
279 }
280
281 /* release inode semaphores we took during this transaction */
282 ocfs2_handle_unlock_inodes(handle);
283
284 /* ocfs2_extend_trans may have had to call journal_restart
285 * which will always commit the transaction, but may return
286 * error for any number of reasons. If this is the case, we
287 * clear k_handle as it's not valid any more. */
288 if (handle->k_handle) {
289 jbd_handle = handle->k_handle;
290
291 if (handle->flags & OCFS2_HANDLE_SYNC)
292 jbd_handle->h_sync = 1;
293 else
294 jbd_handle->h_sync = 0;
295
296 /* actually stop the transaction. if we've set h_sync,
297 * it'll have been committed when we return */
298 retval = journal_stop(jbd_handle);
299 if (retval < 0) {
300 mlog_errno(retval);
301 mlog(ML_ERROR, "Could not commit transaction\n");
302 BUG();
303 }
304
305 handle->k_handle = NULL; /* it's been free'd in journal_stop */
306 }
307
308 ocfs2_handle_cleanup_locks(journal, handle);
309 164
310 up_read(&journal->j_trans_barrier); 165 up_read(&journal->j_trans_barrier);
311 166
312 kfree(handle); 167 return ret;
313 mlog_exit_void();
314} 168}
315 169
316/* 170/*
@@ -326,20 +180,18 @@ void ocfs2_commit_trans(struct ocfs2_journal_handle *handle)
326 * good because transaction ids haven't yet been recorded on the 180 * good because transaction ids haven't yet been recorded on the
327 * cluster locks associated with this handle. 181 * cluster locks associated with this handle.
328 */ 182 */
329int ocfs2_extend_trans(struct ocfs2_journal_handle *handle, 183int ocfs2_extend_trans(handle_t *handle, int nblocks)
330 int nblocks)
331{ 184{
332 int status; 185 int status;
333 186
334 BUG_ON(!handle); 187 BUG_ON(!handle);
335 BUG_ON(!(handle->flags & OCFS2_HANDLE_STARTED));
336 BUG_ON(!nblocks); 188 BUG_ON(!nblocks);
337 189
338 mlog_entry_void(); 190 mlog_entry_void();
339 191
340 mlog(0, "Trying to extend transaction by %d blocks\n", nblocks); 192 mlog(0, "Trying to extend transaction by %d blocks\n", nblocks);
341 193
342 status = journal_extend(handle->k_handle, nblocks); 194 status = journal_extend(handle, nblocks);
343 if (status < 0) { 195 if (status < 0) {
344 mlog_errno(status); 196 mlog_errno(status);
345 goto bail; 197 goto bail;
@@ -347,15 +199,12 @@ int ocfs2_extend_trans(struct ocfs2_journal_handle *handle,
347 199
348 if (status > 0) { 200 if (status > 0) {
349 mlog(0, "journal_extend failed, trying journal_restart\n"); 201 mlog(0, "journal_extend failed, trying journal_restart\n");
350 status = journal_restart(handle->k_handle, nblocks); 202 status = journal_restart(handle, nblocks);
351 if (status < 0) { 203 if (status < 0) {
352 handle->k_handle = NULL;
353 mlog_errno(status); 204 mlog_errno(status);
354 goto bail; 205 goto bail;
355 } 206 }
356 handle->max_buffs = nblocks; 207 }
357 } else
358 handle->max_buffs += nblocks;
359 208
360 status = 0; 209 status = 0;
361bail: 210bail:
@@ -364,7 +213,7 @@ bail:
364 return status; 213 return status;
365} 214}
366 215
367int ocfs2_journal_access(struct ocfs2_journal_handle *handle, 216int ocfs2_journal_access(handle_t *handle,
368 struct inode *inode, 217 struct inode *inode,
369 struct buffer_head *bh, 218 struct buffer_head *bh,
370 int type) 219 int type)
@@ -374,7 +223,6 @@ int ocfs2_journal_access(struct ocfs2_journal_handle *handle,
374 BUG_ON(!inode); 223 BUG_ON(!inode);
375 BUG_ON(!handle); 224 BUG_ON(!handle);
376 BUG_ON(!bh); 225 BUG_ON(!bh);
377 BUG_ON(!(handle->flags & OCFS2_HANDLE_STARTED));
378 226
379 mlog_entry("bh->b_blocknr=%llu, type=%d (\"%s\"), bh->b_size = %zu\n", 227 mlog_entry("bh->b_blocknr=%llu, type=%d (\"%s\"), bh->b_size = %zu\n",
380 (unsigned long long)bh->b_blocknr, type, 228 (unsigned long long)bh->b_blocknr, type,
@@ -403,11 +251,11 @@ int ocfs2_journal_access(struct ocfs2_journal_handle *handle,
403 switch (type) { 251 switch (type) {
404 case OCFS2_JOURNAL_ACCESS_CREATE: 252 case OCFS2_JOURNAL_ACCESS_CREATE:
405 case OCFS2_JOURNAL_ACCESS_WRITE: 253 case OCFS2_JOURNAL_ACCESS_WRITE:
406 status = journal_get_write_access(handle->k_handle, bh); 254 status = journal_get_write_access(handle, bh);
407 break; 255 break;
408 256
409 case OCFS2_JOURNAL_ACCESS_UNDO: 257 case OCFS2_JOURNAL_ACCESS_UNDO:
410 status = journal_get_undo_access(handle->k_handle, bh); 258 status = journal_get_undo_access(handle, bh);
411 break; 259 break;
412 260
413 default: 261 default:
@@ -424,17 +272,15 @@ int ocfs2_journal_access(struct ocfs2_journal_handle *handle,
424 return status; 272 return status;
425} 273}
426 274
427int ocfs2_journal_dirty(struct ocfs2_journal_handle *handle, 275int ocfs2_journal_dirty(handle_t *handle,
428 struct buffer_head *bh) 276 struct buffer_head *bh)
429{ 277{
430 int status; 278 int status;
431 279
432 BUG_ON(!(handle->flags & OCFS2_HANDLE_STARTED));
433
434 mlog_entry("(bh->b_blocknr=%llu)\n", 280 mlog_entry("(bh->b_blocknr=%llu)\n",
435 (unsigned long long)bh->b_blocknr); 281 (unsigned long long)bh->b_blocknr);
436 282
437 status = journal_dirty_metadata(handle->k_handle, bh); 283 status = journal_dirty_metadata(handle, bh);
438 if (status < 0) 284 if (status < 0)
439 mlog(ML_ERROR, "Could not dirty metadata buffer. " 285 mlog(ML_ERROR, "Could not dirty metadata buffer. "
440 "(bh->b_blocknr=%llu)\n", 286 "(bh->b_blocknr=%llu)\n",
@@ -456,59 +302,6 @@ int ocfs2_journal_dirty_data(handle_t *handle,
456 return err; 302 return err;
457} 303}
458 304
459/* We always assume you're adding a metadata lock at level 'ex' */
460int ocfs2_handle_add_lock(struct ocfs2_journal_handle *handle,
461 struct inode *inode)
462{
463 int status;
464 struct ocfs2_journal_lock *lock;
465
466 BUG_ON(!inode);
467
468 lock = kmem_cache_alloc(ocfs2_lock_cache, GFP_NOFS);
469 if (!lock) {
470 status = -ENOMEM;
471 mlog_errno(-ENOMEM);
472 goto bail;
473 }
474
475 if (!igrab(inode))
476 BUG();
477 lock->jl_inode = inode;
478
479 list_add_tail(&(lock->jl_lock_list), &(handle->locks));
480 handle->num_locks++;
481
482 status = 0;
483bail:
484 mlog_exit(status);
485 return status;
486}
487
488static void ocfs2_handle_cleanup_locks(struct ocfs2_journal *journal,
489 struct ocfs2_journal_handle *handle)
490{
491 struct list_head *p, *n;
492 struct ocfs2_journal_lock *lock;
493 struct inode *inode;
494
495 list_for_each_safe(p, n, &(handle->locks)) {
496 lock = list_entry(p, struct ocfs2_journal_lock,
497 jl_lock_list);
498 list_del(&lock->jl_lock_list);
499 handle->num_locks--;
500
501 inode = lock->jl_inode;
502 ocfs2_meta_unlock(inode, 1);
503 if (atomic_read(&inode->i_count) == 1)
504 mlog(ML_ERROR,
505 "Inode %llu, I'm doing a last iput for!",
506 (unsigned long long)OCFS2_I(inode)->ip_blkno);
507 iput(inode);
508 kmem_cache_free(ocfs2_lock_cache, lock);
509 }
510}
511
512#define OCFS2_DEFAULT_COMMIT_INTERVAL (HZ * 5) 305#define OCFS2_DEFAULT_COMMIT_INTERVAL (HZ * 5)
513 306
514void ocfs2_set_journal_params(struct ocfs2_super *osb) 307void ocfs2_set_journal_params(struct ocfs2_super *osb)
@@ -562,8 +355,7 @@ int ocfs2_journal_init(struct ocfs2_journal *journal, int *dirty)
562 /* Skip recovery waits here - journal inode metadata never 355 /* Skip recovery waits here - journal inode metadata never
563 * changes in a live cluster so it can be considered an 356 * changes in a live cluster so it can be considered an
564 * exception to the rule. */ 357 * exception to the rule. */
565 status = ocfs2_meta_lock_full(inode, NULL, &bh, 1, 358 status = ocfs2_meta_lock_full(inode, &bh, 1, OCFS2_META_LOCK_RECOVERY);
566 OCFS2_META_LOCK_RECOVERY);
567 if (status < 0) { 359 if (status < 0) {
568 if (status != -ERESTARTSYS) 360 if (status != -ERESTARTSYS)
569 mlog(ML_ERROR, "Could not get lock on journal!\n"); 361 mlog(ML_ERROR, "Could not get lock on journal!\n");
@@ -1161,8 +953,7 @@ static int ocfs2_replay_journal(struct ocfs2_super *osb,
1161 } 953 }
1162 SET_INODE_JOURNAL(inode); 954 SET_INODE_JOURNAL(inode);
1163 955
1164 status = ocfs2_meta_lock_full(inode, NULL, &bh, 1, 956 status = ocfs2_meta_lock_full(inode, &bh, 1, OCFS2_META_LOCK_RECOVERY);
1165 OCFS2_META_LOCK_RECOVERY);
1166 if (status < 0) { 957 if (status < 0) {
1167 mlog(0, "status returned from ocfs2_meta_lock=%d\n", status); 958 mlog(0, "status returned from ocfs2_meta_lock=%d\n", status);
1168 if (status != -ERESTARTSYS) 959 if (status != -ERESTARTSYS)
@@ -1351,7 +1142,7 @@ static int ocfs2_trylock_journal(struct ocfs2_super *osb,
1351 SET_INODE_JOURNAL(inode); 1142 SET_INODE_JOURNAL(inode);
1352 1143
1353 flags = OCFS2_META_LOCK_RECOVERY | OCFS2_META_LOCK_NOQUEUE; 1144 flags = OCFS2_META_LOCK_RECOVERY | OCFS2_META_LOCK_NOQUEUE;
1354 status = ocfs2_meta_lock_full(inode, NULL, NULL, 1, flags); 1145 status = ocfs2_meta_lock_full(inode, NULL, 1, flags);
1355 if (status < 0) { 1146 if (status < 0) {
1356 if (status != -EAGAIN) 1147 if (status != -EAGAIN)
1357 mlog_errno(status); 1148 mlog_errno(status);
@@ -1434,7 +1225,7 @@ static int ocfs2_queue_orphans(struct ocfs2_super *osb,
1434 } 1225 }
1435 1226
1436 mutex_lock(&orphan_dir_inode->i_mutex); 1227 mutex_lock(&orphan_dir_inode->i_mutex);
1437 status = ocfs2_meta_lock(orphan_dir_inode, NULL, NULL, 0); 1228 status = ocfs2_meta_lock(orphan_dir_inode, NULL, 0);
1438 if (status < 0) { 1229 if (status < 0) {
1439 mlog_errno(status); 1230 mlog_errno(status);
1440 goto out; 1231 goto out;
diff --git a/fs/ocfs2/journal.h b/fs/ocfs2/journal.h
index 5be161a4ad9f..899112ad8136 100644
--- a/fs/ocfs2/journal.h
+++ b/fs/ocfs2/journal.h
@@ -37,7 +37,6 @@ enum ocfs2_journal_state {
37 37
38struct ocfs2_super; 38struct ocfs2_super;
39struct ocfs2_dinode; 39struct ocfs2_dinode;
40struct ocfs2_journal_handle;
41 40
42struct ocfs2_journal { 41struct ocfs2_journal {
43 enum ocfs2_journal_state j_state; /* Journals current state */ 42 enum ocfs2_journal_state j_state; /* Journals current state */
@@ -133,44 +132,6 @@ static inline void ocfs2_inode_set_new(struct ocfs2_super *osb,
133 spin_unlock(&trans_inc_lock); 132 spin_unlock(&trans_inc_lock);
134} 133}
135 134
136extern kmem_cache_t *ocfs2_lock_cache;
137
138struct ocfs2_journal_lock {
139 struct inode *jl_inode;
140 struct list_head jl_lock_list;
141};
142
143struct ocfs2_journal_handle {
144 handle_t *k_handle; /* kernel handle. */
145 struct ocfs2_journal *journal;
146 u32 flags; /* see flags below. */
147 int max_buffs; /* Buffs reserved by this handle */
148
149 /* The following two fields are for ocfs2_handle_add_lock */
150 int num_locks;
151 struct list_head locks; /* A bunch of locks to
152 * release on commit. This
153 * should be a list_head */
154
155 struct list_head inode_list;
156};
157
158#define OCFS2_HANDLE_STARTED 1
159/* should we sync-commit this handle? */
160#define OCFS2_HANDLE_SYNC 2
161static inline int ocfs2_handle_started(struct ocfs2_journal_handle *handle)
162{
163 return handle->flags & OCFS2_HANDLE_STARTED;
164}
165
166static inline void ocfs2_handle_set_sync(struct ocfs2_journal_handle *handle, int sync)
167{
168 if (sync)
169 handle->flags |= OCFS2_HANDLE_SYNC;
170 else
171 handle->flags &= ~OCFS2_HANDLE_SYNC;
172}
173
174/* Exported only for the journal struct init code in super.c. Do not call. */ 135/* Exported only for the journal struct init code in super.c. Do not call. */
175void ocfs2_complete_recovery(struct work_struct *work); 136void ocfs2_complete_recovery(struct work_struct *work);
176 137
@@ -231,15 +192,14 @@ static inline void ocfs2_checkpoint_inode(struct inode *inode)
231 * Transaction Handling: 192 * Transaction Handling:
232 * Manage the lifetime of a transaction handle. 193 * Manage the lifetime of a transaction handle.
233 * 194 *
234 * ocfs2_alloc_handle - Only allocate a handle so we can start putting
235 * cluster locks on it. To actually change blocks,
236 * call ocfs2_start_trans with the handle returned
237 * from this function. You may call ocfs2_commit_trans
238 * at any time in the lifetime of a handle.
239 * ocfs2_start_trans - Begin a transaction. Give it an upper estimate of 195 * ocfs2_start_trans - Begin a transaction. Give it an upper estimate of
240 * the number of blocks that will be changed during 196 * the number of blocks that will be changed during
241 * this handle. 197 * this handle.
242 * ocfs2_commit_trans - Complete a handle. 198 * ocfs2_commit_trans - Complete a handle. It might return -EIO if
199 * the journal was aborted. The majority of paths don't
200 * check the return value as an error there comes too
201 * late to do anything (and will be picked up in a
202 * later transaction).
243 * ocfs2_extend_trans - Extend a handle by nblocks credits. This may 203 * ocfs2_extend_trans - Extend a handle by nblocks credits. This may
244 * commit the handle to disk in the process, but will 204 * commit the handle to disk in the process, but will
245 * not release any locks taken during the transaction. 205 * not release any locks taken during the transaction.
@@ -249,24 +209,16 @@ static inline void ocfs2_checkpoint_inode(struct inode *inode)
249 * ocfs2_journal_dirty - Mark a journalled buffer as having dirty data. 209 * ocfs2_journal_dirty - Mark a journalled buffer as having dirty data.
250 * ocfs2_journal_dirty_data - Indicate that a data buffer should go out before 210 * ocfs2_journal_dirty_data - Indicate that a data buffer should go out before
251 * the current handle commits. 211 * the current handle commits.
252 * ocfs2_handle_add_lock - Sometimes we need to delay lock release
253 * until after a transaction has been completed. Use
254 * ocfs2_handle_add_lock to indicate that a lock needs
255 * to be released at the end of that handle. Locks
256 * will be released in the order that they are added.
257 * ocfs2_handle_add_inode - Add a locked inode to a transaction.
258 */ 212 */
259 213
260/* You must always start_trans with a number of buffs > 0, but it's 214/* You must always start_trans with a number of buffs > 0, but it's
261 * perfectly legal to go through an entire transaction without having 215 * perfectly legal to go through an entire transaction without having
262 * dirtied any buffers. */ 216 * dirtied any buffers. */
263struct ocfs2_journal_handle *ocfs2_alloc_handle(struct ocfs2_super *osb); 217handle_t *ocfs2_start_trans(struct ocfs2_super *osb,
264struct ocfs2_journal_handle *ocfs2_start_trans(struct ocfs2_super *osb,
265 struct ocfs2_journal_handle *handle,
266 int max_buffs); 218 int max_buffs);
267void ocfs2_commit_trans(struct ocfs2_journal_handle *handle); 219int ocfs2_commit_trans(struct ocfs2_super *osb,
268int ocfs2_extend_trans(struct ocfs2_journal_handle *handle, 220 handle_t *handle);
269 int nblocks); 221int ocfs2_extend_trans(handle_t *handle, int nblocks);
270 222
271/* 223/*
272 * Create access is for when we get a newly created buffer and we're 224 * Create access is for when we get a newly created buffer and we're
@@ -283,7 +235,7 @@ int ocfs2_extend_trans(struct ocfs2_journal_handle *handle,
283#define OCFS2_JOURNAL_ACCESS_WRITE 1 235#define OCFS2_JOURNAL_ACCESS_WRITE 1
284#define OCFS2_JOURNAL_ACCESS_UNDO 2 236#define OCFS2_JOURNAL_ACCESS_UNDO 2
285 237
286int ocfs2_journal_access(struct ocfs2_journal_handle *handle, 238int ocfs2_journal_access(handle_t *handle,
287 struct inode *inode, 239 struct inode *inode,
288 struct buffer_head *bh, 240 struct buffer_head *bh,
289 int type); 241 int type);
@@ -306,18 +258,10 @@ int ocfs2_journal_access(struct ocfs2_journal_handle *handle,
306 * <modify the bh> 258 * <modify the bh>
307 * ocfs2_journal_dirty(handle, bh); 259 * ocfs2_journal_dirty(handle, bh);
308 */ 260 */
309int ocfs2_journal_dirty(struct ocfs2_journal_handle *handle, 261int ocfs2_journal_dirty(handle_t *handle,
310 struct buffer_head *bh); 262 struct buffer_head *bh);
311int ocfs2_journal_dirty_data(handle_t *handle, 263int ocfs2_journal_dirty_data(handle_t *handle,
312 struct buffer_head *bh); 264 struct buffer_head *bh);
313int ocfs2_handle_add_lock(struct ocfs2_journal_handle *handle,
314 struct inode *inode);
315/*
316 * Use this to protect from other processes reading buffer state while
317 * it's in flight.
318 */
319void ocfs2_handle_add_inode(struct ocfs2_journal_handle *handle,
320 struct inode *inode);
321 265
322/* 266/*
323 * Credit Macros: 267 * Credit Macros:
diff --git a/fs/ocfs2/localalloc.c b/fs/ocfs2/localalloc.c
index 1f17a4d08287..698d79a74ef8 100644
--- a/fs/ocfs2/localalloc.c
+++ b/fs/ocfs2/localalloc.c
@@ -58,19 +58,18 @@ static int ocfs2_local_alloc_find_clear_bits(struct ocfs2_super *osb,
58static void ocfs2_clear_local_alloc(struct ocfs2_dinode *alloc); 58static void ocfs2_clear_local_alloc(struct ocfs2_dinode *alloc);
59 59
60static int ocfs2_sync_local_to_main(struct ocfs2_super *osb, 60static int ocfs2_sync_local_to_main(struct ocfs2_super *osb,
61 struct ocfs2_journal_handle *handle, 61 handle_t *handle,
62 struct ocfs2_dinode *alloc, 62 struct ocfs2_dinode *alloc,
63 struct inode *main_bm_inode, 63 struct inode *main_bm_inode,
64 struct buffer_head *main_bm_bh); 64 struct buffer_head *main_bm_bh);
65 65
66static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb, 66static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb,
67 struct ocfs2_journal_handle *handle,
68 struct ocfs2_alloc_context **ac, 67 struct ocfs2_alloc_context **ac,
69 struct inode **bitmap_inode, 68 struct inode **bitmap_inode,
70 struct buffer_head **bitmap_bh); 69 struct buffer_head **bitmap_bh);
71 70
72static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb, 71static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb,
73 struct ocfs2_journal_handle *handle, 72 handle_t *handle,
74 struct ocfs2_alloc_context *ac); 73 struct ocfs2_alloc_context *ac);
75 74
76static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb, 75static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb,
@@ -196,7 +195,7 @@ bail:
196void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb) 195void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb)
197{ 196{
198 int status; 197 int status;
199 struct ocfs2_journal_handle *handle = NULL; 198 handle_t *handle;
200 struct inode *local_alloc_inode = NULL; 199 struct inode *local_alloc_inode = NULL;
201 struct buffer_head *bh = NULL; 200 struct buffer_head *bh = NULL;
202 struct buffer_head *main_bm_bh = NULL; 201 struct buffer_head *main_bm_bh = NULL;
@@ -207,7 +206,7 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb)
207 mlog_entry_void(); 206 mlog_entry_void();
208 207
209 if (osb->local_alloc_state == OCFS2_LA_UNUSED) 208 if (osb->local_alloc_state == OCFS2_LA_UNUSED)
210 goto bail; 209 goto out;
211 210
212 local_alloc_inode = 211 local_alloc_inode =
213 ocfs2_get_system_file_inode(osb, 212 ocfs2_get_system_file_inode(osb,
@@ -216,40 +215,34 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb)
216 if (!local_alloc_inode) { 215 if (!local_alloc_inode) {
217 status = -ENOENT; 216 status = -ENOENT;
218 mlog_errno(status); 217 mlog_errno(status);
219 goto bail; 218 goto out;
220 } 219 }
221 220
222 osb->local_alloc_state = OCFS2_LA_DISABLED; 221 osb->local_alloc_state = OCFS2_LA_DISABLED;
223 222
224 handle = ocfs2_alloc_handle(osb);
225 if (!handle) {
226 status = -ENOMEM;
227 mlog_errno(status);
228 goto bail;
229 }
230
231 main_bm_inode = ocfs2_get_system_file_inode(osb, 223 main_bm_inode = ocfs2_get_system_file_inode(osb,
232 GLOBAL_BITMAP_SYSTEM_INODE, 224 GLOBAL_BITMAP_SYSTEM_INODE,
233 OCFS2_INVALID_SLOT); 225 OCFS2_INVALID_SLOT);
234 if (!main_bm_inode) { 226 if (!main_bm_inode) {
235 status = -EINVAL; 227 status = -EINVAL;
236 mlog_errno(status); 228 mlog_errno(status);
237 goto bail; 229 goto out;
238 } 230 }
239 231
240 ocfs2_handle_add_inode(handle, main_bm_inode); 232 mutex_lock(&main_bm_inode->i_mutex);
241 status = ocfs2_meta_lock(main_bm_inode, handle, &main_bm_bh, 1); 233
234 status = ocfs2_meta_lock(main_bm_inode, &main_bm_bh, 1);
242 if (status < 0) { 235 if (status < 0) {
243 mlog_errno(status); 236 mlog_errno(status);
244 goto bail; 237 goto out_mutex;
245 } 238 }
246 239
247 /* WINDOW_MOVE_CREDITS is a bit heavy... */ 240 /* WINDOW_MOVE_CREDITS is a bit heavy... */
248 handle = ocfs2_start_trans(osb, handle, OCFS2_WINDOW_MOVE_CREDITS); 241 handle = ocfs2_start_trans(osb, OCFS2_WINDOW_MOVE_CREDITS);
249 if (IS_ERR(handle)) { 242 if (IS_ERR(handle)) {
250 mlog_errno(PTR_ERR(handle)); 243 mlog_errno(PTR_ERR(handle));
251 handle = NULL; 244 handle = NULL;
252 goto bail; 245 goto out_unlock;
253 } 246 }
254 247
255 bh = osb->local_alloc_bh; 248 bh = osb->local_alloc_bh;
@@ -258,7 +251,7 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb)
258 alloc_copy = kmalloc(bh->b_size, GFP_KERNEL); 251 alloc_copy = kmalloc(bh->b_size, GFP_KERNEL);
259 if (!alloc_copy) { 252 if (!alloc_copy) {
260 status = -ENOMEM; 253 status = -ENOMEM;
261 goto bail; 254 goto out_commit;
262 } 255 }
263 memcpy(alloc_copy, alloc, bh->b_size); 256 memcpy(alloc_copy, alloc, bh->b_size);
264 257
@@ -266,7 +259,7 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb)
266 OCFS2_JOURNAL_ACCESS_WRITE); 259 OCFS2_JOURNAL_ACCESS_WRITE);
267 if (status < 0) { 260 if (status < 0) {
268 mlog_errno(status); 261 mlog_errno(status);
269 goto bail; 262 goto out_commit;
270 } 263 }
271 264
272 ocfs2_clear_local_alloc(alloc); 265 ocfs2_clear_local_alloc(alloc);
@@ -274,7 +267,7 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb)
274 status = ocfs2_journal_dirty(handle, bh); 267 status = ocfs2_journal_dirty(handle, bh);
275 if (status < 0) { 268 if (status < 0) {
276 mlog_errno(status); 269 mlog_errno(status);
277 goto bail; 270 goto out_commit;
278 } 271 }
279 272
280 brelse(bh); 273 brelse(bh);
@@ -286,16 +279,20 @@ void ocfs2_shutdown_local_alloc(struct ocfs2_super *osb)
286 if (status < 0) 279 if (status < 0)
287 mlog_errno(status); 280 mlog_errno(status);
288 281
289bail: 282out_commit:
290 if (handle) 283 ocfs2_commit_trans(osb, handle);
291 ocfs2_commit_trans(handle);
292 284
285out_unlock:
293 if (main_bm_bh) 286 if (main_bm_bh)
294 brelse(main_bm_bh); 287 brelse(main_bm_bh);
295 288
296 if (main_bm_inode) 289 ocfs2_meta_unlock(main_bm_inode, 1);
297 iput(main_bm_inode);
298 290
291out_mutex:
292 mutex_unlock(&main_bm_inode->i_mutex);
293 iput(main_bm_inode);
294
295out:
299 if (local_alloc_inode) 296 if (local_alloc_inode)
300 iput(local_alloc_inode); 297 iput(local_alloc_inode);
301 298
@@ -385,61 +382,59 @@ int ocfs2_complete_local_alloc_recovery(struct ocfs2_super *osb,
385 struct ocfs2_dinode *alloc) 382 struct ocfs2_dinode *alloc)
386{ 383{
387 int status; 384 int status;
388 struct ocfs2_journal_handle *handle = NULL; 385 handle_t *handle;
389 struct buffer_head *main_bm_bh = NULL; 386 struct buffer_head *main_bm_bh = NULL;
390 struct inode *main_bm_inode = NULL; 387 struct inode *main_bm_inode;
391 388
392 mlog_entry_void(); 389 mlog_entry_void();
393 390
394 handle = ocfs2_alloc_handle(osb);
395 if (!handle) {
396 status = -ENOMEM;
397 mlog_errno(status);
398 goto bail;
399 }
400
401 main_bm_inode = ocfs2_get_system_file_inode(osb, 391 main_bm_inode = ocfs2_get_system_file_inode(osb,
402 GLOBAL_BITMAP_SYSTEM_INODE, 392 GLOBAL_BITMAP_SYSTEM_INODE,
403 OCFS2_INVALID_SLOT); 393 OCFS2_INVALID_SLOT);
404 if (!main_bm_inode) { 394 if (!main_bm_inode) {
405 status = -EINVAL; 395 status = -EINVAL;
406 mlog_errno(status); 396 mlog_errno(status);
407 goto bail; 397 goto out;
408 } 398 }
409 399
410 ocfs2_handle_add_inode(handle, main_bm_inode); 400 mutex_lock(&main_bm_inode->i_mutex);
411 status = ocfs2_meta_lock(main_bm_inode, handle, &main_bm_bh, 1); 401
402 status = ocfs2_meta_lock(main_bm_inode, &main_bm_bh, 1);
412 if (status < 0) { 403 if (status < 0) {
413 mlog_errno(status); 404 mlog_errno(status);
414 goto bail; 405 goto out_mutex;
415 } 406 }
416 407
417 handle = ocfs2_start_trans(osb, handle, OCFS2_WINDOW_MOVE_CREDITS); 408 handle = ocfs2_start_trans(osb, OCFS2_WINDOW_MOVE_CREDITS);
418 if (IS_ERR(handle)) { 409 if (IS_ERR(handle)) {
419 status = PTR_ERR(handle); 410 status = PTR_ERR(handle);
420 handle = NULL; 411 handle = NULL;
421 mlog_errno(status); 412 mlog_errno(status);
422 goto bail; 413 goto out_unlock;
423 } 414 }
424 415
425 /* we want the bitmap change to be recorded on disk asap */ 416 /* we want the bitmap change to be recorded on disk asap */
426 ocfs2_handle_set_sync(handle, 1); 417 handle->h_sync = 1;
427 418
428 status = ocfs2_sync_local_to_main(osb, handle, alloc, 419 status = ocfs2_sync_local_to_main(osb, handle, alloc,
429 main_bm_inode, main_bm_bh); 420 main_bm_inode, main_bm_bh);
430 if (status < 0) 421 if (status < 0)
431 mlog_errno(status); 422 mlog_errno(status);
432 423
433bail: 424 ocfs2_commit_trans(osb, handle);
434 if (handle) 425
435 ocfs2_commit_trans(handle); 426out_unlock:
427 ocfs2_meta_unlock(main_bm_inode, 1);
428
429out_mutex:
430 mutex_unlock(&main_bm_inode->i_mutex);
436 431
437 if (main_bm_bh) 432 if (main_bm_bh)
438 brelse(main_bm_bh); 433 brelse(main_bm_bh);
439 434
440 if (main_bm_inode) 435 iput(main_bm_inode);
441 iput(main_bm_inode);
442 436
437out:
443 mlog_exit(status); 438 mlog_exit(status);
444 return status; 439 return status;
445} 440}
@@ -452,7 +447,6 @@ bail:
452 * our own in order to shift windows. 447 * our own in order to shift windows.
453 */ 448 */
454int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, 449int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb,
455 struct ocfs2_journal_handle *passed_handle,
456 u32 bits_wanted, 450 u32 bits_wanted,
457 struct ocfs2_alloc_context *ac) 451 struct ocfs2_alloc_context *ac)
458{ 452{
@@ -463,9 +457,7 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb,
463 457
464 mlog_entry_void(); 458 mlog_entry_void();
465 459
466 BUG_ON(!passed_handle);
467 BUG_ON(!ac); 460 BUG_ON(!ac);
468 BUG_ON(passed_handle->flags & OCFS2_HANDLE_STARTED);
469 461
470 local_alloc_inode = 462 local_alloc_inode =
471 ocfs2_get_system_file_inode(osb, 463 ocfs2_get_system_file_inode(osb,
@@ -476,7 +468,11 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb,
476 mlog_errno(status); 468 mlog_errno(status);
477 goto bail; 469 goto bail;
478 } 470 }
479 ocfs2_handle_add_inode(passed_handle, local_alloc_inode); 471
472 mutex_lock(&local_alloc_inode->i_mutex);
473
474 ac->ac_inode = local_alloc_inode;
475 ac->ac_which = OCFS2_AC_USE_LOCAL;
480 476
481 if (osb->local_alloc_state != OCFS2_LA_ENABLED) { 477 if (osb->local_alloc_state != OCFS2_LA_ENABLED) {
482 status = -ENOSPC; 478 status = -ENOSPC;
@@ -515,21 +511,17 @@ int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb,
515 } 511 }
516 } 512 }
517 513
518 ac->ac_inode = igrab(local_alloc_inode);
519 get_bh(osb->local_alloc_bh); 514 get_bh(osb->local_alloc_bh);
520 ac->ac_bh = osb->local_alloc_bh; 515 ac->ac_bh = osb->local_alloc_bh;
521 ac->ac_which = OCFS2_AC_USE_LOCAL;
522 status = 0; 516 status = 0;
523bail: 517bail:
524 if (local_alloc_inode)
525 iput(local_alloc_inode);
526 518
527 mlog_exit(status); 519 mlog_exit(status);
528 return status; 520 return status;
529} 521}
530 522
531int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb, 523int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb,
532 struct ocfs2_journal_handle *handle, 524 handle_t *handle,
533 struct ocfs2_alloc_context *ac, 525 struct ocfs2_alloc_context *ac,
534 u32 min_bits, 526 u32 min_bits,
535 u32 *bit_off, 527 u32 *bit_off,
@@ -707,7 +699,7 @@ static void ocfs2_verify_zero_bits(unsigned long *bitmap,
707 * passed is used for caching. 699 * passed is used for caching.
708 */ 700 */
709static int ocfs2_sync_local_to_main(struct ocfs2_super *osb, 701static int ocfs2_sync_local_to_main(struct ocfs2_super *osb,
710 struct ocfs2_journal_handle *handle, 702 handle_t *handle,
711 struct ocfs2_dinode *alloc, 703 struct ocfs2_dinode *alloc,
712 struct inode *main_bm_inode, 704 struct inode *main_bm_inode,
713 struct buffer_head *main_bm_bh) 705 struct buffer_head *main_bm_bh)
@@ -778,7 +770,6 @@ bail:
778} 770}
779 771
780static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb, 772static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb,
781 struct ocfs2_journal_handle *handle,
782 struct ocfs2_alloc_context **ac, 773 struct ocfs2_alloc_context **ac,
783 struct inode **bitmap_inode, 774 struct inode **bitmap_inode,
784 struct buffer_head **bitmap_bh) 775 struct buffer_head **bitmap_bh)
@@ -792,7 +783,6 @@ static int ocfs2_local_alloc_reserve_for_window(struct ocfs2_super *osb,
792 goto bail; 783 goto bail;
793 } 784 }
794 785
795 (*ac)->ac_handle = handle;
796 (*ac)->ac_bits_wanted = ocfs2_local_alloc_window_bits(osb); 786 (*ac)->ac_bits_wanted = ocfs2_local_alloc_window_bits(osb);
797 787
798 status = ocfs2_reserve_cluster_bitmap_bits(osb, *ac); 788 status = ocfs2_reserve_cluster_bitmap_bits(osb, *ac);
@@ -821,7 +811,7 @@ bail:
821 * pass it the bitmap lock in lock_bh if you have it. 811 * pass it the bitmap lock in lock_bh if you have it.
822 */ 812 */
823static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb, 813static int ocfs2_local_alloc_new_window(struct ocfs2_super *osb,
824 struct ocfs2_journal_handle *handle, 814 handle_t *handle,
825 struct ocfs2_alloc_context *ac) 815 struct ocfs2_alloc_context *ac)
826{ 816{
827 int status = 0; 817 int status = 0;
@@ -888,23 +878,15 @@ static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb,
888 int status = 0; 878 int status = 0;
889 struct buffer_head *main_bm_bh = NULL; 879 struct buffer_head *main_bm_bh = NULL;
890 struct inode *main_bm_inode = NULL; 880 struct inode *main_bm_inode = NULL;
891 struct ocfs2_journal_handle *handle = NULL; 881 handle_t *handle = NULL;
892 struct ocfs2_dinode *alloc; 882 struct ocfs2_dinode *alloc;
893 struct ocfs2_dinode *alloc_copy = NULL; 883 struct ocfs2_dinode *alloc_copy = NULL;
894 struct ocfs2_alloc_context *ac = NULL; 884 struct ocfs2_alloc_context *ac = NULL;
895 885
896 mlog_entry_void(); 886 mlog_entry_void();
897 887
898 handle = ocfs2_alloc_handle(osb);
899 if (!handle) {
900 status = -ENOMEM;
901 mlog_errno(status);
902 goto bail;
903 }
904
905 /* This will lock the main bitmap for us. */ 888 /* This will lock the main bitmap for us. */
906 status = ocfs2_local_alloc_reserve_for_window(osb, 889 status = ocfs2_local_alloc_reserve_for_window(osb,
907 handle,
908 &ac, 890 &ac,
909 &main_bm_inode, 891 &main_bm_inode,
910 &main_bm_bh); 892 &main_bm_bh);
@@ -914,7 +896,7 @@ static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb,
914 goto bail; 896 goto bail;
915 } 897 }
916 898
917 handle = ocfs2_start_trans(osb, handle, OCFS2_WINDOW_MOVE_CREDITS); 899 handle = ocfs2_start_trans(osb, OCFS2_WINDOW_MOVE_CREDITS);
918 if (IS_ERR(handle)) { 900 if (IS_ERR(handle)) {
919 status = PTR_ERR(handle); 901 status = PTR_ERR(handle);
920 handle = NULL; 902 handle = NULL;
@@ -972,7 +954,7 @@ static int ocfs2_local_alloc_slide_window(struct ocfs2_super *osb,
972 status = 0; 954 status = 0;
973bail: 955bail:
974 if (handle) 956 if (handle)
975 ocfs2_commit_trans(handle); 957 ocfs2_commit_trans(osb, handle);
976 958
977 if (main_bm_bh) 959 if (main_bm_bh)
978 brelse(main_bm_bh); 960 brelse(main_bm_bh);
diff --git a/fs/ocfs2/localalloc.h b/fs/ocfs2/localalloc.h
index 30f88ce14e46..385a10152f9c 100644
--- a/fs/ocfs2/localalloc.h
+++ b/fs/ocfs2/localalloc.h
@@ -42,12 +42,11 @@ int ocfs2_alloc_should_use_local(struct ocfs2_super *osb,
42 42
43struct ocfs2_alloc_context; 43struct ocfs2_alloc_context;
44int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb, 44int ocfs2_reserve_local_alloc_bits(struct ocfs2_super *osb,
45 struct ocfs2_journal_handle *passed_handle,
46 u32 bits_wanted, 45 u32 bits_wanted,
47 struct ocfs2_alloc_context *ac); 46 struct ocfs2_alloc_context *ac);
48 47
49int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb, 48int ocfs2_claim_local_alloc_bits(struct ocfs2_super *osb,
50 struct ocfs2_journal_handle *handle, 49 handle_t *handle,
51 struct ocfs2_alloc_context *ac, 50 struct ocfs2_alloc_context *ac,
52 u32 min_bits, 51 u32 min_bits,
53 u32 *bit_off, 52 u32 *bit_off,
diff --git a/fs/ocfs2/mmap.c b/fs/ocfs2/mmap.c
index 83934e33e5b0..69f85ae392dc 100644
--- a/fs/ocfs2/mmap.c
+++ b/fs/ocfs2/mmap.c
@@ -82,6 +82,8 @@ static struct vm_operations_struct ocfs2_file_vm_ops = {
82 82
83int ocfs2_mmap(struct file *file, struct vm_area_struct *vma) 83int ocfs2_mmap(struct file *file, struct vm_area_struct *vma)
84{ 84{
85 int ret = 0, lock_level = 0;
86
85 /* We don't want to support shared writable mappings yet. */ 87 /* We don't want to support shared writable mappings yet. */
86 if (((vma->vm_flags & VM_SHARED) || (vma->vm_flags & VM_MAYSHARE)) 88 if (((vma->vm_flags & VM_SHARED) || (vma->vm_flags & VM_MAYSHARE))
87 && ((vma->vm_flags & VM_WRITE) || (vma->vm_flags & VM_MAYWRITE))) { 89 && ((vma->vm_flags & VM_WRITE) || (vma->vm_flags & VM_MAYWRITE))) {
@@ -91,7 +93,14 @@ int ocfs2_mmap(struct file *file, struct vm_area_struct *vma)
91 return -EINVAL; 93 return -EINVAL;
92 } 94 }
93 95
94 file_accessed(file); 96 ret = ocfs2_meta_lock_atime(file->f_dentry->d_inode,
97 file->f_vfsmnt, &lock_level);
98 if (ret < 0) {
99 mlog_errno(ret);
100 goto out;
101 }
102 ocfs2_meta_unlock(file->f_dentry->d_inode, lock_level);
103out:
95 vma->vm_ops = &ocfs2_file_vm_ops; 104 vma->vm_ops = &ocfs2_file_vm_ops;
96 return 0; 105 return 0;
97} 106}
diff --git a/fs/ocfs2/namei.c b/fs/ocfs2/namei.c
index a57b751d4f40..21db45ddf144 100644
--- a/fs/ocfs2/namei.c
+++ b/fs/ocfs2/namei.c
@@ -75,12 +75,12 @@ static int inline ocfs2_search_dirblock(struct buffer_head *bh,
75 unsigned long offset, 75 unsigned long offset,
76 struct ocfs2_dir_entry **res_dir); 76 struct ocfs2_dir_entry **res_dir);
77 77
78static int ocfs2_delete_entry(struct ocfs2_journal_handle *handle, 78static int ocfs2_delete_entry(handle_t *handle,
79 struct inode *dir, 79 struct inode *dir,
80 struct ocfs2_dir_entry *de_del, 80 struct ocfs2_dir_entry *de_del,
81 struct buffer_head *bh); 81 struct buffer_head *bh);
82 82
83static int __ocfs2_add_entry(struct ocfs2_journal_handle *handle, 83static int __ocfs2_add_entry(handle_t *handle,
84 struct inode *dir, 84 struct inode *dir,
85 const char *name, int namelen, 85 const char *name, int namelen,
86 struct inode *inode, u64 blkno, 86 struct inode *inode, u64 blkno,
@@ -93,43 +93,37 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
93 dev_t dev, 93 dev_t dev,
94 struct buffer_head **new_fe_bh, 94 struct buffer_head **new_fe_bh,
95 struct buffer_head *parent_fe_bh, 95 struct buffer_head *parent_fe_bh,
96 struct ocfs2_journal_handle *handle, 96 handle_t *handle,
97 struct inode **ret_inode, 97 struct inode **ret_inode,
98 struct ocfs2_alloc_context *inode_ac); 98 struct ocfs2_alloc_context *inode_ac);
99 99
100static int ocfs2_fill_new_dir(struct ocfs2_super *osb, 100static int ocfs2_fill_new_dir(struct ocfs2_super *osb,
101 struct ocfs2_journal_handle *handle, 101 handle_t *handle,
102 struct inode *parent, 102 struct inode *parent,
103 struct inode *inode, 103 struct inode *inode,
104 struct buffer_head *fe_bh, 104 struct buffer_head *fe_bh,
105 struct ocfs2_alloc_context *data_ac); 105 struct ocfs2_alloc_context *data_ac);
106 106
107static int ocfs2_double_lock(struct ocfs2_super *osb,
108 struct ocfs2_journal_handle *handle,
109 struct buffer_head **bh1,
110 struct inode *inode1,
111 struct buffer_head **bh2,
112 struct inode *inode2);
113
114static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, 107static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
115 struct ocfs2_journal_handle *handle, 108 struct inode **ret_orphan_dir,
116 struct inode *inode, 109 struct inode *inode,
117 char *name, 110 char *name,
118 struct buffer_head **de_bh); 111 struct buffer_head **de_bh);
119 112
120static int ocfs2_orphan_add(struct ocfs2_super *osb, 113static int ocfs2_orphan_add(struct ocfs2_super *osb,
121 struct ocfs2_journal_handle *handle, 114 handle_t *handle,
122 struct inode *inode, 115 struct inode *inode,
123 struct ocfs2_dinode *fe, 116 struct ocfs2_dinode *fe,
124 char *name, 117 char *name,
125 struct buffer_head *de_bh); 118 struct buffer_head *de_bh,
119 struct inode *orphan_dir_inode);
126 120
127static int ocfs2_create_symlink_data(struct ocfs2_super *osb, 121static int ocfs2_create_symlink_data(struct ocfs2_super *osb,
128 struct ocfs2_journal_handle *handle, 122 handle_t *handle,
129 struct inode *inode, 123 struct inode *inode,
130 const char *symname); 124 const char *symname);
131 125
132static inline int ocfs2_add_entry(struct ocfs2_journal_handle *handle, 126static inline int ocfs2_add_entry(handle_t *handle,
133 struct dentry *dentry, 127 struct dentry *dentry,
134 struct inode *inode, u64 blkno, 128 struct inode *inode, u64 blkno,
135 struct buffer_head *parent_fe_bh, 129 struct buffer_head *parent_fe_bh,
@@ -165,7 +159,7 @@ static struct dentry *ocfs2_lookup(struct inode *dir, struct dentry *dentry,
165 mlog(0, "find name %.*s in directory %llu\n", dentry->d_name.len, 159 mlog(0, "find name %.*s in directory %llu\n", dentry->d_name.len,
166 dentry->d_name.name, (unsigned long long)OCFS2_I(dir)->ip_blkno); 160 dentry->d_name.name, (unsigned long long)OCFS2_I(dir)->ip_blkno);
167 161
168 status = ocfs2_meta_lock(dir, NULL, NULL, 0); 162 status = ocfs2_meta_lock(dir, NULL, 0);
169 if (status < 0) { 163 if (status < 0) {
170 if (status != -ENOENT) 164 if (status != -ENOENT)
171 mlog_errno(status); 165 mlog_errno(status);
@@ -242,7 +236,7 @@ bail:
242} 236}
243 237
244static int ocfs2_fill_new_dir(struct ocfs2_super *osb, 238static int ocfs2_fill_new_dir(struct ocfs2_super *osb,
245 struct ocfs2_journal_handle *handle, 239 handle_t *handle,
246 struct inode *parent, 240 struct inode *parent,
247 struct inode *inode, 241 struct inode *inode,
248 struct buffer_head *fe_bh, 242 struct buffer_head *fe_bh,
@@ -317,7 +311,7 @@ static int ocfs2_mknod(struct inode *dir,
317{ 311{
318 int status = 0; 312 int status = 0;
319 struct buffer_head *parent_fe_bh = NULL; 313 struct buffer_head *parent_fe_bh = NULL;
320 struct ocfs2_journal_handle *handle = NULL; 314 handle_t *handle = NULL;
321 struct ocfs2_super *osb; 315 struct ocfs2_super *osb;
322 struct ocfs2_dinode *dirfe; 316 struct ocfs2_dinode *dirfe;
323 struct buffer_head *new_fe_bh = NULL; 317 struct buffer_head *new_fe_bh = NULL;
@@ -333,18 +327,11 @@ static int ocfs2_mknod(struct inode *dir,
333 /* get our super block */ 327 /* get our super block */
334 osb = OCFS2_SB(dir->i_sb); 328 osb = OCFS2_SB(dir->i_sb);
335 329
336 handle = ocfs2_alloc_handle(osb); 330 status = ocfs2_meta_lock(dir, &parent_fe_bh, 1);
337 if (handle == NULL) {
338 status = -ENOMEM;
339 mlog_errno(status);
340 goto leave;
341 }
342
343 status = ocfs2_meta_lock(dir, handle, &parent_fe_bh, 1);
344 if (status < 0) { 331 if (status < 0) {
345 if (status != -ENOENT) 332 if (status != -ENOENT)
346 mlog_errno(status); 333 mlog_errno(status);
347 goto leave; 334 return status;
348 } 335 }
349 336
350 if (S_ISDIR(mode) && (dir->i_nlink >= OCFS2_LINK_MAX)) { 337 if (S_ISDIR(mode) && (dir->i_nlink >= OCFS2_LINK_MAX)) {
@@ -374,7 +361,7 @@ static int ocfs2_mknod(struct inode *dir,
374 } 361 }
375 362
376 /* reserve an inode spot */ 363 /* reserve an inode spot */
377 status = ocfs2_reserve_new_inode(osb, handle, &inode_ac); 364 status = ocfs2_reserve_new_inode(osb, &inode_ac);
378 if (status < 0) { 365 if (status < 0) {
379 if (status != -ENOSPC) 366 if (status != -ENOSPC)
380 mlog_errno(status); 367 mlog_errno(status);
@@ -384,7 +371,7 @@ static int ocfs2_mknod(struct inode *dir,
384 /* are we making a directory? If so, reserve a cluster for his 371 /* are we making a directory? If so, reserve a cluster for his
385 * 1st extent. */ 372 * 1st extent. */
386 if (S_ISDIR(mode)) { 373 if (S_ISDIR(mode)) {
387 status = ocfs2_reserve_clusters(osb, handle, 1, &data_ac); 374 status = ocfs2_reserve_clusters(osb, 1, &data_ac);
388 if (status < 0) { 375 if (status < 0) {
389 if (status != -ENOSPC) 376 if (status != -ENOSPC)
390 mlog_errno(status); 377 mlog_errno(status);
@@ -392,7 +379,7 @@ static int ocfs2_mknod(struct inode *dir,
392 } 379 }
393 } 380 }
394 381
395 handle = ocfs2_start_trans(osb, handle, OCFS2_MKNOD_CREDITS); 382 handle = ocfs2_start_trans(osb, OCFS2_MKNOD_CREDITS);
396 if (IS_ERR(handle)) { 383 if (IS_ERR(handle)) {
397 status = PTR_ERR(handle); 384 status = PTR_ERR(handle);
398 handle = NULL; 385 handle = NULL;
@@ -453,7 +440,9 @@ static int ocfs2_mknod(struct inode *dir,
453 status = 0; 440 status = 0;
454leave: 441leave:
455 if (handle) 442 if (handle)
456 ocfs2_commit_trans(handle); 443 ocfs2_commit_trans(osb, handle);
444
445 ocfs2_meta_unlock(dir, 1);
457 446
458 if (status == -ENOSPC) 447 if (status == -ENOSPC)
459 mlog(0, "Disk is full\n"); 448 mlog(0, "Disk is full\n");
@@ -487,7 +476,7 @@ static int ocfs2_mknod_locked(struct ocfs2_super *osb,
487 dev_t dev, 476 dev_t dev,
488 struct buffer_head **new_fe_bh, 477 struct buffer_head **new_fe_bh,
489 struct buffer_head *parent_fe_bh, 478 struct buffer_head *parent_fe_bh,
490 struct ocfs2_journal_handle *handle, 479 handle_t *handle,
491 struct inode **ret_inode, 480 struct inode **ret_inode,
492 struct ocfs2_alloc_context *inode_ac) 481 struct ocfs2_alloc_context *inode_ac)
493{ 482{
@@ -653,7 +642,7 @@ static int ocfs2_link(struct dentry *old_dentry,
653 struct inode *dir, 642 struct inode *dir,
654 struct dentry *dentry) 643 struct dentry *dentry)
655{ 644{
656 struct ocfs2_journal_handle *handle = NULL; 645 handle_t *handle;
657 struct inode *inode = old_dentry->d_inode; 646 struct inode *inode = old_dentry->d_inode;
658 int err; 647 int err;
659 struct buffer_head *fe_bh = NULL; 648 struct buffer_head *fe_bh = NULL;
@@ -666,68 +655,60 @@ static int ocfs2_link(struct dentry *old_dentry,
666 old_dentry->d_name.len, old_dentry->d_name.name, 655 old_dentry->d_name.len, old_dentry->d_name.name,
667 dentry->d_name.len, dentry->d_name.name); 656 dentry->d_name.len, dentry->d_name.name);
668 657
669 if (S_ISDIR(inode->i_mode)) { 658 if (S_ISDIR(inode->i_mode))
670 err = -EPERM; 659 return -EPERM;
671 goto bail;
672 }
673
674 handle = ocfs2_alloc_handle(osb);
675 if (handle == NULL) {
676 err = -ENOMEM;
677 goto bail;
678 }
679 660
680 err = ocfs2_meta_lock(dir, handle, &parent_fe_bh, 1); 661 err = ocfs2_meta_lock(dir, &parent_fe_bh, 1);
681 if (err < 0) { 662 if (err < 0) {
682 if (err != -ENOENT) 663 if (err != -ENOENT)
683 mlog_errno(err); 664 mlog_errno(err);
684 goto bail; 665 return err;
685 } 666 }
686 667
687 if (!dir->i_nlink) { 668 if (!dir->i_nlink) {
688 err = -ENOENT; 669 err = -ENOENT;
689 goto bail; 670 goto out;
690 } 671 }
691 672
692 err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name, 673 err = ocfs2_check_dir_for_entry(dir, dentry->d_name.name,
693 dentry->d_name.len); 674 dentry->d_name.len);
694 if (err) 675 if (err)
695 goto bail; 676 goto out;
696 677
697 err = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh, 678 err = ocfs2_prepare_dir_for_insert(osb, dir, parent_fe_bh,
698 dentry->d_name.name, 679 dentry->d_name.name,
699 dentry->d_name.len, &de_bh); 680 dentry->d_name.len, &de_bh);
700 if (err < 0) { 681 if (err < 0) {
701 mlog_errno(err); 682 mlog_errno(err);
702 goto bail; 683 goto out;
703 } 684 }
704 685
705 err = ocfs2_meta_lock(inode, handle, &fe_bh, 1); 686 err = ocfs2_meta_lock(inode, &fe_bh, 1);
706 if (err < 0) { 687 if (err < 0) {
707 if (err != -ENOENT) 688 if (err != -ENOENT)
708 mlog_errno(err); 689 mlog_errno(err);
709 goto bail; 690 goto out;
710 } 691 }
711 692
712 fe = (struct ocfs2_dinode *) fe_bh->b_data; 693 fe = (struct ocfs2_dinode *) fe_bh->b_data;
713 if (le16_to_cpu(fe->i_links_count) >= OCFS2_LINK_MAX) { 694 if (le16_to_cpu(fe->i_links_count) >= OCFS2_LINK_MAX) {
714 err = -EMLINK; 695 err = -EMLINK;
715 goto bail; 696 goto out_unlock_inode;
716 } 697 }
717 698
718 handle = ocfs2_start_trans(osb, handle, OCFS2_LINK_CREDITS); 699 handle = ocfs2_start_trans(osb, OCFS2_LINK_CREDITS);
719 if (IS_ERR(handle)) { 700 if (IS_ERR(handle)) {
720 err = PTR_ERR(handle); 701 err = PTR_ERR(handle);
721 handle = NULL; 702 handle = NULL;
722 mlog_errno(err); 703 mlog_errno(err);
723 goto bail; 704 goto out_unlock_inode;
724 } 705 }
725 706
726 err = ocfs2_journal_access(handle, inode, fe_bh, 707 err = ocfs2_journal_access(handle, inode, fe_bh,
727 OCFS2_JOURNAL_ACCESS_WRITE); 708 OCFS2_JOURNAL_ACCESS_WRITE);
728 if (err < 0) { 709 if (err < 0) {
729 mlog_errno(err); 710 mlog_errno(err);
730 goto bail; 711 goto out_commit;
731 } 712 }
732 713
733 inc_nlink(inode); 714 inc_nlink(inode);
@@ -741,7 +722,7 @@ static int ocfs2_link(struct dentry *old_dentry,
741 le16_add_cpu(&fe->i_links_count, -1); 722 le16_add_cpu(&fe->i_links_count, -1);
742 drop_nlink(inode); 723 drop_nlink(inode);
743 mlog_errno(err); 724 mlog_errno(err);
744 goto bail; 725 goto out_commit;
745 } 726 }
746 727
747 err = ocfs2_add_entry(handle, dentry, inode, 728 err = ocfs2_add_entry(handle, dentry, inode,
@@ -751,21 +732,27 @@ static int ocfs2_link(struct dentry *old_dentry,
751 le16_add_cpu(&fe->i_links_count, -1); 732 le16_add_cpu(&fe->i_links_count, -1);
752 drop_nlink(inode); 733 drop_nlink(inode);
753 mlog_errno(err); 734 mlog_errno(err);
754 goto bail; 735 goto out_commit;
755 } 736 }
756 737
757 err = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno); 738 err = ocfs2_dentry_attach_lock(dentry, inode, OCFS2_I(dir)->ip_blkno);
758 if (err) { 739 if (err) {
759 mlog_errno(err); 740 mlog_errno(err);
760 goto bail; 741 goto out_commit;
761 } 742 }
762 743
763 atomic_inc(&inode->i_count); 744 atomic_inc(&inode->i_count);
764 dentry->d_op = &ocfs2_dentry_ops; 745 dentry->d_op = &ocfs2_dentry_ops;
765 d_instantiate(dentry, inode); 746 d_instantiate(dentry, inode);
766bail: 747
767 if (handle) 748out_commit:
768 ocfs2_commit_trans(handle); 749 ocfs2_commit_trans(osb, handle);
750out_unlock_inode:
751 ocfs2_meta_unlock(inode, 1);
752
753out:
754 ocfs2_meta_unlock(dir, 1);
755
769 if (de_bh) 756 if (de_bh)
770 brelse(de_bh); 757 brelse(de_bh);
771 if (fe_bh) 758 if (fe_bh)
@@ -812,13 +799,15 @@ static int ocfs2_unlink(struct inode *dir,
812 struct dentry *dentry) 799 struct dentry *dentry)
813{ 800{
814 int status; 801 int status;
802 int child_locked = 0;
815 struct inode *inode = dentry->d_inode; 803 struct inode *inode = dentry->d_inode;
804 struct inode *orphan_dir = NULL;
816 struct ocfs2_super *osb = OCFS2_SB(dir->i_sb); 805 struct ocfs2_super *osb = OCFS2_SB(dir->i_sb);
817 u64 blkno; 806 u64 blkno;
818 struct ocfs2_dinode *fe = NULL; 807 struct ocfs2_dinode *fe = NULL;
819 struct buffer_head *fe_bh = NULL; 808 struct buffer_head *fe_bh = NULL;
820 struct buffer_head *parent_node_bh = NULL; 809 struct buffer_head *parent_node_bh = NULL;
821 struct ocfs2_journal_handle *handle = NULL; 810 handle_t *handle = NULL;
822 struct ocfs2_dir_entry *dirent = NULL; 811 struct ocfs2_dir_entry *dirent = NULL;
823 struct buffer_head *dirent_bh = NULL; 812 struct buffer_head *dirent_bh = NULL;
824 char orphan_name[OCFS2_ORPHAN_NAMELEN + 1]; 813 char orphan_name[OCFS2_ORPHAN_NAMELEN + 1];
@@ -833,22 +822,14 @@ static int ocfs2_unlink(struct inode *dir,
833 822
834 if (inode == osb->root_inode) { 823 if (inode == osb->root_inode) {
835 mlog(0, "Cannot delete the root directory\n"); 824 mlog(0, "Cannot delete the root directory\n");
836 status = -EPERM; 825 return -EPERM;
837 goto leave;
838 } 826 }
839 827
840 handle = ocfs2_alloc_handle(osb); 828 status = ocfs2_meta_lock(dir, &parent_node_bh, 1);
841 if (handle == NULL) {
842 status = -ENOMEM;
843 mlog_errno(status);
844 goto leave;
845 }
846
847 status = ocfs2_meta_lock(dir, handle, &parent_node_bh, 1);
848 if (status < 0) { 829 if (status < 0) {
849 if (status != -ENOENT) 830 if (status != -ENOENT)
850 mlog_errno(status); 831 mlog_errno(status);
851 goto leave; 832 return status;
852 } 833 }
853 834
854 status = ocfs2_find_files_on_disk(dentry->d_name.name, 835 status = ocfs2_find_files_on_disk(dentry->d_name.name,
@@ -869,12 +850,13 @@ static int ocfs2_unlink(struct inode *dir,
869 goto leave; 850 goto leave;
870 } 851 }
871 852
872 status = ocfs2_meta_lock(inode, handle, &fe_bh, 1); 853 status = ocfs2_meta_lock(inode, &fe_bh, 1);
873 if (status < 0) { 854 if (status < 0) {
874 if (status != -ENOENT) 855 if (status != -ENOENT)
875 mlog_errno(status); 856 mlog_errno(status);
876 goto leave; 857 goto leave;
877 } 858 }
859 child_locked = 1;
878 860
879 if (S_ISDIR(inode->i_mode)) { 861 if (S_ISDIR(inode->i_mode)) {
880 if (!ocfs2_empty_dir(inode)) { 862 if (!ocfs2_empty_dir(inode)) {
@@ -895,7 +877,7 @@ static int ocfs2_unlink(struct inode *dir,
895 } 877 }
896 878
897 if (inode_is_unlinkable(inode)) { 879 if (inode_is_unlinkable(inode)) {
898 status = ocfs2_prepare_orphan_dir(osb, handle, inode, 880 status = ocfs2_prepare_orphan_dir(osb, &orphan_dir, inode,
899 orphan_name, 881 orphan_name,
900 &orphan_entry_bh); 882 &orphan_entry_bh);
901 if (status < 0) { 883 if (status < 0) {
@@ -904,7 +886,7 @@ static int ocfs2_unlink(struct inode *dir,
904 } 886 }
905 } 887 }
906 888
907 handle = ocfs2_start_trans(osb, handle, OCFS2_UNLINK_CREDITS); 889 handle = ocfs2_start_trans(osb, OCFS2_UNLINK_CREDITS);
908 if (IS_ERR(handle)) { 890 if (IS_ERR(handle)) {
909 status = PTR_ERR(handle); 891 status = PTR_ERR(handle);
910 handle = NULL; 892 handle = NULL;
@@ -923,7 +905,7 @@ static int ocfs2_unlink(struct inode *dir,
923 905
924 if (inode_is_unlinkable(inode)) { 906 if (inode_is_unlinkable(inode)) {
925 status = ocfs2_orphan_add(osb, handle, inode, fe, orphan_name, 907 status = ocfs2_orphan_add(osb, handle, inode, fe, orphan_name,
926 orphan_entry_bh); 908 orphan_entry_bh, orphan_dir);
927 if (status < 0) { 909 if (status < 0) {
928 mlog_errno(status); 910 mlog_errno(status);
929 goto leave; 911 goto leave;
@@ -960,7 +942,19 @@ static int ocfs2_unlink(struct inode *dir,
960 942
961leave: 943leave:
962 if (handle) 944 if (handle)
963 ocfs2_commit_trans(handle); 945 ocfs2_commit_trans(osb, handle);
946
947 if (child_locked)
948 ocfs2_meta_unlock(inode, 1);
949
950 ocfs2_meta_unlock(dir, 1);
951
952 if (orphan_dir) {
953 /* This was locked for us in ocfs2_prepare_orphan_dir() */
954 ocfs2_meta_unlock(orphan_dir, 1);
955 mutex_unlock(&orphan_dir->i_mutex);
956 iput(orphan_dir);
957 }
964 958
965 if (fe_bh) 959 if (fe_bh)
966 brelse(fe_bh); 960 brelse(fe_bh);
@@ -984,7 +978,6 @@ leave:
984 * if they have the same id, then the 1st one is the only one locked. 978 * if they have the same id, then the 1st one is the only one locked.
985 */ 979 */
986static int ocfs2_double_lock(struct ocfs2_super *osb, 980static int ocfs2_double_lock(struct ocfs2_super *osb,
987 struct ocfs2_journal_handle *handle,
988 struct buffer_head **bh1, 981 struct buffer_head **bh1,
989 struct inode *inode1, 982 struct inode *inode1,
990 struct buffer_head **bh2, 983 struct buffer_head **bh2,
@@ -1000,8 +993,6 @@ static int ocfs2_double_lock(struct ocfs2_super *osb,
1000 (unsigned long long)oi1->ip_blkno, 993 (unsigned long long)oi1->ip_blkno,
1001 (unsigned long long)oi2->ip_blkno); 994 (unsigned long long)oi2->ip_blkno);
1002 995
1003 BUG_ON(!handle);
1004
1005 if (*bh1) 996 if (*bh1)
1006 *bh1 = NULL; 997 *bh1 = NULL;
1007 if (*bh2) 998 if (*bh2)
@@ -1021,25 +1012,41 @@ static int ocfs2_double_lock(struct ocfs2_super *osb,
1021 inode1 = tmpinode; 1012 inode1 = tmpinode;
1022 } 1013 }
1023 /* lock id2 */ 1014 /* lock id2 */
1024 status = ocfs2_meta_lock(inode2, handle, bh2, 1); 1015 status = ocfs2_meta_lock(inode2, bh2, 1);
1025 if (status < 0) { 1016 if (status < 0) {
1026 if (status != -ENOENT) 1017 if (status != -ENOENT)
1027 mlog_errno(status); 1018 mlog_errno(status);
1028 goto bail; 1019 goto bail;
1029 } 1020 }
1030 } 1021 }
1022
1031 /* lock id1 */ 1023 /* lock id1 */
1032 status = ocfs2_meta_lock(inode1, handle, bh1, 1); 1024 status = ocfs2_meta_lock(inode1, bh1, 1);
1033 if (status < 0) { 1025 if (status < 0) {
1026 /*
1027 * An error return must mean that no cluster locks
1028 * were held on function exit.
1029 */
1030 if (oi1->ip_blkno != oi2->ip_blkno)
1031 ocfs2_meta_unlock(inode2, 1);
1032
1034 if (status != -ENOENT) 1033 if (status != -ENOENT)
1035 mlog_errno(status); 1034 mlog_errno(status);
1036 goto bail;
1037 } 1035 }
1036
1038bail: 1037bail:
1039 mlog_exit(status); 1038 mlog_exit(status);
1040 return status; 1039 return status;
1041} 1040}
1042 1041
1042static void ocfs2_double_unlock(struct inode *inode1, struct inode *inode2)
1043{
1044 ocfs2_meta_unlock(inode1, 1);
1045
1046 if (inode1 != inode2)
1047 ocfs2_meta_unlock(inode2, 1);
1048}
1049
1043#define PARENT_INO(buffer) \ 1050#define PARENT_INO(buffer) \
1044 ((struct ocfs2_dir_entry *) \ 1051 ((struct ocfs2_dir_entry *) \
1045 ((char *)buffer + \ 1052 ((char *)buffer + \
@@ -1050,9 +1057,11 @@ static int ocfs2_rename(struct inode *old_dir,
1050 struct inode *new_dir, 1057 struct inode *new_dir,
1051 struct dentry *new_dentry) 1058 struct dentry *new_dentry)
1052{ 1059{
1053 int status = 0, rename_lock = 0; 1060 int status = 0, rename_lock = 0, parents_locked = 0;
1061 int old_child_locked = 0, new_child_locked = 0;
1054 struct inode *old_inode = old_dentry->d_inode; 1062 struct inode *old_inode = old_dentry->d_inode;
1055 struct inode *new_inode = new_dentry->d_inode; 1063 struct inode *new_inode = new_dentry->d_inode;
1064 struct inode *orphan_dir = NULL;
1056 struct ocfs2_dinode *newfe = NULL; 1065 struct ocfs2_dinode *newfe = NULL;
1057 char orphan_name[OCFS2_ORPHAN_NAMELEN + 1]; 1066 char orphan_name[OCFS2_ORPHAN_NAMELEN + 1];
1058 struct buffer_head *orphan_entry_bh = NULL; 1067 struct buffer_head *orphan_entry_bh = NULL;
@@ -1060,7 +1069,7 @@ static int ocfs2_rename(struct inode *old_dir,
1060 struct buffer_head *insert_entry_bh = NULL; 1069 struct buffer_head *insert_entry_bh = NULL;
1061 struct ocfs2_super *osb = NULL; 1070 struct ocfs2_super *osb = NULL;
1062 u64 newfe_blkno; 1071 u64 newfe_blkno;
1063 struct ocfs2_journal_handle *handle = NULL; 1072 handle_t *handle = NULL;
1064 struct buffer_head *old_dir_bh = NULL; 1073 struct buffer_head *old_dir_bh = NULL;
1065 struct buffer_head *new_dir_bh = NULL; 1074 struct buffer_head *new_dir_bh = NULL;
1066 struct ocfs2_dir_entry *old_de = NULL, *new_de = NULL; // dirent for old_dentry 1075 struct ocfs2_dir_entry *old_de = NULL, *new_de = NULL; // dirent for old_dentry
@@ -1105,21 +1114,14 @@ static int ocfs2_rename(struct inode *old_dir,
1105 rename_lock = 1; 1114 rename_lock = 1;
1106 } 1115 }
1107 1116
1108 handle = ocfs2_alloc_handle(osb);
1109 if (handle == NULL) {
1110 status = -ENOMEM;
1111 mlog_errno(status);
1112 goto bail;
1113 }
1114
1115 /* if old and new are the same, this'll just do one lock. */ 1117 /* if old and new are the same, this'll just do one lock. */
1116 status = ocfs2_double_lock(osb, handle, 1118 status = ocfs2_double_lock(osb, &old_dir_bh, old_dir,
1117 &old_dir_bh, old_dir, 1119 &new_dir_bh, new_dir);
1118 &new_dir_bh, new_dir);
1119 if (status < 0) { 1120 if (status < 0) {
1120 mlog_errno(status); 1121 mlog_errno(status);
1121 goto bail; 1122 goto bail;
1122 } 1123 }
1124 parents_locked = 1;
1123 1125
1124 /* make sure both dirs have bhs 1126 /* make sure both dirs have bhs
1125 * get an extra ref on old_dir_bh if old==new */ 1127 * get an extra ref on old_dir_bh if old==new */
@@ -1140,12 +1142,13 @@ static int ocfs2_rename(struct inode *old_dir,
1140 * the vote thread on other nodes won't have to concurrently 1142 * the vote thread on other nodes won't have to concurrently
1141 * downconvert the inode and the dentry locks. 1143 * downconvert the inode and the dentry locks.
1142 */ 1144 */
1143 status = ocfs2_meta_lock(old_inode, handle, NULL, 1); 1145 status = ocfs2_meta_lock(old_inode, NULL, 1);
1144 if (status < 0) { 1146 if (status < 0) {
1145 if (status != -ENOENT) 1147 if (status != -ENOENT)
1146 mlog_errno(status); 1148 mlog_errno(status);
1147 goto bail; 1149 goto bail;
1148 } 1150 }
1151 old_child_locked = 1;
1149 1152
1150 status = ocfs2_remote_dentry_delete(old_dentry); 1153 status = ocfs2_remote_dentry_delete(old_dentry);
1151 if (status < 0) { 1154 if (status < 0) {
@@ -1231,12 +1234,13 @@ static int ocfs2_rename(struct inode *old_dir,
1231 goto bail; 1234 goto bail;
1232 } 1235 }
1233 1236
1234 status = ocfs2_meta_lock(new_inode, handle, &newfe_bh, 1); 1237 status = ocfs2_meta_lock(new_inode, &newfe_bh, 1);
1235 if (status < 0) { 1238 if (status < 0) {
1236 if (status != -ENOENT) 1239 if (status != -ENOENT)
1237 mlog_errno(status); 1240 mlog_errno(status);
1238 goto bail; 1241 goto bail;
1239 } 1242 }
1243 new_child_locked = 1;
1240 1244
1241 status = ocfs2_remote_dentry_delete(new_dentry); 1245 status = ocfs2_remote_dentry_delete(new_dentry);
1242 if (status < 0) { 1246 if (status < 0) {
@@ -1252,7 +1256,7 @@ static int ocfs2_rename(struct inode *old_dir,
1252 (unsigned long long)newfe_bh->b_blocknr : 0ULL); 1256 (unsigned long long)newfe_bh->b_blocknr : 0ULL);
1253 1257
1254 if (S_ISDIR(new_inode->i_mode) || (new_inode->i_nlink == 1)) { 1258 if (S_ISDIR(new_inode->i_mode) || (new_inode->i_nlink == 1)) {
1255 status = ocfs2_prepare_orphan_dir(osb, handle, 1259 status = ocfs2_prepare_orphan_dir(osb, &orphan_dir,
1256 new_inode, 1260 new_inode,
1257 orphan_name, 1261 orphan_name,
1258 &orphan_entry_bh); 1262 &orphan_entry_bh);
@@ -1280,7 +1284,7 @@ static int ocfs2_rename(struct inode *old_dir,
1280 } 1284 }
1281 } 1285 }
1282 1286
1283 handle = ocfs2_start_trans(osb, handle, OCFS2_RENAME_CREDITS); 1287 handle = ocfs2_start_trans(osb, OCFS2_RENAME_CREDITS);
1284 if (IS_ERR(handle)) { 1288 if (IS_ERR(handle)) {
1285 status = PTR_ERR(handle); 1289 status = PTR_ERR(handle);
1286 handle = NULL; 1290 handle = NULL;
@@ -1307,7 +1311,7 @@ static int ocfs2_rename(struct inode *old_dir,
1307 (newfe->i_links_count == cpu_to_le16(1))){ 1311 (newfe->i_links_count == cpu_to_le16(1))){
1308 status = ocfs2_orphan_add(osb, handle, new_inode, 1312 status = ocfs2_orphan_add(osb, handle, new_inode,
1309 newfe, orphan_name, 1313 newfe, orphan_name,
1310 orphan_entry_bh); 1314 orphan_entry_bh, orphan_dir);
1311 if (status < 0) { 1315 if (status < 0) {
1312 mlog_errno(status); 1316 mlog_errno(status);
1313 goto bail; 1317 goto bail;
@@ -1424,7 +1428,23 @@ bail:
1424 ocfs2_rename_unlock(osb); 1428 ocfs2_rename_unlock(osb);
1425 1429
1426 if (handle) 1430 if (handle)
1427 ocfs2_commit_trans(handle); 1431 ocfs2_commit_trans(osb, handle);
1432
1433 if (parents_locked)
1434 ocfs2_double_unlock(old_dir, new_dir);
1435
1436 if (old_child_locked)
1437 ocfs2_meta_unlock(old_inode, 1);
1438
1439 if (new_child_locked)
1440 ocfs2_meta_unlock(new_inode, 1);
1441
1442 if (orphan_dir) {
1443 /* This was locked for us in ocfs2_prepare_orphan_dir() */
1444 ocfs2_meta_unlock(orphan_dir, 1);
1445 mutex_unlock(&orphan_dir->i_mutex);
1446 iput(orphan_dir);
1447 }
1428 1448
1429 if (new_inode) 1449 if (new_inode)
1430 sync_mapping_buffers(old_inode->i_mapping); 1450 sync_mapping_buffers(old_inode->i_mapping);
@@ -1458,7 +1478,7 @@ bail:
1458 * data, including the null terminator. 1478 * data, including the null terminator.
1459 */ 1479 */
1460static int ocfs2_create_symlink_data(struct ocfs2_super *osb, 1480static int ocfs2_create_symlink_data(struct ocfs2_super *osb,
1461 struct ocfs2_journal_handle *handle, 1481 handle_t *handle,
1462 struct inode *inode, 1482 struct inode *inode,
1463 const char *symname) 1483 const char *symname)
1464{ 1484{
@@ -1573,7 +1593,7 @@ static int ocfs2_symlink(struct inode *dir,
1573 struct buffer_head *parent_fe_bh = NULL; 1593 struct buffer_head *parent_fe_bh = NULL;
1574 struct ocfs2_dinode *fe = NULL; 1594 struct ocfs2_dinode *fe = NULL;
1575 struct ocfs2_dinode *dirfe; 1595 struct ocfs2_dinode *dirfe;
1576 struct ocfs2_journal_handle *handle = NULL; 1596 handle_t *handle = NULL;
1577 struct ocfs2_alloc_context *inode_ac = NULL; 1597 struct ocfs2_alloc_context *inode_ac = NULL;
1578 struct ocfs2_alloc_context *data_ac = NULL; 1598 struct ocfs2_alloc_context *data_ac = NULL;
1579 1599
@@ -1587,19 +1607,12 @@ static int ocfs2_symlink(struct inode *dir,
1587 1607
1588 credits = ocfs2_calc_symlink_credits(sb); 1608 credits = ocfs2_calc_symlink_credits(sb);
1589 1609
1590 handle = ocfs2_alloc_handle(osb);
1591 if (handle == NULL) {
1592 status = -ENOMEM;
1593 mlog_errno(status);
1594 goto bail;
1595 }
1596
1597 /* lock the parent directory */ 1610 /* lock the parent directory */
1598 status = ocfs2_meta_lock(dir, handle, &parent_fe_bh, 1); 1611 status = ocfs2_meta_lock(dir, &parent_fe_bh, 1);
1599 if (status < 0) { 1612 if (status < 0) {
1600 if (status != -ENOENT) 1613 if (status != -ENOENT)
1601 mlog_errno(status); 1614 mlog_errno(status);
1602 goto bail; 1615 return status;
1603 } 1616 }
1604 1617
1605 dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data; 1618 dirfe = (struct ocfs2_dinode *) parent_fe_bh->b_data;
@@ -1622,7 +1635,7 @@ static int ocfs2_symlink(struct inode *dir,
1622 goto bail; 1635 goto bail;
1623 } 1636 }
1624 1637
1625 status = ocfs2_reserve_new_inode(osb, handle, &inode_ac); 1638 status = ocfs2_reserve_new_inode(osb, &inode_ac);
1626 if (status < 0) { 1639 if (status < 0) {
1627 if (status != -ENOSPC) 1640 if (status != -ENOSPC)
1628 mlog_errno(status); 1641 mlog_errno(status);
@@ -1631,7 +1644,7 @@ static int ocfs2_symlink(struct inode *dir,
1631 1644
1632 /* don't reserve bitmap space for fast symlinks. */ 1645 /* don't reserve bitmap space for fast symlinks. */
1633 if (l > ocfs2_fast_symlink_chars(sb)) { 1646 if (l > ocfs2_fast_symlink_chars(sb)) {
1634 status = ocfs2_reserve_clusters(osb, handle, 1, &data_ac); 1647 status = ocfs2_reserve_clusters(osb, 1, &data_ac);
1635 if (status < 0) { 1648 if (status < 0) {
1636 if (status != -ENOSPC) 1649 if (status != -ENOSPC)
1637 mlog_errno(status); 1650 mlog_errno(status);
@@ -1639,7 +1652,7 @@ static int ocfs2_symlink(struct inode *dir,
1639 } 1652 }
1640 } 1653 }
1641 1654
1642 handle = ocfs2_start_trans(osb, handle, credits); 1655 handle = ocfs2_start_trans(osb, credits);
1643 if (IS_ERR(handle)) { 1656 if (IS_ERR(handle)) {
1644 status = PTR_ERR(handle); 1657 status = PTR_ERR(handle);
1645 handle = NULL; 1658 handle = NULL;
@@ -1717,7 +1730,10 @@ static int ocfs2_symlink(struct inode *dir,
1717 d_instantiate(dentry, inode); 1730 d_instantiate(dentry, inode);
1718bail: 1731bail:
1719 if (handle) 1732 if (handle)
1720 ocfs2_commit_trans(handle); 1733 ocfs2_commit_trans(osb, handle);
1734
1735 ocfs2_meta_unlock(dir, 1);
1736
1721 if (new_fe_bh) 1737 if (new_fe_bh)
1722 brelse(new_fe_bh); 1738 brelse(new_fe_bh);
1723 if (parent_fe_bh) 1739 if (parent_fe_bh)
@@ -1768,7 +1784,7 @@ int ocfs2_check_dir_entry(struct inode * dir,
1768 * If you pass me insert_bh, I'll skip the search of the other dir 1784 * If you pass me insert_bh, I'll skip the search of the other dir
1769 * blocks and put the record in there. 1785 * blocks and put the record in there.
1770 */ 1786 */
1771static int __ocfs2_add_entry(struct ocfs2_journal_handle *handle, 1787static int __ocfs2_add_entry(handle_t *handle,
1772 struct inode *dir, 1788 struct inode *dir,
1773 const char *name, int namelen, 1789 const char *name, int namelen,
1774 struct inode *inode, u64 blkno, 1790 struct inode *inode, u64 blkno,
@@ -1854,7 +1870,7 @@ bail:
1854 * ocfs2_delete_entry deletes a directory entry by merging it with the 1870 * ocfs2_delete_entry deletes a directory entry by merging it with the
1855 * previous entry 1871 * previous entry
1856 */ 1872 */
1857static int ocfs2_delete_entry(struct ocfs2_journal_handle *handle, 1873static int ocfs2_delete_entry(handle_t *handle,
1858 struct inode *dir, 1874 struct inode *dir,
1859 struct ocfs2_dir_entry *de_del, 1875 struct ocfs2_dir_entry *de_del,
1860 struct buffer_head *bh) 1876 struct buffer_head *bh)
@@ -2085,19 +2101,19 @@ bail:
2085} 2101}
2086 2102
2087static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb, 2103static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
2088 struct ocfs2_journal_handle *handle, 2104 struct inode **ret_orphan_dir,
2089 struct inode *inode, 2105 struct inode *inode,
2090 char *name, 2106 char *name,
2091 struct buffer_head **de_bh) 2107 struct buffer_head **de_bh)
2092{ 2108{
2093 struct inode *orphan_dir_inode = NULL; 2109 struct inode *orphan_dir_inode;
2094 struct buffer_head *orphan_dir_bh = NULL; 2110 struct buffer_head *orphan_dir_bh = NULL;
2095 int status = 0; 2111 int status = 0;
2096 2112
2097 status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno, name); 2113 status = ocfs2_blkno_stringify(OCFS2_I(inode)->ip_blkno, name);
2098 if (status < 0) { 2114 if (status < 0) {
2099 mlog_errno(status); 2115 mlog_errno(status);
2100 goto leave; 2116 return status;
2101 } 2117 }
2102 2118
2103 orphan_dir_inode = ocfs2_get_system_file_inode(osb, 2119 orphan_dir_inode = ocfs2_get_system_file_inode(osb,
@@ -2106,11 +2122,12 @@ static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
2106 if (!orphan_dir_inode) { 2122 if (!orphan_dir_inode) {
2107 status = -ENOENT; 2123 status = -ENOENT;
2108 mlog_errno(status); 2124 mlog_errno(status);
2109 goto leave; 2125 return status;
2110 } 2126 }
2111 2127
2112 ocfs2_handle_add_inode(handle, orphan_dir_inode); 2128 mutex_lock(&orphan_dir_inode->i_mutex);
2113 status = ocfs2_meta_lock(orphan_dir_inode, handle, &orphan_dir_bh, 1); 2129
2130 status = ocfs2_meta_lock(orphan_dir_inode, &orphan_dir_bh, 1);
2114 if (status < 0) { 2131 if (status < 0) {
2115 mlog_errno(status); 2132 mlog_errno(status);
2116 goto leave; 2133 goto leave;
@@ -2120,13 +2137,19 @@ static int ocfs2_prepare_orphan_dir(struct ocfs2_super *osb,
2120 orphan_dir_bh, name, 2137 orphan_dir_bh, name,
2121 OCFS2_ORPHAN_NAMELEN, de_bh); 2138 OCFS2_ORPHAN_NAMELEN, de_bh);
2122 if (status < 0) { 2139 if (status < 0) {
2140 ocfs2_meta_unlock(orphan_dir_inode, 1);
2141
2123 mlog_errno(status); 2142 mlog_errno(status);
2124 goto leave; 2143 goto leave;
2125 } 2144 }
2126 2145
2146 *ret_orphan_dir = orphan_dir_inode;
2147
2127leave: 2148leave:
2128 if (orphan_dir_inode) 2149 if (status) {
2150 mutex_unlock(&orphan_dir_inode->i_mutex);
2129 iput(orphan_dir_inode); 2151 iput(orphan_dir_inode);
2152 }
2130 2153
2131 if (orphan_dir_bh) 2154 if (orphan_dir_bh)
2132 brelse(orphan_dir_bh); 2155 brelse(orphan_dir_bh);
@@ -2136,28 +2159,19 @@ leave:
2136} 2159}
2137 2160
2138static int ocfs2_orphan_add(struct ocfs2_super *osb, 2161static int ocfs2_orphan_add(struct ocfs2_super *osb,
2139 struct ocfs2_journal_handle *handle, 2162 handle_t *handle,
2140 struct inode *inode, 2163 struct inode *inode,
2141 struct ocfs2_dinode *fe, 2164 struct ocfs2_dinode *fe,
2142 char *name, 2165 char *name,
2143 struct buffer_head *de_bh) 2166 struct buffer_head *de_bh,
2167 struct inode *orphan_dir_inode)
2144{ 2168{
2145 struct inode *orphan_dir_inode = NULL;
2146 struct buffer_head *orphan_dir_bh = NULL; 2169 struct buffer_head *orphan_dir_bh = NULL;
2147 int status = 0; 2170 int status = 0;
2148 struct ocfs2_dinode *orphan_fe; 2171 struct ocfs2_dinode *orphan_fe;
2149 2172
2150 mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino); 2173 mlog_entry("(inode->i_ino = %lu)\n", inode->i_ino);
2151 2174
2152 orphan_dir_inode = ocfs2_get_system_file_inode(osb,
2153 ORPHAN_DIR_SYSTEM_INODE,
2154 osb->slot_num);
2155 if (!orphan_dir_inode) {
2156 status = -ENOENT;
2157 mlog_errno(status);
2158 goto leave;
2159 }
2160
2161 status = ocfs2_read_block(osb, 2175 status = ocfs2_read_block(osb,
2162 OCFS2_I(orphan_dir_inode)->ip_blkno, 2176 OCFS2_I(orphan_dir_inode)->ip_blkno,
2163 &orphan_dir_bh, OCFS2_BH_CACHED, 2177 &orphan_dir_bh, OCFS2_BH_CACHED,
@@ -2209,9 +2223,6 @@ static int ocfs2_orphan_add(struct ocfs2_super *osb,
2209 (unsigned long long)OCFS2_I(inode)->ip_blkno, osb->slot_num); 2223 (unsigned long long)OCFS2_I(inode)->ip_blkno, osb->slot_num);
2210 2224
2211leave: 2225leave:
2212 if (orphan_dir_inode)
2213 iput(orphan_dir_inode);
2214
2215 if (orphan_dir_bh) 2226 if (orphan_dir_bh)
2216 brelse(orphan_dir_bh); 2227 brelse(orphan_dir_bh);
2217 2228
@@ -2221,7 +2232,7 @@ leave:
2221 2232
2222/* unlike orphan_add, we expect the orphan dir to already be locked here. */ 2233/* unlike orphan_add, we expect the orphan dir to already be locked here. */
2223int ocfs2_orphan_del(struct ocfs2_super *osb, 2234int ocfs2_orphan_del(struct ocfs2_super *osb,
2224 struct ocfs2_journal_handle *handle, 2235 handle_t *handle,
2225 struct inode *orphan_dir_inode, 2236 struct inode *orphan_dir_inode,
2226 struct inode *inode, 2237 struct inode *inode,
2227 struct buffer_head *orphan_dir_bh) 2238 struct buffer_head *orphan_dir_bh)
@@ -2300,4 +2311,5 @@ struct inode_operations ocfs2_dir_iops = {
2300 .rename = ocfs2_rename, 2311 .rename = ocfs2_rename,
2301 .setattr = ocfs2_setattr, 2312 .setattr = ocfs2_setattr,
2302 .getattr = ocfs2_getattr, 2313 .getattr = ocfs2_getattr,
2314 .permission = ocfs2_permission,
2303}; 2315};
diff --git a/fs/ocfs2/namei.h b/fs/ocfs2/namei.h
index deaaa97dbf0b..8425944fcccd 100644
--- a/fs/ocfs2/namei.h
+++ b/fs/ocfs2/namei.h
@@ -39,7 +39,7 @@ struct buffer_head *ocfs2_find_entry(const char *name,
39 struct inode *dir, 39 struct inode *dir,
40 struct ocfs2_dir_entry **res_dir); 40 struct ocfs2_dir_entry **res_dir);
41int ocfs2_orphan_del(struct ocfs2_super *osb, 41int ocfs2_orphan_del(struct ocfs2_super *osb,
42 struct ocfs2_journal_handle *handle, 42 handle_t *handle,
43 struct inode *orphan_dir_inode, 43 struct inode *orphan_dir_inode,
44 struct inode *inode, 44 struct inode *inode,
45 struct buffer_head *orphan_dir_bh); 45 struct buffer_head *orphan_dir_bh);
diff --git a/fs/ocfs2/ocfs2.h b/fs/ocfs2/ocfs2.h
index 9b1bad1d48ec..b767fd7da6eb 100644
--- a/fs/ocfs2/ocfs2.h
+++ b/fs/ocfs2/ocfs2.h
@@ -34,6 +34,7 @@
34#include <linux/workqueue.h> 34#include <linux/workqueue.h>
35#include <linux/kref.h> 35#include <linux/kref.h>
36#include <linux/mutex.h> 36#include <linux/mutex.h>
37#include <linux/jbd.h>
37 38
38#include "cluster/nodemanager.h" 39#include "cluster/nodemanager.h"
39#include "cluster/heartbeat.h" 40#include "cluster/heartbeat.h"
@@ -179,9 +180,9 @@ enum ocfs2_mount_options
179#define OCFS2_OSB_SOFT_RO 0x0001 180#define OCFS2_OSB_SOFT_RO 0x0001
180#define OCFS2_OSB_HARD_RO 0x0002 181#define OCFS2_OSB_HARD_RO 0x0002
181#define OCFS2_OSB_ERROR_FS 0x0004 182#define OCFS2_OSB_ERROR_FS 0x0004
183#define OCFS2_DEFAULT_ATIME_QUANTUM 60
182 184
183struct ocfs2_journal; 185struct ocfs2_journal;
184struct ocfs2_journal_handle;
185struct ocfs2_super 186struct ocfs2_super
186{ 187{
187 struct task_struct *commit_task; 188 struct task_struct *commit_task;
@@ -218,6 +219,7 @@ struct ocfs2_super
218 unsigned long osb_flags; 219 unsigned long osb_flags;
219 220
220 unsigned long s_mount_opt; 221 unsigned long s_mount_opt;
222 unsigned int s_atime_quantum;
221 223
222 u16 max_slots; 224 u16 max_slots;
223 s16 node_num; 225 s16 node_num;
diff --git a/fs/ocfs2/suballoc.c b/fs/ocfs2/suballoc.c
index 9d91e66f51a9..000d71cca6c5 100644
--- a/fs/ocfs2/suballoc.c
+++ b/fs/ocfs2/suballoc.c
@@ -49,7 +49,7 @@
49static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg); 49static inline void ocfs2_debug_bg(struct ocfs2_group_desc *bg);
50static inline void ocfs2_debug_suballoc_inode(struct ocfs2_dinode *fe); 50static inline void ocfs2_debug_suballoc_inode(struct ocfs2_dinode *fe);
51static inline u16 ocfs2_find_victim_chain(struct ocfs2_chain_list *cl); 51static inline u16 ocfs2_find_victim_chain(struct ocfs2_chain_list *cl);
52static int ocfs2_block_group_fill(struct ocfs2_journal_handle *handle, 52static int ocfs2_block_group_fill(handle_t *handle,
53 struct inode *alloc_inode, 53 struct inode *alloc_inode,
54 struct buffer_head *bg_bh, 54 struct buffer_head *bg_bh,
55 u64 group_blkno, 55 u64 group_blkno,
@@ -59,9 +59,6 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb,
59 struct inode *alloc_inode, 59 struct inode *alloc_inode,
60 struct buffer_head *bh); 60 struct buffer_head *bh);
61 61
62static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb,
63 struct ocfs2_alloc_context *ac);
64
65static int ocfs2_cluster_group_search(struct inode *inode, 62static int ocfs2_cluster_group_search(struct inode *inode,
66 struct buffer_head *group_bh, 63 struct buffer_head *group_bh,
67 u32 bits_wanted, u32 min_bits, 64 u32 bits_wanted, u32 min_bits,
@@ -72,6 +69,7 @@ static int ocfs2_block_group_search(struct inode *inode,
72 u16 *bit_off, u16 *bits_found); 69 u16 *bit_off, u16 *bits_found);
73static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, 70static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb,
74 struct ocfs2_alloc_context *ac, 71 struct ocfs2_alloc_context *ac,
72 handle_t *handle,
75 u32 bits_wanted, 73 u32 bits_wanted,
76 u32 min_bits, 74 u32 min_bits,
77 u16 *bit_off, 75 u16 *bit_off,
@@ -79,20 +77,20 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb,
79 u64 *bg_blkno); 77 u64 *bg_blkno);
80static int ocfs2_test_bg_bit_allocatable(struct buffer_head *bg_bh, 78static int ocfs2_test_bg_bit_allocatable(struct buffer_head *bg_bh,
81 int nr); 79 int nr);
82static inline int ocfs2_block_group_set_bits(struct ocfs2_journal_handle *handle, 80static inline int ocfs2_block_group_set_bits(handle_t *handle,
83 struct inode *alloc_inode, 81 struct inode *alloc_inode,
84 struct ocfs2_group_desc *bg, 82 struct ocfs2_group_desc *bg,
85 struct buffer_head *group_bh, 83 struct buffer_head *group_bh,
86 unsigned int bit_off, 84 unsigned int bit_off,
87 unsigned int num_bits); 85 unsigned int num_bits);
88static inline int ocfs2_block_group_clear_bits(struct ocfs2_journal_handle *handle, 86static inline int ocfs2_block_group_clear_bits(handle_t *handle,
89 struct inode *alloc_inode, 87 struct inode *alloc_inode,
90 struct ocfs2_group_desc *bg, 88 struct ocfs2_group_desc *bg,
91 struct buffer_head *group_bh, 89 struct buffer_head *group_bh,
92 unsigned int bit_off, 90 unsigned int bit_off,
93 unsigned int num_bits); 91 unsigned int num_bits);
94 92
95static int ocfs2_relink_block_group(struct ocfs2_journal_handle *handle, 93static int ocfs2_relink_block_group(handle_t *handle,
96 struct inode *alloc_inode, 94 struct inode *alloc_inode,
97 struct buffer_head *fe_bh, 95 struct buffer_head *fe_bh,
98 struct buffer_head *bg_bh, 96 struct buffer_head *bg_bh,
@@ -100,7 +98,7 @@ static int ocfs2_relink_block_group(struct ocfs2_journal_handle *handle,
100 u16 chain); 98 u16 chain);
101static inline int ocfs2_block_group_reasonably_empty(struct ocfs2_group_desc *bg, 99static inline int ocfs2_block_group_reasonably_empty(struct ocfs2_group_desc *bg,
102 u32 wanted); 100 u32 wanted);
103static int ocfs2_free_suballoc_bits(struct ocfs2_journal_handle *handle, 101static int ocfs2_free_suballoc_bits(handle_t *handle,
104 struct inode *alloc_inode, 102 struct inode *alloc_inode,
105 struct buffer_head *alloc_bh, 103 struct buffer_head *alloc_bh,
106 unsigned int start_bit, 104 unsigned int start_bit,
@@ -120,8 +118,16 @@ static inline void ocfs2_block_to_cluster_group(struct inode *inode,
120 118
121void ocfs2_free_alloc_context(struct ocfs2_alloc_context *ac) 119void ocfs2_free_alloc_context(struct ocfs2_alloc_context *ac)
122{ 120{
123 if (ac->ac_inode) 121 struct inode *inode = ac->ac_inode;
124 iput(ac->ac_inode); 122
123 if (inode) {
124 if (ac->ac_which != OCFS2_AC_USE_LOCAL)
125 ocfs2_meta_unlock(inode, 1);
126
127 mutex_unlock(&inode->i_mutex);
128
129 iput(inode);
130 }
125 if (ac->ac_bh) 131 if (ac->ac_bh)
126 brelse(ac->ac_bh); 132 brelse(ac->ac_bh);
127 kfree(ac); 133 kfree(ac);
@@ -190,7 +196,7 @@ static int ocfs2_check_group_descriptor(struct super_block *sb,
190 return 0; 196 return 0;
191} 197}
192 198
193static int ocfs2_block_group_fill(struct ocfs2_journal_handle *handle, 199static int ocfs2_block_group_fill(handle_t *handle,
194 struct inode *alloc_inode, 200 struct inode *alloc_inode,
195 struct buffer_head *bg_bh, 201 struct buffer_head *bg_bh,
196 u64 group_blkno, 202 u64 group_blkno,
@@ -273,7 +279,7 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb,
273 struct ocfs2_dinode *fe = (struct ocfs2_dinode *) bh->b_data; 279 struct ocfs2_dinode *fe = (struct ocfs2_dinode *) bh->b_data;
274 struct ocfs2_chain_list *cl; 280 struct ocfs2_chain_list *cl;
275 struct ocfs2_alloc_context *ac = NULL; 281 struct ocfs2_alloc_context *ac = NULL;
276 struct ocfs2_journal_handle *handle = NULL; 282 handle_t *handle = NULL;
277 u32 bit_off, num_bits; 283 u32 bit_off, num_bits;
278 u16 alloc_rec; 284 u16 alloc_rec;
279 u64 bg_blkno; 285 u64 bg_blkno;
@@ -284,16 +290,8 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb,
284 290
285 mlog_entry_void(); 291 mlog_entry_void();
286 292
287 handle = ocfs2_alloc_handle(osb);
288 if (!handle) {
289 status = -ENOMEM;
290 mlog_errno(status);
291 goto bail;
292 }
293
294 cl = &fe->id2.i_chain; 293 cl = &fe->id2.i_chain;
295 status = ocfs2_reserve_clusters(osb, 294 status = ocfs2_reserve_clusters(osb,
296 handle,
297 le16_to_cpu(cl->cl_cpg), 295 le16_to_cpu(cl->cl_cpg),
298 &ac); 296 &ac);
299 if (status < 0) { 297 if (status < 0) {
@@ -304,7 +302,7 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb,
304 302
305 credits = ocfs2_calc_group_alloc_credits(osb->sb, 303 credits = ocfs2_calc_group_alloc_credits(osb->sb,
306 le16_to_cpu(cl->cl_cpg)); 304 le16_to_cpu(cl->cl_cpg));
307 handle = ocfs2_start_trans(osb, handle, credits); 305 handle = ocfs2_start_trans(osb, credits);
308 if (IS_ERR(handle)) { 306 if (IS_ERR(handle)) {
309 status = PTR_ERR(handle); 307 status = PTR_ERR(handle);
310 handle = NULL; 308 handle = NULL;
@@ -389,7 +387,7 @@ static int ocfs2_block_group_alloc(struct ocfs2_super *osb,
389 status = 0; 387 status = 0;
390bail: 388bail:
391 if (handle) 389 if (handle)
392 ocfs2_commit_trans(handle); 390 ocfs2_commit_trans(osb, handle);
393 391
394 if (ac) 392 if (ac)
395 ocfs2_free_alloc_context(ac); 393 ocfs2_free_alloc_context(ac);
@@ -402,27 +400,38 @@ bail:
402} 400}
403 401
404static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb, 402static int ocfs2_reserve_suballoc_bits(struct ocfs2_super *osb,
405 struct ocfs2_alloc_context *ac) 403 struct ocfs2_alloc_context *ac,
404 int type,
405 u32 slot)
406{ 406{
407 int status; 407 int status;
408 u32 bits_wanted = ac->ac_bits_wanted; 408 u32 bits_wanted = ac->ac_bits_wanted;
409 struct inode *alloc_inode = ac->ac_inode; 409 struct inode *alloc_inode;
410 struct buffer_head *bh = NULL; 410 struct buffer_head *bh = NULL;
411 struct ocfs2_journal_handle *handle = ac->ac_handle;
412 struct ocfs2_dinode *fe; 411 struct ocfs2_dinode *fe;
413 u32 free_bits; 412 u32 free_bits;
414 413
415 mlog_entry_void(); 414 mlog_entry_void();
416 415
417 BUG_ON(handle->flags & OCFS2_HANDLE_STARTED); 416 alloc_inode = ocfs2_get_system_file_inode(osb, type, slot);
417 if (!alloc_inode) {
418 mlog_errno(-EINVAL);
419 return -EINVAL;
420 }
418 421
419 ocfs2_handle_add_inode(handle, alloc_inode); 422 mutex_lock(&alloc_inode->i_mutex);
420 status = ocfs2_meta_lock(alloc_inode, handle, &bh, 1); 423
424 status = ocfs2_meta_lock(alloc_inode, &bh, 1);
421 if (status < 0) { 425 if (status < 0) {
426 mutex_unlock(&alloc_inode->i_mutex);
427 iput(alloc_inode);
428
422 mlog_errno(status); 429 mlog_errno(status);
423 goto bail; 430 return status;
424 } 431 }
425 432
433 ac->ac_inode = alloc_inode;
434
426 fe = (struct ocfs2_dinode *) bh->b_data; 435 fe = (struct ocfs2_dinode *) bh->b_data;
427 if (!OCFS2_IS_VALID_DINODE(fe)) { 436 if (!OCFS2_IS_VALID_DINODE(fe)) {
428 OCFS2_RO_ON_INVALID_DINODE(alloc_inode->i_sb, fe); 437 OCFS2_RO_ON_INVALID_DINODE(alloc_inode->i_sb, fe);
@@ -473,12 +482,11 @@ bail:
473} 482}
474 483
475int ocfs2_reserve_new_metadata(struct ocfs2_super *osb, 484int ocfs2_reserve_new_metadata(struct ocfs2_super *osb,
476 struct ocfs2_journal_handle *handle,
477 struct ocfs2_dinode *fe, 485 struct ocfs2_dinode *fe,
478 struct ocfs2_alloc_context **ac) 486 struct ocfs2_alloc_context **ac)
479{ 487{
480 int status; 488 int status;
481 struct inode *alloc_inode = NULL; 489 u32 slot;
482 490
483 *ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL); 491 *ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
484 if (!(*ac)) { 492 if (!(*ac)) {
@@ -488,28 +496,18 @@ int ocfs2_reserve_new_metadata(struct ocfs2_super *osb,
488 } 496 }
489 497
490 (*ac)->ac_bits_wanted = ocfs2_extend_meta_needed(fe); 498 (*ac)->ac_bits_wanted = ocfs2_extend_meta_needed(fe);
491 (*ac)->ac_handle = handle;
492 (*ac)->ac_which = OCFS2_AC_USE_META; 499 (*ac)->ac_which = OCFS2_AC_USE_META;
493 500
494#ifndef OCFS2_USE_ALL_METADATA_SUBALLOCATORS 501#ifndef OCFS2_USE_ALL_METADATA_SUBALLOCATORS
495 alloc_inode = ocfs2_get_system_file_inode(osb, 502 slot = 0;
496 EXTENT_ALLOC_SYSTEM_INODE,
497 0);
498#else 503#else
499 alloc_inode = ocfs2_get_system_file_inode(osb, 504 slot = osb->slot_num;
500 EXTENT_ALLOC_SYSTEM_INODE,
501 osb->slot_num);
502#endif 505#endif
503 if (!alloc_inode) {
504 status = -ENOMEM;
505 mlog_errno(status);
506 goto bail;
507 }
508 506
509 (*ac)->ac_inode = igrab(alloc_inode);
510 (*ac)->ac_group_search = ocfs2_block_group_search; 507 (*ac)->ac_group_search = ocfs2_block_group_search;
511 508
512 status = ocfs2_reserve_suballoc_bits(osb, (*ac)); 509 status = ocfs2_reserve_suballoc_bits(osb, (*ac),
510 EXTENT_ALLOC_SYSTEM_INODE, slot);
513 if (status < 0) { 511 if (status < 0) {
514 if (status != -ENOSPC) 512 if (status != -ENOSPC)
515 mlog_errno(status); 513 mlog_errno(status);
@@ -523,19 +521,14 @@ bail:
523 *ac = NULL; 521 *ac = NULL;
524 } 522 }
525 523
526 if (alloc_inode)
527 iput(alloc_inode);
528
529 mlog_exit(status); 524 mlog_exit(status);
530 return status; 525 return status;
531} 526}
532 527
533int ocfs2_reserve_new_inode(struct ocfs2_super *osb, 528int ocfs2_reserve_new_inode(struct ocfs2_super *osb,
534 struct ocfs2_journal_handle *handle,
535 struct ocfs2_alloc_context **ac) 529 struct ocfs2_alloc_context **ac)
536{ 530{
537 int status; 531 int status;
538 struct inode *alloc_inode = NULL;
539 532
540 *ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL); 533 *ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
541 if (!(*ac)) { 534 if (!(*ac)) {
@@ -545,22 +538,13 @@ int ocfs2_reserve_new_inode(struct ocfs2_super *osb,
545 } 538 }
546 539
547 (*ac)->ac_bits_wanted = 1; 540 (*ac)->ac_bits_wanted = 1;
548 (*ac)->ac_handle = handle;
549 (*ac)->ac_which = OCFS2_AC_USE_INODE; 541 (*ac)->ac_which = OCFS2_AC_USE_INODE;
550 542
551 alloc_inode = ocfs2_get_system_file_inode(osb,
552 INODE_ALLOC_SYSTEM_INODE,
553 osb->slot_num);
554 if (!alloc_inode) {
555 status = -ENOMEM;
556 mlog_errno(status);
557 goto bail;
558 }
559
560 (*ac)->ac_inode = igrab(alloc_inode);
561 (*ac)->ac_group_search = ocfs2_block_group_search; 543 (*ac)->ac_group_search = ocfs2_block_group_search;
562 544
563 status = ocfs2_reserve_suballoc_bits(osb, *ac); 545 status = ocfs2_reserve_suballoc_bits(osb, *ac,
546 INODE_ALLOC_SYSTEM_INODE,
547 osb->slot_num);
564 if (status < 0) { 548 if (status < 0) {
565 if (status != -ENOSPC) 549 if (status != -ENOSPC)
566 mlog_errno(status); 550 mlog_errno(status);
@@ -574,9 +558,6 @@ bail:
574 *ac = NULL; 558 *ac = NULL;
575 } 559 }
576 560
577 if (alloc_inode)
578 iput(alloc_inode);
579
580 mlog_exit(status); 561 mlog_exit(status);
581 return status; 562 return status;
582} 563}
@@ -588,20 +569,17 @@ int ocfs2_reserve_cluster_bitmap_bits(struct ocfs2_super *osb,
588{ 569{
589 int status; 570 int status;
590 571
591 ac->ac_inode = ocfs2_get_system_file_inode(osb,
592 GLOBAL_BITMAP_SYSTEM_INODE,
593 OCFS2_INVALID_SLOT);
594 if (!ac->ac_inode) {
595 status = -EINVAL;
596 mlog(ML_ERROR, "Could not get bitmap inode!\n");
597 goto bail;
598 }
599 ac->ac_which = OCFS2_AC_USE_MAIN; 572 ac->ac_which = OCFS2_AC_USE_MAIN;
600 ac->ac_group_search = ocfs2_cluster_group_search; 573 ac->ac_group_search = ocfs2_cluster_group_search;
601 574
602 status = ocfs2_reserve_suballoc_bits(osb, ac); 575 status = ocfs2_reserve_suballoc_bits(osb, ac,
603 if (status < 0 && status != -ENOSPC) 576 GLOBAL_BITMAP_SYSTEM_INODE,
577 OCFS2_INVALID_SLOT);
578 if (status < 0 && status != -ENOSPC) {
604 mlog_errno(status); 579 mlog_errno(status);
580 goto bail;
581 }
582
605bail: 583bail:
606 return status; 584 return status;
607} 585}
@@ -610,7 +588,6 @@ bail:
610 * use so we figure it out for them, but unfortunately this clutters 588 * use so we figure it out for them, but unfortunately this clutters
611 * things a bit. */ 589 * things a bit. */
612int ocfs2_reserve_clusters(struct ocfs2_super *osb, 590int ocfs2_reserve_clusters(struct ocfs2_super *osb,
613 struct ocfs2_journal_handle *handle,
614 u32 bits_wanted, 591 u32 bits_wanted,
615 struct ocfs2_alloc_context **ac) 592 struct ocfs2_alloc_context **ac)
616{ 593{
@@ -618,8 +595,6 @@ int ocfs2_reserve_clusters(struct ocfs2_super *osb,
618 595
619 mlog_entry_void(); 596 mlog_entry_void();
620 597
621 BUG_ON(!handle);
622
623 *ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL); 598 *ac = kcalloc(1, sizeof(struct ocfs2_alloc_context), GFP_KERNEL);
624 if (!(*ac)) { 599 if (!(*ac)) {
625 status = -ENOMEM; 600 status = -ENOMEM;
@@ -628,12 +603,10 @@ int ocfs2_reserve_clusters(struct ocfs2_super *osb,
628 } 603 }
629 604
630 (*ac)->ac_bits_wanted = bits_wanted; 605 (*ac)->ac_bits_wanted = bits_wanted;
631 (*ac)->ac_handle = handle;
632 606
633 status = -ENOSPC; 607 status = -ENOSPC;
634 if (ocfs2_alloc_should_use_local(osb, bits_wanted)) { 608 if (ocfs2_alloc_should_use_local(osb, bits_wanted)) {
635 status = ocfs2_reserve_local_alloc_bits(osb, 609 status = ocfs2_reserve_local_alloc_bits(osb,
636 handle,
637 bits_wanted, 610 bits_wanted,
638 *ac); 611 *ac);
639 if ((status < 0) && (status != -ENOSPC)) { 612 if ((status < 0) && (status != -ENOSPC)) {
@@ -774,7 +747,7 @@ static int ocfs2_block_group_find_clear_bits(struct ocfs2_super *osb,
774 return status; 747 return status;
775} 748}
776 749
777static inline int ocfs2_block_group_set_bits(struct ocfs2_journal_handle *handle, 750static inline int ocfs2_block_group_set_bits(handle_t *handle,
778 struct inode *alloc_inode, 751 struct inode *alloc_inode,
779 struct ocfs2_group_desc *bg, 752 struct ocfs2_group_desc *bg,
780 struct buffer_head *group_bh, 753 struct buffer_head *group_bh,
@@ -845,7 +818,7 @@ static inline u16 ocfs2_find_victim_chain(struct ocfs2_chain_list *cl)
845 return best; 818 return best;
846} 819}
847 820
848static int ocfs2_relink_block_group(struct ocfs2_journal_handle *handle, 821static int ocfs2_relink_block_group(handle_t *handle,
849 struct inode *alloc_inode, 822 struct inode *alloc_inode,
850 struct buffer_head *fe_bh, 823 struct buffer_head *fe_bh,
851 struct buffer_head *bg_bh, 824 struct buffer_head *bg_bh,
@@ -1025,7 +998,7 @@ static int ocfs2_block_group_search(struct inode *inode,
1025} 998}
1026 999
1027static int ocfs2_alloc_dinode_update_counts(struct inode *inode, 1000static int ocfs2_alloc_dinode_update_counts(struct inode *inode,
1028 struct ocfs2_journal_handle *handle, 1001 handle_t *handle,
1029 struct buffer_head *di_bh, 1002 struct buffer_head *di_bh,
1030 u32 num_bits, 1003 u32 num_bits,
1031 u16 chain) 1004 u16 chain)
@@ -1055,6 +1028,7 @@ out:
1055} 1028}
1056 1029
1057static int ocfs2_search_one_group(struct ocfs2_alloc_context *ac, 1030static int ocfs2_search_one_group(struct ocfs2_alloc_context *ac,
1031 handle_t *handle,
1058 u32 bits_wanted, 1032 u32 bits_wanted,
1059 u32 min_bits, 1033 u32 min_bits,
1060 u16 *bit_off, 1034 u16 *bit_off,
@@ -1067,7 +1041,6 @@ static int ocfs2_search_one_group(struct ocfs2_alloc_context *ac,
1067 struct buffer_head *group_bh = NULL; 1041 struct buffer_head *group_bh = NULL;
1068 struct ocfs2_group_desc *gd; 1042 struct ocfs2_group_desc *gd;
1069 struct inode *alloc_inode = ac->ac_inode; 1043 struct inode *alloc_inode = ac->ac_inode;
1070 struct ocfs2_journal_handle *handle = ac->ac_handle;
1071 1044
1072 ret = ocfs2_read_block(OCFS2_SB(alloc_inode->i_sb), gd_blkno, 1045 ret = ocfs2_read_block(OCFS2_SB(alloc_inode->i_sb), gd_blkno,
1073 &group_bh, OCFS2_BH_CACHED, alloc_inode); 1046 &group_bh, OCFS2_BH_CACHED, alloc_inode);
@@ -1115,6 +1088,7 @@ out:
1115} 1088}
1116 1089
1117static int ocfs2_search_chain(struct ocfs2_alloc_context *ac, 1090static int ocfs2_search_chain(struct ocfs2_alloc_context *ac,
1091 handle_t *handle,
1118 u32 bits_wanted, 1092 u32 bits_wanted,
1119 u32 min_bits, 1093 u32 min_bits,
1120 u16 *bit_off, 1094 u16 *bit_off,
@@ -1126,7 +1100,6 @@ static int ocfs2_search_chain(struct ocfs2_alloc_context *ac,
1126 u16 chain, tmp_bits; 1100 u16 chain, tmp_bits;
1127 u32 tmp_used; 1101 u32 tmp_used;
1128 u64 next_group; 1102 u64 next_group;
1129 struct ocfs2_journal_handle *handle = ac->ac_handle;
1130 struct inode *alloc_inode = ac->ac_inode; 1103 struct inode *alloc_inode = ac->ac_inode;
1131 struct buffer_head *group_bh = NULL; 1104 struct buffer_head *group_bh = NULL;
1132 struct buffer_head *prev_group_bh = NULL; 1105 struct buffer_head *prev_group_bh = NULL;
@@ -1272,6 +1245,7 @@ bail:
1272/* will give out up to bits_wanted contiguous bits. */ 1245/* will give out up to bits_wanted contiguous bits. */
1273static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb, 1246static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb,
1274 struct ocfs2_alloc_context *ac, 1247 struct ocfs2_alloc_context *ac,
1248 handle_t *handle,
1275 u32 bits_wanted, 1249 u32 bits_wanted,
1276 u32 min_bits, 1250 u32 min_bits,
1277 u16 *bit_off, 1251 u16 *bit_off,
@@ -1313,8 +1287,8 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb,
1313 * by jumping straight to the most recently used 1287 * by jumping straight to the most recently used
1314 * allocation group. This helps us mantain some 1288 * allocation group. This helps us mantain some
1315 * contiguousness across allocations. */ 1289 * contiguousness across allocations. */
1316 status = ocfs2_search_one_group(ac, bits_wanted, min_bits, 1290 status = ocfs2_search_one_group(ac, handle, bits_wanted,
1317 bit_off, num_bits, 1291 min_bits, bit_off, num_bits,
1318 hint_blkno, &bits_left); 1292 hint_blkno, &bits_left);
1319 if (!status) { 1293 if (!status) {
1320 /* Be careful to update *bg_blkno here as the 1294 /* Be careful to update *bg_blkno here as the
@@ -1336,7 +1310,7 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb,
1336 ac->ac_chain = victim; 1310 ac->ac_chain = victim;
1337 ac->ac_allow_chain_relink = 1; 1311 ac->ac_allow_chain_relink = 1;
1338 1312
1339 status = ocfs2_search_chain(ac, bits_wanted, min_bits, bit_off, 1313 status = ocfs2_search_chain(ac, handle, bits_wanted, min_bits, bit_off,
1340 num_bits, bg_blkno, &bits_left); 1314 num_bits, bg_blkno, &bits_left);
1341 if (!status) 1315 if (!status)
1342 goto set_hint; 1316 goto set_hint;
@@ -1360,7 +1334,7 @@ static int ocfs2_claim_suballoc_bits(struct ocfs2_super *osb,
1360 continue; 1334 continue;
1361 1335
1362 ac->ac_chain = i; 1336 ac->ac_chain = i;
1363 status = ocfs2_search_chain(ac, bits_wanted, min_bits, 1337 status = ocfs2_search_chain(ac, handle, bits_wanted, min_bits,
1364 bit_off, num_bits, bg_blkno, 1338 bit_off, num_bits, bg_blkno,
1365 &bits_left); 1339 &bits_left);
1366 if (!status) 1340 if (!status)
@@ -1388,7 +1362,7 @@ bail:
1388} 1362}
1389 1363
1390int ocfs2_claim_metadata(struct ocfs2_super *osb, 1364int ocfs2_claim_metadata(struct ocfs2_super *osb,
1391 struct ocfs2_journal_handle *handle, 1365 handle_t *handle,
1392 struct ocfs2_alloc_context *ac, 1366 struct ocfs2_alloc_context *ac,
1393 u32 bits_wanted, 1367 u32 bits_wanted,
1394 u16 *suballoc_bit_start, 1368 u16 *suballoc_bit_start,
@@ -1401,10 +1375,10 @@ int ocfs2_claim_metadata(struct ocfs2_super *osb,
1401 BUG_ON(!ac); 1375 BUG_ON(!ac);
1402 BUG_ON(ac->ac_bits_wanted < (ac->ac_bits_given + bits_wanted)); 1376 BUG_ON(ac->ac_bits_wanted < (ac->ac_bits_given + bits_wanted));
1403 BUG_ON(ac->ac_which != OCFS2_AC_USE_META); 1377 BUG_ON(ac->ac_which != OCFS2_AC_USE_META);
1404 BUG_ON(ac->ac_handle != handle);
1405 1378
1406 status = ocfs2_claim_suballoc_bits(osb, 1379 status = ocfs2_claim_suballoc_bits(osb,
1407 ac, 1380 ac,
1381 handle,
1408 bits_wanted, 1382 bits_wanted,
1409 1, 1383 1,
1410 suballoc_bit_start, 1384 suballoc_bit_start,
@@ -1425,7 +1399,7 @@ bail:
1425} 1399}
1426 1400
1427int ocfs2_claim_new_inode(struct ocfs2_super *osb, 1401int ocfs2_claim_new_inode(struct ocfs2_super *osb,
1428 struct ocfs2_journal_handle *handle, 1402 handle_t *handle,
1429 struct ocfs2_alloc_context *ac, 1403 struct ocfs2_alloc_context *ac,
1430 u16 *suballoc_bit, 1404 u16 *suballoc_bit,
1431 u64 *fe_blkno) 1405 u64 *fe_blkno)
@@ -1440,10 +1414,10 @@ int ocfs2_claim_new_inode(struct ocfs2_super *osb,
1440 BUG_ON(ac->ac_bits_given != 0); 1414 BUG_ON(ac->ac_bits_given != 0);
1441 BUG_ON(ac->ac_bits_wanted != 1); 1415 BUG_ON(ac->ac_bits_wanted != 1);
1442 BUG_ON(ac->ac_which != OCFS2_AC_USE_INODE); 1416 BUG_ON(ac->ac_which != OCFS2_AC_USE_INODE);
1443 BUG_ON(ac->ac_handle != handle);
1444 1417
1445 status = ocfs2_claim_suballoc_bits(osb, 1418 status = ocfs2_claim_suballoc_bits(osb,
1446 ac, 1419 ac,
1420 handle,
1447 1, 1421 1,
1448 1, 1422 1,
1449 suballoc_bit, 1423 suballoc_bit,
@@ -1528,7 +1502,7 @@ static inline void ocfs2_block_to_cluster_group(struct inode *inode,
1528 * of any size. 1502 * of any size.
1529 */ 1503 */
1530int ocfs2_claim_clusters(struct ocfs2_super *osb, 1504int ocfs2_claim_clusters(struct ocfs2_super *osb,
1531 struct ocfs2_journal_handle *handle, 1505 handle_t *handle,
1532 struct ocfs2_alloc_context *ac, 1506 struct ocfs2_alloc_context *ac,
1533 u32 min_clusters, 1507 u32 min_clusters,
1534 u32 *cluster_start, 1508 u32 *cluster_start,
@@ -1546,7 +1520,6 @@ int ocfs2_claim_clusters(struct ocfs2_super *osb,
1546 1520
1547 BUG_ON(ac->ac_which != OCFS2_AC_USE_LOCAL 1521 BUG_ON(ac->ac_which != OCFS2_AC_USE_LOCAL
1548 && ac->ac_which != OCFS2_AC_USE_MAIN); 1522 && ac->ac_which != OCFS2_AC_USE_MAIN);
1549 BUG_ON(ac->ac_handle != handle);
1550 1523
1551 if (ac->ac_which == OCFS2_AC_USE_LOCAL) { 1524 if (ac->ac_which == OCFS2_AC_USE_LOCAL) {
1552 status = ocfs2_claim_local_alloc_bits(osb, 1525 status = ocfs2_claim_local_alloc_bits(osb,
@@ -1572,6 +1545,7 @@ int ocfs2_claim_clusters(struct ocfs2_super *osb,
1572 1545
1573 status = ocfs2_claim_suballoc_bits(osb, 1546 status = ocfs2_claim_suballoc_bits(osb,
1574 ac, 1547 ac,
1548 handle,
1575 bits_wanted, 1549 bits_wanted,
1576 min_clusters, 1550 min_clusters,
1577 &bg_bit_off, 1551 &bg_bit_off,
@@ -1598,7 +1572,7 @@ bail:
1598 return status; 1572 return status;
1599} 1573}
1600 1574
1601static inline int ocfs2_block_group_clear_bits(struct ocfs2_journal_handle *handle, 1575static inline int ocfs2_block_group_clear_bits(handle_t *handle,
1602 struct inode *alloc_inode, 1576 struct inode *alloc_inode,
1603 struct ocfs2_group_desc *bg, 1577 struct ocfs2_group_desc *bg,
1604 struct buffer_head *group_bh, 1578 struct buffer_head *group_bh,
@@ -1653,7 +1627,7 @@ bail:
1653/* 1627/*
1654 * expects the suballoc inode to already be locked. 1628 * expects the suballoc inode to already be locked.
1655 */ 1629 */
1656static int ocfs2_free_suballoc_bits(struct ocfs2_journal_handle *handle, 1630static int ocfs2_free_suballoc_bits(handle_t *handle,
1657 struct inode *alloc_inode, 1631 struct inode *alloc_inode,
1658 struct buffer_head *alloc_bh, 1632 struct buffer_head *alloc_bh,
1659 unsigned int start_bit, 1633 unsigned int start_bit,
@@ -1737,7 +1711,7 @@ static inline u64 ocfs2_which_suballoc_group(u64 block, unsigned int bit)
1737 return group; 1711 return group;
1738} 1712}
1739 1713
1740int ocfs2_free_dinode(struct ocfs2_journal_handle *handle, 1714int ocfs2_free_dinode(handle_t *handle,
1741 struct inode *inode_alloc_inode, 1715 struct inode *inode_alloc_inode,
1742 struct buffer_head *inode_alloc_bh, 1716 struct buffer_head *inode_alloc_bh,
1743 struct ocfs2_dinode *di) 1717 struct ocfs2_dinode *di)
@@ -1750,7 +1724,7 @@ int ocfs2_free_dinode(struct ocfs2_journal_handle *handle,
1750 inode_alloc_bh, bit, bg_blkno, 1); 1724 inode_alloc_bh, bit, bg_blkno, 1);
1751} 1725}
1752 1726
1753int ocfs2_free_extent_block(struct ocfs2_journal_handle *handle, 1727int ocfs2_free_extent_block(handle_t *handle,
1754 struct inode *eb_alloc_inode, 1728 struct inode *eb_alloc_inode,
1755 struct buffer_head *eb_alloc_bh, 1729 struct buffer_head *eb_alloc_bh,
1756 struct ocfs2_extent_block *eb) 1730 struct ocfs2_extent_block *eb)
@@ -1763,7 +1737,7 @@ int ocfs2_free_extent_block(struct ocfs2_journal_handle *handle,
1763 bit, bg_blkno, 1); 1737 bit, bg_blkno, 1);
1764} 1738}
1765 1739
1766int ocfs2_free_clusters(struct ocfs2_journal_handle *handle, 1740int ocfs2_free_clusters(handle_t *handle,
1767 struct inode *bitmap_inode, 1741 struct inode *bitmap_inode,
1768 struct buffer_head *bitmap_bh, 1742 struct buffer_head *bitmap_bh,
1769 u64 start_blk, 1743 u64 start_blk,
diff --git a/fs/ocfs2/suballoc.h b/fs/ocfs2/suballoc.h
index c787838d1052..1a3c94cb9250 100644
--- a/fs/ocfs2/suballoc.h
+++ b/fs/ocfs2/suballoc.h
@@ -43,7 +43,6 @@ struct ocfs2_alloc_context {
43#define OCFS2_AC_USE_INODE 3 43#define OCFS2_AC_USE_INODE 3
44#define OCFS2_AC_USE_META 4 44#define OCFS2_AC_USE_META 4
45 u32 ac_which; 45 u32 ac_which;
46 struct ocfs2_journal_handle *ac_handle;
47 46
48 /* these are used by the chain search */ 47 /* these are used by the chain search */
49 u16 ac_chain; 48 u16 ac_chain;
@@ -60,45 +59,42 @@ static inline int ocfs2_alloc_context_bits_left(struct ocfs2_alloc_context *ac)
60} 59}
61 60
62int ocfs2_reserve_new_metadata(struct ocfs2_super *osb, 61int ocfs2_reserve_new_metadata(struct ocfs2_super *osb,
63 struct ocfs2_journal_handle *handle,
64 struct ocfs2_dinode *fe, 62 struct ocfs2_dinode *fe,
65 struct ocfs2_alloc_context **ac); 63 struct ocfs2_alloc_context **ac);
66int ocfs2_reserve_new_inode(struct ocfs2_super *osb, 64int ocfs2_reserve_new_inode(struct ocfs2_super *osb,
67 struct ocfs2_journal_handle *handle,
68 struct ocfs2_alloc_context **ac); 65 struct ocfs2_alloc_context **ac);
69int ocfs2_reserve_clusters(struct ocfs2_super *osb, 66int ocfs2_reserve_clusters(struct ocfs2_super *osb,
70 struct ocfs2_journal_handle *handle,
71 u32 bits_wanted, 67 u32 bits_wanted,
72 struct ocfs2_alloc_context **ac); 68 struct ocfs2_alloc_context **ac);
73 69
74int ocfs2_claim_metadata(struct ocfs2_super *osb, 70int ocfs2_claim_metadata(struct ocfs2_super *osb,
75 struct ocfs2_journal_handle *handle, 71 handle_t *handle,
76 struct ocfs2_alloc_context *ac, 72 struct ocfs2_alloc_context *ac,
77 u32 bits_wanted, 73 u32 bits_wanted,
78 u16 *suballoc_bit_start, 74 u16 *suballoc_bit_start,
79 u32 *num_bits, 75 u32 *num_bits,
80 u64 *blkno_start); 76 u64 *blkno_start);
81int ocfs2_claim_new_inode(struct ocfs2_super *osb, 77int ocfs2_claim_new_inode(struct ocfs2_super *osb,
82 struct ocfs2_journal_handle *handle, 78 handle_t *handle,
83 struct ocfs2_alloc_context *ac, 79 struct ocfs2_alloc_context *ac,
84 u16 *suballoc_bit, 80 u16 *suballoc_bit,
85 u64 *fe_blkno); 81 u64 *fe_blkno);
86int ocfs2_claim_clusters(struct ocfs2_super *osb, 82int ocfs2_claim_clusters(struct ocfs2_super *osb,
87 struct ocfs2_journal_handle *handle, 83 handle_t *handle,
88 struct ocfs2_alloc_context *ac, 84 struct ocfs2_alloc_context *ac,
89 u32 min_clusters, 85 u32 min_clusters,
90 u32 *cluster_start, 86 u32 *cluster_start,
91 u32 *num_clusters); 87 u32 *num_clusters);
92 88
93int ocfs2_free_dinode(struct ocfs2_journal_handle *handle, 89int ocfs2_free_dinode(handle_t *handle,
94 struct inode *inode_alloc_inode, 90 struct inode *inode_alloc_inode,
95 struct buffer_head *inode_alloc_bh, 91 struct buffer_head *inode_alloc_bh,
96 struct ocfs2_dinode *di); 92 struct ocfs2_dinode *di);
97int ocfs2_free_extent_block(struct ocfs2_journal_handle *handle, 93int ocfs2_free_extent_block(handle_t *handle,
98 struct inode *eb_alloc_inode, 94 struct inode *eb_alloc_inode,
99 struct buffer_head *eb_alloc_bh, 95 struct buffer_head *eb_alloc_bh,
100 struct ocfs2_extent_block *eb); 96 struct ocfs2_extent_block *eb);
101int ocfs2_free_clusters(struct ocfs2_journal_handle *handle, 97int ocfs2_free_clusters(handle_t *handle,
102 struct inode *bitmap_inode, 98 struct inode *bitmap_inode,
103 struct buffer_head *bitmap_bh, 99 struct buffer_head *bitmap_bh,
104 u64 start_blk, 100 u64 start_blk,
diff --git a/fs/ocfs2/super.c b/fs/ocfs2/super.c
index 9a8089030f55..d9b4214a12da 100644
--- a/fs/ocfs2/super.c
+++ b/fs/ocfs2/super.c
@@ -70,8 +70,6 @@
70 70
71static kmem_cache_t *ocfs2_inode_cachep = NULL; 71static kmem_cache_t *ocfs2_inode_cachep = NULL;
72 72
73kmem_cache_t *ocfs2_lock_cache = NULL;
74
75/* OCFS2 needs to schedule several differnt types of work which 73/* OCFS2 needs to schedule several differnt types of work which
76 * require cluster locking, disk I/O, recovery waits, etc. Since these 74 * require cluster locking, disk I/O, recovery waits, etc. Since these
77 * types of work tend to be heavy we avoid using the kernel events 75 * types of work tend to be heavy we avoid using the kernel events
@@ -141,6 +139,7 @@ enum {
141 Opt_hb_local, 139 Opt_hb_local,
142 Opt_data_ordered, 140 Opt_data_ordered,
143 Opt_data_writeback, 141 Opt_data_writeback,
142 Opt_atime_quantum,
144 Opt_err, 143 Opt_err,
145}; 144};
146 145
@@ -154,6 +153,7 @@ static match_table_t tokens = {
154 {Opt_hb_local, OCFS2_HB_LOCAL}, 153 {Opt_hb_local, OCFS2_HB_LOCAL},
155 {Opt_data_ordered, "data=ordered"}, 154 {Opt_data_ordered, "data=ordered"},
156 {Opt_data_writeback, "data=writeback"}, 155 {Opt_data_writeback, "data=writeback"},
156 {Opt_atime_quantum, "atime_quantum=%u"},
157 {Opt_err, NULL} 157 {Opt_err, NULL}
158}; 158};
159 159
@@ -707,6 +707,7 @@ static int ocfs2_parse_options(struct super_block *sb,
707 while ((p = strsep(&options, ",")) != NULL) { 707 while ((p = strsep(&options, ",")) != NULL) {
708 int token, option; 708 int token, option;
709 substring_t args[MAX_OPT_ARGS]; 709 substring_t args[MAX_OPT_ARGS];
710 struct ocfs2_super * osb = OCFS2_SB(sb);
710 711
711 if (!*p) 712 if (!*p)
712 continue; 713 continue;
@@ -747,6 +748,16 @@ static int ocfs2_parse_options(struct super_block *sb,
747 case Opt_data_writeback: 748 case Opt_data_writeback:
748 *mount_opt |= OCFS2_MOUNT_DATA_WRITEBACK; 749 *mount_opt |= OCFS2_MOUNT_DATA_WRITEBACK;
749 break; 750 break;
751 case Opt_atime_quantum:
752 if (match_int(&args[0], &option)) {
753 status = 0;
754 goto bail;
755 }
756 if (option >= 0)
757 osb->s_atime_quantum = option;
758 else
759 osb->s_atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM;
760 break;
750 default: 761 default:
751 mlog(ML_ERROR, 762 mlog(ML_ERROR,
752 "Unrecognized mount option \"%s\" " 763 "Unrecognized mount option \"%s\" "
@@ -867,7 +878,7 @@ static int ocfs2_statfs(struct dentry *dentry, struct kstatfs *buf)
867 goto bail; 878 goto bail;
868 } 879 }
869 880
870 status = ocfs2_meta_lock(inode, NULL, &bh, 0); 881 status = ocfs2_meta_lock(inode, &bh, 0);
871 if (status < 0) { 882 if (status < 0) {
872 mlog_errno(status); 883 mlog_errno(status);
873 goto bail; 884 goto bail;
@@ -914,9 +925,7 @@ static void ocfs2_inode_init_once(void *data,
914 oi->ip_open_count = 0; 925 oi->ip_open_count = 0;
915 spin_lock_init(&oi->ip_lock); 926 spin_lock_init(&oi->ip_lock);
916 ocfs2_extent_map_init(&oi->vfs_inode); 927 ocfs2_extent_map_init(&oi->vfs_inode);
917 INIT_LIST_HEAD(&oi->ip_handle_list);
918 INIT_LIST_HEAD(&oi->ip_io_markers); 928 INIT_LIST_HEAD(&oi->ip_io_markers);
919 oi->ip_handle = NULL;
920 oi->ip_created_trans = 0; 929 oi->ip_created_trans = 0;
921 oi->ip_last_trans = 0; 930 oi->ip_last_trans = 0;
922 oi->ip_dir_start_lookup = 0; 931 oi->ip_dir_start_lookup = 0;
@@ -948,14 +957,6 @@ static int ocfs2_initialize_mem_caches(void)
948 if (!ocfs2_inode_cachep) 957 if (!ocfs2_inode_cachep)
949 return -ENOMEM; 958 return -ENOMEM;
950 959
951 ocfs2_lock_cache = kmem_cache_create("ocfs2_lock",
952 sizeof(struct ocfs2_journal_lock),
953 0,
954 SLAB_HWCACHE_ALIGN,
955 NULL, NULL);
956 if (!ocfs2_lock_cache)
957 return -ENOMEM;
958
959 return 0; 960 return 0;
960} 961}
961 962
@@ -963,11 +964,8 @@ static void ocfs2_free_mem_caches(void)
963{ 964{
964 if (ocfs2_inode_cachep) 965 if (ocfs2_inode_cachep)
965 kmem_cache_destroy(ocfs2_inode_cachep); 966 kmem_cache_destroy(ocfs2_inode_cachep);
966 if (ocfs2_lock_cache)
967 kmem_cache_destroy(ocfs2_lock_cache);
968 967
969 ocfs2_inode_cachep = NULL; 968 ocfs2_inode_cachep = NULL;
970 ocfs2_lock_cache = NULL;
971} 969}
972 970
973static int ocfs2_get_sector(struct super_block *sb, 971static int ocfs2_get_sector(struct super_block *sb,
@@ -1280,6 +1278,8 @@ static int ocfs2_initialize_super(struct super_block *sb,
1280 init_waitqueue_head(&osb->checkpoint_event); 1278 init_waitqueue_head(&osb->checkpoint_event);
1281 atomic_set(&osb->needs_checkpoint, 0); 1279 atomic_set(&osb->needs_checkpoint, 0);
1282 1280
1281 osb->s_atime_quantum = OCFS2_DEFAULT_ATIME_QUANTUM;
1282
1283 osb->node_num = O2NM_INVALID_NODE_NUM; 1283 osb->node_num = O2NM_INVALID_NODE_NUM;
1284 osb->slot_num = OCFS2_INVALID_SLOT; 1284 osb->slot_num = OCFS2_INVALID_SLOT;
1285 1285
diff --git a/fs/ocfs2/symlink.c b/fs/ocfs2/symlink.c
index c0f68aa6c175..957d6878b03e 100644
--- a/fs/ocfs2/symlink.c
+++ b/fs/ocfs2/symlink.c
@@ -126,6 +126,10 @@ static int ocfs2_readlink(struct dentry *dentry,
126 goto out; 126 goto out;
127 } 127 }
128 128
129 /*
130 * Without vfsmount we can't update atime now,
131 * but we will update atime here ultimately.
132 */
129 ret = vfs_readlink(dentry, buffer, buflen, link); 133 ret = vfs_readlink(dentry, buffer, buflen, link);
130 134
131 brelse(bh); 135 brelse(bh);
diff --git a/fs/partitions/mac.c b/fs/partitions/mac.c
index c0871002d00d..d4a0fad3563b 100644
--- a/fs/partitions/mac.c
+++ b/fs/partitions/mac.c
@@ -74,6 +74,8 @@ int mac_partition(struct parsed_partitions *state, struct block_device *bdev)
74 be32_to_cpu(part->start_block) * (secsize/512), 74 be32_to_cpu(part->start_block) * (secsize/512),
75 be32_to_cpu(part->block_count) * (secsize/512)); 75 be32_to_cpu(part->block_count) * (secsize/512));
76 76
77 if (!strnicmp(part->type, "Linux_RAID", 10))
78 state->parts[slot].flags = 1;
77#ifdef CONFIG_PPC_PMAC 79#ifdef CONFIG_PPC_PMAC
78 /* 80 /*
79 * If this is the first bootable partition, tell the 81 * If this is the first bootable partition, tell the
diff --git a/fs/proc/root.c b/fs/proc/root.c
index ffe66c38488b..64d242b6dcfa 100644
--- a/fs/proc/root.c
+++ b/fs/proc/root.c
@@ -13,6 +13,7 @@
13#include <linux/proc_fs.h> 13#include <linux/proc_fs.h>
14#include <linux/stat.h> 14#include <linux/stat.h>
15#include <linux/init.h> 15#include <linux/init.h>
16#include <linux/sched.h>
16#include <linux/module.h> 17#include <linux/module.h>
17#include <linux/bitops.h> 18#include <linux/bitops.h>
18#include <linux/smp_lock.h> 19#include <linux/smp_lock.h>
diff --git a/fs/super.c b/fs/super.c
index 47e554c12e76..84c320f6ad7e 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -221,6 +221,24 @@ static int grab_super(struct super_block *s) __releases(sb_lock)
221} 221}
222 222
223/* 223/*
224 * Superblock locking. We really ought to get rid of these two.
225 */
226void lock_super(struct super_block * sb)
227{
228 get_fs_excl();
229 mutex_lock(&sb->s_lock);
230}
231
232void unlock_super(struct super_block * sb)
233{
234 put_fs_excl();
235 mutex_unlock(&sb->s_lock);
236}
237
238EXPORT_SYMBOL(lock_super);
239EXPORT_SYMBOL(unlock_super);
240
241/*
224 * Write out and wait upon all dirty data associated with this 242 * Write out and wait upon all dirty data associated with this
225 * superblock. Filesystem data as well as the underlying block 243 * superblock. Filesystem data as well as the underlying block
226 * device. Takes the superblock lock. Requires a second blkdev 244 * device. Takes the superblock lock. Requires a second blkdev
diff --git a/fs/sync.c b/fs/sync.c
index 1de747b5ddb9..865f32be386e 100644
--- a/fs/sync.c
+++ b/fs/sync.c
@@ -6,6 +6,7 @@
6#include <linux/file.h> 6#include <linux/file.h>
7#include <linux/fs.h> 7#include <linux/fs.h>
8#include <linux/module.h> 8#include <linux/module.h>
9#include <linux/sched.h>
9#include <linux/writeback.h> 10#include <linux/writeback.h>
10#include <linux/syscalls.h> 11#include <linux/syscalls.h>
11#include <linux/linkage.h> 12#include <linux/linkage.h>
diff --git a/fs/utimes.c b/fs/utimes.c
index 1bcd852fc4a9..99cf2cb11fec 100644
--- a/fs/utimes.c
+++ b/fs/utimes.c
@@ -2,6 +2,7 @@
2#include <linux/fs.h> 2#include <linux/fs.h>
3#include <linux/linkage.h> 3#include <linux/linkage.h>
4#include <linux/namei.h> 4#include <linux/namei.h>
5#include <linux/sched.h>
5#include <linux/utime.h> 6#include <linux/utime.h>
6#include <asm/uaccess.h> 7#include <asm/uaccess.h>
7#include <asm/unistd.h> 8#include <asm/unistd.h>
diff --git a/include/asm-arm/arch-ixp4xx/platform.h b/include/asm-arm/arch-ixp4xx/platform.h
index 8d10a9187693..ab194e5f6653 100644
--- a/include/asm-arm/arch-ixp4xx/platform.h
+++ b/include/asm-arm/arch-ixp4xx/platform.h
@@ -86,6 +86,19 @@ struct ixp4xx_i2c_pins {
86 unsigned long scl_pin; 86 unsigned long scl_pin;
87}; 87};
88 88
89/*
90 * This structure provide a means for the board setup code
91 * to give information to th pata_ixp4xx driver. It is
92 * passed as platform_data.
93 */
94struct ixp4xx_pata_data {
95 volatile u32 *cs0_cfg;
96 volatile u32 *cs1_cfg;
97 unsigned long cs0_bits;
98 unsigned long cs1_bits;
99 void __iomem *cs0;
100 void __iomem *cs1;
101};
89 102
90struct sys_timer; 103struct sys_timer;
91 104
diff --git a/include/asm-avr32/types.h b/include/asm-avr32/types.h
index 3f47db9675af..2bff153a32ed 100644
--- a/include/asm-avr32/types.h
+++ b/include/asm-avr32/types.h
@@ -57,11 +57,6 @@ typedef unsigned long long u64;
57 57
58typedef u32 dma_addr_t; 58typedef u32 dma_addr_t;
59 59
60#ifdef CONFIG_LBD
61typedef u64 sector_t;
62#define HAVE_SECTOR_T
63#endif
64
65#endif /* __ASSEMBLY__ */ 60#endif /* __ASSEMBLY__ */
66 61
67#endif /* __KERNEL__ */ 62#endif /* __KERNEL__ */
diff --git a/include/asm-h8300/types.h b/include/asm-h8300/types.h
index da2402b86540..2a8b1b2be782 100644
--- a/include/asm-h8300/types.h
+++ b/include/asm-h8300/types.h
@@ -55,12 +55,6 @@ typedef unsigned long long u64;
55 55
56typedef u32 dma_addr_t; 56typedef u32 dma_addr_t;
57 57
58#define HAVE_SECTOR_T
59typedef u64 sector_t;
60
61#define HAVE_BLKCNT_T
62typedef u64 blkcnt_t;
63
64#endif /* __KERNEL__ */ 58#endif /* __KERNEL__ */
65 59
66#endif /* __ASSEMBLY__ */ 60#endif /* __ASSEMBLY__ */
diff --git a/include/asm-i386/types.h b/include/asm-i386/types.h
index 4b4b295ccdb9..ad0a55bd782f 100644
--- a/include/asm-i386/types.h
+++ b/include/asm-i386/types.h
@@ -57,16 +57,6 @@ typedef u32 dma_addr_t;
57#endif 57#endif
58typedef u64 dma64_addr_t; 58typedef u64 dma64_addr_t;
59 59
60#ifdef CONFIG_LBD
61typedef u64 sector_t;
62#define HAVE_SECTOR_T
63#endif
64
65#ifdef CONFIG_LSF
66typedef u64 blkcnt_t;
67#define HAVE_BLKCNT_T
68#endif
69
70#endif /* __ASSEMBLY__ */ 60#endif /* __ASSEMBLY__ */
71 61
72#endif /* __KERNEL__ */ 62#endif /* __KERNEL__ */
diff --git a/include/asm-m68knommu/dma-mapping.h b/include/asm-m68knommu/dma-mapping.h
index 5622b855a577..6aeab18e58bd 100644
--- a/include/asm-m68knommu/dma-mapping.h
+++ b/include/asm-m68knommu/dma-mapping.h
@@ -1,9 +1,10 @@
1#ifndef _M68KNOMMU_DMA_MAPPING_H 1#ifndef _M68KNOMMU_DMA_MAPPING_H
2#define _M68KNOMMU_DMA_MAPPING_H 2#define _M68KNOMMU_DMA_MAPPING_H
3 3
4
5#ifdef CONFIG_PCI 4#ifdef CONFIG_PCI
6#include <asm-generic/dma-mapping.h> 5#include <asm-generic/dma-mapping.h>
6#else
7#include <asm-generic/dma-mapping-broken.h>
7#endif 8#endif
8 9
9#endif /* _M68KNOMMU_DMA_MAPPING_H */ 10#endif /* _M68KNOMMU_DMA_MAPPING_H */
diff --git a/include/asm-m68knommu/m520xsim.h b/include/asm-m68knommu/m520xsim.h
index 1dac22ea95ba..49d016e6391a 100644
--- a/include/asm-m68knommu/m520xsim.h
+++ b/include/asm-m68knommu/m520xsim.h
@@ -31,6 +31,16 @@
31#define MCFINT_QSPI 31 /* Interrupt number for QSPI */ 31#define MCFINT_QSPI 31 /* Interrupt number for QSPI */
32#define MCFINT_PIT1 4 /* Interrupt number for PIT1 (PIT0 in processor) */ 32#define MCFINT_PIT1 4 /* Interrupt number for PIT1 (PIT0 in processor) */
33 33
34/*
35 * SDRAM configuration registers.
36 */
37#define MCFSIM_SDMR 0x000a8000 /* SDRAM Mode/Extended Mode Register */
38#define MCFSIM_SDCR 0x000a8004 /* SDRAM Control Register */
39#define MCFSIM_SDCFG1 0x000a8008 /* SDRAM Configuration Register 1 */
40#define MCFSIM_SDCFG2 0x000a800c /* SDRAM Configuration Register 2 */
41#define MCFSIM_SDCS0 0x000a8110 /* SDRAM Chip Select 0 Configuration */
42#define MCFSIM_SDCS1 0x000a8114 /* SDRAM Chip Select 1 Configuration */
43
34 44
35#define MCF_GPIO_PAR_UART (0xA4036) 45#define MCF_GPIO_PAR_UART (0xA4036)
36#define MCF_GPIO_PAR_FECI2C (0xA4033) 46#define MCF_GPIO_PAR_FECI2C (0xA4033)
@@ -47,7 +57,7 @@
47 57
48#define ICR_INTRCONF 0x05 58#define ICR_INTRCONF 0x05
49#define MCFPIT_IMR MCFINTC_IMRL 59#define MCFPIT_IMR MCFINTC_IMRL
50#define MCFPIT_IMR_IBIT (1 << MCFINT_PIT1) 60#define MCFPIT_IMR_IBIT (1 << MCFINT_PIT1)
51 61
52/****************************************************************************/ 62/****************************************************************************/
53#endif /* m520xsim_h */ 63#endif /* m520xsim_h */
diff --git a/include/asm-m68knommu/scatterlist.h b/include/asm-m68knommu/scatterlist.h
index 12309b181d29..2085d6ff8782 100644
--- a/include/asm-m68knommu/scatterlist.h
+++ b/include/asm-m68knommu/scatterlist.h
@@ -10,7 +10,7 @@ struct scatterlist {
10 unsigned int length; 10 unsigned int length;
11}; 11};
12 12
13#define sg_address(sg) (page_address((sg)->page) + (sg)->offset 13#define sg_address(sg) (page_address((sg)->page) + (sg)->offset)
14#define sg_dma_address(sg) ((sg)->dma_address) 14#define sg_dma_address(sg) ((sg)->dma_address)
15#define sg_dma_len(sg) ((sg)->length) 15#define sg_dma_len(sg) ((sg)->length)
16 16
diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h
index 7978d8e11647..c1a2409bb52a 100644
--- a/include/asm-mips/atomic.h
+++ b/include/asm-mips/atomic.h
@@ -15,6 +15,7 @@
15#define _ASM_ATOMIC_H 15#define _ASM_ATOMIC_H
16 16
17#include <linux/irqflags.h> 17#include <linux/irqflags.h>
18#include <asm/barrier.h>
18#include <asm/cpu-features.h> 19#include <asm/cpu-features.h>
19#include <asm/war.h> 20#include <asm/war.h>
20 21
@@ -130,6 +131,8 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
130{ 131{
131 unsigned long result; 132 unsigned long result;
132 133
134 smp_mb();
135
133 if (cpu_has_llsc && R10000_LLSC_WAR) { 136 if (cpu_has_llsc && R10000_LLSC_WAR) {
134 unsigned long temp; 137 unsigned long temp;
135 138
@@ -140,7 +143,6 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
140 " sc %0, %2 \n" 143 " sc %0, %2 \n"
141 " beqzl %0, 1b \n" 144 " beqzl %0, 1b \n"
142 " addu %0, %1, %3 \n" 145 " addu %0, %1, %3 \n"
143 " sync \n"
144 " .set mips0 \n" 146 " .set mips0 \n"
145 : "=&r" (result), "=&r" (temp), "=m" (v->counter) 147 : "=&r" (result), "=&r" (temp), "=m" (v->counter)
146 : "Ir" (i), "m" (v->counter) 148 : "Ir" (i), "m" (v->counter)
@@ -155,7 +157,6 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
155 " sc %0, %2 \n" 157 " sc %0, %2 \n"
156 " beqz %0, 1b \n" 158 " beqz %0, 1b \n"
157 " addu %0, %1, %3 \n" 159 " addu %0, %1, %3 \n"
158 " sync \n"
159 " .set mips0 \n" 160 " .set mips0 \n"
160 : "=&r" (result), "=&r" (temp), "=m" (v->counter) 161 : "=&r" (result), "=&r" (temp), "=m" (v->counter)
161 : "Ir" (i), "m" (v->counter) 162 : "Ir" (i), "m" (v->counter)
@@ -170,6 +171,8 @@ static __inline__ int atomic_add_return(int i, atomic_t * v)
170 local_irq_restore(flags); 171 local_irq_restore(flags);
171 } 172 }
172 173
174 smp_mb();
175
173 return result; 176 return result;
174} 177}
175 178
@@ -177,6 +180,8 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
177{ 180{
178 unsigned long result; 181 unsigned long result;
179 182
183 smp_mb();
184
180 if (cpu_has_llsc && R10000_LLSC_WAR) { 185 if (cpu_has_llsc && R10000_LLSC_WAR) {
181 unsigned long temp; 186 unsigned long temp;
182 187
@@ -187,7 +192,6 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
187 " sc %0, %2 \n" 192 " sc %0, %2 \n"
188 " beqzl %0, 1b \n" 193 " beqzl %0, 1b \n"
189 " subu %0, %1, %3 \n" 194 " subu %0, %1, %3 \n"
190 " sync \n"
191 " .set mips0 \n" 195 " .set mips0 \n"
192 : "=&r" (result), "=&r" (temp), "=m" (v->counter) 196 : "=&r" (result), "=&r" (temp), "=m" (v->counter)
193 : "Ir" (i), "m" (v->counter) 197 : "Ir" (i), "m" (v->counter)
@@ -202,7 +206,6 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
202 " sc %0, %2 \n" 206 " sc %0, %2 \n"
203 " beqz %0, 1b \n" 207 " beqz %0, 1b \n"
204 " subu %0, %1, %3 \n" 208 " subu %0, %1, %3 \n"
205 " sync \n"
206 " .set mips0 \n" 209 " .set mips0 \n"
207 : "=&r" (result), "=&r" (temp), "=m" (v->counter) 210 : "=&r" (result), "=&r" (temp), "=m" (v->counter)
208 : "Ir" (i), "m" (v->counter) 211 : "Ir" (i), "m" (v->counter)
@@ -217,6 +220,8 @@ static __inline__ int atomic_sub_return(int i, atomic_t * v)
217 local_irq_restore(flags); 220 local_irq_restore(flags);
218 } 221 }
219 222
223 smp_mb();
224
220 return result; 225 return result;
221} 226}
222 227
@@ -232,6 +237,8 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
232{ 237{
233 unsigned long result; 238 unsigned long result;
234 239
240 smp_mb();
241
235 if (cpu_has_llsc && R10000_LLSC_WAR) { 242 if (cpu_has_llsc && R10000_LLSC_WAR) {
236 unsigned long temp; 243 unsigned long temp;
237 244
@@ -245,7 +252,6 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
245 " beqzl %0, 1b \n" 252 " beqzl %0, 1b \n"
246 " subu %0, %1, %3 \n" 253 " subu %0, %1, %3 \n"
247 " .set reorder \n" 254 " .set reorder \n"
248 " sync \n"
249 "1: \n" 255 "1: \n"
250 " .set mips0 \n" 256 " .set mips0 \n"
251 : "=&r" (result), "=&r" (temp), "=m" (v->counter) 257 : "=&r" (result), "=&r" (temp), "=m" (v->counter)
@@ -264,7 +270,6 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
264 " beqz %0, 1b \n" 270 " beqz %0, 1b \n"
265 " subu %0, %1, %3 \n" 271 " subu %0, %1, %3 \n"
266 " .set reorder \n" 272 " .set reorder \n"
267 " sync \n"
268 "1: \n" 273 "1: \n"
269 " .set mips0 \n" 274 " .set mips0 \n"
270 : "=&r" (result), "=&r" (temp), "=m" (v->counter) 275 : "=&r" (result), "=&r" (temp), "=m" (v->counter)
@@ -281,6 +286,8 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
281 local_irq_restore(flags); 286 local_irq_restore(flags);
282 } 287 }
283 288
289 smp_mb();
290
284 return result; 291 return result;
285} 292}
286 293
@@ -375,7 +382,7 @@ static __inline__ int atomic_sub_if_positive(int i, atomic_t * v)
375 382
376#ifdef CONFIG_64BIT 383#ifdef CONFIG_64BIT
377 384
378typedef struct { volatile __s64 counter; } atomic64_t; 385typedef struct { volatile long counter; } atomic64_t;
379 386
380#define ATOMIC64_INIT(i) { (i) } 387#define ATOMIC64_INIT(i) { (i) }
381 388
@@ -484,6 +491,8 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
484{ 491{
485 unsigned long result; 492 unsigned long result;
486 493
494 smp_mb();
495
487 if (cpu_has_llsc && R10000_LLSC_WAR) { 496 if (cpu_has_llsc && R10000_LLSC_WAR) {
488 unsigned long temp; 497 unsigned long temp;
489 498
@@ -494,7 +503,6 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
494 " scd %0, %2 \n" 503 " scd %0, %2 \n"
495 " beqzl %0, 1b \n" 504 " beqzl %0, 1b \n"
496 " addu %0, %1, %3 \n" 505 " addu %0, %1, %3 \n"
497 " sync \n"
498 " .set mips0 \n" 506 " .set mips0 \n"
499 : "=&r" (result), "=&r" (temp), "=m" (v->counter) 507 : "=&r" (result), "=&r" (temp), "=m" (v->counter)
500 : "Ir" (i), "m" (v->counter) 508 : "Ir" (i), "m" (v->counter)
@@ -509,7 +517,6 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
509 " scd %0, %2 \n" 517 " scd %0, %2 \n"
510 " beqz %0, 1b \n" 518 " beqz %0, 1b \n"
511 " addu %0, %1, %3 \n" 519 " addu %0, %1, %3 \n"
512 " sync \n"
513 " .set mips0 \n" 520 " .set mips0 \n"
514 : "=&r" (result), "=&r" (temp), "=m" (v->counter) 521 : "=&r" (result), "=&r" (temp), "=m" (v->counter)
515 : "Ir" (i), "m" (v->counter) 522 : "Ir" (i), "m" (v->counter)
@@ -524,6 +531,8 @@ static __inline__ long atomic64_add_return(long i, atomic64_t * v)
524 local_irq_restore(flags); 531 local_irq_restore(flags);
525 } 532 }
526 533
534 smp_mb();
535
527 return result; 536 return result;
528} 537}
529 538
@@ -531,6 +540,8 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
531{ 540{
532 unsigned long result; 541 unsigned long result;
533 542
543 smp_mb();
544
534 if (cpu_has_llsc && R10000_LLSC_WAR) { 545 if (cpu_has_llsc && R10000_LLSC_WAR) {
535 unsigned long temp; 546 unsigned long temp;
536 547
@@ -541,7 +552,6 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
541 " scd %0, %2 \n" 552 " scd %0, %2 \n"
542 " beqzl %0, 1b \n" 553 " beqzl %0, 1b \n"
543 " subu %0, %1, %3 \n" 554 " subu %0, %1, %3 \n"
544 " sync \n"
545 " .set mips0 \n" 555 " .set mips0 \n"
546 : "=&r" (result), "=&r" (temp), "=m" (v->counter) 556 : "=&r" (result), "=&r" (temp), "=m" (v->counter)
547 : "Ir" (i), "m" (v->counter) 557 : "Ir" (i), "m" (v->counter)
@@ -556,7 +566,6 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
556 " scd %0, %2 \n" 566 " scd %0, %2 \n"
557 " beqz %0, 1b \n" 567 " beqz %0, 1b \n"
558 " subu %0, %1, %3 \n" 568 " subu %0, %1, %3 \n"
559 " sync \n"
560 " .set mips0 \n" 569 " .set mips0 \n"
561 : "=&r" (result), "=&r" (temp), "=m" (v->counter) 570 : "=&r" (result), "=&r" (temp), "=m" (v->counter)
562 : "Ir" (i), "m" (v->counter) 571 : "Ir" (i), "m" (v->counter)
@@ -571,6 +580,8 @@ static __inline__ long atomic64_sub_return(long i, atomic64_t * v)
571 local_irq_restore(flags); 580 local_irq_restore(flags);
572 } 581 }
573 582
583 smp_mb();
584
574 return result; 585 return result;
575} 586}
576 587
@@ -586,6 +597,8 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
586{ 597{
587 unsigned long result; 598 unsigned long result;
588 599
600 smp_mb();
601
589 if (cpu_has_llsc && R10000_LLSC_WAR) { 602 if (cpu_has_llsc && R10000_LLSC_WAR) {
590 unsigned long temp; 603 unsigned long temp;
591 604
@@ -599,7 +612,6 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
599 " beqzl %0, 1b \n" 612 " beqzl %0, 1b \n"
600 " dsubu %0, %1, %3 \n" 613 " dsubu %0, %1, %3 \n"
601 " .set reorder \n" 614 " .set reorder \n"
602 " sync \n"
603 "1: \n" 615 "1: \n"
604 " .set mips0 \n" 616 " .set mips0 \n"
605 : "=&r" (result), "=&r" (temp), "=m" (v->counter) 617 : "=&r" (result), "=&r" (temp), "=m" (v->counter)
@@ -618,7 +630,6 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
618 " beqz %0, 1b \n" 630 " beqz %0, 1b \n"
619 " dsubu %0, %1, %3 \n" 631 " dsubu %0, %1, %3 \n"
620 " .set reorder \n" 632 " .set reorder \n"
621 " sync \n"
622 "1: \n" 633 "1: \n"
623 " .set mips0 \n" 634 " .set mips0 \n"
624 : "=&r" (result), "=&r" (temp), "=m" (v->counter) 635 : "=&r" (result), "=&r" (temp), "=m" (v->counter)
@@ -635,6 +646,8 @@ static __inline__ long atomic64_sub_if_positive(long i, atomic64_t * v)
635 local_irq_restore(flags); 646 local_irq_restore(flags);
636 } 647 }
637 648
649 smp_mb();
650
638 return result; 651 return result;
639} 652}
640 653
diff --git a/include/asm-mips/barrier.h b/include/asm-mips/barrier.h
new file mode 100644
index 000000000000..ed82631b0017
--- /dev/null
+++ b/include/asm-mips/barrier.h
@@ -0,0 +1,132 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (C) 2006 by Ralf Baechle (ralf@linux-mips.org)
7 */
8#ifndef __ASM_BARRIER_H
9#define __ASM_BARRIER_H
10
11/*
12 * read_barrier_depends - Flush all pending reads that subsequents reads
13 * depend on.
14 *
15 * No data-dependent reads from memory-like regions are ever reordered
16 * over this barrier. All reads preceding this primitive are guaranteed
17 * to access memory (but not necessarily other CPUs' caches) before any
18 * reads following this primitive that depend on the data return by
19 * any of the preceding reads. This primitive is much lighter weight than
20 * rmb() on most CPUs, and is never heavier weight than is
21 * rmb().
22 *
23 * These ordering constraints are respected by both the local CPU
24 * and the compiler.
25 *
26 * Ordering is not guaranteed by anything other than these primitives,
27 * not even by data dependencies. See the documentation for
28 * memory_barrier() for examples and URLs to more information.
29 *
30 * For example, the following code would force ordering (the initial
31 * value of "a" is zero, "b" is one, and "p" is "&a"):
32 *
33 * <programlisting>
34 * CPU 0 CPU 1
35 *
36 * b = 2;
37 * memory_barrier();
38 * p = &b; q = p;
39 * read_barrier_depends();
40 * d = *q;
41 * </programlisting>
42 *
43 * because the read of "*q" depends on the read of "p" and these
44 * two reads are separated by a read_barrier_depends(). However,
45 * the following code, with the same initial values for "a" and "b":
46 *
47 * <programlisting>
48 * CPU 0 CPU 1
49 *
50 * a = 2;
51 * memory_barrier();
52 * b = 3; y = b;
53 * read_barrier_depends();
54 * x = a;
55 * </programlisting>
56 *
57 * does not enforce ordering, since there is no data dependency between
58 * the read of "a" and the read of "b". Therefore, on some CPUs, such
59 * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb()
60 * in cases like this where there are no data dependencies.
61 */
62
63#define read_barrier_depends() do { } while(0)
64#define smp_read_barrier_depends() do { } while(0)
65
66#ifdef CONFIG_CPU_HAS_SYNC
67#define __sync() \
68 __asm__ __volatile__( \
69 ".set push\n\t" \
70 ".set noreorder\n\t" \
71 ".set mips2\n\t" \
72 "sync\n\t" \
73 ".set pop" \
74 : /* no output */ \
75 : /* no input */ \
76 : "memory")
77#else
78#define __sync() do { } while(0)
79#endif
80
81#define __fast_iob() \
82 __asm__ __volatile__( \
83 ".set push\n\t" \
84 ".set noreorder\n\t" \
85 "lw $0,%0\n\t" \
86 "nop\n\t" \
87 ".set pop" \
88 : /* no output */ \
89 : "m" (*(int *)CKSEG1) \
90 : "memory")
91
92#define fast_wmb() __sync()
93#define fast_rmb() __sync()
94#define fast_mb() __sync()
95#define fast_iob() \
96 do { \
97 __sync(); \
98 __fast_iob(); \
99 } while (0)
100
101#ifdef CONFIG_CPU_HAS_WB
102
103#include <asm/wbflush.h>
104
105#define wmb() fast_wmb()
106#define rmb() fast_rmb()
107#define mb() wbflush()
108#define iob() wbflush()
109
110#else /* !CONFIG_CPU_HAS_WB */
111
112#define wmb() fast_wmb()
113#define rmb() fast_rmb()
114#define mb() fast_mb()
115#define iob() fast_iob()
116
117#endif /* !CONFIG_CPU_HAS_WB */
118
119#if defined(CONFIG_WEAK_ORDERING) && defined(CONFIG_SMP)
120#define __WEAK_ORDERING_MB " sync \n"
121#else
122#define __WEAK_ORDERING_MB " \n"
123#endif
124
125#define smp_mb() __asm__ __volatile__(__WEAK_ORDERING_MB : : :"memory")
126#define smp_rmb() __asm__ __volatile__(__WEAK_ORDERING_MB : : :"memory")
127#define smp_wmb() __asm__ __volatile__(__WEAK_ORDERING_MB : : :"memory")
128
129#define set_mb(var, value) \
130 do { var = value; smp_mb(); } while (0)
131
132#endif /* __ASM_BARRIER_H */
diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h
index b9007411b60f..06445de1324b 100644
--- a/include/asm-mips/bitops.h
+++ b/include/asm-mips/bitops.h
@@ -3,7 +3,7 @@
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (c) 1994 - 1997, 1999, 2000 Ralf Baechle (ralf@gnu.org) 6 * Copyright (c) 1994 - 1997, 1999, 2000, 06 Ralf Baechle (ralf@linux-mips.org)
7 * Copyright (c) 1999, 2000 Silicon Graphics, Inc. 7 * Copyright (c) 1999, 2000 Silicon Graphics, Inc.
8 */ 8 */
9#ifndef _ASM_BITOPS_H 9#ifndef _ASM_BITOPS_H
@@ -12,6 +12,7 @@
12#include <linux/compiler.h> 12#include <linux/compiler.h>
13#include <linux/irqflags.h> 13#include <linux/irqflags.h>
14#include <linux/types.h> 14#include <linux/types.h>
15#include <asm/barrier.h>
15#include <asm/bug.h> 16#include <asm/bug.h>
16#include <asm/byteorder.h> /* sigh ... */ 17#include <asm/byteorder.h> /* sigh ... */
17#include <asm/cpu-features.h> 18#include <asm/cpu-features.h>
@@ -204,9 +205,6 @@ static inline int test_and_set_bit(unsigned long nr,
204 " " __SC "%2, %1 \n" 205 " " __SC "%2, %1 \n"
205 " beqzl %2, 1b \n" 206 " beqzl %2, 1b \n"
206 " and %2, %0, %3 \n" 207 " and %2, %0, %3 \n"
207#ifdef CONFIG_SMP
208 " sync \n"
209#endif
210 " .set mips0 \n" 208 " .set mips0 \n"
211 : "=&r" (temp), "=m" (*m), "=&r" (res) 209 : "=&r" (temp), "=m" (*m), "=&r" (res)
212 : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) 210 : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
@@ -226,9 +224,6 @@ static inline int test_and_set_bit(unsigned long nr,
226 " " __SC "%2, %1 \n" 224 " " __SC "%2, %1 \n"
227 " beqz %2, 1b \n" 225 " beqz %2, 1b \n"
228 " and %2, %0, %3 \n" 226 " and %2, %0, %3 \n"
229#ifdef CONFIG_SMP
230 " sync \n"
231#endif
232 " .set pop \n" 227 " .set pop \n"
233 : "=&r" (temp), "=m" (*m), "=&r" (res) 228 : "=&r" (temp), "=m" (*m), "=&r" (res)
234 : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) 229 : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
@@ -250,6 +245,8 @@ static inline int test_and_set_bit(unsigned long nr,
250 245
251 return retval; 246 return retval;
252 } 247 }
248
249 smp_mb();
253} 250}
254 251
255/* 252/*
@@ -275,9 +272,6 @@ static inline int test_and_clear_bit(unsigned long nr,
275 " " __SC "%2, %1 \n" 272 " " __SC "%2, %1 \n"
276 " beqzl %2, 1b \n" 273 " beqzl %2, 1b \n"
277 " and %2, %0, %3 \n" 274 " and %2, %0, %3 \n"
278#ifdef CONFIG_SMP
279 " sync \n"
280#endif
281 " .set mips0 \n" 275 " .set mips0 \n"
282 : "=&r" (temp), "=m" (*m), "=&r" (res) 276 : "=&r" (temp), "=m" (*m), "=&r" (res)
283 : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) 277 : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
@@ -298,9 +292,6 @@ static inline int test_and_clear_bit(unsigned long nr,
298 " " __SC "%2, %1 \n" 292 " " __SC "%2, %1 \n"
299 " beqz %2, 1b \n" 293 " beqz %2, 1b \n"
300 " and %2, %0, %3 \n" 294 " and %2, %0, %3 \n"
301#ifdef CONFIG_SMP
302 " sync \n"
303#endif
304 " .set pop \n" 295 " .set pop \n"
305 : "=&r" (temp), "=m" (*m), "=&r" (res) 296 : "=&r" (temp), "=m" (*m), "=&r" (res)
306 : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) 297 : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
@@ -322,6 +313,8 @@ static inline int test_and_clear_bit(unsigned long nr,
322 313
323 return retval; 314 return retval;
324 } 315 }
316
317 smp_mb();
325} 318}
326 319
327/* 320/*
@@ -346,9 +339,6 @@ static inline int test_and_change_bit(unsigned long nr,
346 " " __SC "%2, %1 \n" 339 " " __SC "%2, %1 \n"
347 " beqzl %2, 1b \n" 340 " beqzl %2, 1b \n"
348 " and %2, %0, %3 \n" 341 " and %2, %0, %3 \n"
349#ifdef CONFIG_SMP
350 " sync \n"
351#endif
352 " .set mips0 \n" 342 " .set mips0 \n"
353 : "=&r" (temp), "=m" (*m), "=&r" (res) 343 : "=&r" (temp), "=m" (*m), "=&r" (res)
354 : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) 344 : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
@@ -368,9 +358,6 @@ static inline int test_and_change_bit(unsigned long nr,
368 " " __SC "\t%2, %1 \n" 358 " " __SC "\t%2, %1 \n"
369 " beqz %2, 1b \n" 359 " beqz %2, 1b \n"
370 " and %2, %0, %3 \n" 360 " and %2, %0, %3 \n"
371#ifdef CONFIG_SMP
372 " sync \n"
373#endif
374 " .set pop \n" 361 " .set pop \n"
375 : "=&r" (temp), "=m" (*m), "=&r" (res) 362 : "=&r" (temp), "=m" (*m), "=&r" (res)
376 : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m) 363 : "r" (1UL << (nr & SZLONG_MASK)), "m" (*m)
@@ -391,6 +378,8 @@ static inline int test_and_change_bit(unsigned long nr,
391 378
392 return retval; 379 return retval;
393 } 380 }
381
382 smp_mb();
394} 383}
395 384
396#include <asm-generic/bitops/non-atomic.h> 385#include <asm-generic/bitops/non-atomic.h>
diff --git a/include/asm-mips/compat.h b/include/asm-mips/compat.h
index 900f472fdd2b..55a0152feb08 100644
--- a/include/asm-mips/compat.h
+++ b/include/asm-mips/compat.h
@@ -32,6 +32,7 @@ typedef struct {
32 s32 val[2]; 32 s32 val[2];
33} compat_fsid_t; 33} compat_fsid_t;
34typedef s32 compat_timer_t; 34typedef s32 compat_timer_t;
35typedef s32 compat_key_t;
35 36
36typedef s32 compat_int_t; 37typedef s32 compat_int_t;
37typedef s32 compat_long_t; 38typedef s32 compat_long_t;
@@ -146,4 +147,71 @@ static inline void __user *compat_alloc_user_space(long len)
146 return (void __user *) (regs->regs[29] - len); 147 return (void __user *) (regs->regs[29] - len);
147} 148}
148 149
150struct compat_ipc64_perm {
151 compat_key_t key;
152 __compat_uid32_t uid;
153 __compat_gid32_t gid;
154 __compat_uid32_t cuid;
155 __compat_gid32_t cgid;
156 compat_mode_t mode;
157 unsigned short seq;
158 unsigned short __pad2;
159 compat_ulong_t __unused1;
160 compat_ulong_t __unused2;
161};
162
163struct compat_semid64_ds {
164 struct compat_ipc64_perm sem_perm;
165 compat_time_t sem_otime;
166 compat_time_t sem_ctime;
167 compat_ulong_t sem_nsems;
168 compat_ulong_t __unused1;
169 compat_ulong_t __unused2;
170};
171
172struct compat_msqid64_ds {
173 struct compat_ipc64_perm msg_perm;
174#ifndef CONFIG_CPU_LITTLE_ENDIAN
175 compat_ulong_t __unused1;
176#endif
177 compat_time_t msg_stime;
178#ifdef CONFIG_CPU_LITTLE_ENDIAN
179 compat_ulong_t __unused1;
180#endif
181#ifndef CONFIG_CPU_LITTLE_ENDIAN
182 compat_ulong_t __unused2;
183#endif
184 compat_time_t msg_rtime;
185#ifdef CONFIG_CPU_LITTLE_ENDIAN
186 compat_ulong_t __unused2;
187#endif
188#ifndef CONFIG_CPU_LITTLE_ENDIAN
189 compat_ulong_t __unused3;
190#endif
191 compat_time_t msg_ctime;
192#ifdef CONFIG_CPU_LITTLE_ENDIAN
193 compat_ulong_t __unused3;
194#endif
195 compat_ulong_t msg_cbytes;
196 compat_ulong_t msg_qnum;
197 compat_ulong_t msg_qbytes;
198 compat_pid_t msg_lspid;
199 compat_pid_t msg_lrpid;
200 compat_ulong_t __unused4;
201 compat_ulong_t __unused5;
202};
203
204struct compat_shmid64_ds {
205 struct compat_ipc64_perm shm_perm;
206 compat_size_t shm_segsz;
207 compat_time_t shm_atime;
208 compat_time_t shm_dtime;
209 compat_time_t shm_ctime;
210 compat_pid_t shm_cpid;
211 compat_pid_t shm_lpid;
212 compat_ulong_t shm_nattch;
213 compat_ulong_t __unused1;
214 compat_ulong_t __unused2;
215};
216
149#endif /* _ASM_COMPAT_H */ 217#endif /* _ASM_COMPAT_H */
diff --git a/include/asm-mips/futex.h b/include/asm-mips/futex.h
index ed023eae0674..927a216bd530 100644
--- a/include/asm-mips/futex.h
+++ b/include/asm-mips/futex.h
@@ -1,19 +1,21 @@
1/*
2 * This file is subject to the terms and conditions of the GNU General Public
3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details.
5 *
6 * Copyright (c) 2006 Ralf Baechle (ralf@linux-mips.org)
7 */
1#ifndef _ASM_FUTEX_H 8#ifndef _ASM_FUTEX_H
2#define _ASM_FUTEX_H 9#define _ASM_FUTEX_H
3 10
4#ifdef __KERNEL__ 11#ifdef __KERNEL__
5 12
6#include <linux/futex.h> 13#include <linux/futex.h>
14#include <asm/barrier.h>
7#include <asm/errno.h> 15#include <asm/errno.h>
8#include <asm/uaccess.h> 16#include <asm/uaccess.h>
9#include <asm/war.h> 17#include <asm/war.h>
10 18
11#ifdef CONFIG_SMP
12#define __FUTEX_SMP_SYNC " sync \n"
13#else
14#define __FUTEX_SMP_SYNC
15#endif
16
17#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \ 19#define __futex_atomic_op(insn, ret, oldval, uaddr, oparg) \
18{ \ 20{ \
19 if (cpu_has_llsc && R10000_LLSC_WAR) { \ 21 if (cpu_has_llsc && R10000_LLSC_WAR) { \
@@ -27,7 +29,7 @@
27 " .set mips3 \n" \ 29 " .set mips3 \n" \
28 "2: sc $1, %2 \n" \ 30 "2: sc $1, %2 \n" \
29 " beqzl $1, 1b \n" \ 31 " beqzl $1, 1b \n" \
30 __FUTEX_SMP_SYNC \ 32 __WEAK_ORDERING_MB \
31 "3: \n" \ 33 "3: \n" \
32 " .set pop \n" \ 34 " .set pop \n" \
33 " .set mips0 \n" \ 35 " .set mips0 \n" \
@@ -53,7 +55,7 @@
53 " .set mips3 \n" \ 55 " .set mips3 \n" \
54 "2: sc $1, %2 \n" \ 56 "2: sc $1, %2 \n" \
55 " beqz $1, 1b \n" \ 57 " beqz $1, 1b \n" \
56 __FUTEX_SMP_SYNC \ 58 __WEAK_ORDERING_MB \
57 "3: \n" \ 59 "3: \n" \
58 " .set pop \n" \ 60 " .set pop \n" \
59 " .set mips0 \n" \ 61 " .set mips0 \n" \
@@ -150,7 +152,7 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
150 " .set mips3 \n" 152 " .set mips3 \n"
151 "2: sc $1, %1 \n" 153 "2: sc $1, %1 \n"
152 " beqzl $1, 1b \n" 154 " beqzl $1, 1b \n"
153 __FUTEX_SMP_SYNC 155 __WEAK_ORDERING_MB
154 "3: \n" 156 "3: \n"
155 " .set pop \n" 157 " .set pop \n"
156 " .section .fixup,\"ax\" \n" 158 " .section .fixup,\"ax\" \n"
@@ -177,7 +179,7 @@ futex_atomic_cmpxchg_inatomic(int __user *uaddr, int oldval, int newval)
177 " .set mips3 \n" 179 " .set mips3 \n"
178 "2: sc $1, %1 \n" 180 "2: sc $1, %1 \n"
179 " beqz $1, 1b \n" 181 " beqz $1, 1b \n"
180 __FUTEX_SMP_SYNC 182 __WEAK_ORDERING_MB
181 "3: \n" 183 "3: \n"
182 " .set pop \n" 184 " .set pop \n"
183 " .section .fixup,\"ax\" \n" 185 " .section .fixup,\"ax\" \n"
diff --git a/include/asm-mips/sn/klconfig.h b/include/asm-mips/sn/klconfig.h
index b63cd0655b3d..15d70ca56187 100644
--- a/include/asm-mips/sn/klconfig.h
+++ b/include/asm-mips/sn/klconfig.h
@@ -176,7 +176,7 @@ typedef struct kl_config_hdr {
176/* --- New Macros for the changed kl_config_hdr_t structure --- */ 176/* --- New Macros for the changed kl_config_hdr_t structure --- */
177 177
178#define PTR_CH_MALLOC_HDR(_k) ((klc_malloc_hdr_t *)\ 178#define PTR_CH_MALLOC_HDR(_k) ((klc_malloc_hdr_t *)\
179 (unsigned long)_k + (_k->ch_malloc_hdr_off))) 179 ((unsigned long)_k + (_k->ch_malloc_hdr_off)))
180 180
181#define KL_CONFIG_CH_MALLOC_HDR(_n) PTR_CH_MALLOC_HDR(KL_CONFIG_HDR(_n)) 181#define KL_CONFIG_CH_MALLOC_HDR(_n) PTR_CH_MALLOC_HDR(KL_CONFIG_HDR(_n))
182 182
diff --git a/include/asm-mips/spinlock.h b/include/asm-mips/spinlock.h
index c8d5587467bb..fc3217fc1118 100644
--- a/include/asm-mips/spinlock.h
+++ b/include/asm-mips/spinlock.h
@@ -3,12 +3,13 @@
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 1999, 2000 by Ralf Baechle 6 * Copyright (C) 1999, 2000, 06 by Ralf Baechle
7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc. 7 * Copyright (C) 1999, 2000 Silicon Graphics, Inc.
8 */ 8 */
9#ifndef _ASM_SPINLOCK_H 9#ifndef _ASM_SPINLOCK_H
10#define _ASM_SPINLOCK_H 10#define _ASM_SPINLOCK_H
11 11
12#include <asm/barrier.h>
12#include <asm/war.h> 13#include <asm/war.h>
13 14
14/* 15/*
@@ -40,7 +41,6 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock)
40 " sc %1, %0 \n" 41 " sc %1, %0 \n"
41 " beqzl %1, 1b \n" 42 " beqzl %1, 1b \n"
42 " nop \n" 43 " nop \n"
43 " sync \n"
44 " .set reorder \n" 44 " .set reorder \n"
45 : "=m" (lock->lock), "=&r" (tmp) 45 : "=m" (lock->lock), "=&r" (tmp)
46 : "m" (lock->lock) 46 : "m" (lock->lock)
@@ -53,19 +53,22 @@ static inline void __raw_spin_lock(raw_spinlock_t *lock)
53 " li %1, 1 \n" 53 " li %1, 1 \n"
54 " sc %1, %0 \n" 54 " sc %1, %0 \n"
55 " beqz %1, 1b \n" 55 " beqz %1, 1b \n"
56 " sync \n" 56 " nop \n"
57 " .set reorder \n" 57 " .set reorder \n"
58 : "=m" (lock->lock), "=&r" (tmp) 58 : "=m" (lock->lock), "=&r" (tmp)
59 : "m" (lock->lock) 59 : "m" (lock->lock)
60 : "memory"); 60 : "memory");
61 } 61 }
62
63 smp_mb();
62} 64}
63 65
64static inline void __raw_spin_unlock(raw_spinlock_t *lock) 66static inline void __raw_spin_unlock(raw_spinlock_t *lock)
65{ 67{
68 smp_mb();
69
66 __asm__ __volatile__( 70 __asm__ __volatile__(
67 " .set noreorder # __raw_spin_unlock \n" 71 " .set noreorder # __raw_spin_unlock \n"
68 " sync \n"
69 " sw $0, %0 \n" 72 " sw $0, %0 \n"
70 " .set\treorder \n" 73 " .set\treorder \n"
71 : "=m" (lock->lock) 74 : "=m" (lock->lock)
@@ -86,7 +89,6 @@ static inline unsigned int __raw_spin_trylock(raw_spinlock_t *lock)
86 " beqzl %2, 1b \n" 89 " beqzl %2, 1b \n"
87 " nop \n" 90 " nop \n"
88 " andi %2, %0, 1 \n" 91 " andi %2, %0, 1 \n"
89 " sync \n"
90 " .set reorder" 92 " .set reorder"
91 : "=&r" (temp), "=m" (lock->lock), "=&r" (res) 93 : "=&r" (temp), "=m" (lock->lock), "=&r" (res)
92 : "m" (lock->lock) 94 : "m" (lock->lock)
@@ -99,13 +101,14 @@ static inline unsigned int __raw_spin_trylock(raw_spinlock_t *lock)
99 " sc %2, %1 \n" 101 " sc %2, %1 \n"
100 " beqz %2, 1b \n" 102 " beqz %2, 1b \n"
101 " andi %2, %0, 1 \n" 103 " andi %2, %0, 1 \n"
102 " sync \n"
103 " .set reorder" 104 " .set reorder"
104 : "=&r" (temp), "=m" (lock->lock), "=&r" (res) 105 : "=&r" (temp), "=m" (lock->lock), "=&r" (res)
105 : "m" (lock->lock) 106 : "m" (lock->lock)
106 : "memory"); 107 : "memory");
107 } 108 }
108 109
110 smp_mb();
111
109 return res == 0; 112 return res == 0;
110} 113}
111 114
@@ -143,7 +146,6 @@ static inline void __raw_read_lock(raw_rwlock_t *rw)
143 " sc %1, %0 \n" 146 " sc %1, %0 \n"
144 " beqzl %1, 1b \n" 147 " beqzl %1, 1b \n"
145 " nop \n" 148 " nop \n"
146 " sync \n"
147 " .set reorder \n" 149 " .set reorder \n"
148 : "=m" (rw->lock), "=&r" (tmp) 150 : "=m" (rw->lock), "=&r" (tmp)
149 : "m" (rw->lock) 151 : "m" (rw->lock)
@@ -156,12 +158,14 @@ static inline void __raw_read_lock(raw_rwlock_t *rw)
156 " addu %1, 1 \n" 158 " addu %1, 1 \n"
157 " sc %1, %0 \n" 159 " sc %1, %0 \n"
158 " beqz %1, 1b \n" 160 " beqz %1, 1b \n"
159 " sync \n" 161 " nop \n"
160 " .set reorder \n" 162 " .set reorder \n"
161 : "=m" (rw->lock), "=&r" (tmp) 163 : "=m" (rw->lock), "=&r" (tmp)
162 : "m" (rw->lock) 164 : "m" (rw->lock)
163 : "memory"); 165 : "memory");
164 } 166 }
167
168 smp_mb();
165} 169}
166 170
167/* Note the use of sub, not subu which will make the kernel die with an 171/* Note the use of sub, not subu which will make the kernel die with an
@@ -171,13 +175,14 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw)
171{ 175{
172 unsigned int tmp; 176 unsigned int tmp;
173 177
178 smp_mb();
179
174 if (R10000_LLSC_WAR) { 180 if (R10000_LLSC_WAR) {
175 __asm__ __volatile__( 181 __asm__ __volatile__(
176 "1: ll %1, %2 # __raw_read_unlock \n" 182 "1: ll %1, %2 # __raw_read_unlock \n"
177 " sub %1, 1 \n" 183 " sub %1, 1 \n"
178 " sc %1, %0 \n" 184 " sc %1, %0 \n"
179 " beqzl %1, 1b \n" 185 " beqzl %1, 1b \n"
180 " sync \n"
181 : "=m" (rw->lock), "=&r" (tmp) 186 : "=m" (rw->lock), "=&r" (tmp)
182 : "m" (rw->lock) 187 : "m" (rw->lock)
183 : "memory"); 188 : "memory");
@@ -188,7 +193,7 @@ static inline void __raw_read_unlock(raw_rwlock_t *rw)
188 " sub %1, 1 \n" 193 " sub %1, 1 \n"
189 " sc %1, %0 \n" 194 " sc %1, %0 \n"
190 " beqz %1, 1b \n" 195 " beqz %1, 1b \n"
191 " sync \n" 196 " nop \n"
192 " .set reorder \n" 197 " .set reorder \n"
193 : "=m" (rw->lock), "=&r" (tmp) 198 : "=m" (rw->lock), "=&r" (tmp)
194 : "m" (rw->lock) 199 : "m" (rw->lock)
@@ -208,7 +213,7 @@ static inline void __raw_write_lock(raw_rwlock_t *rw)
208 " lui %1, 0x8000 \n" 213 " lui %1, 0x8000 \n"
209 " sc %1, %0 \n" 214 " sc %1, %0 \n"
210 " beqzl %1, 1b \n" 215 " beqzl %1, 1b \n"
211 " sync \n" 216 " nop \n"
212 " .set reorder \n" 217 " .set reorder \n"
213 : "=m" (rw->lock), "=&r" (tmp) 218 : "=m" (rw->lock), "=&r" (tmp)
214 : "m" (rw->lock) 219 : "m" (rw->lock)
@@ -221,18 +226,22 @@ static inline void __raw_write_lock(raw_rwlock_t *rw)
221 " lui %1, 0x8000 \n" 226 " lui %1, 0x8000 \n"
222 " sc %1, %0 \n" 227 " sc %1, %0 \n"
223 " beqz %1, 1b \n" 228 " beqz %1, 1b \n"
224 " sync \n" 229 " nop \n"
225 " .set reorder \n" 230 " .set reorder \n"
226 : "=m" (rw->lock), "=&r" (tmp) 231 : "=m" (rw->lock), "=&r" (tmp)
227 : "m" (rw->lock) 232 : "m" (rw->lock)
228 : "memory"); 233 : "memory");
229 } 234 }
235
236 smp_mb();
230} 237}
231 238
232static inline void __raw_write_unlock(raw_rwlock_t *rw) 239static inline void __raw_write_unlock(raw_rwlock_t *rw)
233{ 240{
241 smp_mb();
242
234 __asm__ __volatile__( 243 __asm__ __volatile__(
235 " sync # __raw_write_unlock \n" 244 " # __raw_write_unlock \n"
236 " sw $0, %0 \n" 245 " sw $0, %0 \n"
237 : "=m" (rw->lock) 246 : "=m" (rw->lock)
238 : "m" (rw->lock) 247 : "m" (rw->lock)
@@ -252,11 +261,10 @@ static inline int __raw_read_trylock(raw_rwlock_t *rw)
252 " bnez %1, 2f \n" 261 " bnez %1, 2f \n"
253 " addu %1, 1 \n" 262 " addu %1, 1 \n"
254 " sc %1, %0 \n" 263 " sc %1, %0 \n"
255 " beqzl %1, 1b \n"
256 " .set reorder \n" 264 " .set reorder \n"
257#ifdef CONFIG_SMP 265 " beqzl %1, 1b \n"
258 " sync \n" 266 " nop \n"
259#endif 267 __WEAK_ORDERING_MB
260 " li %2, 1 \n" 268 " li %2, 1 \n"
261 "2: \n" 269 "2: \n"
262 : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) 270 : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret)
@@ -271,10 +279,9 @@ static inline int __raw_read_trylock(raw_rwlock_t *rw)
271 " addu %1, 1 \n" 279 " addu %1, 1 \n"
272 " sc %1, %0 \n" 280 " sc %1, %0 \n"
273 " beqz %1, 1b \n" 281 " beqz %1, 1b \n"
282 " nop \n"
274 " .set reorder \n" 283 " .set reorder \n"
275#ifdef CONFIG_SMP 284 __WEAK_ORDERING_MB
276 " sync \n"
277#endif
278 " li %2, 1 \n" 285 " li %2, 1 \n"
279 "2: \n" 286 "2: \n"
280 : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret) 287 : "=m" (rw->lock), "=&r" (tmp), "=&r" (ret)
@@ -299,7 +306,8 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
299 " lui %1, 0x8000 \n" 306 " lui %1, 0x8000 \n"
300 " sc %1, %0 \n" 307 " sc %1, %0 \n"
301 " beqzl %1, 1b \n" 308 " beqzl %1, 1b \n"
302 " sync \n" 309 " nop \n"
310 __WEAK_ORDERING_MB
303 " li %2, 1 \n" 311 " li %2, 1 \n"
304 " .set reorder \n" 312 " .set reorder \n"
305 "2: \n" 313 "2: \n"
@@ -315,7 +323,8 @@ static inline int __raw_write_trylock(raw_rwlock_t *rw)
315 " lui %1, 0x8000 \n" 323 " lui %1, 0x8000 \n"
316 " sc %1, %0 \n" 324 " sc %1, %0 \n"
317 " beqz %1, 1b \n" 325 " beqz %1, 1b \n"
318 " sync \n" 326 " nop \n"
327 __WEAK_ORDERING_MB
319 " li %2, 1 \n" 328 " li %2, 1 \n"
320 " .set reorder \n" 329 " .set reorder \n"
321 "2: \n" 330 "2: \n"
diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h
index 3056feed5a36..9428057a50cf 100644
--- a/include/asm-mips/system.h
+++ b/include/asm-mips/system.h
@@ -3,7 +3,7 @@
3 * License. See the file "COPYING" in the main directory of this archive 3 * License. See the file "COPYING" in the main directory of this archive
4 * for more details. 4 * for more details.
5 * 5 *
6 * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003 by Ralf Baechle 6 * Copyright (C) 1994, 95, 96, 97, 98, 99, 2003, 06 by Ralf Baechle
7 * Copyright (C) 1996 by Paul M. Antoine 7 * Copyright (C) 1996 by Paul M. Antoine
8 * Copyright (C) 1999 Silicon Graphics 8 * Copyright (C) 1999 Silicon Graphics
9 * Kevin D. Kissell, kevink@mips.org and Carsten Langgaard, carstenl@mips.com 9 * Kevin D. Kissell, kevink@mips.org and Carsten Langgaard, carstenl@mips.com
@@ -16,132 +16,12 @@
16#include <linux/irqflags.h> 16#include <linux/irqflags.h>
17 17
18#include <asm/addrspace.h> 18#include <asm/addrspace.h>
19#include <asm/barrier.h>
19#include <asm/cpu-features.h> 20#include <asm/cpu-features.h>
20#include <asm/dsp.h> 21#include <asm/dsp.h>
21#include <asm/ptrace.h> 22#include <asm/ptrace.h>
22#include <asm/war.h> 23#include <asm/war.h>
23 24
24/*
25 * read_barrier_depends - Flush all pending reads that subsequents reads
26 * depend on.
27 *
28 * No data-dependent reads from memory-like regions are ever reordered
29 * over this barrier. All reads preceding this primitive are guaranteed
30 * to access memory (but not necessarily other CPUs' caches) before any
31 * reads following this primitive that depend on the data return by
32 * any of the preceding reads. This primitive is much lighter weight than
33 * rmb() on most CPUs, and is never heavier weight than is
34 * rmb().
35 *
36 * These ordering constraints are respected by both the local CPU
37 * and the compiler.
38 *
39 * Ordering is not guaranteed by anything other than these primitives,
40 * not even by data dependencies. See the documentation for
41 * memory_barrier() for examples and URLs to more information.
42 *
43 * For example, the following code would force ordering (the initial
44 * value of "a" is zero, "b" is one, and "p" is "&a"):
45 *
46 * <programlisting>
47 * CPU 0 CPU 1
48 *
49 * b = 2;
50 * memory_barrier();
51 * p = &b; q = p;
52 * read_barrier_depends();
53 * d = *q;
54 * </programlisting>
55 *
56 * because the read of "*q" depends on the read of "p" and these
57 * two reads are separated by a read_barrier_depends(). However,
58 * the following code, with the same initial values for "a" and "b":
59 *
60 * <programlisting>
61 * CPU 0 CPU 1
62 *
63 * a = 2;
64 * memory_barrier();
65 * b = 3; y = b;
66 * read_barrier_depends();
67 * x = a;
68 * </programlisting>
69 *
70 * does not enforce ordering, since there is no data dependency between
71 * the read of "a" and the read of "b". Therefore, on some CPUs, such
72 * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb()
73 * in cases like this where there are no data dependencies.
74 */
75
76#define read_barrier_depends() do { } while(0)
77
78#ifdef CONFIG_CPU_HAS_SYNC
79#define __sync() \
80 __asm__ __volatile__( \
81 ".set push\n\t" \
82 ".set noreorder\n\t" \
83 ".set mips2\n\t" \
84 "sync\n\t" \
85 ".set pop" \
86 : /* no output */ \
87 : /* no input */ \
88 : "memory")
89#else
90#define __sync() do { } while(0)
91#endif
92
93#define __fast_iob() \
94 __asm__ __volatile__( \
95 ".set push\n\t" \
96 ".set noreorder\n\t" \
97 "lw $0,%0\n\t" \
98 "nop\n\t" \
99 ".set pop" \
100 : /* no output */ \
101 : "m" (*(int *)CKSEG1) \
102 : "memory")
103
104#define fast_wmb() __sync()
105#define fast_rmb() __sync()
106#define fast_mb() __sync()
107#define fast_iob() \
108 do { \
109 __sync(); \
110 __fast_iob(); \
111 } while (0)
112
113#ifdef CONFIG_CPU_HAS_WB
114
115#include <asm/wbflush.h>
116
117#define wmb() fast_wmb()
118#define rmb() fast_rmb()
119#define mb() wbflush()
120#define iob() wbflush()
121
122#else /* !CONFIG_CPU_HAS_WB */
123
124#define wmb() fast_wmb()
125#define rmb() fast_rmb()
126#define mb() fast_mb()
127#define iob() fast_iob()
128
129#endif /* !CONFIG_CPU_HAS_WB */
130
131#ifdef CONFIG_SMP
132#define smp_mb() mb()
133#define smp_rmb() rmb()
134#define smp_wmb() wmb()
135#define smp_read_barrier_depends() read_barrier_depends()
136#else
137#define smp_mb() barrier()
138#define smp_rmb() barrier()
139#define smp_wmb() barrier()
140#define smp_read_barrier_depends() do { } while(0)
141#endif
142
143#define set_mb(var, value) \
144do { var = value; mb(); } while (0)
145 25
146/* 26/*
147 * switch_to(n) should switch tasks to task nr n, first 27 * switch_to(n) should switch tasks to task nr n, first
@@ -217,9 +97,6 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
217 " .set mips3 \n" 97 " .set mips3 \n"
218 " sc %2, %1 \n" 98 " sc %2, %1 \n"
219 " beqzl %2, 1b \n" 99 " beqzl %2, 1b \n"
220#ifdef CONFIG_SMP
221 " sync \n"
222#endif
223 " .set mips0 \n" 100 " .set mips0 \n"
224 : "=&r" (retval), "=m" (*m), "=&r" (dummy) 101 : "=&r" (retval), "=m" (*m), "=&r" (dummy)
225 : "R" (*m), "Jr" (val) 102 : "R" (*m), "Jr" (val)
@@ -235,9 +112,6 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
235 " .set mips3 \n" 112 " .set mips3 \n"
236 " sc %2, %1 \n" 113 " sc %2, %1 \n"
237 " beqz %2, 1b \n" 114 " beqz %2, 1b \n"
238#ifdef CONFIG_SMP
239 " sync \n"
240#endif
241 " .set mips0 \n" 115 " .set mips0 \n"
242 : "=&r" (retval), "=m" (*m), "=&r" (dummy) 116 : "=&r" (retval), "=m" (*m), "=&r" (dummy)
243 : "R" (*m), "Jr" (val) 117 : "R" (*m), "Jr" (val)
@@ -251,6 +125,8 @@ static inline unsigned long __xchg_u32(volatile int * m, unsigned int val)
251 local_irq_restore(flags); /* implies memory barrier */ 125 local_irq_restore(flags); /* implies memory barrier */
252 } 126 }
253 127
128 smp_mb();
129
254 return retval; 130 return retval;
255} 131}
256 132
@@ -268,9 +144,6 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
268 " move %2, %z4 \n" 144 " move %2, %z4 \n"
269 " scd %2, %1 \n" 145 " scd %2, %1 \n"
270 " beqzl %2, 1b \n" 146 " beqzl %2, 1b \n"
271#ifdef CONFIG_SMP
272 " sync \n"
273#endif
274 " .set mips0 \n" 147 " .set mips0 \n"
275 : "=&r" (retval), "=m" (*m), "=&r" (dummy) 148 : "=&r" (retval), "=m" (*m), "=&r" (dummy)
276 : "R" (*m), "Jr" (val) 149 : "R" (*m), "Jr" (val)
@@ -284,9 +157,6 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
284 " move %2, %z4 \n" 157 " move %2, %z4 \n"
285 " scd %2, %1 \n" 158 " scd %2, %1 \n"
286 " beqz %2, 1b \n" 159 " beqz %2, 1b \n"
287#ifdef CONFIG_SMP
288 " sync \n"
289#endif
290 " .set mips0 \n" 160 " .set mips0 \n"
291 : "=&r" (retval), "=m" (*m), "=&r" (dummy) 161 : "=&r" (retval), "=m" (*m), "=&r" (dummy)
292 : "R" (*m), "Jr" (val) 162 : "R" (*m), "Jr" (val)
@@ -300,6 +170,8 @@ static inline __u64 __xchg_u64(volatile __u64 * m, __u64 val)
300 local_irq_restore(flags); /* implies memory barrier */ 170 local_irq_restore(flags); /* implies memory barrier */
301 } 171 }
302 172
173 smp_mb();
174
303 return retval; 175 return retval;
304} 176}
305#else 177#else
@@ -345,9 +217,6 @@ static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old,
345 " .set mips3 \n" 217 " .set mips3 \n"
346 " sc $1, %1 \n" 218 " sc $1, %1 \n"
347 " beqzl $1, 1b \n" 219 " beqzl $1, 1b \n"
348#ifdef CONFIG_SMP
349 " sync \n"
350#endif
351 "2: \n" 220 "2: \n"
352 " .set pop \n" 221 " .set pop \n"
353 : "=&r" (retval), "=R" (*m) 222 : "=&r" (retval), "=R" (*m)
@@ -365,9 +234,6 @@ static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old,
365 " .set mips3 \n" 234 " .set mips3 \n"
366 " sc $1, %1 \n" 235 " sc $1, %1 \n"
367 " beqz $1, 1b \n" 236 " beqz $1, 1b \n"
368#ifdef CONFIG_SMP
369 " sync \n"
370#endif
371 "2: \n" 237 "2: \n"
372 " .set pop \n" 238 " .set pop \n"
373 : "=&r" (retval), "=R" (*m) 239 : "=&r" (retval), "=R" (*m)
@@ -383,6 +249,8 @@ static inline unsigned long __cmpxchg_u32(volatile int * m, unsigned long old,
383 local_irq_restore(flags); /* implies memory barrier */ 249 local_irq_restore(flags); /* implies memory barrier */
384 } 250 }
385 251
252 smp_mb();
253
386 return retval; 254 return retval;
387} 255}
388 256
@@ -402,9 +270,6 @@ static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old,
402 " move $1, %z4 \n" 270 " move $1, %z4 \n"
403 " scd $1, %1 \n" 271 " scd $1, %1 \n"
404 " beqzl $1, 1b \n" 272 " beqzl $1, 1b \n"
405#ifdef CONFIG_SMP
406 " sync \n"
407#endif
408 "2: \n" 273 "2: \n"
409 " .set pop \n" 274 " .set pop \n"
410 : "=&r" (retval), "=R" (*m) 275 : "=&r" (retval), "=R" (*m)
@@ -420,9 +285,6 @@ static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old,
420 " move $1, %z4 \n" 285 " move $1, %z4 \n"
421 " scd $1, %1 \n" 286 " scd $1, %1 \n"
422 " beqz $1, 1b \n" 287 " beqz $1, 1b \n"
423#ifdef CONFIG_SMP
424 " sync \n"
425#endif
426 "2: \n" 288 "2: \n"
427 " .set pop \n" 289 " .set pop \n"
428 : "=&r" (retval), "=R" (*m) 290 : "=&r" (retval), "=R" (*m)
@@ -438,6 +300,8 @@ static inline unsigned long __cmpxchg_u64(volatile int * m, unsigned long old,
438 local_irq_restore(flags); /* implies memory barrier */ 300 local_irq_restore(flags); /* implies memory barrier */
439 } 301 }
440 302
303 smp_mb();
304
441 return retval; 305 return retval;
442} 306}
443#else 307#else
diff --git a/include/asm-mips/types.h b/include/asm-mips/types.h
index 2b52e180c6f2..63a13c5bd832 100644
--- a/include/asm-mips/types.h
+++ b/include/asm-mips/types.h
@@ -93,16 +93,6 @@ typedef unsigned long long phys_t;
93typedef unsigned long phys_t; 93typedef unsigned long phys_t;
94#endif 94#endif
95 95
96#ifdef CONFIG_LBD
97typedef u64 sector_t;
98#define HAVE_SECTOR_T
99#endif
100
101#ifdef CONFIG_LSF
102typedef u64 blkcnt_t;
103#define HAVE_BLKCNT_T
104#endif
105
106#endif /* __ASSEMBLY__ */ 96#endif /* __ASSEMBLY__ */
107 97
108#endif /* __KERNEL__ */ 98#endif /* __KERNEL__ */
diff --git a/include/asm-powerpc/Kbuild b/include/asm-powerpc/Kbuild
index 9827849953a3..1e637381c118 100644
--- a/include/asm-powerpc/Kbuild
+++ b/include/asm-powerpc/Kbuild
@@ -17,6 +17,7 @@ header-y += ipc.h
17header-y += poll.h 17header-y += poll.h
18header-y += shmparam.h 18header-y += shmparam.h
19header-y += sockios.h 19header-y += sockios.h
20header-y += spu_info.h
20header-y += ucontext.h 21header-y += ucontext.h
21header-y += ioctl.h 22header-y += ioctl.h
22header-y += linkage.h 23header-y += linkage.h
diff --git a/include/asm-powerpc/cell-pmu.h b/include/asm-powerpc/cell-pmu.h
new file mode 100644
index 000000000000..e8c2ebd3ddda
--- /dev/null
+++ b/include/asm-powerpc/cell-pmu.h
@@ -0,0 +1,113 @@
1/*
2 * Cell Broadband Engine Performance Monitor
3 *
4 * (C) Copyright IBM Corporation 2006
5 *
6 * Author:
7 * David Erb (djerb@us.ibm.com)
8 * Kevin Corry (kevcorry@us.ibm.com)
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2, or (at your option)
13 * any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
23 */
24
25#ifndef __ASM_CELL_PMU_H__
26#define __ASM_CELL_PMU_H__
27
28/* The Cell PMU has four hardware performance counters, which can be
29 * configured as four 32-bit counters or eight 16-bit counters.
30 */
31#define NR_PHYS_CTRS 4
32#define NR_CTRS (NR_PHYS_CTRS * 2)
33
34/* Macros for the pm_control register. */
35#define CBE_PM_16BIT_CTR(ctr) (1 << (24 - ((ctr) & (NR_PHYS_CTRS - 1))))
36#define CBE_PM_ENABLE_PERF_MON 0x80000000
37#define CBE_PM_STOP_AT_MAX 0x40000000
38#define CBE_PM_TRACE_MODE_GET(pm_control) (((pm_control) >> 28) & 0x3)
39#define CBE_PM_TRACE_MODE_SET(mode) (((mode) & 0x3) << 28)
40#define CBE_PM_COUNT_MODE_SET(count) (((count) & 0x3) << 18)
41#define CBE_PM_FREEZE_ALL_CTRS 0x00100000
42#define CBE_PM_ENABLE_EXT_TRACE 0x00008000
43
44/* Macros for the trace_address register. */
45#define CBE_PM_TRACE_BUF_FULL 0x00000800
46#define CBE_PM_TRACE_BUF_EMPTY 0x00000400
47#define CBE_PM_TRACE_BUF_DATA_COUNT(ta) ((ta) & 0x3ff)
48#define CBE_PM_TRACE_BUF_MAX_COUNT 0x400
49
50/* Macros for the pm07_control registers. */
51#define CBE_PM_CTR_INPUT_MUX(pm07_control) (((pm07_control) >> 26) & 0x3f)
52#define CBE_PM_CTR_INPUT_CONTROL 0x02000000
53#define CBE_PM_CTR_POLARITY 0x01000000
54#define CBE_PM_CTR_COUNT_CYCLES 0x00800000
55#define CBE_PM_CTR_ENABLE 0x00400000
56
57/* Macros for the pm_status register. */
58#define CBE_PM_CTR_OVERFLOW_INTR(ctr) (1 << (31 - ((ctr) & 7)))
59
60enum pm_reg_name {
61 group_control,
62 debug_bus_control,
63 trace_address,
64 ext_tr_timer,
65 pm_status,
66 pm_control,
67 pm_interval,
68 pm_start_stop,
69};
70
71/* Routines for reading/writing the PMU registers. */
72extern u32 cbe_read_phys_ctr(u32 cpu, u32 phys_ctr);
73extern void cbe_write_phys_ctr(u32 cpu, u32 phys_ctr, u32 val);
74extern u32 cbe_read_ctr(u32 cpu, u32 ctr);
75extern void cbe_write_ctr(u32 cpu, u32 ctr, u32 val);
76
77extern u32 cbe_read_pm07_control(u32 cpu, u32 ctr);
78extern void cbe_write_pm07_control(u32 cpu, u32 ctr, u32 val);
79extern u32 cbe_read_pm(u32 cpu, enum pm_reg_name reg);
80extern void cbe_write_pm(u32 cpu, enum pm_reg_name reg, u32 val);
81
82extern u32 cbe_get_ctr_size(u32 cpu, u32 phys_ctr);
83extern void cbe_set_ctr_size(u32 cpu, u32 phys_ctr, u32 ctr_size);
84
85extern void cbe_enable_pm(u32 cpu);
86extern void cbe_disable_pm(u32 cpu);
87
88extern void cbe_read_trace_buffer(u32 cpu, u64 *buf);
89
90extern void cbe_enable_pm_interrupts(u32 cpu, u32 thread, u32 mask);
91extern void cbe_disable_pm_interrupts(u32 cpu);
92extern u32 cbe_query_pm_interrupts(u32 cpu);
93extern u32 cbe_clear_pm_interrupts(u32 cpu);
94extern void cbe_sync_irq(int node);
95
96/* Utility functions, macros */
97extern u32 cbe_get_hw_thread_id(int cpu);
98
99#define cbe_cpu_to_node(cpu) ((cpu) >> 1)
100
101#define CBE_COUNT_SUPERVISOR_MODE 0
102#define CBE_COUNT_HYPERVISOR_MODE 1
103#define CBE_COUNT_PROBLEM_MODE 2
104#define CBE_COUNT_ALL_MODES 3
105
106/* Macros for the pm07_control registers. */
107#define PM07_CTR_INPUT_MUX(x) (((x) & 0x3F) << 26)
108#define PM07_CTR_INPUT_CONTROL(x) (((x) & 1) << 25)
109#define PM07_CTR_POLARITY(x) (((x) & 1) << 24)
110#define PM07_CTR_COUNT_CYCLES(x) (((x) & 1) << 23)
111#define PM07_CTR_ENABLE(x) (((x) & 1) << 22)
112
113#endif /* __ASM_CELL_PMU_H__ */
diff --git a/include/asm-powerpc/cputable.h b/include/asm-powerpc/cputable.h
index a9a40149a7c0..6fe5c9d4ca3b 100644
--- a/include/asm-powerpc/cputable.h
+++ b/include/asm-powerpc/cputable.h
@@ -24,6 +24,8 @@
24#define PPC_FEATURE_ICACHE_SNOOP 0x00002000 24#define PPC_FEATURE_ICACHE_SNOOP 0x00002000
25#define PPC_FEATURE_ARCH_2_05 0x00001000 25#define PPC_FEATURE_ARCH_2_05 0x00001000
26#define PPC_FEATURE_PA6T 0x00000800 26#define PPC_FEATURE_PA6T 0x00000800
27#define PPC_FEATURE_HAS_DFP 0x00000400
28#define PPC_FEATURE_POWER6_EXT 0x00000200
27 29
28#define PPC_FEATURE_TRUE_LE 0x00000002 30#define PPC_FEATURE_TRUE_LE 0x00000002
29#define PPC_FEATURE_PPC_LE 0x00000001 31#define PPC_FEATURE_PPC_LE 0x00000001
@@ -45,6 +47,7 @@ enum powerpc_oprofile_type {
45 PPC_OPROFILE_POWER4 = 2, 47 PPC_OPROFILE_POWER4 = 2,
46 PPC_OPROFILE_G4 = 3, 48 PPC_OPROFILE_G4 = 3,
47 PPC_OPROFILE_BOOKE = 4, 49 PPC_OPROFILE_BOOKE = 4,
50 PPC_OPROFILE_CELL = 5,
48}; 51};
49 52
50struct cpu_spec { 53struct cpu_spec {
@@ -91,7 +94,7 @@ extern struct cpu_spec *cur_cpu_spec;
91 94
92extern unsigned int __start___ftr_fixup, __stop___ftr_fixup; 95extern unsigned int __start___ftr_fixup, __stop___ftr_fixup;
93 96
94extern struct cpu_spec *identify_cpu(unsigned long offset); 97extern struct cpu_spec *identify_cpu(unsigned long offset, unsigned int pvr);
95extern void do_feature_fixups(unsigned long value, void *fixup_start, 98extern void do_feature_fixups(unsigned long value, void *fixup_start,
96 void *fixup_end); 99 void *fixup_end);
97 100
@@ -148,19 +151,13 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start,
148#define CPU_FTR_PAUSE_ZERO LONG_ASM_CONST(0x0000200000000000) 151#define CPU_FTR_PAUSE_ZERO LONG_ASM_CONST(0x0000200000000000)
149#define CPU_FTR_PURR LONG_ASM_CONST(0x0000400000000000) 152#define CPU_FTR_PURR LONG_ASM_CONST(0x0000400000000000)
150#define CPU_FTR_CELL_TB_BUG LONG_ASM_CONST(0x0000800000000000) 153#define CPU_FTR_CELL_TB_BUG LONG_ASM_CONST(0x0000800000000000)
154#define CPU_FTR_SPURR LONG_ASM_CONST(0x0001000000000000)
151 155
152#ifndef __ASSEMBLY__ 156#ifndef __ASSEMBLY__
153 157
154#define CPU_FTR_PPCAS_ARCH_V2_BASE (CPU_FTR_SLB | \ 158#define CPU_FTR_PPCAS_ARCH_V2 (CPU_FTR_SLB | \
155 CPU_FTR_TLBIEL | CPU_FTR_NOEXECUTE | \ 159 CPU_FTR_TLBIEL | CPU_FTR_NOEXECUTE | \
156 CPU_FTR_NODSISRALIGN) 160 CPU_FTR_NODSISRALIGN | CPU_FTR_16M_PAGE)
157
158/* iSeries doesn't support large pages */
159#ifdef CONFIG_PPC_ISERIES
160#define CPU_FTR_PPCAS_ARCH_V2 (CPU_FTR_PPCAS_ARCH_V2_BASE)
161#else
162#define CPU_FTR_PPCAS_ARCH_V2 (CPU_FTR_PPCAS_ARCH_V2_BASE | CPU_FTR_16M_PAGE)
163#endif /* CONFIG_PPC_ISERIES */
164 161
165/* We only set the altivec features if the kernel was compiled with altivec 162/* We only set the altivec features if the kernel was compiled with altivec
166 * support 163 * support
@@ -311,7 +308,8 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start,
311#define CPU_FTRS_E500_2 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ 308#define CPU_FTRS_E500_2 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
312 CPU_FTR_BIG_PHYS | CPU_FTR_NODSISRALIGN) 309 CPU_FTR_BIG_PHYS | CPU_FTR_NODSISRALIGN)
313#define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN) 310#define CPU_FTRS_GENERIC_32 (CPU_FTR_COMMON | CPU_FTR_NODSISRALIGN)
314#ifdef __powerpc64__ 311
312/* 64-bit CPUs */
315#define CPU_FTRS_POWER3 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ 313#define CPU_FTRS_POWER3 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
316 CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | CPU_FTR_PPC_LE) 314 CPU_FTR_HPTE_TABLE | CPU_FTR_IABR | CPU_FTR_PPC_LE)
317#define CPU_FTRS_RS64 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ 315#define CPU_FTRS_RS64 (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
@@ -332,7 +330,13 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start,
332 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ 330 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
333 CPU_FTR_MMCRA | CPU_FTR_SMT | \ 331 CPU_FTR_MMCRA | CPU_FTR_SMT | \
334 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \ 332 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
335 CPU_FTR_PURR | CPU_FTR_CI_LARGE_PAGE | CPU_FTR_REAL_LE) 333 CPU_FTR_PURR | CPU_FTR_SPURR | CPU_FTR_REAL_LE)
334#define CPU_FTRS_POWER6X (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
335 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
336 CPU_FTR_MMCRA | CPU_FTR_SMT | \
337 CPU_FTR_COHERENT_ICACHE | CPU_FTR_LOCKLESS_TLBIE | \
338 CPU_FTR_PURR | CPU_FTR_CI_LARGE_PAGE | \
339 CPU_FTR_SPURR | CPU_FTR_REAL_LE)
336#define CPU_FTRS_CELL (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ 340#define CPU_FTRS_CELL (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
337 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \ 341 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2 | CPU_FTR_CTRL | \
338 CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \ 342 CPU_FTR_ALTIVEC_COMP | CPU_FTR_MMCRA | CPU_FTR_SMT | \
@@ -343,7 +347,6 @@ extern void do_feature_fixups(unsigned long value, void *fixup_start,
343 CPU_FTR_PURR | CPU_FTR_REAL_LE) 347 CPU_FTR_PURR | CPU_FTR_REAL_LE)
344#define CPU_FTRS_COMPATIBLE (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \ 348#define CPU_FTRS_COMPATIBLE (CPU_FTR_SPLIT_ID_CACHE | CPU_FTR_USE_TB | \
345 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2) 349 CPU_FTR_HPTE_TABLE | CPU_FTR_PPCAS_ARCH_V2)
346#endif
347 350
348#ifdef __powerpc64__ 351#ifdef __powerpc64__
349#define CPU_FTRS_POSSIBLE \ 352#define CPU_FTRS_POSSIBLE \
diff --git a/include/asm-powerpc/dbdma.h b/include/asm-powerpc/dbdma.h
index 8973565f95d3..e23f07e73cb3 100644
--- a/include/asm-powerpc/dbdma.h
+++ b/include/asm-powerpc/dbdma.h
@@ -95,7 +95,13 @@ struct dbdma_cmd {
95#define DBDMA_DO_STOP(regs) do { \ 95#define DBDMA_DO_STOP(regs) do { \
96 out_le32(&((regs)->control), (RUN|FLUSH)<<16); \ 96 out_le32(&((regs)->control), (RUN|FLUSH)<<16); \
97 while(in_le32(&((regs)->status)) & (ACTIVE|FLUSH)) \ 97 while(in_le32(&((regs)->status)) & (ACTIVE|FLUSH)) \
98 ; \ 98 ; \
99} while(0)
100
101#define DBDMA_DO_RESET(regs) do { \
102 out_le32(&((regs)->control), (ACTIVE|DEAD|WAKE|FLUSH|PAUSE|RUN)<<16);\
103 while(in_le32(&((regs)->status)) & (RUN)) \
104 ; \
99} while(0) 105} while(0)
100 106
101#endif /* _ASM_DBDMA_H_ */ 107#endif /* _ASM_DBDMA_H_ */
diff --git a/include/asm-powerpc/dcr-mmio.h b/include/asm-powerpc/dcr-mmio.h
new file mode 100644
index 000000000000..5dbfca8dde36
--- /dev/null
+++ b/include/asm-powerpc/dcr-mmio.h
@@ -0,0 +1,51 @@
1/*
2 * (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp.
3 * <benh@kernel.crashing.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#ifndef _ASM_POWERPC_DCR_MMIO_H
21#define _ASM_POWERPC_DCR_MMIO_H
22#ifdef __KERNEL__
23
24#include <asm/io.h>
25
26typedef struct { void __iomem *token; unsigned int stride; } dcr_host_t;
27
28#define DCR_MAP_OK(host) ((host).token != NULL)
29
30extern dcr_host_t dcr_map(struct device_node *dev, unsigned int dcr_n,
31 unsigned int dcr_c);
32extern void dcr_unmap(dcr_host_t host, unsigned int dcr_n, unsigned int dcr_c);
33
34static inline u32 dcr_read(dcr_host_t host, unsigned int dcr_n)
35{
36 return in_be32(host.token + dcr_n * host.stride);
37}
38
39static inline void dcr_write(dcr_host_t host, unsigned int dcr_n, u32 value)
40{
41 out_be32(host.token + dcr_n * host.stride, value);
42}
43
44extern u64 of_translate_dcr_address(struct device_node *dev,
45 unsigned int dcr_n,
46 unsigned int *stride);
47
48#endif /* __KERNEL__ */
49#endif /* _ASM_POWERPC_DCR_MMIO_H */
50
51
diff --git a/include/asm-powerpc/dcr-native.h b/include/asm-powerpc/dcr-native.h
new file mode 100644
index 000000000000..fd4a5f5e33d1
--- /dev/null
+++ b/include/asm-powerpc/dcr-native.h
@@ -0,0 +1,39 @@
1/*
2 * (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp.
3 * <benh@kernel.crashing.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#ifndef _ASM_POWERPC_DCR_NATIVE_H
21#define _ASM_POWERPC_DCR_NATIVE_H
22#ifdef __KERNEL__
23
24#include <asm/reg.h>
25
26typedef struct {} dcr_host_t;
27
28#define DCR_MAP_OK(host) (1)
29
30#define dcr_map(dev, dcr_n, dcr_c) {}
31#define dcr_unmap(host, dcr_n, dcr_c) {}
32#define dcr_read(host, dcr_n) mfdcr(dcr_n)
33#define dcr_write(host, dcr_n, value) mtdcr(dcr_n, value)
34
35
36#endif /* __KERNEL__ */
37#endif /* _ASM_POWERPC_DCR_NATIVE_H */
38
39
diff --git a/include/asm-powerpc/dcr.h b/include/asm-powerpc/dcr.h
new file mode 100644
index 000000000000..473f2c7fd892
--- /dev/null
+++ b/include/asm-powerpc/dcr.h
@@ -0,0 +1,42 @@
1/*
2 * (c) Copyright 2006 Benjamin Herrenschmidt, IBM Corp.
3 * <benh@kernel.crashing.org>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
13 * the GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 */
19
20#ifndef _ASM_POWERPC_DCR_H
21#define _ASM_POWERPC_DCR_H
22#ifdef __KERNEL__
23
24#ifdef CONFIG_PPC_DCR_NATIVE
25#include <asm/dcr-native.h>
26#else
27#include <asm/dcr-mmio.h>
28#endif
29
30/*
31 * On CONFIG_PPC_MERGE, we have additional helpers to read the DCR
32 * base from the device-tree
33 */
34#ifdef CONFIG_PPC_MERGE
35extern unsigned int dcr_resource_start(struct device_node *np,
36 unsigned int index);
37extern unsigned int dcr_resource_len(struct device_node *np,
38 unsigned int index);
39#endif /* CONFIG_PPC_MERGE */
40
41#endif /* __KERNEL__ */
42#endif /* _ASM_POWERPC_DCR_H */
diff --git a/include/asm-powerpc/device.h b/include/asm-powerpc/device.h
index d8f9872b0e2d..228ab2a315b9 100644
--- a/include/asm-powerpc/device.h
+++ b/include/asm-powerpc/device.h
@@ -3,5 +3,22 @@
3 * 3 *
4 * This file is released under the GPLv2 4 * This file is released under the GPLv2
5 */ 5 */
6#include <asm-generic/device.h> 6#ifndef _ASM_POWERPC_DEVICE_H
7#define _ASM_POWERPC_DEVICE_H
7 8
9struct dma_mapping_ops;
10struct device_node;
11
12struct dev_archdata {
13 /* Optional pointer to an OF device node */
14 struct device_node *of_node;
15
16 /* DMA operations on that device */
17 struct dma_mapping_ops *dma_ops;
18 void *dma_data;
19
20 /* NUMA node if applicable */
21 int numa_node;
22};
23
24#endif /* _ASM_POWERPC_DEVICE_H */
diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h
index 2ab9baf78bb4..7e38b5fddada 100644
--- a/include/asm-powerpc/dma-mapping.h
+++ b/include/asm-powerpc/dma-mapping.h
@@ -44,26 +44,150 @@ extern void __dma_sync_page(struct page *page, unsigned long offset,
44#endif /* ! CONFIG_NOT_COHERENT_CACHE */ 44#endif /* ! CONFIG_NOT_COHERENT_CACHE */
45 45
46#ifdef CONFIG_PPC64 46#ifdef CONFIG_PPC64
47/*
48 * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO
49 */
50struct dma_mapping_ops {
51 void * (*alloc_coherent)(struct device *dev, size_t size,
52 dma_addr_t *dma_handle, gfp_t flag);
53 void (*free_coherent)(struct device *dev, size_t size,
54 void *vaddr, dma_addr_t dma_handle);
55 dma_addr_t (*map_single)(struct device *dev, void *ptr,
56 size_t size, enum dma_data_direction direction);
57 void (*unmap_single)(struct device *dev, dma_addr_t dma_addr,
58 size_t size, enum dma_data_direction direction);
59 int (*map_sg)(struct device *dev, struct scatterlist *sg,
60 int nents, enum dma_data_direction direction);
61 void (*unmap_sg)(struct device *dev, struct scatterlist *sg,
62 int nents, enum dma_data_direction direction);
63 int (*dma_supported)(struct device *dev, u64 mask);
64 int (*dac_dma_supported)(struct device *dev, u64 mask);
65 int (*set_dma_mask)(struct device *dev, u64 dma_mask);
66};
67
68static inline struct dma_mapping_ops *get_dma_ops(struct device *dev)
69{
70 /* We don't handle the NULL dev case for ISA for now. We could
71 * do it via an out of line call but it is not needed for now. The
72 * only ISA DMA device we support is the floppy and we have a hack
73 * in the floppy driver directly to get a device for us.
74 */
75 if (unlikely(dev == NULL || dev->archdata.dma_ops == NULL))
76 return NULL;
77 return dev->archdata.dma_ops;
78}
47 79
48extern int dma_supported(struct device *dev, u64 mask); 80static inline int dma_supported(struct device *dev, u64 mask)
49extern int dma_set_mask(struct device *dev, u64 dma_mask); 81{
50extern void *dma_alloc_coherent(struct device *dev, size_t size, 82 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
51 dma_addr_t *dma_handle, gfp_t flag); 83
52extern void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, 84 if (unlikely(dma_ops == NULL))
53 dma_addr_t dma_handle); 85 return 0;
54extern dma_addr_t dma_map_single(struct device *dev, void *cpu_addr, 86 if (dma_ops->dma_supported == NULL)
55 size_t size, enum dma_data_direction direction); 87 return 1;
56extern void dma_unmap_single(struct device *dev, dma_addr_t dma_addr, 88 return dma_ops->dma_supported(dev, mask);
57 size_t size, enum dma_data_direction direction); 89}
58extern dma_addr_t dma_map_page(struct device *dev, struct page *page, 90
59 unsigned long offset, size_t size, 91static inline int dma_set_mask(struct device *dev, u64 dma_mask)
60 enum dma_data_direction direction); 92{
61extern void dma_unmap_page(struct device *dev, dma_addr_t dma_address, 93 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
62 size_t size, enum dma_data_direction direction); 94
63extern int dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, 95 if (unlikely(dma_ops == NULL))
64 enum dma_data_direction direction); 96 return -EIO;
65extern void dma_unmap_sg(struct device *dev, struct scatterlist *sg, 97 if (dma_ops->set_dma_mask != NULL)
66 int nhwentries, enum dma_data_direction direction); 98 return dma_ops->set_dma_mask(dev, dma_mask);
99 if (!dev->dma_mask || !dma_supported(dev, *dev->dma_mask))
100 return -EIO;
101 *dev->dma_mask = dma_mask;
102 return 0;
103}
104
105static inline void *dma_alloc_coherent(struct device *dev, size_t size,
106 dma_addr_t *dma_handle, gfp_t flag)
107{
108 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
109
110 BUG_ON(!dma_ops);
111 return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
112}
113
114static inline void dma_free_coherent(struct device *dev, size_t size,
115 void *cpu_addr, dma_addr_t dma_handle)
116{
117 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
118
119 BUG_ON(!dma_ops);
120 dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
121}
122
123static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
124 size_t size,
125 enum dma_data_direction direction)
126{
127 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
128
129 BUG_ON(!dma_ops);
130 return dma_ops->map_single(dev, cpu_addr, size, direction);
131}
132
133static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
134 size_t size,
135 enum dma_data_direction direction)
136{
137 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
138
139 BUG_ON(!dma_ops);
140 dma_ops->unmap_single(dev, dma_addr, size, direction);
141}
142
143static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
144 unsigned long offset, size_t size,
145 enum dma_data_direction direction)
146{
147 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
148
149 BUG_ON(!dma_ops);
150 return dma_ops->map_single(dev, page_address(page) + offset, size,
151 direction);
152}
153
154static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
155 size_t size,
156 enum dma_data_direction direction)
157{
158 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
159
160 BUG_ON(!dma_ops);
161 dma_ops->unmap_single(dev, dma_address, size, direction);
162}
163
164static inline int dma_map_sg(struct device *dev, struct scatterlist *sg,
165 int nents, enum dma_data_direction direction)
166{
167 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
168
169 BUG_ON(!dma_ops);
170 return dma_ops->map_sg(dev, sg, nents, direction);
171}
172
173static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg,
174 int nhwentries,
175 enum dma_data_direction direction)
176{
177 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
178
179 BUG_ON(!dma_ops);
180 dma_ops->unmap_sg(dev, sg, nhwentries, direction);
181}
182
183
184/*
185 * Available generic sets of operations
186 */
187extern struct dma_mapping_ops dma_iommu_ops;
188extern struct dma_mapping_ops dma_direct_ops;
189
190extern unsigned long dma_direct_offset;
67 191
68#else /* CONFIG_PPC64 */ 192#else /* CONFIG_PPC64 */
69 193
@@ -261,25 +385,5 @@ static inline void dma_cache_sync(void *vaddr, size_t size,
261 __dma_sync(vaddr, size, (int)direction); 385 __dma_sync(vaddr, size, (int)direction);
262} 386}
263 387
264/*
265 * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO
266 */
267struct dma_mapping_ops {
268 void * (*alloc_coherent)(struct device *dev, size_t size,
269 dma_addr_t *dma_handle, gfp_t flag);
270 void (*free_coherent)(struct device *dev, size_t size,
271 void *vaddr, dma_addr_t dma_handle);
272 dma_addr_t (*map_single)(struct device *dev, void *ptr,
273 size_t size, enum dma_data_direction direction);
274 void (*unmap_single)(struct device *dev, dma_addr_t dma_addr,
275 size_t size, enum dma_data_direction direction);
276 int (*map_sg)(struct device *dev, struct scatterlist *sg,
277 int nents, enum dma_data_direction direction);
278 void (*unmap_sg)(struct device *dev, struct scatterlist *sg,
279 int nents, enum dma_data_direction direction);
280 int (*dma_supported)(struct device *dev, u64 mask);
281 int (*dac_dma_supported)(struct device *dev, u64 mask);
282};
283
284#endif /* __KERNEL__ */ 388#endif /* __KERNEL__ */
285#endif /* _ASM_DMA_MAPPING_H */ 389#endif /* _ASM_DMA_MAPPING_H */
diff --git a/include/asm-powerpc/eeh.h b/include/asm-powerpc/eeh.h
index 6a784396660b..b886bec67016 100644
--- a/include/asm-powerpc/eeh.h
+++ b/include/asm-powerpc/eeh.h
@@ -120,10 +120,6 @@ static inline u8 eeh_readb(const volatile void __iomem *addr)
120 return eeh_check_failure(addr, val); 120 return eeh_check_failure(addr, val);
121 return val; 121 return val;
122} 122}
123static inline void eeh_writeb(u8 val, volatile void __iomem *addr)
124{
125 out_8(addr, val);
126}
127 123
128static inline u16 eeh_readw(const volatile void __iomem *addr) 124static inline u16 eeh_readw(const volatile void __iomem *addr)
129{ 125{
@@ -132,21 +128,6 @@ static inline u16 eeh_readw(const volatile void __iomem *addr)
132 return eeh_check_failure(addr, val); 128 return eeh_check_failure(addr, val);
133 return val; 129 return val;
134} 130}
135static inline void eeh_writew(u16 val, volatile void __iomem *addr)
136{
137 out_le16(addr, val);
138}
139static inline u16 eeh_raw_readw(const volatile void __iomem *addr)
140{
141 u16 val = in_be16(addr);
142 if (EEH_POSSIBLE_ERROR(val, u16))
143 return eeh_check_failure(addr, val);
144 return val;
145}
146static inline void eeh_raw_writew(u16 val, volatile void __iomem *addr) {
147 volatile u16 __iomem *vaddr = (volatile u16 __iomem *) addr;
148 out_be16(vaddr, val);
149}
150 131
151static inline u32 eeh_readl(const volatile void __iomem *addr) 132static inline u32 eeh_readl(const volatile void __iomem *addr)
152{ 133{
@@ -155,205 +136,75 @@ static inline u32 eeh_readl(const volatile void __iomem *addr)
155 return eeh_check_failure(addr, val); 136 return eeh_check_failure(addr, val);
156 return val; 137 return val;
157} 138}
158static inline void eeh_writel(u32 val, volatile void __iomem *addr) 139
159{ 140static inline u64 eeh_readq(const volatile void __iomem *addr)
160 out_le32(addr, val);
161}
162static inline u32 eeh_raw_readl(const volatile void __iomem *addr)
163{ 141{
164 u32 val = in_be32(addr); 142 u64 val = in_le64(addr);
165 if (EEH_POSSIBLE_ERROR(val, u32)) 143 if (EEH_POSSIBLE_ERROR(val, u64))
166 return eeh_check_failure(addr, val); 144 return eeh_check_failure(addr, val);
167 return val; 145 return val;
168} 146}
169static inline void eeh_raw_writel(u32 val, volatile void __iomem *addr)
170{
171 out_be32(addr, val);
172}
173 147
174static inline u64 eeh_readq(const volatile void __iomem *addr) 148static inline u16 eeh_readw_be(const volatile void __iomem *addr)
175{ 149{
176 u64 val = in_le64(addr); 150 u16 val = in_be16(addr);
177 if (EEH_POSSIBLE_ERROR(val, u64)) 151 if (EEH_POSSIBLE_ERROR(val, u16))
178 return eeh_check_failure(addr, val); 152 return eeh_check_failure(addr, val);
179 return val; 153 return val;
180} 154}
181static inline void eeh_writeq(u64 val, volatile void __iomem *addr) 155
156static inline u32 eeh_readl_be(const volatile void __iomem *addr)
182{ 157{
183 out_le64(addr, val); 158 u32 val = in_be32(addr);
159 if (EEH_POSSIBLE_ERROR(val, u32))
160 return eeh_check_failure(addr, val);
161 return val;
184} 162}
185static inline u64 eeh_raw_readq(const volatile void __iomem *addr) 163
164static inline u64 eeh_readq_be(const volatile void __iomem *addr)
186{ 165{
187 u64 val = in_be64(addr); 166 u64 val = in_be64(addr);
188 if (EEH_POSSIBLE_ERROR(val, u64)) 167 if (EEH_POSSIBLE_ERROR(val, u64))
189 return eeh_check_failure(addr, val); 168 return eeh_check_failure(addr, val);
190 return val; 169 return val;
191} 170}
192static inline void eeh_raw_writeq(u64 val, volatile void __iomem *addr)
193{
194 out_be64(addr, val);
195}
196
197#define EEH_CHECK_ALIGN(v,a) \
198 ((((unsigned long)(v)) & ((a) - 1)) == 0)
199 171
200static inline void eeh_memset_io(volatile void __iomem *addr, int c, 172static inline void eeh_memcpy_fromio(void *dest, const
201 unsigned long n) 173 volatile void __iomem *src,
202{
203 void *p = (void __force *)addr;
204 u32 lc = c;
205 lc |= lc << 8;
206 lc |= lc << 16;
207
208 __asm__ __volatile__ ("sync" : : : "memory");
209 while(n && !EEH_CHECK_ALIGN(p, 4)) {
210 *((volatile u8 *)p) = c;
211 p++;
212 n--;
213 }
214 while(n >= 4) {
215 *((volatile u32 *)p) = lc;
216 p += 4;
217 n -= 4;
218 }
219 while(n) {
220 *((volatile u8 *)p) = c;
221 p++;
222 n--;
223 }
224 __asm__ __volatile__ ("sync" : : : "memory");
225}
226static inline void eeh_memcpy_fromio(void *dest, const volatile void __iomem *src,
227 unsigned long n) 174 unsigned long n)
228{ 175{
229 void *vsrc = (void __force *) src; 176 _memcpy_fromio(dest, src, n);
230 void *destsave = dest;
231 unsigned long nsave = n;
232
233 __asm__ __volatile__ ("sync" : : : "memory");
234 while(n && (!EEH_CHECK_ALIGN(vsrc, 4) || !EEH_CHECK_ALIGN(dest, 4))) {
235 *((u8 *)dest) = *((volatile u8 *)vsrc);
236 __asm__ __volatile__ ("eieio" : : : "memory");
237 vsrc++;
238 dest++;
239 n--;
240 }
241 while(n > 4) {
242 *((u32 *)dest) = *((volatile u32 *)vsrc);
243 __asm__ __volatile__ ("eieio" : : : "memory");
244 vsrc += 4;
245 dest += 4;
246 n -= 4;
247 }
248 while(n) {
249 *((u8 *)dest) = *((volatile u8 *)vsrc);
250 __asm__ __volatile__ ("eieio" : : : "memory");
251 vsrc++;
252 dest++;
253 n--;
254 }
255 __asm__ __volatile__ ("sync" : : : "memory");
256 177
257 /* Look for ffff's here at dest[n]. Assume that at least 4 bytes 178 /* Look for ffff's here at dest[n]. Assume that at least 4 bytes
258 * were copied. Check all four bytes. 179 * were copied. Check all four bytes.
259 */ 180 */
260 if ((nsave >= 4) && 181 if (n >= 4 && EEH_POSSIBLE_ERROR(*((u32 *)(dest + n - 4)), u32))
261 (EEH_POSSIBLE_ERROR((*((u32 *) destsave+nsave-4)), u32))) { 182 eeh_check_failure(src, *((u32 *)(dest + n - 4)));
262 eeh_check_failure(src, (*((u32 *) destsave+nsave-4)));
263 }
264}
265
266static inline void eeh_memcpy_toio(volatile void __iomem *dest, const void *src,
267 unsigned long n)
268{
269 void *vdest = (void __force *) dest;
270
271 __asm__ __volatile__ ("sync" : : : "memory");
272 while(n && (!EEH_CHECK_ALIGN(vdest, 4) || !EEH_CHECK_ALIGN(src, 4))) {
273 *((volatile u8 *)vdest) = *((u8 *)src);
274 src++;
275 vdest++;
276 n--;
277 }
278 while(n > 4) {
279 *((volatile u32 *)vdest) = *((volatile u32 *)src);
280 src += 4;
281 vdest += 4;
282 n-=4;
283 }
284 while(n) {
285 *((volatile u8 *)vdest) = *((u8 *)src);
286 src++;
287 vdest++;
288 n--;
289 }
290 __asm__ __volatile__ ("sync" : : : "memory");
291}
292
293#undef EEH_CHECK_ALIGN
294
295static inline u8 eeh_inb(unsigned long port)
296{
297 u8 val;
298 val = in_8((u8 __iomem *)(port+pci_io_base));
299 if (EEH_POSSIBLE_ERROR(val, u8))
300 return eeh_check_failure((void __iomem *)(port), val);
301 return val;
302}
303
304static inline void eeh_outb(u8 val, unsigned long port)
305{
306 out_8((u8 __iomem *)(port+pci_io_base), val);
307}
308
309static inline u16 eeh_inw(unsigned long port)
310{
311 u16 val;
312 val = in_le16((u16 __iomem *)(port+pci_io_base));
313 if (EEH_POSSIBLE_ERROR(val, u16))
314 return eeh_check_failure((void __iomem *)(port), val);
315 return val;
316}
317
318static inline void eeh_outw(u16 val, unsigned long port)
319{
320 out_le16((u16 __iomem *)(port+pci_io_base), val);
321}
322
323static inline u32 eeh_inl(unsigned long port)
324{
325 u32 val;
326 val = in_le32((u32 __iomem *)(port+pci_io_base));
327 if (EEH_POSSIBLE_ERROR(val, u32))
328 return eeh_check_failure((void __iomem *)(port), val);
329 return val;
330}
331
332static inline void eeh_outl(u32 val, unsigned long port)
333{
334 out_le32((u32 __iomem *)(port+pci_io_base), val);
335} 183}
336 184
337/* in-string eeh macros */ 185/* in-string eeh macros */
338static inline void eeh_insb(unsigned long port, void * buf, int ns) 186static inline void eeh_readsb(const volatile void __iomem *addr, void * buf,
187 int ns)
339{ 188{
340 _insb((u8 __iomem *)(port+pci_io_base), buf, ns); 189 _insb(addr, buf, ns);
341 if (EEH_POSSIBLE_ERROR((*(((u8*)buf)+ns-1)), u8)) 190 if (EEH_POSSIBLE_ERROR((*(((u8*)buf)+ns-1)), u8))
342 eeh_check_failure((void __iomem *)(port), *(u8*)buf); 191 eeh_check_failure(addr, *(u8*)buf);
343} 192}
344 193
345static inline void eeh_insw_ns(unsigned long port, void * buf, int ns) 194static inline void eeh_readsw(const volatile void __iomem *addr, void * buf,
195 int ns)
346{ 196{
347 _insw_ns((u16 __iomem *)(port+pci_io_base), buf, ns); 197 _insw(addr, buf, ns);
348 if (EEH_POSSIBLE_ERROR((*(((u16*)buf)+ns-1)), u16)) 198 if (EEH_POSSIBLE_ERROR((*(((u16*)buf)+ns-1)), u16))
349 eeh_check_failure((void __iomem *)(port), *(u16*)buf); 199 eeh_check_failure(addr, *(u16*)buf);
350} 200}
351 201
352static inline void eeh_insl_ns(unsigned long port, void * buf, int nl) 202static inline void eeh_readsl(const volatile void __iomem *addr, void * buf,
203 int nl)
353{ 204{
354 _insl_ns((u32 __iomem *)(port+pci_io_base), buf, nl); 205 _insl(addr, buf, nl);
355 if (EEH_POSSIBLE_ERROR((*(((u32*)buf)+nl-1)), u32)) 206 if (EEH_POSSIBLE_ERROR((*(((u32*)buf)+nl-1)), u32))
356 eeh_check_failure((void __iomem *)(port), *(u32*)buf); 207 eeh_check_failure(addr, *(u32*)buf);
357} 208}
358 209
359#endif /* __KERNEL__ */ 210#endif /* __KERNEL__ */
diff --git a/include/asm-powerpc/elf.h b/include/asm-powerpc/elf.h
index 9a83a987d396..b5436642a109 100644
--- a/include/asm-powerpc/elf.h
+++ b/include/asm-powerpc/elf.h
@@ -411,4 +411,17 @@ do { \
411/* Keep this the last entry. */ 411/* Keep this the last entry. */
412#define R_PPC64_NUM 107 412#define R_PPC64_NUM 107
413 413
414#ifdef CONFIG_SPU_BASE
415/* Notes used in ET_CORE. Note name is "SPU/<fd>/<filename>". */
416#define NT_SPU 1
417
418extern int arch_notes_size(void);
419extern void arch_write_notes(struct file *file);
420
421#define ELF_CORE_EXTRA_NOTES_SIZE arch_notes_size()
422#define ELF_CORE_WRITE_EXTRA_NOTES arch_write_notes(file)
423
424#define ARCH_HAVE_EXTRA_ELF_NOTES
425#endif /* CONFIG_PPC_CELL */
426
414#endif /* _ASM_POWERPC_ELF_H */ 427#endif /* _ASM_POWERPC_ELF_H */
diff --git a/include/asm-powerpc/firmware.h b/include/asm-powerpc/firmware.h
index fdf9aff71150..98f7b62422c9 100644
--- a/include/asm-powerpc/firmware.h
+++ b/include/asm-powerpc/firmware.h
@@ -42,6 +42,7 @@
42#define FW_FEATURE_SPLPAR ASM_CONST(0x0000000000100000) 42#define FW_FEATURE_SPLPAR ASM_CONST(0x0000000000100000)
43#define FW_FEATURE_ISERIES ASM_CONST(0x0000000000200000) 43#define FW_FEATURE_ISERIES ASM_CONST(0x0000000000200000)
44#define FW_FEATURE_LPAR ASM_CONST(0x0000000000400000) 44#define FW_FEATURE_LPAR ASM_CONST(0x0000000000400000)
45#define FW_FEATURE_PS3_LV1 ASM_CONST(0x0000000000800000)
45 46
46#ifndef __ASSEMBLY__ 47#ifndef __ASSEMBLY__
47 48
@@ -58,6 +59,10 @@ enum {
58 FW_FEATURE_PSERIES_ALWAYS = 0, 59 FW_FEATURE_PSERIES_ALWAYS = 0,
59 FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES | FW_FEATURE_LPAR, 60 FW_FEATURE_ISERIES_POSSIBLE = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
60 FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES | FW_FEATURE_LPAR, 61 FW_FEATURE_ISERIES_ALWAYS = FW_FEATURE_ISERIES | FW_FEATURE_LPAR,
62 FW_FEATURE_PS3_POSSIBLE = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
63 FW_FEATURE_PS3_ALWAYS = FW_FEATURE_LPAR | FW_FEATURE_PS3_LV1,
64 FW_FEATURE_NATIVE_POSSIBLE = 0,
65 FW_FEATURE_NATIVE_ALWAYS = 0,
61 FW_FEATURE_POSSIBLE = 66 FW_FEATURE_POSSIBLE =
62#ifdef CONFIG_PPC_PSERIES 67#ifdef CONFIG_PPC_PSERIES
63 FW_FEATURE_PSERIES_POSSIBLE | 68 FW_FEATURE_PSERIES_POSSIBLE |
@@ -65,6 +70,12 @@ enum {
65#ifdef CONFIG_PPC_ISERIES 70#ifdef CONFIG_PPC_ISERIES
66 FW_FEATURE_ISERIES_POSSIBLE | 71 FW_FEATURE_ISERIES_POSSIBLE |
67#endif 72#endif
73#ifdef CONFIG_PPC_PS3
74 FW_FEATURE_PS3_POSSIBLE |
75#endif
76#ifdef CONFIG_PPC_NATIVE
77 FW_FEATURE_NATIVE_ALWAYS |
78#endif
68 0, 79 0,
69 FW_FEATURE_ALWAYS = 80 FW_FEATURE_ALWAYS =
70#ifdef CONFIG_PPC_PSERIES 81#ifdef CONFIG_PPC_PSERIES
@@ -73,6 +84,12 @@ enum {
73#ifdef CONFIG_PPC_ISERIES 84#ifdef CONFIG_PPC_ISERIES
74 FW_FEATURE_ISERIES_ALWAYS & 85 FW_FEATURE_ISERIES_ALWAYS &
75#endif 86#endif
87#ifdef CONFIG_PPC_PS3
88 FW_FEATURE_PS3_ALWAYS &
89#endif
90#ifdef CONFIG_PPC_NATIVE
91 FW_FEATURE_NATIVE_ALWAYS &
92#endif
76 FW_FEATURE_POSSIBLE, 93 FW_FEATURE_POSSIBLE,
77 94
78#else /* CONFIG_PPC64 */ 95#else /* CONFIG_PPC64 */
diff --git a/include/asm-powerpc/hw_irq.h b/include/asm-powerpc/hw_irq.h
index d40359204aba..d604863d72fb 100644
--- a/include/asm-powerpc/hw_irq.h
+++ b/include/asm-powerpc/hw_irq.h
@@ -7,16 +7,40 @@
7#ifdef __KERNEL__ 7#ifdef __KERNEL__
8 8
9#include <linux/errno.h> 9#include <linux/errno.h>
10#include <linux/compiler.h>
10#include <asm/ptrace.h> 11#include <asm/ptrace.h>
11#include <asm/processor.h> 12#include <asm/processor.h>
12 13
13extern void timer_interrupt(struct pt_regs *); 14extern void timer_interrupt(struct pt_regs *);
14 15
15#ifdef CONFIG_PPC_ISERIES 16#ifdef CONFIG_PPC64
17#include <asm/paca.h>
18
19static inline unsigned long local_get_flags(void)
20{
21 unsigned long flags;
22
23 __asm__ __volatile__("lbz %0,%1(13)"
24 : "=r" (flags)
25 : "i" (offsetof(struct paca_struct, soft_enabled)));
26
27 return flags;
28}
29
30static inline unsigned long local_irq_disable(void)
31{
32 unsigned long flags, zero;
33
34 __asm__ __volatile__("li %1,0; lbz %0,%2(13); stb %1,%2(13)"
35 : "=r" (flags), "=&r" (zero)
36 : "i" (offsetof(struct paca_struct, soft_enabled))
37 : "memory");
38
39 return flags;
40}
16 41
17extern unsigned long local_get_flags(void);
18extern unsigned long local_irq_disable(void);
19extern void local_irq_restore(unsigned long); 42extern void local_irq_restore(unsigned long);
43extern void iseries_handle_interrupts(void);
20 44
21#define local_irq_enable() local_irq_restore(1) 45#define local_irq_enable() local_irq_restore(1)
22#define local_save_flags(flags) ((flags) = local_get_flags()) 46#define local_save_flags(flags) ((flags) = local_get_flags())
@@ -24,17 +48,14 @@ extern void local_irq_restore(unsigned long);
24 48
25#define irqs_disabled() (local_get_flags() == 0) 49#define irqs_disabled() (local_get_flags() == 0)
26 50
51#define hard_irq_enable() __mtmsrd(mfmsr() | MSR_EE, 1)
52#define hard_irq_disable() __mtmsrd(mfmsr() & ~MSR_EE, 1)
53
27#else 54#else
28 55
29#if defined(CONFIG_BOOKE) 56#if defined(CONFIG_BOOKE)
30#define SET_MSR_EE(x) mtmsr(x) 57#define SET_MSR_EE(x) mtmsr(x)
31#define local_irq_restore(flags) __asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory") 58#define local_irq_restore(flags) __asm__ __volatile__("wrtee %0" : : "r" (flags) : "memory")
32#elif defined(__powerpc64__)
33#define SET_MSR_EE(x) __mtmsrd(x, 1)
34#define local_irq_restore(flags) do { \
35 __asm__ __volatile__("": : :"memory"); \
36 __mtmsrd((flags), 1); \
37} while(0)
38#else 59#else
39#define SET_MSR_EE(x) mtmsr(x) 60#define SET_MSR_EE(x) mtmsr(x)
40#define local_irq_restore(flags) mtmsr(flags) 61#define local_irq_restore(flags) mtmsr(flags)
@@ -81,7 +102,10 @@ static inline void local_irq_save_ptr(unsigned long *flags)
81#define local_irq_save(flags) local_irq_save_ptr(&flags) 102#define local_irq_save(flags) local_irq_save_ptr(&flags)
82#define irqs_disabled() ((mfmsr() & MSR_EE) == 0) 103#define irqs_disabled() ((mfmsr() & MSR_EE) == 0)
83 104
84#endif /* CONFIG_PPC_ISERIES */ 105#define hard_irq_enable() local_irq_enable()
106#define hard_irq_disable() local_irq_disable()
107
108#endif /* CONFIG_PPC64 */
85 109
86#define mask_irq(irq) \ 110#define mask_irq(irq) \
87 ({ \ 111 ({ \
diff --git a/include/asm-powerpc/ibmebus.h b/include/asm-powerpc/ibmebus.h
index 3493429b70f5..66112114b8c5 100644
--- a/include/asm-powerpc/ibmebus.h
+++ b/include/asm-powerpc/ibmebus.h
@@ -44,7 +44,6 @@
44#include <linux/mod_devicetable.h> 44#include <linux/mod_devicetable.h>
45#include <asm/of_device.h> 45#include <asm/of_device.h>
46 46
47extern struct dma_mapping_ops ibmebus_dma_ops;
48extern struct bus_type ibmebus_bus_type; 47extern struct bus_type ibmebus_bus_type;
49 48
50struct ibmebus_dev { 49struct ibmebus_dev {
diff --git a/include/asm-powerpc/ide.h b/include/asm-powerpc/ide.h
index c8390f9485de..0f66f0f82c32 100644
--- a/include/asm-powerpc/ide.h
+++ b/include/asm-powerpc/ide.h
@@ -22,10 +22,10 @@
22#endif 22#endif
23#endif 23#endif
24 24
25#define __ide_mm_insw(p, a, c) _insw_ns((volatile u16 __iomem *)(p), (a), (c)) 25#define __ide_mm_insw(p, a, c) readsw((void __iomem *)(p), (a), (c))
26#define __ide_mm_insl(p, a, c) _insl_ns((volatile u32 __iomem *)(p), (a), (c)) 26#define __ide_mm_insl(p, a, c) readsl((void __iomem *)(p), (a), (c))
27#define __ide_mm_outsw(p, a, c) _outsw_ns((volatile u16 __iomem *)(p), (a), (c)) 27#define __ide_mm_outsw(p, a, c) writesw((void __iomem *)(p), (a), (c))
28#define __ide_mm_outsl(p, a, c) _outsl_ns((volatile u32 __iomem *)(p), (a), (c)) 28#define __ide_mm_outsl(p, a, c) writesl((void __iomem *)(p), (a), (c))
29 29
30#ifndef __powerpc64__ 30#ifndef __powerpc64__
31#include <linux/hdreg.h> 31#include <linux/hdreg.h>
diff --git a/include/asm-powerpc/immap_qe.h b/include/asm-powerpc/immap_qe.h
index ce12f85fff9b..9fdd0491f6a3 100644
--- a/include/asm-powerpc/immap_qe.h
+++ b/include/asm-powerpc/immap_qe.h
@@ -136,22 +136,7 @@ struct qe_timers {
136 136
137/* BRG */ 137/* BRG */
138struct qe_brg { 138struct qe_brg {
139 __be32 brgc1; /* BRG1 configuration register */ 139 __be32 brgc[16]; /* BRG configuration registers */
140 __be32 brgc2; /* BRG2 configuration register */
141 __be32 brgc3; /* BRG3 configuration register */
142 __be32 brgc4; /* BRG4 configuration register */
143 __be32 brgc5; /* BRG5 configuration register */
144 __be32 brgc6; /* BRG6 configuration register */
145 __be32 brgc7; /* BRG7 configuration register */
146 __be32 brgc8; /* BRG8 configuration register */
147 __be32 brgc9; /* BRG9 configuration register */
148 __be32 brgc10; /* BRG10 configuration register */
149 __be32 brgc11; /* BRG11 configuration register */
150 __be32 brgc12; /* BRG12 configuration register */
151 __be32 brgc13; /* BRG13 configuration register */
152 __be32 brgc14; /* BRG14 configuration register */
153 __be32 brgc15; /* BRG15 configuration register */
154 __be32 brgc16; /* BRG16 configuration register */
155 u8 res0[0x40]; 140 u8 res0[0x40];
156} __attribute__ ((packed)); 141} __attribute__ ((packed));
157 142
diff --git a/include/asm-powerpc/io-defs.h b/include/asm-powerpc/io-defs.h
new file mode 100644
index 000000000000..03691ab69217
--- /dev/null
+++ b/include/asm-powerpc/io-defs.h
@@ -0,0 +1,59 @@
1/* This file is meant to be include multiple times by other headers */
2
3DEF_PCI_AC_RET(readb, u8, (const PCI_IO_ADDR addr), (addr))
4DEF_PCI_AC_RET(readw, u16, (const PCI_IO_ADDR addr), (addr))
5DEF_PCI_AC_RET(readl, u32, (const PCI_IO_ADDR addr), (addr))
6DEF_PCI_AC_RET(readw_be, u16, (const PCI_IO_ADDR addr), (addr))
7DEF_PCI_AC_RET(readl_be, u32, (const PCI_IO_ADDR addr), (addr))
8DEF_PCI_AC_NORET(writeb, (u8 val, PCI_IO_ADDR addr), (val, addr))
9DEF_PCI_AC_NORET(writew, (u16 val, PCI_IO_ADDR addr), (val, addr))
10DEF_PCI_AC_NORET(writel, (u32 val, PCI_IO_ADDR addr), (val, addr))
11DEF_PCI_AC_NORET(writew_be, (u16 val, PCI_IO_ADDR addr), (val, addr))
12DEF_PCI_AC_NORET(writel_be, (u32 val, PCI_IO_ADDR addr), (val, addr))
13
14#ifdef __powerpc64__
15DEF_PCI_AC_RET(readq, u64, (const PCI_IO_ADDR addr), (addr))
16DEF_PCI_AC_RET(readq_be, u64, (const PCI_IO_ADDR addr), (addr))
17DEF_PCI_AC_NORET(writeq, (u64 val, PCI_IO_ADDR addr), (val, addr))
18DEF_PCI_AC_NORET(writeq_be, (u64 val, PCI_IO_ADDR addr), (val, addr))
19#endif /* __powerpc64__ */
20
21DEF_PCI_AC_RET(inb, u8, (unsigned long port), (port))
22DEF_PCI_AC_RET(inw, u16, (unsigned long port), (port))
23DEF_PCI_AC_RET(inl, u32, (unsigned long port), (port))
24DEF_PCI_AC_NORET(outb, (u8 val, unsigned long port), (val, port))
25DEF_PCI_AC_NORET(outw, (u16 val, unsigned long port), (val, port))
26DEF_PCI_AC_NORET(outl, (u32 val, unsigned long port), (val, port))
27
28DEF_PCI_AC_NORET(readsb, (const PCI_IO_ADDR a, void *b, unsigned long c), \
29 (a, b, c))
30DEF_PCI_AC_NORET(readsw, (const PCI_IO_ADDR a, void *b, unsigned long c), \
31 (a, b, c))
32DEF_PCI_AC_NORET(readsl, (const PCI_IO_ADDR a, void *b, unsigned long c), \
33 (a, b, c))
34DEF_PCI_AC_NORET(writesb, (PCI_IO_ADDR a, const void *b, unsigned long c), \
35 (a, b, c))
36DEF_PCI_AC_NORET(writesw, (PCI_IO_ADDR a, const void *b, unsigned long c), \
37 (a, b, c))
38DEF_PCI_AC_NORET(writesl, (PCI_IO_ADDR a, const void *b, unsigned long c), \
39 (a, b, c))
40
41DEF_PCI_AC_NORET(insb, (unsigned long p, void *b, unsigned long c), \
42 (p, b, c))
43DEF_PCI_AC_NORET(insw, (unsigned long p, void *b, unsigned long c), \
44 (p, b, c))
45DEF_PCI_AC_NORET(insl, (unsigned long p, void *b, unsigned long c), \
46 (p, b, c))
47DEF_PCI_AC_NORET(outsb, (unsigned long p, const void *b, unsigned long c), \
48 (p, b, c))
49DEF_PCI_AC_NORET(outsw, (unsigned long p, const void *b, unsigned long c), \
50 (p, b, c))
51DEF_PCI_AC_NORET(outsl, (unsigned long p, const void *b, unsigned long c), \
52 (p, b, c))
53
54DEF_PCI_AC_NORET(memset_io, (PCI_IO_ADDR a, int c, unsigned long n), \
55 (a, c, n))
56DEF_PCI_AC_NORET(memcpy_fromio,(void *d,const PCI_IO_ADDR s,unsigned long n), \
57 (d, s, n))
58DEF_PCI_AC_NORET(memcpy_toio,(PCI_IO_ADDR d,const void *s,unsigned long n), \
59 (d, s, n))
diff --git a/include/asm-powerpc/io.h b/include/asm-powerpc/io.h
index c2c5f14b5f5f..1cd532379c30 100644
--- a/include/asm-powerpc/io.h
+++ b/include/asm-powerpc/io.h
@@ -13,154 +13,530 @@
13extern int check_legacy_ioport(unsigned long base_port); 13extern int check_legacy_ioport(unsigned long base_port);
14#define PNPBIOS_BASE 0xf000 /* only relevant for PReP */ 14#define PNPBIOS_BASE 0xf000 /* only relevant for PReP */
15 15
16#ifndef CONFIG_PPC64
17#include <asm-ppc/io.h>
18#else
19
20#include <linux/compiler.h> 16#include <linux/compiler.h>
21#include <asm/page.h> 17#include <asm/page.h>
22#include <asm/byteorder.h> 18#include <asm/byteorder.h>
23#include <asm/paca.h>
24#include <asm/synch.h> 19#include <asm/synch.h>
25#include <asm/delay.h> 20#include <asm/delay.h>
21#include <asm/mmu.h>
26 22
27#include <asm-generic/iomap.h> 23#include <asm-generic/iomap.h>
28 24
25#ifdef CONFIG_PPC64
26#include <asm/paca.h>
27#endif
28
29#define SIO_CONFIG_RA 0x398 29#define SIO_CONFIG_RA 0x398
30#define SIO_CONFIG_RD 0x399 30#define SIO_CONFIG_RD 0x399
31 31
32#define SLOW_DOWN_IO 32#define SLOW_DOWN_IO
33 33
34/* 32 bits uses slightly different variables for the various IO
35 * bases. Most of this file only uses _IO_BASE though which we
36 * define properly based on the platform
37 */
38#ifndef CONFIG_PCI
39#define _IO_BASE 0
40#define _ISA_MEM_BASE 0
41#define PCI_DRAM_OFFSET 0
42#elif defined(CONFIG_PPC32)
43#define _IO_BASE isa_io_base
44#define _ISA_MEM_BASE isa_mem_base
45#define PCI_DRAM_OFFSET pci_dram_offset
46#else
47#define _IO_BASE pci_io_base
48#define _ISA_MEM_BASE 0
49#define PCI_DRAM_OFFSET 0
50#endif
51
34extern unsigned long isa_io_base; 52extern unsigned long isa_io_base;
53extern unsigned long isa_mem_base;
35extern unsigned long pci_io_base; 54extern unsigned long pci_io_base;
55extern unsigned long pci_dram_offset;
56
57#if defined(CONFIG_PPC32) && defined(CONFIG_PPC_INDIRECT_IO)
58#error CONFIG_PPC_INDIRECT_IO is not yet supported on 32 bits
59#endif
60
61/*
62 *
63 * Low level MMIO accessors
64 *
65 * This provides the non-bus specific accessors to MMIO. Those are PowerPC
66 * specific and thus shouldn't be used in generic code. The accessors
67 * provided here are:
68 *
69 * in_8, in_le16, in_be16, in_le32, in_be32, in_le64, in_be64
70 * out_8, out_le16, out_be16, out_le32, out_be32, out_le64, out_be64
71 * _insb, _insw_ns, _insl_ns, _outsb, _outsw_ns, _outsl_ns
72 *
73 * Those operate directly on a kernel virtual address. Note that the prototype
74 * for the out_* accessors has the arguments in opposite order from the usual
75 * linux PCI accessors. Unlike those, they take the address first and the value
76 * next.
77 *
78 * Note: I might drop the _ns suffix on the stream operations soon as it is
79 * simply normal for stream operations to not swap in the first place.
80 *
81 */
82
83#ifdef CONFIG_PPC64
84#define IO_SET_SYNC_FLAG() do { get_paca()->io_sync = 1; } while(0)
85#else
86#define IO_SET_SYNC_FLAG()
87#endif
88
89#define DEF_MMIO_IN(name, type, insn) \
90static inline type name(const volatile type __iomem *addr) \
91{ \
92 type ret; \
93 __asm__ __volatile__("sync;" insn ";twi 0,%0,0;isync" \
94 : "=r" (ret) : "r" (addr), "m" (*addr)); \
95 return ret; \
96}
97
98#define DEF_MMIO_OUT(name, type, insn) \
99static inline void name(volatile type __iomem *addr, type val) \
100{ \
101 __asm__ __volatile__("sync;" insn \
102 : "=m" (*addr) : "r" (val), "r" (addr)); \
103 IO_SET_SYNC_FLAG(); \
104}
105
106
107#define DEF_MMIO_IN_BE(name, size, insn) \
108 DEF_MMIO_IN(name, u##size, __stringify(insn)"%U2%X2 %0,%2")
109#define DEF_MMIO_IN_LE(name, size, insn) \
110 DEF_MMIO_IN(name, u##size, __stringify(insn)" %0,0,%1")
111
112#define DEF_MMIO_OUT_BE(name, size, insn) \
113 DEF_MMIO_OUT(name, u##size, __stringify(insn)"%U0%X0 %1,%0")
114#define DEF_MMIO_OUT_LE(name, size, insn) \
115 DEF_MMIO_OUT(name, u##size, __stringify(insn)" %1,0,%2")
116
117DEF_MMIO_IN_BE(in_8, 8, lbz);
118DEF_MMIO_IN_BE(in_be16, 16, lhz);
119DEF_MMIO_IN_BE(in_be32, 32, lwz);
120DEF_MMIO_IN_LE(in_le16, 16, lhbrx);
121DEF_MMIO_IN_LE(in_le32, 32, lwbrx);
122
123DEF_MMIO_OUT_BE(out_8, 8, stb);
124DEF_MMIO_OUT_BE(out_be16, 16, sth);
125DEF_MMIO_OUT_BE(out_be32, 32, stw);
126DEF_MMIO_OUT_LE(out_le16, 16, sthbrx);
127DEF_MMIO_OUT_LE(out_le32, 32, stwbrx);
128
129#ifdef __powerpc64__
130DEF_MMIO_OUT_BE(out_be64, 64, std);
131DEF_MMIO_IN_BE(in_be64, 64, ld);
132
133/* There is no asm instructions for 64 bits reverse loads and stores */
134static inline u64 in_le64(const volatile u64 __iomem *addr)
135{
136 return le64_to_cpu(in_be64(addr));
137}
138
139static inline void out_le64(volatile u64 __iomem *addr, u64 val)
140{
141 out_be64(addr, cpu_to_le64(val));
142}
143#endif /* __powerpc64__ */
144
145/*
146 * Low level IO stream instructions are defined out of line for now
147 */
148extern void _insb(const volatile u8 __iomem *addr, void *buf, long count);
149extern void _outsb(volatile u8 __iomem *addr,const void *buf,long count);
150extern void _insw_ns(const volatile u16 __iomem *addr, void *buf, long count);
151extern void _outsw_ns(volatile u16 __iomem *addr, const void *buf, long count);
152extern void _insl_ns(const volatile u32 __iomem *addr, void *buf, long count);
153extern void _outsl_ns(volatile u32 __iomem *addr, const void *buf, long count);
154
155/* The _ns naming is historical and will be removed. For now, just #define
156 * the non _ns equivalent names
157 */
158#define _insw _insw_ns
159#define _insl _insl_ns
160#define _outsw _outsw_ns
161#define _outsl _outsl_ns
162
163
164/*
165 * memset_io, memcpy_toio, memcpy_fromio base implementations are out of line
166 */
167
168extern void _memset_io(volatile void __iomem *addr, int c, unsigned long n);
169extern void _memcpy_fromio(void *dest, const volatile void __iomem *src,
170 unsigned long n);
171extern void _memcpy_toio(volatile void __iomem *dest, const void *src,
172 unsigned long n);
173
174/*
175 *
176 * PCI and standard ISA accessors
177 *
178 * Those are globally defined linux accessors for devices on PCI or ISA
179 * busses. They follow the Linux defined semantics. The current implementation
180 * for PowerPC is as close as possible to the x86 version of these, and thus
181 * provides fairly heavy weight barriers for the non-raw versions
182 *
183 * In addition, they support a hook mechanism when CONFIG_PPC_INDIRECT_IO
184 * allowing the platform to provide its own implementation of some or all
185 * of the accessors.
186 */
187
188/*
189 * Include the EEH definitions when EEH is enabled only so they don't get
190 * in the way when building for 32 bits
191 */
192#ifdef CONFIG_EEH
193#include <asm/eeh.h>
194#endif
195
196/* Shortcut to the MMIO argument pointer */
197#define PCI_IO_ADDR volatile void __iomem *
198
199/* Indirect IO address tokens:
200 *
201 * When CONFIG_PPC_INDIRECT_IO is set, the platform can provide hooks
202 * on all IOs. (Note that this is all 64 bits only for now)
203 *
204 * To help platforms who may need to differenciate MMIO addresses in
205 * their hooks, a bitfield is reserved for use by the platform near the
206 * top of MMIO addresses (not PIO, those have to cope the hard way).
207 *
208 * This bit field is 12 bits and is at the top of the IO virtual
209 * addresses PCI_IO_INDIRECT_TOKEN_MASK.
210 *
211 * The kernel virtual space is thus:
212 *
213 * 0xD000000000000000 : vmalloc
214 * 0xD000080000000000 : PCI PHB IO space
215 * 0xD000080080000000 : ioremap
216 * 0xD0000fffffffffff : end of ioremap region
217 *
218 * Since the top 4 bits are reserved as the region ID, we use thus
219 * the next 12 bits and keep 4 bits available for the future if the
220 * virtual address space is ever to be extended.
221 *
222 * The direct IO mapping operations will then mask off those bits
223 * before doing the actual access, though that only happen when
224 * CONFIG_PPC_INDIRECT_IO is set, thus be careful when you use that
225 * mechanism
226 */
227
228#ifdef CONFIG_PPC_INDIRECT_IO
229#define PCI_IO_IND_TOKEN_MASK 0x0fff000000000000ul
230#define PCI_IO_IND_TOKEN_SHIFT 48
231#define PCI_FIX_ADDR(addr) \
232 ((PCI_IO_ADDR)(((unsigned long)(addr)) & ~PCI_IO_IND_TOKEN_MASK))
233#define PCI_GET_ADDR_TOKEN(addr) \
234 (((unsigned long)(addr) & PCI_IO_IND_TOKEN_MASK) >> \
235 PCI_IO_IND_TOKEN_SHIFT)
236#define PCI_SET_ADDR_TOKEN(addr, token) \
237do { \
238 unsigned long __a = (unsigned long)(addr); \
239 __a &= ~PCI_IO_IND_TOKEN_MASK; \
240 __a |= ((unsigned long)(token)) << PCI_IO_IND_TOKEN_SHIFT; \
241 (addr) = (void __iomem *)__a; \
242} while(0)
243#else
244#define PCI_FIX_ADDR(addr) (addr)
245#endif
36 246
37#ifdef CONFIG_PPC_ISERIES 247
38 248/*
39extern int in_8(const volatile unsigned char __iomem *addr); 249 * Non ordered and non-swapping "raw" accessors
40extern void out_8(volatile unsigned char __iomem *addr, int val); 250 */
41extern int in_le16(const volatile unsigned short __iomem *addr);
42extern int in_be16(const volatile unsigned short __iomem *addr);
43extern void out_le16(volatile unsigned short __iomem *addr, int val);
44extern void out_be16(volatile unsigned short __iomem *addr, int val);
45extern unsigned in_le32(const volatile unsigned __iomem *addr);
46extern unsigned in_be32(const volatile unsigned __iomem *addr);
47extern void out_le32(volatile unsigned __iomem *addr, int val);
48extern void out_be32(volatile unsigned __iomem *addr, int val);
49extern unsigned long in_le64(const volatile unsigned long __iomem *addr);
50extern unsigned long in_be64(const volatile unsigned long __iomem *addr);
51extern void out_le64(volatile unsigned long __iomem *addr, unsigned long val);
52extern void out_be64(volatile unsigned long __iomem *addr, unsigned long val);
53
54extern unsigned char __raw_readb(const volatile void __iomem *addr);
55extern unsigned short __raw_readw(const volatile void __iomem *addr);
56extern unsigned int __raw_readl(const volatile void __iomem *addr);
57extern unsigned long __raw_readq(const volatile void __iomem *addr);
58extern void __raw_writeb(unsigned char v, volatile void __iomem *addr);
59extern void __raw_writew(unsigned short v, volatile void __iomem *addr);
60extern void __raw_writel(unsigned int v, volatile void __iomem *addr);
61extern void __raw_writeq(unsigned long v, volatile void __iomem *addr);
62
63extern void memset_io(volatile void __iomem *addr, int c, unsigned long n);
64extern void memcpy_fromio(void *dest, const volatile void __iomem *src,
65 unsigned long n);
66extern void memcpy_toio(volatile void __iomem *dest, const void *src,
67 unsigned long n);
68
69#else /* CONFIG_PPC_ISERIES */
70
71#define in_8(addr) __in_8((addr))
72#define out_8(addr, val) __out_8((addr), (val))
73#define in_le16(addr) __in_le16((addr))
74#define in_be16(addr) __in_be16((addr))
75#define out_le16(addr, val) __out_le16((addr), (val))
76#define out_be16(addr, val) __out_be16((addr), (val))
77#define in_le32(addr) __in_le32((addr))
78#define in_be32(addr) __in_be32((addr))
79#define out_le32(addr, val) __out_le32((addr), (val))
80#define out_be32(addr, val) __out_be32((addr), (val))
81#define in_le64(addr) __in_le64((addr))
82#define in_be64(addr) __in_be64((addr))
83#define out_le64(addr, val) __out_le64((addr), (val))
84#define out_be64(addr, val) __out_be64((addr), (val))
85 251
86static inline unsigned char __raw_readb(const volatile void __iomem *addr) 252static inline unsigned char __raw_readb(const volatile void __iomem *addr)
87{ 253{
88 return *(volatile unsigned char __force *)addr; 254 return *(volatile unsigned char __force *)PCI_FIX_ADDR(addr);
89} 255}
90static inline unsigned short __raw_readw(const volatile void __iomem *addr) 256static inline unsigned short __raw_readw(const volatile void __iomem *addr)
91{ 257{
92 return *(volatile unsigned short __force *)addr; 258 return *(volatile unsigned short __force *)PCI_FIX_ADDR(addr);
93} 259}
94static inline unsigned int __raw_readl(const volatile void __iomem *addr) 260static inline unsigned int __raw_readl(const volatile void __iomem *addr)
95{ 261{
96 return *(volatile unsigned int __force *)addr; 262 return *(volatile unsigned int __force *)PCI_FIX_ADDR(addr);
97}
98static inline unsigned long __raw_readq(const volatile void __iomem *addr)
99{
100 return *(volatile unsigned long __force *)addr;
101} 263}
102static inline void __raw_writeb(unsigned char v, volatile void __iomem *addr) 264static inline void __raw_writeb(unsigned char v, volatile void __iomem *addr)
103{ 265{
104 *(volatile unsigned char __force *)addr = v; 266 *(volatile unsigned char __force *)PCI_FIX_ADDR(addr) = v;
105} 267}
106static inline void __raw_writew(unsigned short v, volatile void __iomem *addr) 268static inline void __raw_writew(unsigned short v, volatile void __iomem *addr)
107{ 269{
108 *(volatile unsigned short __force *)addr = v; 270 *(volatile unsigned short __force *)PCI_FIX_ADDR(addr) = v;
109} 271}
110static inline void __raw_writel(unsigned int v, volatile void __iomem *addr) 272static inline void __raw_writel(unsigned int v, volatile void __iomem *addr)
111{ 273{
112 *(volatile unsigned int __force *)addr = v; 274 *(volatile unsigned int __force *)PCI_FIX_ADDR(addr) = v;
275}
276
277#ifdef __powerpc64__
278static inline unsigned long __raw_readq(const volatile void __iomem *addr)
279{
280 return *(volatile unsigned long __force *)PCI_FIX_ADDR(addr);
113} 281}
114static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr) 282static inline void __raw_writeq(unsigned long v, volatile void __iomem *addr)
115{ 283{
116 *(volatile unsigned long __force *)addr = v; 284 *(volatile unsigned long __force *)PCI_FIX_ADDR(addr) = v;
285}
286#endif /* __powerpc64__ */
287
288/*
289 *
290 * PCI PIO and MMIO accessors.
291 *
292 *
293 * On 32 bits, PIO operations have a recovery mechanism in case they trigger
294 * machine checks (which they occasionally do when probing non existing
295 * IO ports on some platforms, like PowerMac and 8xx).
296 * I always found it to be of dubious reliability and I am tempted to get
297 * rid of it one of these days. So if you think it's important to keep it,
298 * please voice up asap. We never had it for 64 bits and I do not intend
299 * to port it over
300 */
301
302#ifdef CONFIG_PPC32
303
304#define __do_in_asm(name, op) \
305static inline unsigned int name(unsigned int port) \
306{ \
307 unsigned int x; \
308 __asm__ __volatile__( \
309 "sync\n" \
310 "0:" op " %0,0,%1\n" \
311 "1: twi 0,%0,0\n" \
312 "2: isync\n" \
313 "3: nop\n" \
314 "4:\n" \
315 ".section .fixup,\"ax\"\n" \
316 "5: li %0,-1\n" \
317 " b 4b\n" \
318 ".previous\n" \
319 ".section __ex_table,\"a\"\n" \
320 " .align 2\n" \
321 " .long 0b,5b\n" \
322 " .long 1b,5b\n" \
323 " .long 2b,5b\n" \
324 " .long 3b,5b\n" \
325 ".previous" \
326 : "=&r" (x) \
327 : "r" (port + _IO_BASE)); \
328 return x; \
329}
330
331#define __do_out_asm(name, op) \
332static inline void name(unsigned int val, unsigned int port) \
333{ \
334 __asm__ __volatile__( \
335 "sync\n" \
336 "0:" op " %0,0,%1\n" \
337 "1: sync\n" \
338 "2:\n" \
339 ".section __ex_table,\"a\"\n" \
340 " .align 2\n" \
341 " .long 0b,2b\n" \
342 " .long 1b,2b\n" \
343 ".previous" \
344 : : "r" (val), "r" (port + _IO_BASE)); \
345}
346
347__do_in_asm(_rec_inb, "lbzx")
348__do_in_asm(_rec_inw, "lhbrx")
349__do_in_asm(_rec_inl, "lwbrx")
350__do_out_asm(_rec_outb, "stbx")
351__do_out_asm(_rec_outw, "sthbrx")
352__do_out_asm(_rec_outl, "stwbrx")
353
354#endif /* CONFIG_PPC32 */
355
356/* The "__do_*" operations below provide the actual "base" implementation
357 * for each of the defined acccessor. Some of them use the out_* functions
358 * directly, some of them still use EEH, though we might change that in the
359 * future. Those macros below provide the necessary argument swapping and
360 * handling of the IO base for PIO.
361 *
362 * They are themselves used by the macros that define the actual accessors
363 * and can be used by the hooks if any.
364 *
365 * Note that PIO operations are always defined in terms of their corresonding
366 * MMIO operations. That allows platforms like iSeries who want to modify the
367 * behaviour of both to only hook on the MMIO version and get both. It's also
368 * possible to hook directly at the toplevel PIO operation if they have to
369 * be handled differently
370 */
371#define __do_writeb(val, addr) out_8(PCI_FIX_ADDR(addr), val)
372#define __do_writew(val, addr) out_le16(PCI_FIX_ADDR(addr), val)
373#define __do_writel(val, addr) out_le32(PCI_FIX_ADDR(addr), val)
374#define __do_writeq(val, addr) out_le64(PCI_FIX_ADDR(addr), val)
375#define __do_writew_be(val, addr) out_be16(PCI_FIX_ADDR(addr), val)
376#define __do_writel_be(val, addr) out_be32(PCI_FIX_ADDR(addr), val)
377#define __do_writeq_be(val, addr) out_be64(PCI_FIX_ADDR(addr), val)
378
379#ifdef CONFIG_EEH
380#define __do_readb(addr) eeh_readb(PCI_FIX_ADDR(addr))
381#define __do_readw(addr) eeh_readw(PCI_FIX_ADDR(addr))
382#define __do_readl(addr) eeh_readl(PCI_FIX_ADDR(addr))
383#define __do_readq(addr) eeh_readq(PCI_FIX_ADDR(addr))
384#define __do_readw_be(addr) eeh_readw_be(PCI_FIX_ADDR(addr))
385#define __do_readl_be(addr) eeh_readl_be(PCI_FIX_ADDR(addr))
386#define __do_readq_be(addr) eeh_readq_be(PCI_FIX_ADDR(addr))
387#else /* CONFIG_EEH */
388#define __do_readb(addr) in_8(PCI_FIX_ADDR(addr))
389#define __do_readw(addr) in_le16(PCI_FIX_ADDR(addr))
390#define __do_readl(addr) in_le32(PCI_FIX_ADDR(addr))
391#define __do_readq(addr) in_le64(PCI_FIX_ADDR(addr))
392#define __do_readw_be(addr) in_be16(PCI_FIX_ADDR(addr))
393#define __do_readl_be(addr) in_be32(PCI_FIX_ADDR(addr))
394#define __do_readq_be(addr) in_be64(PCI_FIX_ADDR(addr))
395#endif /* !defined(CONFIG_EEH) */
396
397#ifdef CONFIG_PPC32
398#define __do_outb(val, port) _rec_outb(val, port)
399#define __do_outw(val, port) _rec_outw(val, port)
400#define __do_outl(val, port) _rec_outl(val, port)
401#define __do_inb(port) _rec_inb(port)
402#define __do_inw(port) _rec_inw(port)
403#define __do_inl(port) _rec_inl(port)
404#else /* CONFIG_PPC32 */
405#define __do_outb(val, port) writeb(val,(PCI_IO_ADDR)_IO_BASE+port);
406#define __do_outw(val, port) writew(val,(PCI_IO_ADDR)_IO_BASE+port);
407#define __do_outl(val, port) writel(val,(PCI_IO_ADDR)_IO_BASE+port);
408#define __do_inb(port) readb((PCI_IO_ADDR)_IO_BASE + port);
409#define __do_inw(port) readw((PCI_IO_ADDR)_IO_BASE + port);
410#define __do_inl(port) readl((PCI_IO_ADDR)_IO_BASE + port);
411#endif /* !CONFIG_PPC32 */
412
413#ifdef CONFIG_EEH
414#define __do_readsb(a, b, n) eeh_readsb(PCI_FIX_ADDR(a), (b), (n))
415#define __do_readsw(a, b, n) eeh_readsw(PCI_FIX_ADDR(a), (b), (n))
416#define __do_readsl(a, b, n) eeh_readsl(PCI_FIX_ADDR(a), (b), (n))
417#else /* CONFIG_EEH */
418#define __do_readsb(a, b, n) _insb(PCI_FIX_ADDR(a), (b), (n))
419#define __do_readsw(a, b, n) _insw(PCI_FIX_ADDR(a), (b), (n))
420#define __do_readsl(a, b, n) _insl(PCI_FIX_ADDR(a), (b), (n))
421#endif /* !CONFIG_EEH */
422#define __do_writesb(a, b, n) _outsb(PCI_FIX_ADDR(a),(b),(n))
423#define __do_writesw(a, b, n) _outsw(PCI_FIX_ADDR(a),(b),(n))
424#define __do_writesl(a, b, n) _outsl(PCI_FIX_ADDR(a),(b),(n))
425
426#define __do_insb(p, b, n) readsb((PCI_IO_ADDR)_IO_BASE+(p), (b), (n))
427#define __do_insw(p, b, n) readsw((PCI_IO_ADDR)_IO_BASE+(p), (b), (n))
428#define __do_insl(p, b, n) readsl((PCI_IO_ADDR)_IO_BASE+(p), (b), (n))
429#define __do_outsb(p, b, n) writesb((PCI_IO_ADDR)_IO_BASE+(p),(b),(n))
430#define __do_outsw(p, b, n) writesw((PCI_IO_ADDR)_IO_BASE+(p),(b),(n))
431#define __do_outsl(p, b, n) writesl((PCI_IO_ADDR)_IO_BASE+(p),(b),(n))
432
433#define __do_memset_io(addr, c, n) \
434 _memset_io(PCI_FIX_ADDR(addr), c, n)
435#define __do_memcpy_toio(dst, src, n) \
436 _memcpy_toio(PCI_FIX_ADDR(dst), src, n)
437
438#ifdef CONFIG_EEH
439#define __do_memcpy_fromio(dst, src, n) \
440 eeh_memcpy_fromio(dst, PCI_FIX_ADDR(src), n)
441#else /* CONFIG_EEH */
442#define __do_memcpy_fromio(dst, src, n) \
443 _memcpy_fromio(dst,PCI_FIX_ADDR(src),n)
444#endif /* !CONFIG_EEH */
445
446#ifdef CONFIG_PPC_INDIRECT_IO
447#define DEF_PCI_HOOK(x) x
448#else
449#define DEF_PCI_HOOK(x) NULL
450#endif
451
452/* Structure containing all the hooks */
453extern struct ppc_pci_io {
454
455#define DEF_PCI_AC_RET(name, ret, at, al) ret (*name) at;
456#define DEF_PCI_AC_NORET(name, at, al) void (*name) at;
457
458#include <asm/io-defs.h>
459
460#undef DEF_PCI_AC_RET
461#undef DEF_PCI_AC_NORET
462
463} ppc_pci_io;
464
465/* The inline wrappers */
466#define DEF_PCI_AC_RET(name, ret, at, al) \
467static inline ret name at \
468{ \
469 if (DEF_PCI_HOOK(ppc_pci_io.name) != NULL) \
470 return ppc_pci_io.name al; \
471 return __do_##name al; \
472}
473
474#define DEF_PCI_AC_NORET(name, at, al) \
475static inline void name at \
476{ \
477 if (DEF_PCI_HOOK(ppc_pci_io.name) != NULL) \
478 ppc_pci_io.name al; \
479 else \
480 __do_##name al; \
117} 481}
118#define memset_io(a,b,c) eeh_memset_io((a),(b),(c))
119#define memcpy_fromio(a,b,c) eeh_memcpy_fromio((a),(b),(c))
120#define memcpy_toio(a,b,c) eeh_memcpy_toio((a),(b),(c))
121 482
122#endif /* CONFIG_PPC_ISERIES */ 483#include <asm/io-defs.h>
484
485#undef DEF_PCI_AC_RET
486#undef DEF_PCI_AC_NORET
487
488/* Some drivers check for the presence of readq & writeq with
489 * a #ifdef, so we make them happy here.
490 */
491#ifdef __powerpc64__
492#define readq readq
493#define writeq writeq
494#endif
495
496#ifdef CONFIG_NOT_COHERENT_CACHE
497
498#define dma_cache_inv(_start,_size) \
499 invalidate_dcache_range(_start, (_start + _size))
500#define dma_cache_wback(_start,_size) \
501 clean_dcache_range(_start, (_start + _size))
502#define dma_cache_wback_inv(_start,_size) \
503 flush_dcache_range(_start, (_start + _size))
504
505#else /* CONFIG_NOT_COHERENT_CACHE */
506
507#define dma_cache_inv(_start,_size) do { } while (0)
508#define dma_cache_wback(_start,_size) do { } while (0)
509#define dma_cache_wback_inv(_start,_size) do { } while (0)
510
511#endif /* !CONFIG_NOT_COHERENT_CACHE */
123 512
124/* 513/*
125 * The insw/outsw/insl/outsl macros don't do byte-swapping. 514 * Convert a physical pointer to a virtual kernel pointer for /dev/mem
126 * They are only used in practice for transferring buffers which 515 * access
127 * are arrays of bytes, and byte-swapping is not appropriate in 516 */
128 * that case. - paulus */ 517#define xlate_dev_mem_ptr(p) __va(p)
129#define insb(port, buf, ns) eeh_insb((port), (buf), (ns)) 518
130#define insw(port, buf, ns) eeh_insw_ns((port), (buf), (ns)) 519/*
131#define insl(port, buf, nl) eeh_insl_ns((port), (buf), (nl)) 520 * Convert a virtual cached pointer to an uncached pointer
132 521 */
133#define outsb(port, buf, ns) _outsb((u8 __iomem *)((port)+pci_io_base), (buf), (ns)) 522#define xlate_dev_kmem_ptr(p) p
134#define outsw(port, buf, ns) _outsw_ns((u16 __iomem *)((port)+pci_io_base), (buf), (ns))
135#define outsl(port, buf, nl) _outsl_ns((u32 __iomem *)((port)+pci_io_base), (buf), (nl))
136
137#define readb(addr) eeh_readb(addr)
138#define readw(addr) eeh_readw(addr)
139#define readl(addr) eeh_readl(addr)
140#define readq(addr) eeh_readq(addr)
141#define writeb(data, addr) eeh_writeb((data), (addr))
142#define writew(data, addr) eeh_writew((data), (addr))
143#define writel(data, addr) eeh_writel((data), (addr))
144#define writeq(data, addr) eeh_writeq((data), (addr))
145#define inb(port) eeh_inb((unsigned long)port)
146#define outb(val, port) eeh_outb(val, (unsigned long)port)
147#define inw(port) eeh_inw((unsigned long)port)
148#define outw(val, port) eeh_outw(val, (unsigned long)port)
149#define inl(port) eeh_inl((unsigned long)port)
150#define outl(val, port) eeh_outl(val, (unsigned long)port)
151 523
524/*
525 * We don't do relaxed operations yet, at least not with this semantic
526 */
152#define readb_relaxed(addr) readb(addr) 527#define readb_relaxed(addr) readb(addr)
153#define readw_relaxed(addr) readw(addr) 528#define readw_relaxed(addr) readw(addr)
154#define readl_relaxed(addr) readl(addr) 529#define readl_relaxed(addr) readl(addr)
155#define readq_relaxed(addr) readq(addr) 530#define readq_relaxed(addr) readq(addr)
156 531
157extern void _insb(volatile u8 __iomem *port, void *buf, long count); 532#ifdef CONFIG_PPC32
158extern void _outsb(volatile u8 __iomem *port, const void *buf, long count); 533#define mmiowb()
159extern void _insw_ns(volatile u16 __iomem *port, void *buf, long count); 534#else
160extern void _outsw_ns(volatile u16 __iomem *port, const void *buf, long count); 535/*
161extern void _insl_ns(volatile u32 __iomem *port, void *buf, long count); 536 * Enforce synchronisation of stores vs. spin_unlock
162extern void _outsl_ns(volatile u32 __iomem *port, const void *buf, long count); 537 * (this does it explicitely, though our implementation of spin_unlock
163 538 * does it implicitely too)
539 */
164static inline void mmiowb(void) 540static inline void mmiowb(void)
165{ 541{
166 unsigned long tmp; 542 unsigned long tmp;
@@ -169,6 +545,24 @@ static inline void mmiowb(void)
169 : "=&r" (tmp) : "i" (offsetof(struct paca_struct, io_sync)) 545 : "=&r" (tmp) : "i" (offsetof(struct paca_struct, io_sync))
170 : "memory"); 546 : "memory");
171} 547}
548#endif /* !CONFIG_PPC32 */
549
550static inline void iosync(void)
551{
552 __asm__ __volatile__ ("sync" : : : "memory");
553}
554
555/* Enforce in-order execution of data I/O.
556 * No distinction between read/write on PPC; use eieio for all three.
557 * Those are fairly week though. They don't provide a barrier between
558 * MMIO and cacheable storage nor do they provide a barrier vs. locks,
559 * they only provide barriers between 2 __raw MMIO operations and
560 * possibly break write combining.
561 */
562#define iobarrier_rw() eieio()
563#define iobarrier_r() eieio()
564#define iobarrier_w() eieio()
565
172 566
173/* 567/*
174 * output pause versions need a delay at least for the 568 * output pause versions need a delay at least for the
@@ -185,11 +579,6 @@ static inline void mmiowb(void)
185#define IO_SPACE_LIMIT ~(0UL) 579#define IO_SPACE_LIMIT ~(0UL)
186 580
187 581
188extern int __ioremap_explicit(unsigned long p_addr, unsigned long v_addr,
189 unsigned long size, unsigned long flags);
190extern void __iomem *__ioremap(unsigned long address, unsigned long size,
191 unsigned long flags);
192
193/** 582/**
194 * ioremap - map bus memory into CPU space 583 * ioremap - map bus memory into CPU space
195 * @address: bus address of the memory 584 * @address: bus address of the memory
@@ -200,14 +589,77 @@ extern void __iomem *__ioremap(unsigned long address, unsigned long size,
200 * writew/writel functions and the other mmio helpers. The returned 589 * writew/writel functions and the other mmio helpers. The returned
201 * address is not guaranteed to be usable directly as a virtual 590 * address is not guaranteed to be usable directly as a virtual
202 * address. 591 * address.
592 *
593 * We provide a few variations of it:
594 *
595 * * ioremap is the standard one and provides non-cacheable guarded mappings
596 * and can be hooked by the platform via ppc_md
597 *
598 * * ioremap_flags allows to specify the page flags as an argument and can
599 * also be hooked by the platform via ppc_md
600 *
601 * * ioremap_nocache is identical to ioremap
602 *
603 * * iounmap undoes such a mapping and can be hooked
604 *
605 * * __ioremap_explicit (and the pending __iounmap_explicit) are low level
606 * functions to create hand-made mappings for use only by the PCI code
607 * and cannot currently be hooked.
608 *
609 * * __ioremap is the low level implementation used by ioremap and
610 * ioremap_flags and cannot be hooked (but can be used by a hook on one
611 * of the previous ones)
612 *
613 * * __iounmap, is the low level implementation used by iounmap and cannot
614 * be hooked (but can be used by a hook on iounmap)
615 *
203 */ 616 */
204extern void __iomem *ioremap(unsigned long address, unsigned long size); 617extern void __iomem *ioremap(phys_addr_t address, unsigned long size);
205 618extern void __iomem *ioremap_flags(phys_addr_t address, unsigned long size,
619 unsigned long flags);
206#define ioremap_nocache(addr, size) ioremap((addr), (size)) 620#define ioremap_nocache(addr, size) ioremap((addr), (size))
207extern int iounmap_explicit(volatile void __iomem *addr, unsigned long size);
208extern void iounmap(volatile void __iomem *addr); 621extern void iounmap(volatile void __iomem *addr);
622
623extern void __iomem *__ioremap(phys_addr_t, unsigned long size,
624 unsigned long flags);
625extern void __iounmap(volatile void __iomem *addr);
626
627extern int __ioremap_explicit(phys_addr_t p_addr, unsigned long v_addr,
628 unsigned long size, unsigned long flags);
629extern int __iounmap_explicit(volatile void __iomem *start,
630 unsigned long size);
631
209extern void __iomem * reserve_phb_iospace(unsigned long size); 632extern void __iomem * reserve_phb_iospace(unsigned long size);
210 633
634/* Those are more 32 bits only functions */
635extern unsigned long iopa(unsigned long addr);
636extern unsigned long mm_ptov(unsigned long addr) __attribute_const__;
637extern void io_block_mapping(unsigned long virt, phys_addr_t phys,
638 unsigned int size, int flags);
639
640
641/*
642 * When CONFIG_PPC_INDIRECT_IO is set, we use the generic iomap implementation
643 * which needs some additional definitions here. They basically allow PIO
644 * space overall to be 1GB. This will work as long as we never try to use
645 * iomap to map MMIO below 1GB which should be fine on ppc64
646 */
647#define HAVE_ARCH_PIO_SIZE 1
648#define PIO_OFFSET 0x00000000UL
649#define PIO_MASK 0x3fffffffUL
650#define PIO_RESERVED 0x40000000UL
651
652#define mmio_read16be(addr) readw_be(addr)
653#define mmio_read32be(addr) readl_be(addr)
654#define mmio_write16be(val, addr) writew_be(val, addr)
655#define mmio_write32be(val, addr) writel_be(val, addr)
656#define mmio_insb(addr, dst, count) readsb(addr, dst, count)
657#define mmio_insw(addr, dst, count) readsw(addr, dst, count)
658#define mmio_insl(addr, dst, count) readsl(addr, dst, count)
659#define mmio_outsb(addr, src, count) writesb(addr, src, count)
660#define mmio_outsw(addr, src, count) writesw(addr, src, count)
661#define mmio_outsl(addr, src, count) writesl(addr, src, count)
662
211/** 663/**
212 * virt_to_phys - map virtual addresses to physical 664 * virt_to_phys - map virtual addresses to physical
213 * @address: address to remap 665 * @address: address to remap
@@ -254,178 +706,33 @@ static inline void * phys_to_virt(unsigned long address)
254 */ 706 */
255#define BIO_VMERGE_BOUNDARY 0 707#define BIO_VMERGE_BOUNDARY 0
256 708
257static inline void iosync(void)
258{
259 __asm__ __volatile__ ("sync" : : : "memory");
260}
261
262/* Enforce in-order execution of data I/O.
263 * No distinction between read/write on PPC; use eieio for all three.
264 */
265#define iobarrier_rw() eieio()
266#define iobarrier_r() eieio()
267#define iobarrier_w() eieio()
268
269/* 709/*
270 * 8, 16 and 32 bit, big and little endian I/O operations, with barrier. 710 * 32 bits still uses virt_to_bus() for it's implementation of DMA
271 * These routines do not perform EEH-related I/O address translation, 711 * mappings se we have to keep it defined here. We also have some old
272 * and should not be used directly by device drivers. Use inb/readb 712 * drivers (shame shame shame) that use bus_to_virt() and haven't been
273 * instead. 713 * fixed yet so I need to define it here.
274 */ 714 */
275static inline int __in_8(const volatile unsigned char __iomem *addr) 715#ifdef CONFIG_PPC32
276{
277 int ret;
278 716
279 __asm__ __volatile__("sync; lbz%U1%X1 %0,%1; twi 0,%0,0; isync" 717static inline unsigned long virt_to_bus(volatile void * address)
280 : "=r" (ret) : "m" (*addr));
281 return ret;
282}
283
284static inline void __out_8(volatile unsigned char __iomem *addr, int val)
285{
286 __asm__ __volatile__("sync; stb%U0%X0 %1,%0"
287 : "=m" (*addr) : "r" (val));
288 get_paca()->io_sync = 1;
289}
290
291static inline int __in_le16(const volatile unsigned short __iomem *addr)
292{ 718{
293 int ret; 719 if (address == NULL)
294 720 return 0;
295 __asm__ __volatile__("sync; lhbrx %0,0,%1; twi 0,%0,0; isync" 721 return __pa(address) + PCI_DRAM_OFFSET;
296 : "=r" (ret) : "r" (addr), "m" (*addr));
297 return ret;
298} 722}
299 723
300static inline int __in_be16(const volatile unsigned short __iomem *addr) 724static inline void * bus_to_virt(unsigned long address)
301{ 725{
302 int ret; 726 if (address == 0)
303 727 return NULL;
304 __asm__ __volatile__("sync; lhz%U1%X1 %0,%1; twi 0,%0,0; isync" 728 return __va(address - PCI_DRAM_OFFSET);
305 : "=r" (ret) : "m" (*addr));
306 return ret;
307} 729}
308 730
309static inline void __out_le16(volatile unsigned short __iomem *addr, int val) 731#define page_to_bus(page) (page_to_phys(page) + PCI_DRAM_OFFSET)
310{
311 __asm__ __volatile__("sync; sthbrx %1,0,%2"
312 : "=m" (*addr) : "r" (val), "r" (addr));
313 get_paca()->io_sync = 1;
314}
315
316static inline void __out_be16(volatile unsigned short __iomem *addr, int val)
317{
318 __asm__ __volatile__("sync; sth%U0%X0 %1,%0"
319 : "=m" (*addr) : "r" (val));
320 get_paca()->io_sync = 1;
321}
322
323static inline unsigned __in_le32(const volatile unsigned __iomem *addr)
324{
325 unsigned ret;
326
327 __asm__ __volatile__("sync; lwbrx %0,0,%1; twi 0,%0,0; isync"
328 : "=r" (ret) : "r" (addr), "m" (*addr));
329 return ret;
330}
331 732
332static inline unsigned __in_be32(const volatile unsigned __iomem *addr) 733#endif /* CONFIG_PPC32 */
333{
334 unsigned ret;
335
336 __asm__ __volatile__("sync; lwz%U1%X1 %0,%1; twi 0,%0,0; isync"
337 : "=r" (ret) : "m" (*addr));
338 return ret;
339}
340
341static inline void __out_le32(volatile unsigned __iomem *addr, int val)
342{
343 __asm__ __volatile__("sync; stwbrx %1,0,%2" : "=m" (*addr)
344 : "r" (val), "r" (addr));
345 get_paca()->io_sync = 1;
346}
347
348static inline void __out_be32(volatile unsigned __iomem *addr, int val)
349{
350 __asm__ __volatile__("sync; stw%U0%X0 %1,%0"
351 : "=m" (*addr) : "r" (val));
352 get_paca()->io_sync = 1;
353}
354
355static inline unsigned long __in_le64(const volatile unsigned long __iomem *addr)
356{
357 unsigned long tmp, ret;
358
359 __asm__ __volatile__(
360 "sync\n"
361 "ld %1,0(%2)\n"
362 "twi 0,%1,0\n"
363 "isync\n"
364 "rldimi %0,%1,5*8,1*8\n"
365 "rldimi %0,%1,3*8,2*8\n"
366 "rldimi %0,%1,1*8,3*8\n"
367 "rldimi %0,%1,7*8,4*8\n"
368 "rldicl %1,%1,32,0\n"
369 "rlwimi %0,%1,8,8,31\n"
370 "rlwimi %0,%1,24,16,23\n"
371 : "=r" (ret) , "=r" (tmp) : "b" (addr) , "m" (*addr));
372 return ret;
373}
374
375static inline unsigned long __in_be64(const volatile unsigned long __iomem *addr)
376{
377 unsigned long ret;
378 734
379 __asm__ __volatile__("sync; ld%U1%X1 %0,%1; twi 0,%0,0; isync"
380 : "=r" (ret) : "m" (*addr));
381 return ret;
382}
383
384static inline void __out_le64(volatile unsigned long __iomem *addr, unsigned long val)
385{
386 unsigned long tmp;
387
388 __asm__ __volatile__(
389 "rldimi %0,%1,5*8,1*8\n"
390 "rldimi %0,%1,3*8,2*8\n"
391 "rldimi %0,%1,1*8,3*8\n"
392 "rldimi %0,%1,7*8,4*8\n"
393 "rldicl %1,%1,32,0\n"
394 "rlwimi %0,%1,8,8,31\n"
395 "rlwimi %0,%1,24,16,23\n"
396 "sync\n"
397 "std %0,0(%3)"
398 : "=&r" (tmp) , "=&r" (val) : "1" (val) , "b" (addr) , "m" (*addr));
399 get_paca()->io_sync = 1;
400}
401
402static inline void __out_be64(volatile unsigned long __iomem *addr, unsigned long val)
403{
404 __asm__ __volatile__("sync; std%U0%X0 %1,%0" : "=m" (*addr) : "r" (val));
405 get_paca()->io_sync = 1;
406}
407
408#include <asm/eeh.h>
409
410/* Nothing to do */
411
412#define dma_cache_inv(_start,_size) do { } while (0)
413#define dma_cache_wback(_start,_size) do { } while (0)
414#define dma_cache_wback_inv(_start,_size) do { } while (0)
415
416
417/*
418 * Convert a physical pointer to a virtual kernel pointer for /dev/mem
419 * access
420 */
421#define xlate_dev_mem_ptr(p) __va(p)
422
423/*
424 * Convert a virtual cached pointer to an uncached pointer
425 */
426#define xlate_dev_kmem_ptr(p) p
427 735
428#endif /* __KERNEL__ */ 736#endif /* __KERNEL__ */
429 737
430#endif /* CONFIG_PPC64 */
431#endif /* _ASM_POWERPC_IO_H */ 738#endif /* _ASM_POWERPC_IO_H */
diff --git a/include/asm-powerpc/iommu.h b/include/asm-powerpc/iommu.h
index 39fad685ffab..f85dbd305558 100644
--- a/include/asm-powerpc/iommu.h
+++ b/include/asm-powerpc/iommu.h
@@ -34,7 +34,9 @@
34#define IOMMU_PAGE_MASK (~((1 << IOMMU_PAGE_SHIFT) - 1)) 34#define IOMMU_PAGE_MASK (~((1 << IOMMU_PAGE_SHIFT) - 1))
35#define IOMMU_PAGE_ALIGN(addr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE) 35#define IOMMU_PAGE_ALIGN(addr) _ALIGN_UP(addr, IOMMU_PAGE_SIZE)
36 36
37#ifndef __ASSEMBLY__ 37/* Boot time flags */
38extern int iommu_is_off;
39extern int iommu_force_on;
38 40
39/* Pure 2^n version of get_order */ 41/* Pure 2^n version of get_order */
40static __inline__ __attribute_const__ int get_iommu_order(unsigned long size) 42static __inline__ __attribute_const__ int get_iommu_order(unsigned long size)
@@ -42,8 +44,6 @@ static __inline__ __attribute_const__ int get_iommu_order(unsigned long size)
42 return __ilog2((size - 1) >> IOMMU_PAGE_SHIFT) + 1; 44 return __ilog2((size - 1) >> IOMMU_PAGE_SHIFT) + 1;
43} 45}
44 46
45#endif /* __ASSEMBLY__ */
46
47 47
48/* 48/*
49 * IOMAP_MAX_ORDER defines the largest contiguous block 49 * IOMAP_MAX_ORDER defines the largest contiguous block
@@ -70,39 +70,31 @@ struct iommu_table {
70struct scatterlist; 70struct scatterlist;
71struct device_node; 71struct device_node;
72 72
73#ifdef CONFIG_PPC_MULTIPLATFORM
74
75/* Walks all buses and creates iommu tables */
76extern void iommu_setup_pSeries(void);
77extern void iommu_setup_dart(void);
78
79/* Frees table for an individual device node */ 73/* Frees table for an individual device node */
80extern void iommu_free_table(struct device_node *dn); 74extern void iommu_free_table(struct device_node *dn);
81 75
82#endif /* CONFIG_PPC_MULTIPLATFORM */
83
84/* Initializes an iommu_table based in values set in the passed-in 76/* Initializes an iommu_table based in values set in the passed-in
85 * structure 77 * structure
86 */ 78 */
87extern struct iommu_table *iommu_init_table(struct iommu_table * tbl, 79extern struct iommu_table *iommu_init_table(struct iommu_table * tbl,
88 int nid); 80 int nid);
89 81
90extern int iommu_map_sg(struct device *dev, struct iommu_table *tbl, 82extern int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
91 struct scatterlist *sglist, int nelems, unsigned long mask, 83 int nelems, unsigned long mask,
92 enum dma_data_direction direction); 84 enum dma_data_direction direction);
93extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, 85extern void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
94 int nelems, enum dma_data_direction direction); 86 int nelems, enum dma_data_direction direction);
95 87
96extern void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size, 88extern void *iommu_alloc_coherent(struct iommu_table *tbl, size_t size,
97 dma_addr_t *dma_handle, unsigned long mask, 89 dma_addr_t *dma_handle, unsigned long mask,
98 gfp_t flag, int node); 90 gfp_t flag, int node);
99extern void iommu_free_coherent(struct iommu_table *tbl, size_t size, 91extern void iommu_free_coherent(struct iommu_table *tbl, size_t size,
100 void *vaddr, dma_addr_t dma_handle); 92 void *vaddr, dma_addr_t dma_handle);
101extern dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr, 93extern dma_addr_t iommu_map_single(struct iommu_table *tbl, void *vaddr,
102 size_t size, unsigned long mask, 94 size_t size, unsigned long mask,
103 enum dma_data_direction direction); 95 enum dma_data_direction direction);
104extern void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle, 96extern void iommu_unmap_single(struct iommu_table *tbl, dma_addr_t dma_handle,
105 size_t size, enum dma_data_direction direction); 97 size_t size, enum dma_data_direction direction);
106 98
107extern void iommu_init_early_pSeries(void); 99extern void iommu_init_early_pSeries(void);
108extern void iommu_init_early_iSeries(void); 100extern void iommu_init_early_iSeries(void);
diff --git a/include/asm-powerpc/irq.h b/include/asm-powerpc/irq.h
index f960f5346f40..46476e9a494a 100644
--- a/include/asm-powerpc/irq.h
+++ b/include/asm-powerpc/irq.h
@@ -135,6 +135,10 @@ struct irq_map_entry {
135 135
136extern struct irq_map_entry irq_map[NR_IRQS]; 136extern struct irq_map_entry irq_map[NR_IRQS];
137 137
138static inline irq_hw_number_t virq_to_hw(unsigned int virq)
139{
140 return irq_map[virq].hwirq;
141}
138 142
139/** 143/**
140 * irq_alloc_host - Allocate a new irq_host data structure 144 * irq_alloc_host - Allocate a new irq_host data structure
diff --git a/include/asm-powerpc/iseries/iommu.h b/include/asm-powerpc/iseries/iommu.h
index 0edbfe10cb37..6e323a13ac30 100644
--- a/include/asm-powerpc/iseries/iommu.h
+++ b/include/asm-powerpc/iseries/iommu.h
@@ -21,11 +21,13 @@
21 * Boston, MA 02111-1307 USA 21 * Boston, MA 02111-1307 USA
22 */ 22 */
23 23
24struct pci_dev;
24struct device_node; 25struct device_node;
25struct iommu_table; 26struct iommu_table;
26 27
27/* Creates table for an individual device node */ 28/* Creates table for an individual device node */
28extern void iommu_devnode_init_iSeries(struct device_node *dn); 29extern void iommu_devnode_init_iSeries(struct pci_dev *pdev,
30 struct device_node *dn);
29 31
30/* Get table parameters from HV */ 32/* Get table parameters from HV */
31extern void iommu_table_getparms_iSeries(unsigned long busno, 33extern void iommu_table_getparms_iSeries(unsigned long busno,
diff --git a/include/asm-powerpc/lv1call.h b/include/asm-powerpc/lv1call.h
new file mode 100644
index 000000000000..f733beeea63a
--- /dev/null
+++ b/include/asm-powerpc/lv1call.h
@@ -0,0 +1,345 @@
1/*
2 * PS3 hvcall interface.
3 *
4 * Copyright (C) 2006 Sony Computer Entertainment Inc.
5 * Copyright 2006 Sony Corp.
6 * Copyright 2003, 2004 (c) MontaVista Software, Inc.
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; version 2 of the License.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#if !defined(_ASM_POWERPC_LV1CALL_H)
23#define _ASM_POWERPC_LV1CALL_H
24
25#if !defined(__ASSEMBLY__)
26
27#include <linux/types.h>
28
29/* lv1 call declaration macros */
30
31#define LV1_1_IN_ARG_DECL u64 in_1
32#define LV1_2_IN_ARG_DECL LV1_1_IN_ARG_DECL, u64 in_2
33#define LV1_3_IN_ARG_DECL LV1_2_IN_ARG_DECL, u64 in_3
34#define LV1_4_IN_ARG_DECL LV1_3_IN_ARG_DECL, u64 in_4
35#define LV1_5_IN_ARG_DECL LV1_4_IN_ARG_DECL, u64 in_5
36#define LV1_6_IN_ARG_DECL LV1_5_IN_ARG_DECL, u64 in_6
37#define LV1_7_IN_ARG_DECL LV1_6_IN_ARG_DECL, u64 in_7
38#define LV1_8_IN_ARG_DECL LV1_7_IN_ARG_DECL, u64 in_8
39#define LV1_1_OUT_ARG_DECL u64 *out_1
40#define LV1_2_OUT_ARG_DECL LV1_1_OUT_ARG_DECL, u64 *out_2
41#define LV1_3_OUT_ARG_DECL LV1_2_OUT_ARG_DECL, u64 *out_3
42#define LV1_4_OUT_ARG_DECL LV1_3_OUT_ARG_DECL, u64 *out_4
43#define LV1_5_OUT_ARG_DECL LV1_4_OUT_ARG_DECL, u64 *out_5
44#define LV1_6_OUT_ARG_DECL LV1_5_OUT_ARG_DECL, u64 *out_6
45#define LV1_7_OUT_ARG_DECL LV1_6_OUT_ARG_DECL, u64 *out_7
46
47#define LV1_0_IN_0_OUT_ARG_DECL void
48#define LV1_1_IN_0_OUT_ARG_DECL LV1_1_IN_ARG_DECL
49#define LV1_2_IN_0_OUT_ARG_DECL LV1_2_IN_ARG_DECL
50#define LV1_3_IN_0_OUT_ARG_DECL LV1_3_IN_ARG_DECL
51#define LV1_4_IN_0_OUT_ARG_DECL LV1_4_IN_ARG_DECL
52#define LV1_5_IN_0_OUT_ARG_DECL LV1_5_IN_ARG_DECL
53#define LV1_6_IN_0_OUT_ARG_DECL LV1_6_IN_ARG_DECL
54#define LV1_7_IN_0_OUT_ARG_DECL LV1_7_IN_ARG_DECL
55
56#define LV1_0_IN_1_OUT_ARG_DECL LV1_1_OUT_ARG_DECL
57#define LV1_1_IN_1_OUT_ARG_DECL LV1_1_IN_ARG_DECL, LV1_1_OUT_ARG_DECL
58#define LV1_2_IN_1_OUT_ARG_DECL LV1_2_IN_ARG_DECL, LV1_1_OUT_ARG_DECL
59#define LV1_3_IN_1_OUT_ARG_DECL LV1_3_IN_ARG_DECL, LV1_1_OUT_ARG_DECL
60#define LV1_4_IN_1_OUT_ARG_DECL LV1_4_IN_ARG_DECL, LV1_1_OUT_ARG_DECL
61#define LV1_5_IN_1_OUT_ARG_DECL LV1_5_IN_ARG_DECL, LV1_1_OUT_ARG_DECL
62#define LV1_6_IN_1_OUT_ARG_DECL LV1_6_IN_ARG_DECL, LV1_1_OUT_ARG_DECL
63#define LV1_7_IN_1_OUT_ARG_DECL LV1_7_IN_ARG_DECL, LV1_1_OUT_ARG_DECL
64#define LV1_8_IN_1_OUT_ARG_DECL LV1_8_IN_ARG_DECL, LV1_1_OUT_ARG_DECL
65
66#define LV1_0_IN_2_OUT_ARG_DECL LV1_2_OUT_ARG_DECL
67#define LV1_1_IN_2_OUT_ARG_DECL LV1_1_IN_ARG_DECL, LV1_2_OUT_ARG_DECL
68#define LV1_2_IN_2_OUT_ARG_DECL LV1_2_IN_ARG_DECL, LV1_2_OUT_ARG_DECL
69#define LV1_3_IN_2_OUT_ARG_DECL LV1_3_IN_ARG_DECL, LV1_2_OUT_ARG_DECL
70#define LV1_4_IN_2_OUT_ARG_DECL LV1_4_IN_ARG_DECL, LV1_2_OUT_ARG_DECL
71#define LV1_5_IN_2_OUT_ARG_DECL LV1_5_IN_ARG_DECL, LV1_2_OUT_ARG_DECL
72#define LV1_6_IN_2_OUT_ARG_DECL LV1_6_IN_ARG_DECL, LV1_2_OUT_ARG_DECL
73#define LV1_7_IN_2_OUT_ARG_DECL LV1_7_IN_ARG_DECL, LV1_2_OUT_ARG_DECL
74
75#define LV1_0_IN_3_OUT_ARG_DECL LV1_3_OUT_ARG_DECL
76#define LV1_1_IN_3_OUT_ARG_DECL LV1_1_IN_ARG_DECL, LV1_3_OUT_ARG_DECL
77#define LV1_2_IN_3_OUT_ARG_DECL LV1_2_IN_ARG_DECL, LV1_3_OUT_ARG_DECL
78#define LV1_3_IN_3_OUT_ARG_DECL LV1_3_IN_ARG_DECL, LV1_3_OUT_ARG_DECL
79#define LV1_4_IN_3_OUT_ARG_DECL LV1_4_IN_ARG_DECL, LV1_3_OUT_ARG_DECL
80#define LV1_5_IN_3_OUT_ARG_DECL LV1_5_IN_ARG_DECL, LV1_3_OUT_ARG_DECL
81#define LV1_6_IN_3_OUT_ARG_DECL LV1_6_IN_ARG_DECL, LV1_3_OUT_ARG_DECL
82#define LV1_7_IN_3_OUT_ARG_DECL LV1_7_IN_ARG_DECL, LV1_3_OUT_ARG_DECL
83
84#define LV1_0_IN_4_OUT_ARG_DECL LV1_4_OUT_ARG_DECL
85#define LV1_1_IN_4_OUT_ARG_DECL LV1_1_IN_ARG_DECL, LV1_4_OUT_ARG_DECL
86#define LV1_2_IN_4_OUT_ARG_DECL LV1_2_IN_ARG_DECL, LV1_4_OUT_ARG_DECL
87#define LV1_3_IN_4_OUT_ARG_DECL LV1_3_IN_ARG_DECL, LV1_4_OUT_ARG_DECL
88#define LV1_4_IN_4_OUT_ARG_DECL LV1_4_IN_ARG_DECL, LV1_4_OUT_ARG_DECL
89#define LV1_5_IN_4_OUT_ARG_DECL LV1_5_IN_ARG_DECL, LV1_4_OUT_ARG_DECL
90#define LV1_6_IN_4_OUT_ARG_DECL LV1_6_IN_ARG_DECL, LV1_4_OUT_ARG_DECL
91#define LV1_7_IN_4_OUT_ARG_DECL LV1_7_IN_ARG_DECL, LV1_4_OUT_ARG_DECL
92
93#define LV1_0_IN_5_OUT_ARG_DECL LV1_5_OUT_ARG_DECL
94#define LV1_1_IN_5_OUT_ARG_DECL LV1_1_IN_ARG_DECL, LV1_5_OUT_ARG_DECL
95#define LV1_2_IN_5_OUT_ARG_DECL LV1_2_IN_ARG_DECL, LV1_5_OUT_ARG_DECL
96#define LV1_3_IN_5_OUT_ARG_DECL LV1_3_IN_ARG_DECL, LV1_5_OUT_ARG_DECL
97#define LV1_4_IN_5_OUT_ARG_DECL LV1_4_IN_ARG_DECL, LV1_5_OUT_ARG_DECL
98#define LV1_5_IN_5_OUT_ARG_DECL LV1_5_IN_ARG_DECL, LV1_5_OUT_ARG_DECL
99#define LV1_6_IN_5_OUT_ARG_DECL LV1_6_IN_ARG_DECL, LV1_5_OUT_ARG_DECL
100#define LV1_7_IN_5_OUT_ARG_DECL LV1_7_IN_ARG_DECL, LV1_5_OUT_ARG_DECL
101
102#define LV1_0_IN_6_OUT_ARG_DECL LV1_6_OUT_ARG_DECL
103#define LV1_1_IN_6_OUT_ARG_DECL LV1_1_IN_ARG_DECL, LV1_6_OUT_ARG_DECL
104#define LV1_2_IN_6_OUT_ARG_DECL LV1_2_IN_ARG_DECL, LV1_6_OUT_ARG_DECL
105#define LV1_3_IN_6_OUT_ARG_DECL LV1_3_IN_ARG_DECL, LV1_6_OUT_ARG_DECL
106#define LV1_4_IN_6_OUT_ARG_DECL LV1_4_IN_ARG_DECL, LV1_6_OUT_ARG_DECL
107#define LV1_5_IN_6_OUT_ARG_DECL LV1_5_IN_ARG_DECL, LV1_6_OUT_ARG_DECL
108#define LV1_6_IN_6_OUT_ARG_DECL LV1_6_IN_ARG_DECL, LV1_6_OUT_ARG_DECL
109#define LV1_7_IN_6_OUT_ARG_DECL LV1_7_IN_ARG_DECL, LV1_6_OUT_ARG_DECL
110
111#define LV1_0_IN_7_OUT_ARG_DECL LV1_7_OUT_ARG_DECL
112#define LV1_1_IN_7_OUT_ARG_DECL LV1_1_IN_ARG_DECL, LV1_7_OUT_ARG_DECL
113#define LV1_2_IN_7_OUT_ARG_DECL LV1_2_IN_ARG_DECL, LV1_7_OUT_ARG_DECL
114#define LV1_3_IN_7_OUT_ARG_DECL LV1_3_IN_ARG_DECL, LV1_7_OUT_ARG_DECL
115#define LV1_4_IN_7_OUT_ARG_DECL LV1_4_IN_ARG_DECL, LV1_7_OUT_ARG_DECL
116#define LV1_5_IN_7_OUT_ARG_DECL LV1_5_IN_ARG_DECL, LV1_7_OUT_ARG_DECL
117#define LV1_6_IN_7_OUT_ARG_DECL LV1_6_IN_ARG_DECL, LV1_7_OUT_ARG_DECL
118#define LV1_7_IN_7_OUT_ARG_DECL LV1_7_IN_ARG_DECL, LV1_7_OUT_ARG_DECL
119
120#define LV1_1_IN_ARGS in_1
121#define LV1_2_IN_ARGS LV1_1_IN_ARGS, in_2
122#define LV1_3_IN_ARGS LV1_2_IN_ARGS, in_3
123#define LV1_4_IN_ARGS LV1_3_IN_ARGS, in_4
124#define LV1_5_IN_ARGS LV1_4_IN_ARGS, in_5
125#define LV1_6_IN_ARGS LV1_5_IN_ARGS, in_6
126#define LV1_7_IN_ARGS LV1_6_IN_ARGS, in_7
127#define LV1_8_IN_ARGS LV1_7_IN_ARGS, in_8
128
129#define LV1_1_OUT_ARGS out_1
130#define LV1_2_OUT_ARGS LV1_1_OUT_ARGS, out_2
131#define LV1_3_OUT_ARGS LV1_2_OUT_ARGS, out_3
132#define LV1_4_OUT_ARGS LV1_3_OUT_ARGS, out_4
133#define LV1_5_OUT_ARGS LV1_4_OUT_ARGS, out_5
134#define LV1_6_OUT_ARGS LV1_5_OUT_ARGS, out_6
135#define LV1_7_OUT_ARGS LV1_6_OUT_ARGS, out_7
136
137#define LV1_0_IN_0_OUT_ARGS
138#define LV1_1_IN_0_OUT_ARGS LV1_1_IN_ARGS
139#define LV1_2_IN_0_OUT_ARGS LV1_2_IN_ARGS
140#define LV1_3_IN_0_OUT_ARGS LV1_3_IN_ARGS
141#define LV1_4_IN_0_OUT_ARGS LV1_4_IN_ARGS
142#define LV1_5_IN_0_OUT_ARGS LV1_5_IN_ARGS
143#define LV1_6_IN_0_OUT_ARGS LV1_6_IN_ARGS
144#define LV1_7_IN_0_OUT_ARGS LV1_7_IN_ARGS
145
146#define LV1_0_IN_1_OUT_ARGS LV1_1_OUT_ARGS
147#define LV1_1_IN_1_OUT_ARGS LV1_1_IN_ARGS, LV1_1_OUT_ARGS
148#define LV1_2_IN_1_OUT_ARGS LV1_2_IN_ARGS, LV1_1_OUT_ARGS
149#define LV1_3_IN_1_OUT_ARGS LV1_3_IN_ARGS, LV1_1_OUT_ARGS
150#define LV1_4_IN_1_OUT_ARGS LV1_4_IN_ARGS, LV1_1_OUT_ARGS
151#define LV1_5_IN_1_OUT_ARGS LV1_5_IN_ARGS, LV1_1_OUT_ARGS
152#define LV1_6_IN_1_OUT_ARGS LV1_6_IN_ARGS, LV1_1_OUT_ARGS
153#define LV1_7_IN_1_OUT_ARGS LV1_7_IN_ARGS, LV1_1_OUT_ARGS
154#define LV1_8_IN_1_OUT_ARGS LV1_8_IN_ARGS, LV1_1_OUT_ARGS
155
156#define LV1_0_IN_2_OUT_ARGS LV1_2_OUT_ARGS
157#define LV1_1_IN_2_OUT_ARGS LV1_1_IN_ARGS, LV1_2_OUT_ARGS
158#define LV1_2_IN_2_OUT_ARGS LV1_2_IN_ARGS, LV1_2_OUT_ARGS
159#define LV1_3_IN_2_OUT_ARGS LV1_3_IN_ARGS, LV1_2_OUT_ARGS
160#define LV1_4_IN_2_OUT_ARGS LV1_4_IN_ARGS, LV1_2_OUT_ARGS
161#define LV1_5_IN_2_OUT_ARGS LV1_5_IN_ARGS, LV1_2_OUT_ARGS
162#define LV1_6_IN_2_OUT_ARGS LV1_6_IN_ARGS, LV1_2_OUT_ARGS
163#define LV1_7_IN_2_OUT_ARGS LV1_7_IN_ARGS, LV1_2_OUT_ARGS
164
165#define LV1_0_IN_3_OUT_ARGS LV1_3_OUT_ARGS
166#define LV1_1_IN_3_OUT_ARGS LV1_1_IN_ARGS, LV1_3_OUT_ARGS
167#define LV1_2_IN_3_OUT_ARGS LV1_2_IN_ARGS, LV1_3_OUT_ARGS
168#define LV1_3_IN_3_OUT_ARGS LV1_3_IN_ARGS, LV1_3_OUT_ARGS
169#define LV1_4_IN_3_OUT_ARGS LV1_4_IN_ARGS, LV1_3_OUT_ARGS
170#define LV1_5_IN_3_OUT_ARGS LV1_5_IN_ARGS, LV1_3_OUT_ARGS
171#define LV1_6_IN_3_OUT_ARGS LV1_6_IN_ARGS, LV1_3_OUT_ARGS
172#define LV1_7_IN_3_OUT_ARGS LV1_7_IN_ARGS, LV1_3_OUT_ARGS
173
174#define LV1_0_IN_4_OUT_ARGS LV1_4_OUT_ARGS
175#define LV1_1_IN_4_OUT_ARGS LV1_1_IN_ARGS, LV1_4_OUT_ARGS
176#define LV1_2_IN_4_OUT_ARGS LV1_2_IN_ARGS, LV1_4_OUT_ARGS
177#define LV1_3_IN_4_OUT_ARGS LV1_3_IN_ARGS, LV1_4_OUT_ARGS
178#define LV1_4_IN_4_OUT_ARGS LV1_4_IN_ARGS, LV1_4_OUT_ARGS
179#define LV1_5_IN_4_OUT_ARGS LV1_5_IN_ARGS, LV1_4_OUT_ARGS
180#define LV1_6_IN_4_OUT_ARGS LV1_6_IN_ARGS, LV1_4_OUT_ARGS
181#define LV1_7_IN_4_OUT_ARGS LV1_7_IN_ARGS, LV1_4_OUT_ARGS
182
183#define LV1_0_IN_5_OUT_ARGS LV1_5_OUT_ARGS
184#define LV1_1_IN_5_OUT_ARGS LV1_1_IN_ARGS, LV1_5_OUT_ARGS
185#define LV1_2_IN_5_OUT_ARGS LV1_2_IN_ARGS, LV1_5_OUT_ARGS
186#define LV1_3_IN_5_OUT_ARGS LV1_3_IN_ARGS, LV1_5_OUT_ARGS
187#define LV1_4_IN_5_OUT_ARGS LV1_4_IN_ARGS, LV1_5_OUT_ARGS
188#define LV1_5_IN_5_OUT_ARGS LV1_5_IN_ARGS, LV1_5_OUT_ARGS
189#define LV1_6_IN_5_OUT_ARGS LV1_6_IN_ARGS, LV1_5_OUT_ARGS
190#define LV1_7_IN_5_OUT_ARGS LV1_7_IN_ARGS, LV1_5_OUT_ARGS
191
192#define LV1_0_IN_6_OUT_ARGS LV1_6_OUT_ARGS
193#define LV1_1_IN_6_OUT_ARGS LV1_1_IN_ARGS, LV1_6_OUT_ARGS
194#define LV1_2_IN_6_OUT_ARGS LV1_2_IN_ARGS, LV1_6_OUT_ARGS
195#define LV1_3_IN_6_OUT_ARGS LV1_3_IN_ARGS, LV1_6_OUT_ARGS
196#define LV1_4_IN_6_OUT_ARGS LV1_4_IN_ARGS, LV1_6_OUT_ARGS
197#define LV1_5_IN_6_OUT_ARGS LV1_5_IN_ARGS, LV1_6_OUT_ARGS
198#define LV1_6_IN_6_OUT_ARGS LV1_6_IN_ARGS, LV1_6_OUT_ARGS
199#define LV1_7_IN_6_OUT_ARGS LV1_7_IN_ARGS, LV1_6_OUT_ARGS
200
201#define LV1_0_IN_7_OUT_ARGS LV1_7_OUT_ARGS
202#define LV1_1_IN_7_OUT_ARGS LV1_1_IN_ARGS, LV1_7_OUT_ARGS
203#define LV1_2_IN_7_OUT_ARGS LV1_2_IN_ARGS, LV1_7_OUT_ARGS
204#define LV1_3_IN_7_OUT_ARGS LV1_3_IN_ARGS, LV1_7_OUT_ARGS
205#define LV1_4_IN_7_OUT_ARGS LV1_4_IN_ARGS, LV1_7_OUT_ARGS
206#define LV1_5_IN_7_OUT_ARGS LV1_5_IN_ARGS, LV1_7_OUT_ARGS
207#define LV1_6_IN_7_OUT_ARGS LV1_6_IN_ARGS, LV1_7_OUT_ARGS
208#define LV1_7_IN_7_OUT_ARGS LV1_7_IN_ARGS, LV1_7_OUT_ARGS
209
210/*
211 * This LV1_CALL() macro is for use by callers. It expands into an
212 * inline call wrapper and an underscored HV call declaration. The
213 * wrapper can be used to instrument the lv1 call interface. The
214 * file lv1call.S defines its own LV1_CALL() macro to expand into
215 * the actual underscored call definition.
216 */
217
218#if !defined(LV1_CALL)
219#define LV1_CALL(name, in, out, num) \
220 extern s64 _lv1_##name(LV1_##in##_IN_##out##_OUT_ARG_DECL); \
221 static inline int lv1_##name(LV1_##in##_IN_##out##_OUT_ARG_DECL) \
222 {return _lv1_##name(LV1_##in##_IN_##out##_OUT_ARGS);}
223#endif
224
225#endif /* !defined(__ASSEMBLY__) */
226
227/* lv1 call table */
228
229LV1_CALL(allocate_memory, 4, 2, 0 )
230LV1_CALL(write_htab_entry, 4, 0, 1 )
231LV1_CALL(construct_virtual_address_space, 3, 2, 2 )
232LV1_CALL(invalidate_htab_entries, 5, 0, 3 )
233LV1_CALL(get_virtual_address_space_id_of_ppe, 1, 1, 4 )
234LV1_CALL(query_logical_partition_address_region_info, 1, 5, 6 )
235LV1_CALL(select_virtual_address_space, 1, 0, 7 )
236LV1_CALL(pause, 1, 0, 9 )
237LV1_CALL(destruct_virtual_address_space, 1, 0, 10 )
238LV1_CALL(configure_irq_state_bitmap, 3, 0, 11 )
239LV1_CALL(connect_irq_plug_ext, 5, 0, 12 )
240LV1_CALL(release_memory, 1, 0, 13 )
241LV1_CALL(disconnect_irq_plug_ext, 3, 0, 17 )
242LV1_CALL(construct_event_receive_port, 0, 1, 18 )
243LV1_CALL(destruct_event_receive_port, 1, 0, 19 )
244LV1_CALL(send_event_locally, 1, 0, 24 )
245LV1_CALL(end_of_interrupt, 1, 0, 27 )
246LV1_CALL(connect_irq_plug, 2, 0, 28 )
247LV1_CALL(disconnect_irq_plug, 1, 0, 29 )
248LV1_CALL(end_of_interrupt_ext, 3, 0, 30 )
249LV1_CALL(did_update_interrupt_mask, 2, 0, 31 )
250LV1_CALL(shutdown_logical_partition, 1, 0, 44 )
251LV1_CALL(destruct_logical_spe, 1, 0, 54 )
252LV1_CALL(construct_logical_spe, 7, 6, 57 )
253LV1_CALL(set_spe_interrupt_mask, 3, 0, 61 )
254LV1_CALL(set_spe_transition_notifier, 3, 0, 64 )
255LV1_CALL(disable_logical_spe, 2, 0, 65 )
256LV1_CALL(clear_spe_interrupt_status, 4, 0, 66 )
257LV1_CALL(get_spe_interrupt_status, 2, 1, 67 )
258LV1_CALL(get_logical_ppe_id, 0, 1, 69 )
259LV1_CALL(set_interrupt_mask, 5, 0, 73 )
260LV1_CALL(get_logical_partition_id, 0, 1, 74 )
261LV1_CALL(configure_execution_time_variable, 1, 0, 77 )
262LV1_CALL(get_spe_irq_outlet, 2, 1, 78 )
263LV1_CALL(set_spe_privilege_state_area_1_register, 3, 0, 79 )
264LV1_CALL(create_repository_node, 6, 0, 90 )
265LV1_CALL(get_repository_node_value, 5, 2, 91 )
266LV1_CALL(modify_repository_node_value, 6, 0, 92 )
267LV1_CALL(remove_repository_node, 4, 0, 93 )
268LV1_CALL(read_htab_entries, 2, 5, 95 )
269LV1_CALL(set_dabr, 2, 0, 96 )
270LV1_CALL(get_total_execution_time, 2, 1, 103 )
271LV1_CALL(construct_io_irq_outlet, 1, 1, 120 )
272LV1_CALL(destruct_io_irq_outlet, 1, 0, 121 )
273LV1_CALL(map_htab, 1, 1, 122 )
274LV1_CALL(unmap_htab, 1, 0, 123 )
275LV1_CALL(get_version_info, 0, 1, 127 )
276LV1_CALL(insert_htab_entry, 6, 3, 158 )
277LV1_CALL(read_virtual_uart, 3, 1, 162 )
278LV1_CALL(write_virtual_uart, 3, 1, 163 )
279LV1_CALL(set_virtual_uart_param, 3, 0, 164 )
280LV1_CALL(get_virtual_uart_param, 2, 1, 165 )
281LV1_CALL(configure_virtual_uart_irq, 1, 1, 166 )
282LV1_CALL(open_device, 3, 0, 170 )
283LV1_CALL(close_device, 2, 0, 171 )
284LV1_CALL(map_device_mmio_region, 5, 1, 172 )
285LV1_CALL(unmap_device_mmio_region, 3, 0, 173 )
286LV1_CALL(allocate_device_dma_region, 5, 1, 174 )
287LV1_CALL(free_device_dma_region, 3, 0, 175 )
288LV1_CALL(map_device_dma_region, 6, 0, 176 )
289LV1_CALL(unmap_device_dma_region, 4, 0, 177 )
290LV1_CALL(net_add_multicast_address, 4, 0, 185 )
291LV1_CALL(net_remove_multicast_address, 4, 0, 186 )
292LV1_CALL(net_start_tx_dma, 4, 0, 187 )
293LV1_CALL(net_stop_tx_dma, 3, 0, 188 )
294LV1_CALL(net_start_rx_dma, 4, 0, 189 )
295LV1_CALL(net_stop_rx_dma, 3, 0, 190 )
296LV1_CALL(net_set_interrupt_status_indicator, 4, 0, 191 )
297LV1_CALL(net_set_interrupt_mask, 4, 0, 193 )
298LV1_CALL(net_control, 6, 2, 194 )
299LV1_CALL(connect_interrupt_event_receive_port, 4, 0, 197 )
300LV1_CALL(disconnect_interrupt_event_receive_port, 4, 0, 198 )
301LV1_CALL(get_spe_all_interrupt_statuses, 1, 1, 199 )
302LV1_CALL(deconfigure_virtual_uart_irq, 0, 0, 202 )
303LV1_CALL(enable_logical_spe, 2, 0, 207 )
304LV1_CALL(gpu_open, 1, 0, 210 )
305LV1_CALL(gpu_close, 0, 0, 211 )
306LV1_CALL(gpu_device_map, 1, 2, 212 )
307LV1_CALL(gpu_device_unmap, 1, 0, 213 )
308LV1_CALL(gpu_memory_allocate, 5, 2, 214 )
309LV1_CALL(gpu_memory_free, 1, 0, 216 )
310LV1_CALL(gpu_context_allocate, 2, 5, 217 )
311LV1_CALL(gpu_context_free, 1, 0, 218 )
312LV1_CALL(gpu_context_iomap, 5, 0, 221 )
313LV1_CALL(gpu_context_attribute, 6, 0, 225 )
314LV1_CALL(gpu_context_intr, 1, 1, 227 )
315LV1_CALL(gpu_attribute, 5, 0, 228 )
316LV1_CALL(get_rtc, 0, 2, 232 )
317LV1_CALL(set_ppe_periodic_tracer_frequency, 1, 0, 240 )
318LV1_CALL(start_ppe_periodic_tracer, 5, 0, 241 )
319LV1_CALL(stop_ppe_periodic_tracer, 1, 1, 242 )
320LV1_CALL(storage_read, 6, 1, 245 )
321LV1_CALL(storage_write, 6, 1, 246 )
322LV1_CALL(storage_send_device_command, 6, 1, 248 )
323LV1_CALL(storage_get_async_status, 1, 2, 249 )
324LV1_CALL(storage_check_async_status, 2, 1, 254 )
325LV1_CALL(panic, 1, 0, 255 )
326LV1_CALL(construct_lpm, 6, 3, 140 )
327LV1_CALL(destruct_lpm, 1, 0, 141 )
328LV1_CALL(start_lpm, 1, 0, 142 )
329LV1_CALL(stop_lpm, 1, 1, 143 )
330LV1_CALL(copy_lpm_trace_buffer, 3, 1, 144 )
331LV1_CALL(add_lpm_event_bookmark, 5, 0, 145 )
332LV1_CALL(delete_lpm_event_bookmark, 3, 0, 146 )
333LV1_CALL(set_lpm_interrupt_mask, 3, 1, 147 )
334LV1_CALL(get_lpm_interrupt_status, 1, 1, 148 )
335LV1_CALL(set_lpm_general_control, 5, 2, 149 )
336LV1_CALL(set_lpm_interval, 3, 1, 150 )
337LV1_CALL(set_lpm_trigger_control, 3, 1, 151 )
338LV1_CALL(set_lpm_counter_control, 4, 1, 152 )
339LV1_CALL(set_lpm_group_control, 3, 1, 153 )
340LV1_CALL(set_lpm_debug_bus_control, 3, 1, 154 )
341LV1_CALL(set_lpm_counter, 5, 2, 155 )
342LV1_CALL(set_lpm_signal, 7, 0, 156 )
343LV1_CALL(set_lpm_spr_trigger, 2, 0, 157 )
344
345#endif
diff --git a/include/asm-powerpc/machdep.h b/include/asm-powerpc/machdep.h
index dac90dc341cb..1b04e5723548 100644
--- a/include/asm-powerpc/machdep.h
+++ b/include/asm-powerpc/machdep.h
@@ -26,6 +26,7 @@ struct device_node;
26struct iommu_table; 26struct iommu_table;
27struct rtc_time; 27struct rtc_time;
28struct file; 28struct file;
29struct pci_controller;
29#ifdef CONFIG_KEXEC 30#ifdef CONFIG_KEXEC
30struct kimage; 31struct kimage;
31#endif 32#endif
@@ -84,9 +85,12 @@ struct machdep_calls {
84 unsigned long (*tce_get)(struct iommu_table *tbl, 85 unsigned long (*tce_get)(struct iommu_table *tbl,
85 long index); 86 long index);
86 void (*tce_flush)(struct iommu_table *tbl); 87 void (*tce_flush)(struct iommu_table *tbl);
87 void (*iommu_dev_setup)(struct pci_dev *dev); 88 void (*pci_dma_dev_setup)(struct pci_dev *dev);
88 void (*iommu_bus_setup)(struct pci_bus *bus); 89 void (*pci_dma_bus_setup)(struct pci_bus *bus);
89 void (*irq_bus_setup)(struct pci_bus *bus); 90
91 void __iomem * (*ioremap)(phys_addr_t addr, unsigned long size,
92 unsigned long flags);
93 void (*iounmap)(volatile void __iomem *token);
90#endif /* CONFIG_PPC64 */ 94#endif /* CONFIG_PPC64 */
91 95
92 int (*probe)(void); 96 int (*probe)(void);
@@ -106,6 +110,10 @@ struct machdep_calls {
106 /* Called after scanning the bus, before allocating resources */ 110 /* Called after scanning the bus, before allocating resources */
107 void (*pcibios_fixup)(void); 111 void (*pcibios_fixup)(void);
108 int (*pci_probe_mode)(struct pci_bus *); 112 int (*pci_probe_mode)(struct pci_bus *);
113 void (*pci_irq_fixup)(struct pci_dev *dev);
114
115 /* To setup PHBs when using automatic OF platform driver for PCI */
116 int (*pci_setup_phb)(struct pci_controller *host);
109 117
110 void (*restart)(char *cmd); 118 void (*restart)(char *cmd);
111 void (*power_off)(void); 119 void (*power_off)(void);
@@ -199,10 +207,6 @@ struct machdep_calls {
199 * Returns 0 to allow assignment/enabling of the device. */ 207 * Returns 0 to allow assignment/enabling of the device. */
200 int (*pcibios_enable_device_hook)(struct pci_dev *, int initial); 208 int (*pcibios_enable_device_hook)(struct pci_dev *, int initial);
201 209
202 /* For interrupt routing */
203 unsigned char (*pci_swizzle)(struct pci_dev *, unsigned char *);
204 int (*pci_map_irq)(struct pci_dev *, unsigned char, unsigned char);
205
206 /* Called in indirect_* to avoid touching devices */ 210 /* Called in indirect_* to avoid touching devices */
207 int (*pci_exclude_device)(unsigned char, unsigned char); 211 int (*pci_exclude_device)(unsigned char, unsigned char);
208 212
diff --git a/include/asm-powerpc/mmu.h b/include/asm-powerpc/mmu.h
index c3fc7a28e3cd..41c8c9c5a254 100644
--- a/include/asm-powerpc/mmu.h
+++ b/include/asm-powerpc/mmu.h
@@ -248,21 +248,6 @@ extern void hpte_init_native(void);
248extern void hpte_init_lpar(void); 248extern void hpte_init_lpar(void);
249extern void hpte_init_iSeries(void); 249extern void hpte_init_iSeries(void);
250 250
251extern long pSeries_lpar_hpte_insert(unsigned long hpte_group,
252 unsigned long va, unsigned long prpn,
253 unsigned long rflags,
254 unsigned long vflags, int psize);
255
256extern long native_hpte_insert(unsigned long hpte_group,
257 unsigned long va, unsigned long prpn,
258 unsigned long rflags,
259 unsigned long vflags, int psize);
260
261extern long iSeries_hpte_insert(unsigned long hpte_group,
262 unsigned long va, unsigned long prpn,
263 unsigned long rflags,
264 unsigned long vflags, int psize);
265
266extern void stabs_alloc(void); 251extern void stabs_alloc(void);
267extern void slb_initialize(void); 252extern void slb_initialize(void);
268extern void slb_flush_and_rebolt(void); 253extern void slb_flush_and_rebolt(void);
diff --git a/include/asm-powerpc/mpc52xx.h b/include/asm-powerpc/mpc52xx.h
new file mode 100644
index 000000000000..4a28a850998c
--- /dev/null
+++ b/include/asm-powerpc/mpc52xx.h
@@ -0,0 +1,254 @@
1/*
2 * Prototypes, etc. for the Freescale MPC52xx embedded cpu chips
3 * May need to be cleaned as the port goes on ...
4 *
5 * Copyright (C) 2004-2005 Sylvain Munaut <tnt@246tNt.com>
6 * Copyright (C) 2003 MontaVista, Software, Inc.
7 *
8 * This file is licensed under the terms of the GNU General Public License
9 * version 2. This program is licensed "as is" without any warranty of any
10 * kind, whether express or implied.
11 */
12
13#ifndef __ASM_POWERPC_MPC52xx_H__
14#define __ASM_POWERPC_MPC52xx_H__
15
16#ifndef __ASSEMBLY__
17#include <asm/types.h>
18#include <asm/prom.h>
19#endif /* __ASSEMBLY__ */
20
21
22/* ======================================================================== */
23/* Structures mapping of some unit register set */
24/* ======================================================================== */
25
26#ifndef __ASSEMBLY__
27
28/* Memory Mapping Control */
29struct mpc52xx_mmap_ctl {
30 u32 mbar; /* MMAP_CTRL + 0x00 */
31
32 u32 cs0_start; /* MMAP_CTRL + 0x04 */
33 u32 cs0_stop; /* MMAP_CTRL + 0x08 */
34 u32 cs1_start; /* MMAP_CTRL + 0x0c */
35 u32 cs1_stop; /* MMAP_CTRL + 0x10 */
36 u32 cs2_start; /* MMAP_CTRL + 0x14 */
37 u32 cs2_stop; /* MMAP_CTRL + 0x18 */
38 u32 cs3_start; /* MMAP_CTRL + 0x1c */
39 u32 cs3_stop; /* MMAP_CTRL + 0x20 */
40 u32 cs4_start; /* MMAP_CTRL + 0x24 */
41 u32 cs4_stop; /* MMAP_CTRL + 0x28 */
42 u32 cs5_start; /* MMAP_CTRL + 0x2c */
43 u32 cs5_stop; /* MMAP_CTRL + 0x30 */
44
45 u32 sdram0; /* MMAP_CTRL + 0x34 */
46 u32 sdram1; /* MMAP_CTRL + 0X38 */
47
48 u32 reserved[4]; /* MMAP_CTRL + 0x3c .. 0x48 */
49
50 u32 boot_start; /* MMAP_CTRL + 0x4c */
51 u32 boot_stop; /* MMAP_CTRL + 0x50 */
52
53 u32 ipbi_ws_ctrl; /* MMAP_CTRL + 0x54 */
54
55 u32 cs6_start; /* MMAP_CTRL + 0x58 */
56 u32 cs6_stop; /* MMAP_CTRL + 0x5c */
57 u32 cs7_start; /* MMAP_CTRL + 0x60 */
58 u32 cs7_stop; /* MMAP_CTRL + 0x64 */
59};
60
61/* SDRAM control */
62struct mpc52xx_sdram {
63 u32 mode; /* SDRAM + 0x00 */
64 u32 ctrl; /* SDRAM + 0x04 */
65 u32 config1; /* SDRAM + 0x08 */
66 u32 config2; /* SDRAM + 0x0c */
67};
68
69/* SDMA */
70struct mpc52xx_sdma {
71 u32 taskBar; /* SDMA + 0x00 */
72 u32 currentPointer; /* SDMA + 0x04 */
73 u32 endPointer; /* SDMA + 0x08 */
74 u32 variablePointer; /* SDMA + 0x0c */
75
76 u8 IntVect1; /* SDMA + 0x10 */
77 u8 IntVect2; /* SDMA + 0x11 */
78 u16 PtdCntrl; /* SDMA + 0x12 */
79
80 u32 IntPend; /* SDMA + 0x14 */
81 u32 IntMask; /* SDMA + 0x18 */
82
83 u16 tcr[16]; /* SDMA + 0x1c .. 0x3a */
84
85 u8 ipr[32]; /* SDMA + 0x3c .. 0x5b */
86
87 u32 cReqSelect; /* SDMA + 0x5c */
88 u32 task_size0; /* SDMA + 0x60 */
89 u32 task_size1; /* SDMA + 0x64 */
90 u32 MDEDebug; /* SDMA + 0x68 */
91 u32 ADSDebug; /* SDMA + 0x6c */
92 u32 Value1; /* SDMA + 0x70 */
93 u32 Value2; /* SDMA + 0x74 */
94 u32 Control; /* SDMA + 0x78 */
95 u32 Status; /* SDMA + 0x7c */
96 u32 PTDDebug; /* SDMA + 0x80 */
97};
98
99/* GPT */
100struct mpc52xx_gpt {
101 u32 mode; /* GPTx + 0x00 */
102 u32 count; /* GPTx + 0x04 */
103 u32 pwm; /* GPTx + 0x08 */
104 u32 status; /* GPTx + 0X0c */
105};
106
107/* GPIO */
108struct mpc52xx_gpio {
109 u32 port_config; /* GPIO + 0x00 */
110 u32 simple_gpioe; /* GPIO + 0x04 */
111 u32 simple_ode; /* GPIO + 0x08 */
112 u32 simple_ddr; /* GPIO + 0x0c */
113 u32 simple_dvo; /* GPIO + 0x10 */
114 u32 simple_ival; /* GPIO + 0x14 */
115 u8 outo_gpioe; /* GPIO + 0x18 */
116 u8 reserved1[3]; /* GPIO + 0x19 */
117 u8 outo_dvo; /* GPIO + 0x1c */
118 u8 reserved2[3]; /* GPIO + 0x1d */
119 u8 sint_gpioe; /* GPIO + 0x20 */
120 u8 reserved3[3]; /* GPIO + 0x21 */
121 u8 sint_ode; /* GPIO + 0x24 */
122 u8 reserved4[3]; /* GPIO + 0x25 */
123 u8 sint_ddr; /* GPIO + 0x28 */
124 u8 reserved5[3]; /* GPIO + 0x29 */
125 u8 sint_dvo; /* GPIO + 0x2c */
126 u8 reserved6[3]; /* GPIO + 0x2d */
127 u8 sint_inten; /* GPIO + 0x30 */
128 u8 reserved7[3]; /* GPIO + 0x31 */
129 u16 sint_itype; /* GPIO + 0x34 */
130 u16 reserved8; /* GPIO + 0x36 */
131 u8 gpio_control; /* GPIO + 0x38 */
132 u8 reserved9[3]; /* GPIO + 0x39 */
133 u8 sint_istat; /* GPIO + 0x3c */
134 u8 sint_ival; /* GPIO + 0x3d */
135 u8 bus_errs; /* GPIO + 0x3e */
136 u8 reserved10; /* GPIO + 0x3f */
137};
138
139#define MPC52xx_GPIO_PSC_CONFIG_UART_WITHOUT_CD 4
140#define MPC52xx_GPIO_PSC_CONFIG_UART_WITH_CD 5
141#define MPC52xx_GPIO_PCI_DIS (1<<15)
142
143/* GPIO with WakeUp*/
144struct mpc52xx_gpio_wkup {
145 u8 wkup_gpioe; /* GPIO_WKUP + 0x00 */
146 u8 reserved1[3]; /* GPIO_WKUP + 0x03 */
147 u8 wkup_ode; /* GPIO_WKUP + 0x04 */
148 u8 reserved2[3]; /* GPIO_WKUP + 0x05 */
149 u8 wkup_ddr; /* GPIO_WKUP + 0x08 */
150 u8 reserved3[3]; /* GPIO_WKUP + 0x09 */
151 u8 wkup_dvo; /* GPIO_WKUP + 0x0C */
152 u8 reserved4[3]; /* GPIO_WKUP + 0x0D */
153 u8 wkup_inten; /* GPIO_WKUP + 0x10 */
154 u8 reserved5[3]; /* GPIO_WKUP + 0x11 */
155 u8 wkup_iinten; /* GPIO_WKUP + 0x14 */
156 u8 reserved6[3]; /* GPIO_WKUP + 0x15 */
157 u16 wkup_itype; /* GPIO_WKUP + 0x18 */
158 u8 reserved7[2]; /* GPIO_WKUP + 0x1A */
159 u8 wkup_maste; /* GPIO_WKUP + 0x1C */
160 u8 reserved8[3]; /* GPIO_WKUP + 0x1D */
161 u8 wkup_ival; /* GPIO_WKUP + 0x20 */
162 u8 reserved9[3]; /* GPIO_WKUP + 0x21 */
163 u8 wkup_istat; /* GPIO_WKUP + 0x24 */
164 u8 reserved10[3]; /* GPIO_WKUP + 0x25 */
165};
166
167/* XLB Bus control */
168struct mpc52xx_xlb {
169 u8 reserved[0x40];
170 u32 config; /* XLB + 0x40 */
171 u32 version; /* XLB + 0x44 */
172 u32 status; /* XLB + 0x48 */
173 u32 int_enable; /* XLB + 0x4c */
174 u32 addr_capture; /* XLB + 0x50 */
175 u32 bus_sig_capture; /* XLB + 0x54 */
176 u32 addr_timeout; /* XLB + 0x58 */
177 u32 data_timeout; /* XLB + 0x5c */
178 u32 bus_act_timeout; /* XLB + 0x60 */
179 u32 master_pri_enable; /* XLB + 0x64 */
180 u32 master_priority; /* XLB + 0x68 */
181 u32 base_address; /* XLB + 0x6c */
182 u32 snoop_window; /* XLB + 0x70 */
183};
184
185#define MPC52xx_XLB_CFG_PLDIS (1 << 31)
186#define MPC52xx_XLB_CFG_SNOOP (1 << 15)
187
188/* Clock Distribution control */
189struct mpc52xx_cdm {
190 u32 jtag_id; /* CDM + 0x00 reg0 read only */
191 u32 rstcfg; /* CDM + 0x04 reg1 read only */
192 u32 breadcrumb; /* CDM + 0x08 reg2 */
193
194 u8 mem_clk_sel; /* CDM + 0x0c reg3 byte0 */
195 u8 xlb_clk_sel; /* CDM + 0x0d reg3 byte1 read only */
196 u8 ipb_clk_sel; /* CDM + 0x0e reg3 byte2 */
197 u8 pci_clk_sel; /* CDM + 0x0f reg3 byte3 */
198
199 u8 ext_48mhz_en; /* CDM + 0x10 reg4 byte0 */
200 u8 fd_enable; /* CDM + 0x11 reg4 byte1 */
201 u16 fd_counters; /* CDM + 0x12 reg4 byte2,3 */
202
203 u32 clk_enables; /* CDM + 0x14 reg5 */
204
205 u8 osc_disable; /* CDM + 0x18 reg6 byte0 */
206 u8 reserved0[3]; /* CDM + 0x19 reg6 byte1,2,3 */
207
208 u8 ccs_sleep_enable; /* CDM + 0x1c reg7 byte0 */
209 u8 osc_sleep_enable; /* CDM + 0x1d reg7 byte1 */
210 u8 reserved1; /* CDM + 0x1e reg7 byte2 */
211 u8 ccs_qreq_test; /* CDM + 0x1f reg7 byte3 */
212
213 u8 soft_reset; /* CDM + 0x20 u8 byte0 */
214 u8 no_ckstp; /* CDM + 0x21 u8 byte0 */
215 u8 reserved2[2]; /* CDM + 0x22 u8 byte1,2,3 */
216
217 u8 pll_lock; /* CDM + 0x24 reg9 byte0 */
218 u8 pll_looselock; /* CDM + 0x25 reg9 byte1 */
219 u8 pll_sm_lockwin; /* CDM + 0x26 reg9 byte2 */
220 u8 reserved3; /* CDM + 0x27 reg9 byte3 */
221
222 u16 reserved4; /* CDM + 0x28 reg10 byte0,1 */
223 u16 mclken_div_psc1; /* CDM + 0x2a reg10 byte2,3 */
224
225 u16 reserved5; /* CDM + 0x2c reg11 byte0,1 */
226 u16 mclken_div_psc2; /* CDM + 0x2e reg11 byte2,3 */
227
228 u16 reserved6; /* CDM + 0x30 reg12 byte0,1 */
229 u16 mclken_div_psc3; /* CDM + 0x32 reg12 byte2,3 */
230
231 u16 reserved7; /* CDM + 0x34 reg13 byte0,1 */
232 u16 mclken_div_psc6; /* CDM + 0x36 reg13 byte2,3 */
233};
234
235#endif /* __ASSEMBLY__ */
236
237
238/* ========================================================================= */
239/* Prototypes for MPC52xx sysdev */
240/* ========================================================================= */
241
242#ifndef __ASSEMBLY__
243
244extern void __iomem * mpc52xx_find_and_map(const char *);
245extern unsigned int mpc52xx_find_ipb_freq(struct device_node *node);
246extern void mpc52xx_setup_cpu(void);
247
248extern void mpc52xx_init_irq(void);
249extern unsigned int mpc52xx_get_irq(void);
250
251#endif /* __ASSEMBLY__ */
252
253#endif /* __ASM_POWERPC_MPC52xx_H__ */
254
diff --git a/include/asm-powerpc/mpc85xx.h b/include/asm-powerpc/mpc85xx.h
index ccdb8a21138f..54142997a584 100644
--- a/include/asm-powerpc/mpc85xx.h
+++ b/include/asm-powerpc/mpc85xx.h
@@ -31,14 +31,6 @@
31#include <platforms/85xx/mpc85xx_cds.h> 31#include <platforms/85xx/mpc85xx_cds.h>
32#endif 32#endif
33 33
34#define _IO_BASE isa_io_base
35#define _ISA_MEM_BASE isa_mem_base
36#ifdef CONFIG_PCI
37#define PCI_DRAM_OFFSET pci_dram_offset
38#else
39#define PCI_DRAM_OFFSET 0
40#endif
41
42/* Let modules/drivers get at CCSRBAR */ 34/* Let modules/drivers get at CCSRBAR */
43extern phys_addr_t get_ccsrbar(void); 35extern phys_addr_t get_ccsrbar(void);
44 36
diff --git a/include/asm-powerpc/mpic.h b/include/asm-powerpc/mpic.h
index ef0a5458d2b2..b71e7b32a555 100644
--- a/include/asm-powerpc/mpic.h
+++ b/include/asm-powerpc/mpic.h
@@ -3,6 +3,7 @@
3#ifdef __KERNEL__ 3#ifdef __KERNEL__
4 4
5#include <linux/irq.h> 5#include <linux/irq.h>
6#include <asm/dcr.h>
6 7
7/* 8/*
8 * Global registers 9 * Global registers
@@ -225,6 +226,23 @@ struct mpic_irq_fixup
225#endif /* CONFIG_MPIC_BROKEN_U3 */ 226#endif /* CONFIG_MPIC_BROKEN_U3 */
226 227
227 228
229enum mpic_reg_type {
230 mpic_access_mmio_le,
231 mpic_access_mmio_be,
232#ifdef CONFIG_PPC_DCR
233 mpic_access_dcr
234#endif
235};
236
237struct mpic_reg_bank {
238 u32 __iomem *base;
239#ifdef CONFIG_PPC_DCR
240 dcr_host_t dhost;
241 unsigned int dbase;
242 unsigned int doff;
243#endif /* CONFIG_PPC_DCR */
244};
245
228/* The instance data of a given MPIC */ 246/* The instance data of a given MPIC */
229struct mpic 247struct mpic
230{ 248{
@@ -264,11 +282,18 @@ struct mpic
264 spinlock_t fixup_lock; 282 spinlock_t fixup_lock;
265#endif 283#endif
266 284
285 /* Register access method */
286 enum mpic_reg_type reg_type;
287
267 /* The various ioremap'ed bases */ 288 /* The various ioremap'ed bases */
268 volatile u32 __iomem *gregs; 289 struct mpic_reg_bank gregs;
269 volatile u32 __iomem *tmregs; 290 struct mpic_reg_bank tmregs;
270 volatile u32 __iomem *cpuregs[MPIC_MAX_CPUS]; 291 struct mpic_reg_bank cpuregs[MPIC_MAX_CPUS];
271 volatile u32 __iomem *isus[MPIC_MAX_ISU]; 292 struct mpic_reg_bank isus[MPIC_MAX_ISU];
293
294#ifdef CONFIG_PPC_DCR
295 unsigned int dcr_base;
296#endif
272 297
273#ifdef CONFIG_MPIC_WEIRD 298#ifdef CONFIG_MPIC_WEIRD
274 /* Pointer to HW info array */ 299 /* Pointer to HW info array */
@@ -305,6 +330,8 @@ struct mpic
305#define MPIC_SPV_EOI 0x00000020 330#define MPIC_SPV_EOI 0x00000020
306/* No passthrough disable */ 331/* No passthrough disable */
307#define MPIC_NO_PTHROU_DIS 0x00000040 332#define MPIC_NO_PTHROU_DIS 0x00000040
333/* DCR based MPIC */
334#define MPIC_USES_DCR 0x00000080
308 335
309/* MPIC HW modification ID */ 336/* MPIC HW modification ID */
310#define MPIC_REGSET_MASK 0xf0000000 337#define MPIC_REGSET_MASK 0xf0000000
@@ -337,7 +364,7 @@ struct mpic
337 * that is senses[0] correspond to linux irq "irq_offset". 364 * that is senses[0] correspond to linux irq "irq_offset".
338 */ 365 */
339extern struct mpic *mpic_alloc(struct device_node *node, 366extern struct mpic *mpic_alloc(struct device_node *node,
340 unsigned long phys_addr, 367 phys_addr_t phys_addr,
341 unsigned int flags, 368 unsigned int flags,
342 unsigned int isu_size, 369 unsigned int isu_size,
343 unsigned int irq_count, 370 unsigned int irq_count,
@@ -350,7 +377,7 @@ extern struct mpic *mpic_alloc(struct device_node *node,
350 * @phys_addr: physical address of the ISU 377 * @phys_addr: physical address of the ISU
351 */ 378 */
352extern void mpic_assign_isu(struct mpic *mpic, unsigned int isu_num, 379extern void mpic_assign_isu(struct mpic *mpic, unsigned int isu_num,
353 unsigned long phys_addr); 380 phys_addr_t phys_addr);
354 381
355/* Set default sense codes 382/* Set default sense codes
356 * 383 *
diff --git a/include/asm-powerpc/of_device.h b/include/asm-powerpc/of_device.h
index c5c0b0b3cd52..a889b2005bf5 100644
--- a/include/asm-powerpc/of_device.h
+++ b/include/asm-powerpc/of_device.h
@@ -6,12 +6,6 @@
6#include <linux/mod_devicetable.h> 6#include <linux/mod_devicetable.h>
7#include <asm/prom.h> 7#include <asm/prom.h>
8 8
9/*
10 * The of_platform_bus_type is a bus type used by drivers that do not
11 * attach to a macio or similar bus but still use OF probing
12 * mechanism
13 */
14extern struct bus_type of_platform_bus_type;
15 9
16/* 10/*
17 * The of_device is a kind of "base class" that is a superset of 11 * The of_device is a kind of "base class" that is a superset of
@@ -20,46 +14,22 @@ extern struct bus_type of_platform_bus_type;
20 */ 14 */
21struct of_device 15struct of_device
22{ 16{
23 struct device_node *node; /* OF device node */ 17 struct device_node *node; /* to be obsoleted */
24 u64 dma_mask; /* DMA mask */ 18 u64 dma_mask; /* DMA mask */
25 struct device dev; /* Generic device interface */ 19 struct device dev; /* Generic device interface */
26}; 20};
27#define to_of_device(d) container_of(d, struct of_device, dev) 21#define to_of_device(d) container_of(d, struct of_device, dev)
28 22
23extern const struct of_device_id *of_match_node(
24 const struct of_device_id *matches, const struct device_node *node);
29extern const struct of_device_id *of_match_device( 25extern const struct of_device_id *of_match_device(
30 const struct of_device_id *matches, const struct of_device *dev); 26 const struct of_device_id *matches, const struct of_device *dev);
31 27
32extern struct of_device *of_dev_get(struct of_device *dev); 28extern struct of_device *of_dev_get(struct of_device *dev);
33extern void of_dev_put(struct of_device *dev); 29extern void of_dev_put(struct of_device *dev);
34 30
35/*
36 * An of_platform_driver driver is attached to a basic of_device on
37 * the "platform bus" (of_platform_bus_type)
38 */
39struct of_platform_driver
40{
41 char *name;
42 struct of_device_id *match_table;
43 struct module *owner;
44
45 int (*probe)(struct of_device* dev, const struct of_device_id *match);
46 int (*remove)(struct of_device* dev);
47
48 int (*suspend)(struct of_device* dev, pm_message_t state);
49 int (*resume)(struct of_device* dev);
50 int (*shutdown)(struct of_device* dev);
51
52 struct device_driver driver;
53};
54#define to_of_platform_driver(drv) container_of(drv,struct of_platform_driver, driver)
55
56extern int of_register_driver(struct of_platform_driver *drv);
57extern void of_unregister_driver(struct of_platform_driver *drv);
58extern int of_device_register(struct of_device *ofdev); 31extern int of_device_register(struct of_device *ofdev);
59extern void of_device_unregister(struct of_device *ofdev); 32extern void of_device_unregister(struct of_device *ofdev);
60extern struct of_device *of_platform_device_create(struct device_node *np,
61 const char *bus_id,
62 struct device *parent);
63extern void of_release_dev(struct device *dev); 33extern void of_release_dev(struct device *dev);
64 34
65#endif /* __KERNEL__ */ 35#endif /* __KERNEL__ */
diff --git a/include/asm-powerpc/of_platform.h b/include/asm-powerpc/of_platform.h
new file mode 100644
index 000000000000..217eafb167e9
--- /dev/null
+++ b/include/asm-powerpc/of_platform.h
@@ -0,0 +1,60 @@
1/*
2 * Copyright (C) 2006 Benjamin Herrenschmidt, IBM Corp.
3 * <benh@kernel.crashing.org>
4 *
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License
7 * as published by the Free Software Foundation; either version
8 * 2 of the License, or (at your option) any later version.
9 *
10 */
11
12#include <asm/of_device.h>
13
14/*
15 * The of_platform_bus_type is a bus type used by drivers that do not
16 * attach to a macio or similar bus but still use OF probing
17 * mechanism
18 */
19extern struct bus_type of_platform_bus_type;
20
21/*
22 * An of_platform_driver driver is attached to a basic of_device on
23 * the "platform bus" (of_platform_bus_type)
24 */
25struct of_platform_driver
26{
27 char *name;
28 struct of_device_id *match_table;
29 struct module *owner;
30
31 int (*probe)(struct of_device* dev,
32 const struct of_device_id *match);
33 int (*remove)(struct of_device* dev);
34
35 int (*suspend)(struct of_device* dev, pm_message_t state);
36 int (*resume)(struct of_device* dev);
37 int (*shutdown)(struct of_device* dev);
38
39 struct device_driver driver;
40};
41#define to_of_platform_driver(drv) \
42 container_of(drv,struct of_platform_driver, driver)
43
44/* Platform drivers register/unregister */
45extern int of_register_platform_driver(struct of_platform_driver *drv);
46extern void of_unregister_platform_driver(struct of_platform_driver *drv);
47
48/* Platform devices and busses creation */
49extern struct of_device *of_platform_device_create(struct device_node *np,
50 const char *bus_id,
51 struct device *parent);
52/* pseudo "matches" value to not do deep probe */
53#define OF_NO_DEEP_PROBE ((struct of_device_id *)-1)
54
55extern int of_platform_bus_probe(struct device_node *root,
56 struct of_device_id *matches,
57 struct device *parent);
58
59extern struct of_device *of_find_device_by_node(struct device_node *np);
60extern struct of_device *of_find_device_by_phandle(phandle ph);
diff --git a/include/asm-powerpc/oprofile_impl.h b/include/asm-powerpc/oprofile_impl.h
index 07a10e590c1d..71043bf3641f 100644
--- a/include/asm-powerpc/oprofile_impl.h
+++ b/include/asm-powerpc/oprofile_impl.h
@@ -44,7 +44,9 @@ struct op_powerpc_model {
44 int num_counters); 44 int num_counters);
45 void (*cpu_setup) (struct op_counter_config *); 45 void (*cpu_setup) (struct op_counter_config *);
46 void (*start) (struct op_counter_config *); 46 void (*start) (struct op_counter_config *);
47 void (*global_start) (struct op_counter_config *);
47 void (*stop) (void); 48 void (*stop) (void);
49 void (*global_stop) (void);
48 void (*handle_interrupt) (struct pt_regs *, 50 void (*handle_interrupt) (struct pt_regs *,
49 struct op_counter_config *); 51 struct op_counter_config *);
50 int num_counters; 52 int num_counters;
@@ -54,6 +56,7 @@ extern struct op_powerpc_model op_model_fsl_booke;
54extern struct op_powerpc_model op_model_rs64; 56extern struct op_powerpc_model op_model_rs64;
55extern struct op_powerpc_model op_model_power4; 57extern struct op_powerpc_model op_model_power4;
56extern struct op_powerpc_model op_model_7450; 58extern struct op_powerpc_model op_model_7450;
59extern struct op_powerpc_model op_model_cell;
57 60
58#ifndef CONFIG_FSL_BOOKE 61#ifndef CONFIG_FSL_BOOKE
59 62
diff --git a/include/asm-powerpc/paca.h b/include/asm-powerpc/paca.h
index 0a4e5c93e8e6..0d3adc09c847 100644
--- a/include/asm-powerpc/paca.h
+++ b/include/asm-powerpc/paca.h
@@ -93,7 +93,8 @@ struct paca_struct {
93 u64 stab_rr; /* stab/slb round-robin counter */ 93 u64 stab_rr; /* stab/slb round-robin counter */
94 u64 saved_r1; /* r1 save for RTAS calls */ 94 u64 saved_r1; /* r1 save for RTAS calls */
95 u64 saved_msr; /* MSR saved here by enter_rtas */ 95 u64 saved_msr; /* MSR saved here by enter_rtas */
96 u8 proc_enabled; /* irq soft-enable flag */ 96 u8 soft_enabled; /* irq soft-enable flag */
97 u8 hard_enabled; /* set if irqs are enabled in MSR */
97 u8 io_sync; /* writel() needs spin_unlock sync */ 98 u8 io_sync; /* writel() needs spin_unlock sync */
98 99
99 /* Stuff for accurate time accounting */ 100 /* Stuff for accurate time accounting */
diff --git a/include/asm-powerpc/pci-bridge.h b/include/asm-powerpc/pci-bridge.h
index 86ee46b09b8a..7bb7f9009806 100644
--- a/include/asm-powerpc/pci-bridge.h
+++ b/include/asm-powerpc/pci-bridge.h
@@ -25,6 +25,7 @@ struct pci_controller {
25 int node; 25 int node;
26 void *arch_data; 26 void *arch_data;
27 struct list_head list_node; 27 struct list_head list_node;
28 struct device *parent;
28 29
29 int first_busno; 30 int first_busno;
30 int last_busno; 31 int last_busno;
diff --git a/include/asm-powerpc/pci.h b/include/asm-powerpc/pci.h
index 721c97f09b20..16f13319c769 100644
--- a/include/asm-powerpc/pci.h
+++ b/include/asm-powerpc/pci.h
@@ -70,15 +70,15 @@ static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel)
70 */ 70 */
71#define PCI_DISABLE_MWI 71#define PCI_DISABLE_MWI
72 72
73extern struct dma_mapping_ops pci_dma_ops; 73extern struct dma_mapping_ops *pci_dma_ops;
74 74
75/* For DAC DMA, we currently don't support it by default, but 75/* For DAC DMA, we currently don't support it by default, but
76 * we let 64-bit platforms override this. 76 * we let 64-bit platforms override this.
77 */ 77 */
78static inline int pci_dac_dma_supported(struct pci_dev *hwdev,u64 mask) 78static inline int pci_dac_dma_supported(struct pci_dev *hwdev,u64 mask)
79{ 79{
80 if (pci_dma_ops.dac_dma_supported) 80 if (pci_dma_ops && pci_dma_ops->dac_dma_supported)
81 return pci_dma_ops.dac_dma_supported(&hwdev->dev, mask); 81 return pci_dma_ops->dac_dma_supported(&hwdev->dev, mask);
82 return 0; 82 return 0;
83} 83}
84 84
@@ -210,6 +210,8 @@ extern int remap_bus_range(struct pci_bus *bus);
210extern void pcibios_fixup_device_resources(struct pci_dev *dev, 210extern void pcibios_fixup_device_resources(struct pci_dev *dev,
211 struct pci_bus *bus); 211 struct pci_bus *bus);
212 212
213extern void pcibios_setup_new_device(struct pci_dev *dev);
214
213extern void pcibios_claim_one_bus(struct pci_bus *b); 215extern void pcibios_claim_one_bus(struct pci_bus *b);
214 216
215extern struct pci_controller *init_phb_dynamic(struct device_node *dn); 217extern struct pci_controller *init_phb_dynamic(struct device_node *dn);
@@ -232,12 +234,10 @@ extern pgprot_t pci_phys_mem_access_prot(struct file *file,
232 unsigned long size, 234 unsigned long size,
233 pgprot_t prot); 235 pgprot_t prot);
234 236
235#if defined(CONFIG_PPC_MULTIPLATFORM) || defined(CONFIG_PPC32)
236#define HAVE_ARCH_PCI_RESOURCE_TO_USER 237#define HAVE_ARCH_PCI_RESOURCE_TO_USER
237extern void pci_resource_to_user(const struct pci_dev *dev, int bar, 238extern void pci_resource_to_user(const struct pci_dev *dev, int bar,
238 const struct resource *rsrc, 239 const struct resource *rsrc,
239 resource_size_t *start, resource_size_t *end); 240 resource_size_t *start, resource_size_t *end);
240#endif /* CONFIG_PPC_MULTIPLATFORM || CONFIG_PPC32 */
241 241
242#endif /* __KERNEL__ */ 242#endif /* __KERNEL__ */
243#endif /* __ASM_POWERPC_PCI_H */ 243#endif /* __ASM_POWERPC_PCI_H */
diff --git a/include/asm-powerpc/ppc-pci.h b/include/asm-powerpc/ppc-pci.h
index 1115756c79f9..ab6eddb518c7 100644
--- a/include/asm-powerpc/ppc-pci.h
+++ b/include/asm-powerpc/ppc-pci.h
@@ -36,18 +36,17 @@ typedef void *(*traverse_func)(struct device_node *me, void *data);
36void *traverse_pci_devices(struct device_node *start, traverse_func pre, 36void *traverse_pci_devices(struct device_node *start, traverse_func pre,
37 void *data); 37 void *data);
38 38
39void pci_devs_phb_init(void); 39extern void pci_devs_phb_init(void);
40void pci_devs_phb_init_dynamic(struct pci_controller *phb); 40extern void pci_devs_phb_init_dynamic(struct pci_controller *phb);
41int setup_phb(struct device_node *dev, struct pci_controller *phb); 41extern void scan_phb(struct pci_controller *hose);
42void __devinit scan_phb(struct pci_controller *hose);
43 42
44/* From rtas_pci.h */ 43/* From rtas_pci.h */
45void init_pci_config_tokens (void); 44extern void init_pci_config_tokens (void);
46unsigned long get_phb_buid (struct device_node *); 45extern unsigned long get_phb_buid (struct device_node *);
46extern int rtas_setup_phb(struct pci_controller *phb);
47 47
48/* From pSeries_pci.h */ 48/* From pSeries_pci.h */
49extern void pSeries_final_fixup(void); 49extern void pSeries_final_fixup(void);
50extern void pSeries_irq_bus_setup(struct pci_bus *bus);
51 50
52extern unsigned long pci_probe_only; 51extern unsigned long pci_probe_only;
53 52
diff --git a/include/asm-powerpc/processor.h b/include/asm-powerpc/processor.h
index 6cb6fb19e57f..a26c32ee5527 100644
--- a/include/asm-powerpc/processor.h
+++ b/include/asm-powerpc/processor.h
@@ -53,10 +53,6 @@ extern unsigned char ucBoardRevMaj, ucBoardRevMin;
53 53
54#endif /* CONFIG_PPC_PREP */ 54#endif /* CONFIG_PPC_PREP */
55 55
56#ifndef CONFIG_PPC_MULTIPLATFORM
57#define _machine 0
58#endif /* CONFIG_PPC_MULTIPLATFORM */
59
60#endif /* defined(__KERNEL__) && defined(CONFIG_PPC32) */ 56#endif /* defined(__KERNEL__) && defined(CONFIG_PPC32) */
61 57
62/* 58/*
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
index ec11d44eaeb5..0afee17f33b4 100644
--- a/include/asm-powerpc/prom.h
+++ b/include/asm-powerpc/prom.h
@@ -17,6 +17,7 @@
17 */ 17 */
18#include <linux/types.h> 18#include <linux/types.h>
19#include <linux/proc_fs.h> 19#include <linux/proc_fs.h>
20#include <linux/platform_device.h>
20#include <asm/atomic.h> 21#include <asm/atomic.h>
21 22
22/* Definitions used by the flattened device tree */ 23/* Definitions used by the flattened device tree */
@@ -333,6 +334,20 @@ extern int of_irq_map_one(struct device_node *device, int index,
333struct pci_dev; 334struct pci_dev;
334extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq); 335extern int of_irq_map_pci(struct pci_dev *pdev, struct of_irq *out_irq);
335 336
337static inline int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
338{
339 int irq = irq_of_parse_and_map(dev, index);
340
341 /* Only dereference the resource if both the
342 * resource and the irq are valid. */
343 if (r && irq != NO_IRQ) {
344 r->start = r->end = irq;
345 r->flags = IORESOURCE_IRQ;
346 }
347
348 return irq;
349}
350
336 351
337#endif /* __KERNEL__ */ 352#endif /* __KERNEL__ */
338#endif /* _POWERPC_PROM_H */ 353#endif /* _POWERPC_PROM_H */
diff --git a/include/asm-powerpc/ps3.h b/include/asm-powerpc/ps3.h
new file mode 100644
index 000000000000..52a69ed0d90a
--- /dev/null
+++ b/include/asm-powerpc/ps3.h
@@ -0,0 +1,462 @@
1/*
2 * PS3 platform declarations.
3 *
4 * Copyright (C) 2006 Sony Computer Entertainment Inc.
5 * Copyright 2006 Sony Corp.
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; version 2 of the License.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 */
20
21#if !defined(_ASM_POWERPC_PS3_H)
22#define _ASM_POWERPC_PS3_H
23
24#include <linux/compiler.h> /* for __deprecated */
25#include <linux/init.h>
26#include <linux/types.h>
27#include <linux/device.h>
28
29/**
30 * struct ps3_device_id - HV bus device identifier from the system repository
31 * @bus_id: HV bus id, {1..} (zero invalid)
32 * @dev_id: HV device id, {0..}
33 */
34
35struct ps3_device_id {
36 unsigned int bus_id;
37 unsigned int dev_id;
38};
39
40
41/* dma routines */
42
43enum ps3_dma_page_size {
44 PS3_DMA_4K = 12U,
45 PS3_DMA_64K = 16U,
46 PS3_DMA_1M = 20U,
47 PS3_DMA_16M = 24U,
48};
49
50enum ps3_dma_region_type {
51 PS3_DMA_OTHER = 0,
52 PS3_DMA_INTERNAL = 2,
53};
54
55/**
56 * struct ps3_dma_region - A per device dma state variables structure
57 * @did: The HV device id.
58 * @page_size: The ioc pagesize.
59 * @region_type: The HV region type.
60 * @bus_addr: The 'translated' bus address of the region.
61 * @len: The length in bytes of the region.
62 * @chunk_list: Opaque variable used by the ioc page manager.
63 */
64
65struct ps3_dma_region {
66 struct ps3_device_id did;
67 enum ps3_dma_page_size page_size;
68 enum ps3_dma_region_type region_type;
69 unsigned long bus_addr;
70 unsigned long len;
71 struct {
72 spinlock_t lock;
73 struct list_head head;
74 } chunk_list;
75};
76
77/**
78 * struct ps3_dma_region_init - Helper to initialize structure variables
79 *
80 * Helper to properly initialize variables prior to calling
81 * ps3_system_bus_device_register.
82 */
83
84static inline void ps3_dma_region_init(struct ps3_dma_region *r,
85 const struct ps3_device_id* did, enum ps3_dma_page_size page_size,
86 enum ps3_dma_region_type region_type)
87{
88 r->did = *did;
89 r->page_size = page_size;
90 r->region_type = region_type;
91}
92int ps3_dma_region_create(struct ps3_dma_region *r);
93int ps3_dma_region_free(struct ps3_dma_region *r);
94int ps3_dma_map(struct ps3_dma_region *r, unsigned long virt_addr,
95 unsigned long len, unsigned long *bus_addr);
96int ps3_dma_unmap(struct ps3_dma_region *r, unsigned long bus_addr,
97 unsigned long len);
98
99/* mmio routines */
100
101enum ps3_mmio_page_size {
102 PS3_MMIO_4K = 12U,
103 PS3_MMIO_64K = 16U
104};
105
106/**
107 * struct ps3_mmio_region - a per device mmio state variables structure
108 *
109 * Current systems can be supported with a single region per device.
110 */
111
112struct ps3_mmio_region {
113 struct ps3_device_id did;
114 unsigned long bus_addr;
115 unsigned long len;
116 enum ps3_mmio_page_size page_size;
117 unsigned long lpar_addr;
118};
119
120/**
121 * struct ps3_mmio_region_init - Helper to initialize structure variables
122 *
123 * Helper to properly initialize variables prior to calling
124 * ps3_system_bus_device_register.
125 */
126
127static inline void ps3_mmio_region_init(struct ps3_mmio_region *r,
128 const struct ps3_device_id* did, unsigned long bus_addr,
129 unsigned long len, enum ps3_mmio_page_size page_size)
130{
131 r->did = *did;
132 r->bus_addr = bus_addr;
133 r->len = len;
134 r->page_size = page_size;
135}
136int ps3_mmio_region_create(struct ps3_mmio_region *r);
137int ps3_free_mmio_region(struct ps3_mmio_region *r);
138unsigned long ps3_mm_phys_to_lpar(unsigned long phys_addr);
139
140/* inrerrupt routines */
141
142int ps3_alloc_io_irq(unsigned int interrupt_id, unsigned int *virq);
143int ps3_free_io_irq(unsigned int virq);
144int ps3_alloc_event_irq(unsigned int *virq);
145int ps3_free_event_irq(unsigned int virq);
146int ps3_send_event_locally(unsigned int virq);
147int ps3_connect_event_irq(const struct ps3_device_id *did,
148 unsigned int interrupt_id, unsigned int *virq);
149int ps3_disconnect_event_irq(const struct ps3_device_id *did,
150 unsigned int interrupt_id, unsigned int virq);
151int ps3_alloc_vuart_irq(void* virt_addr_bmp, unsigned int *virq);
152int ps3_free_vuart_irq(unsigned int virq);
153int ps3_alloc_spe_irq(unsigned long spe_id, unsigned int class,
154 unsigned int *virq);
155int ps3_free_spe_irq(unsigned int virq);
156
157/* lv1 result codes */
158
159enum lv1_result {
160 LV1_SUCCESS = 0,
161 /* not used -1 */
162 LV1_RESOURCE_SHORTAGE = -2,
163 LV1_NO_PRIVILEGE = -3,
164 LV1_DENIED_BY_POLICY = -4,
165 LV1_ACCESS_VIOLATION = -5,
166 LV1_NO_ENTRY = -6,
167 LV1_DUPLICATE_ENTRY = -7,
168 LV1_TYPE_MISMATCH = -8,
169 LV1_BUSY = -9,
170 LV1_EMPTY = -10,
171 LV1_WRONG_STATE = -11,
172 /* not used -12 */
173 LV1_NO_MATCH = -13,
174 LV1_ALREADY_CONNECTED = -14,
175 LV1_UNSUPPORTED_PARAMETER_VALUE = -15,
176 LV1_CONDITION_NOT_SATISFIED = -16,
177 LV1_ILLEGAL_PARAMETER_VALUE = -17,
178 LV1_BAD_OPTION = -18,
179 LV1_IMPLEMENTATION_LIMITATION = -19,
180 LV1_NOT_IMPLEMENTED = -20,
181 LV1_INVALID_CLASS_ID = -21,
182 LV1_CONSTRAINT_NOT_SATISFIED = -22,
183 LV1_ALIGNMENT_ERROR = -23,
184 LV1_INTERNAL_ERROR = -32768,
185};
186
187static inline const char* ps3_result(int result)
188{
189#if defined(DEBUG)
190 switch (result) {
191 case LV1_SUCCESS:
192 return "LV1_SUCCESS (0)";
193 case -1:
194 return "** unknown result ** (-1)";
195 case LV1_RESOURCE_SHORTAGE:
196 return "LV1_RESOURCE_SHORTAGE (-2)";
197 case LV1_NO_PRIVILEGE:
198 return "LV1_NO_PRIVILEGE (-3)";
199 case LV1_DENIED_BY_POLICY:
200 return "LV1_DENIED_BY_POLICY (-4)";
201 case LV1_ACCESS_VIOLATION:
202 return "LV1_ACCESS_VIOLATION (-5)";
203 case LV1_NO_ENTRY:
204 return "LV1_NO_ENTRY (-6)";
205 case LV1_DUPLICATE_ENTRY:
206 return "LV1_DUPLICATE_ENTRY (-7)";
207 case LV1_TYPE_MISMATCH:
208 return "LV1_TYPE_MISMATCH (-8)";
209 case LV1_BUSY:
210 return "LV1_BUSY (-9)";
211 case LV1_EMPTY:
212 return "LV1_EMPTY (-10)";
213 case LV1_WRONG_STATE:
214 return "LV1_WRONG_STATE (-11)";
215 case -12:
216 return "** unknown result ** (-12)";
217 case LV1_NO_MATCH:
218 return "LV1_NO_MATCH (-13)";
219 case LV1_ALREADY_CONNECTED:
220 return "LV1_ALREADY_CONNECTED (-14)";
221 case LV1_UNSUPPORTED_PARAMETER_VALUE:
222 return "LV1_UNSUPPORTED_PARAMETER_VALUE (-15)";
223 case LV1_CONDITION_NOT_SATISFIED:
224 return "LV1_CONDITION_NOT_SATISFIED (-16)";
225 case LV1_ILLEGAL_PARAMETER_VALUE:
226 return "LV1_ILLEGAL_PARAMETER_VALUE (-17)";
227 case LV1_BAD_OPTION:
228 return "LV1_BAD_OPTION (-18)";
229 case LV1_IMPLEMENTATION_LIMITATION:
230 return "LV1_IMPLEMENTATION_LIMITATION (-19)";
231 case LV1_NOT_IMPLEMENTED:
232 return "LV1_NOT_IMPLEMENTED (-20)";
233 case LV1_INVALID_CLASS_ID:
234 return "LV1_INVALID_CLASS_ID (-21)";
235 case LV1_CONSTRAINT_NOT_SATISFIED:
236 return "LV1_CONSTRAINT_NOT_SATISFIED (-22)";
237 case LV1_ALIGNMENT_ERROR:
238 return "LV1_ALIGNMENT_ERROR (-23)";
239 case LV1_INTERNAL_ERROR:
240 return "LV1_INTERNAL_ERROR (-32768)";
241 default:
242 BUG();
243 return "** unknown result **";
244 };
245#else
246 return "";
247#endif
248}
249
250/* repository bus info */
251
252enum ps3_bus_type {
253 PS3_BUS_TYPE_SB = 4,
254 PS3_BUS_TYPE_STORAGE = 5,
255};
256
257enum ps3_dev_type {
258 PS3_DEV_TYPE_SB_GELIC = 3,
259 PS3_DEV_TYPE_SB_USB = 4,
260 PS3_DEV_TYPE_SB_GPIO = 6,
261};
262
263int ps3_repository_read_bus_str(unsigned int bus_index, const char *bus_str,
264 u64 *value);
265int ps3_repository_read_bus_id(unsigned int bus_index, unsigned int *bus_id);
266int ps3_repository_read_bus_type(unsigned int bus_index,
267 enum ps3_bus_type *bus_type);
268int ps3_repository_read_bus_num_dev(unsigned int bus_index,
269 unsigned int *num_dev);
270
271/* repository bus device info */
272
273enum ps3_interrupt_type {
274 PS3_INTERRUPT_TYPE_EVENT_PORT = 2,
275 PS3_INTERRUPT_TYPE_SB_OHCI = 3,
276 PS3_INTERRUPT_TYPE_SB_EHCI = 4,
277 PS3_INTERRUPT_TYPE_OTHER = 5,
278};
279
280enum ps3_region_type {
281 PS3_REGION_TYPE_SB_OHCI = 3,
282 PS3_REGION_TYPE_SB_EHCI = 4,
283 PS3_REGION_TYPE_SB_GPIO = 5,
284};
285
286int ps3_repository_read_dev_str(unsigned int bus_index,
287 unsigned int dev_index, const char *dev_str, u64 *value);
288int ps3_repository_read_dev_id(unsigned int bus_index, unsigned int dev_index,
289 unsigned int *dev_id);
290int ps3_repository_read_dev_type(unsigned int bus_index,
291 unsigned int dev_index, enum ps3_dev_type *dev_type);
292int ps3_repository_read_dev_intr(unsigned int bus_index,
293 unsigned int dev_index, unsigned int intr_index,
294 enum ps3_interrupt_type *intr_type, unsigned int *interrupt_id);
295int ps3_repository_read_dev_reg_type(unsigned int bus_index,
296 unsigned int dev_index, unsigned int reg_index,
297 enum ps3_region_type *reg_type);
298int ps3_repository_read_dev_reg_addr(unsigned int bus_index,
299 unsigned int dev_index, unsigned int reg_index, u64 *bus_addr,
300 u64 *len);
301int ps3_repository_read_dev_reg(unsigned int bus_index,
302 unsigned int dev_index, unsigned int reg_index,
303 enum ps3_region_type *reg_type, u64 *bus_addr, u64 *len);
304
305/* repository bus enumerators */
306
307struct ps3_repository_device {
308 unsigned int bus_index;
309 unsigned int dev_index;
310 struct ps3_device_id did;
311};
312
313int ps3_repository_find_device(enum ps3_bus_type bus_type,
314 enum ps3_dev_type dev_type,
315 const struct ps3_repository_device *start_dev,
316 struct ps3_repository_device *dev);
317static inline int ps3_repository_find_first_device(
318 enum ps3_bus_type bus_type, enum ps3_dev_type dev_type,
319 struct ps3_repository_device *dev)
320{
321 return ps3_repository_find_device(bus_type, dev_type, NULL, dev);
322}
323int ps3_repository_find_interrupt(const struct ps3_repository_device *dev,
324 enum ps3_interrupt_type intr_type, unsigned int *interrupt_id);
325int ps3_repository_find_region(const struct ps3_repository_device *dev,
326 enum ps3_region_type reg_type, u64 *bus_addr, u64 *len);
327
328/* repository block device info */
329
330int ps3_repository_read_dev_port(unsigned int bus_index,
331 unsigned int dev_index, u64 *port);
332int ps3_repository_read_dev_blk_size(unsigned int bus_index,
333 unsigned int dev_index, u64 *blk_size);
334int ps3_repository_read_dev_num_blocks(unsigned int bus_index,
335 unsigned int dev_index, u64 *num_blocks);
336int ps3_repository_read_dev_num_regions(unsigned int bus_index,
337 unsigned int dev_index, unsigned int *num_regions);
338int ps3_repository_read_dev_region_id(unsigned int bus_index,
339 unsigned int dev_index, unsigned int region_index,
340 unsigned int *region_id);
341int ps3_repository_read_dev_region_size(unsigned int bus_index,
342 unsigned int dev_index, unsigned int region_index, u64 *region_size);
343int ps3_repository_read_dev_region_start(unsigned int bus_index,
344 unsigned int dev_index, unsigned int region_index, u64 *region_start);
345
346/* repository pu and memory info */
347
348int ps3_repository_read_num_pu(unsigned int *num_pu);
349int ps3_repository_read_ppe_id(unsigned int *pu_index, unsigned int *ppe_id);
350int ps3_repository_read_rm_base(unsigned int ppe_id, u64 *rm_base);
351int ps3_repository_read_rm_size(unsigned int ppe_id, u64 *rm_size);
352int ps3_repository_read_region_total(u64 *region_total);
353int ps3_repository_read_mm_info(u64 *rm_base, u64 *rm_size,
354 u64 *region_total);
355
356/* repository pme info */
357
358int ps3_repository_read_num_be(unsigned int *num_be);
359int ps3_repository_read_be_node_id(unsigned int be_index, u64 *node_id);
360int ps3_repository_read_tb_freq(u64 node_id, u64 *tb_freq);
361int ps3_repository_read_be_tb_freq(unsigned int be_index, u64 *tb_freq);
362
363/* repository 'Other OS' area */
364
365int ps3_repository_read_boot_dat_addr(u64 *lpar_addr);
366int ps3_repository_read_boot_dat_size(unsigned int *size);
367int ps3_repository_read_boot_dat_info(u64 *lpar_addr, unsigned int *size);
368
369/* repository spu info */
370
371/**
372 * enum spu_resource_type - Type of spu resource.
373 * @spu_resource_type_shared: Logical spu is shared with other partions.
374 * @spu_resource_type_exclusive: Logical spu is not shared with other partions.
375 *
376 * Returned by ps3_repository_read_spu_resource_id().
377 */
378
379enum ps3_spu_resource_type {
380 PS3_SPU_RESOURCE_TYPE_SHARED = 0,
381 PS3_SPU_RESOURCE_TYPE_EXCLUSIVE = 0x8000000000000000UL,
382};
383
384int ps3_repository_read_num_spu_reserved(unsigned int *num_spu_reserved);
385int ps3_repository_read_num_spu_resource_id(unsigned int *num_resource_id);
386int ps3_repository_read_spu_resource_id(unsigned int res_index,
387 enum ps3_spu_resource_type* resource_type, unsigned int *resource_id);
388
389
390/* system bus routines */
391
392enum ps3_match_id {
393 PS3_MATCH_ID_EHCI = 1,
394 PS3_MATCH_ID_OHCI,
395 PS3_MATCH_ID_GELIC,
396 PS3_MATCH_ID_AV_SETTINGS,
397 PS3_MATCH_ID_SYSTEM_MANAGER,
398};
399
400/**
401 * struct ps3_system_bus_device - a device on the system bus
402 */
403
404struct ps3_system_bus_device {
405 enum ps3_match_id match_id;
406 struct ps3_device_id did;
407 unsigned int interrupt_id;
408/* struct iommu_table *iommu_table; -- waiting for Ben's cleanups */
409 struct ps3_dma_region *d_region;
410 struct ps3_mmio_region *m_region;
411 struct device core;
412};
413
414/**
415 * struct ps3_system_bus_driver - a driver for a device on the system bus
416 */
417
418struct ps3_system_bus_driver {
419 enum ps3_match_id match_id;
420 struct device_driver core;
421 int (*probe)(struct ps3_system_bus_device *);
422 int (*remove)(struct ps3_system_bus_device *);
423/* int (*suspend)(struct ps3_system_bus_device *, pm_message_t); */
424/* int (*resume)(struct ps3_system_bus_device *); */
425};
426
427int ps3_system_bus_device_register(struct ps3_system_bus_device *dev);
428int ps3_system_bus_driver_register(struct ps3_system_bus_driver *drv);
429void ps3_system_bus_driver_unregister(struct ps3_system_bus_driver *drv);
430static inline struct ps3_system_bus_driver *to_ps3_system_bus_driver(
431 struct device_driver *_drv)
432{
433 return container_of(_drv, struct ps3_system_bus_driver, core);
434}
435static inline struct ps3_system_bus_device *to_ps3_system_bus_device(
436 struct device *_dev)
437{
438 return container_of(_dev, struct ps3_system_bus_device, core);
439}
440
441/**
442 * ps3_system_bus_set_drvdata -
443 * @dev: device structure
444 * @data: Data to set
445 */
446
447static inline void ps3_system_bus_set_driver_data(
448 struct ps3_system_bus_device *dev, void *data)
449{
450 dev->core.driver_data = data;
451}
452static inline void *ps3_system_bus_get_driver_data(
453 struct ps3_system_bus_device *dev)
454{
455 return dev->core.driver_data;
456}
457
458/* These two need global scope for get_dma_ops(). */
459
460extern struct bus_type ps3_system_bus_type;
461
462#endif
diff --git a/include/asm-powerpc/rtas.h b/include/asm-powerpc/rtas.h
index d34f9e1f242c..5a0c136c0416 100644
--- a/include/asm-powerpc/rtas.h
+++ b/include/asm-powerpc/rtas.h
@@ -54,8 +54,6 @@ struct rtas_args {
54 rtas_arg_t *rets; /* Pointer to return values in args[]. */ 54 rtas_arg_t *rets; /* Pointer to return values in args[]. */
55}; 55};
56 56
57extern struct rtas_args rtas_stop_self_args;
58
59struct rtas_t { 57struct rtas_t {
60 unsigned long entry; /* physical address pointer */ 58 unsigned long entry; /* physical address pointer */
61 unsigned long base; /* physical address pointer */ 59 unsigned long base; /* physical address pointer */
diff --git a/include/asm-powerpc/sparsemem.h b/include/asm-powerpc/sparsemem.h
index 38b1ea3b58fd..48ad807a0b8a 100644
--- a/include/asm-powerpc/sparsemem.h
+++ b/include/asm-powerpc/sparsemem.h
@@ -9,8 +9,14 @@
9 * MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space 9 * MAX_PHYSMEM_BITS 2^N: how much memory we can have in that space
10 */ 10 */
11#define SECTION_SIZE_BITS 24 11#define SECTION_SIZE_BITS 24
12
13#if defined(CONFIG_PS3_USE_LPAR_ADDR)
14#define MAX_PHYSADDR_BITS 47
15#define MAX_PHYSMEM_BITS 47
16#else
12#define MAX_PHYSADDR_BITS 44 17#define MAX_PHYSADDR_BITS 44
13#define MAX_PHYSMEM_BITS 44 18#define MAX_PHYSMEM_BITS 44
19#endif
14 20
15#ifdef CONFIG_MEMORY_HOTPLUG 21#ifdef CONFIG_MEMORY_HOTPLUG
16extern void create_section_mapping(unsigned long start, unsigned long end); 22extern void create_section_mapping(unsigned long start, unsigned long end);
diff --git a/include/asm-powerpc/spu.h b/include/asm-powerpc/spu.h
index e73ea00efd8b..fdad4267b447 100644
--- a/include/asm-powerpc/spu.h
+++ b/include/asm-powerpc/spu.h
@@ -111,14 +111,12 @@ struct spu {
111 u8 *local_store; 111 u8 *local_store;
112 unsigned long problem_phys; 112 unsigned long problem_phys;
113 struct spu_problem __iomem *problem; 113 struct spu_problem __iomem *problem;
114 struct spu_priv1 __iomem *priv1;
115 struct spu_priv2 __iomem *priv2; 114 struct spu_priv2 __iomem *priv2;
116 struct list_head list; 115 struct list_head list;
117 struct list_head sched_list; 116 struct list_head sched_list;
117 struct list_head full_list;
118 int number; 118 int number;
119 int nid;
120 unsigned int irqs[3]; 119 unsigned int irqs[3];
121 u32 isrc;
122 u32 node; 120 u32 node;
123 u64 flags; 121 u64 flags;
124 u64 dar; 122 u64 dar;
@@ -144,6 +142,7 @@ struct spu {
144 char irq_c1[8]; 142 char irq_c1[8];
145 char irq_c2[8]; 143 char irq_c2[8];
146 144
145 void* pdata; /* platform private data */
147 struct sys_device sysdev; 146 struct sys_device sysdev;
148}; 147};
149 148
@@ -170,6 +169,13 @@ extern struct spufs_calls {
170 struct module *owner; 169 struct module *owner;
171} spufs_calls; 170} spufs_calls;
172 171
172/* coredump calls implemented in spufs */
173struct spu_coredump_calls {
174 asmlinkage int (*arch_notes_size)(void);
175 asmlinkage void (*arch_write_notes)(struct file *file);
176 struct module *owner;
177};
178
173/* return status from spu_run, same as in libspe */ 179/* return status from spu_run, same as in libspe */
174#define SPE_EVENT_DMA_ALIGNMENT 0x0008 /*A DMA alignment error */ 180#define SPE_EVENT_DMA_ALIGNMENT 0x0008 /*A DMA alignment error */
175#define SPE_EVENT_SPE_ERROR 0x0010 /*An illegal instruction error*/ 181#define SPE_EVENT_SPE_ERROR 0x0010 /*An illegal instruction error*/
@@ -182,8 +188,10 @@ extern struct spufs_calls {
182 */ 188 */
183#define SPU_CREATE_EVENTS_ENABLED 0x0001 189#define SPU_CREATE_EVENTS_ENABLED 0x0001
184#define SPU_CREATE_GANG 0x0002 190#define SPU_CREATE_GANG 0x0002
191#define SPU_CREATE_NOSCHED 0x0004
192#define SPU_CREATE_ISOLATE 0x0008
185 193
186#define SPU_CREATE_FLAG_ALL 0x0003 /* mask of all valid flags */ 194#define SPU_CREATE_FLAG_ALL 0x000f /* mask of all valid flags */
187 195
188 196
189#ifdef CONFIG_SPU_FS_MODULE 197#ifdef CONFIG_SPU_FS_MODULE
@@ -199,6 +207,15 @@ static inline void unregister_spu_syscalls(struct spufs_calls *calls)
199} 207}
200#endif /* MODULE */ 208#endif /* MODULE */
201 209
210int register_arch_coredump_calls(struct spu_coredump_calls *calls);
211void unregister_arch_coredump_calls(struct spu_coredump_calls *calls);
212
213int spu_add_sysdev_attr(struct sysdev_attribute *attr);
214void spu_remove_sysdev_attr(struct sysdev_attribute *attr);
215
216int spu_add_sysdev_attr_group(struct attribute_group *attrs);
217void spu_remove_sysdev_attr_group(struct attribute_group *attrs);
218
202 219
203/* 220/*
204 * Notifier blocks: 221 * Notifier blocks:
@@ -277,6 +294,7 @@ struct spu_problem {
277 u32 spu_runcntl_RW; /* 0x401c */ 294 u32 spu_runcntl_RW; /* 0x401c */
278#define SPU_RUNCNTL_STOP 0L 295#define SPU_RUNCNTL_STOP 0L
279#define SPU_RUNCNTL_RUNNABLE 1L 296#define SPU_RUNCNTL_RUNNABLE 1L
297#define SPU_RUNCNTL_ISOLATE 2L
280 u8 pad_0x4020_0x4024[0x4]; /* 0x4020 */ 298 u8 pad_0x4020_0x4024[0x4]; /* 0x4020 */
281 u32 spu_status_R; /* 0x4024 */ 299 u32 spu_status_R; /* 0x4024 */
282#define SPU_STOP_STATUS_SHIFT 16 300#define SPU_STOP_STATUS_SHIFT 16
@@ -289,8 +307,8 @@ struct spu_problem {
289#define SPU_STATUS_INVALID_INSTR 0x20 307#define SPU_STATUS_INVALID_INSTR 0x20
290#define SPU_STATUS_INVALID_CH 0x40 308#define SPU_STATUS_INVALID_CH 0x40
291#define SPU_STATUS_ISOLATED_STATE 0x80 309#define SPU_STATUS_ISOLATED_STATE 0x80
292#define SPU_STATUS_ISOLATED_LOAD_STAUTUS 0x200 310#define SPU_STATUS_ISOLATED_LOAD_STATUS 0x200
293#define SPU_STATUS_ISOLATED_EXIT_STAUTUS 0x400 311#define SPU_STATUS_ISOLATED_EXIT_STATUS 0x400
294 u8 pad_0x4028_0x402c[0x4]; /* 0x4028 */ 312 u8 pad_0x4028_0x402c[0x4]; /* 0x4028 */
295 u32 spu_spe_R; /* 0x402c */ 313 u32 spu_spe_R; /* 0x402c */
296 u8 pad_0x4030_0x4034[0x4]; /* 0x4030 */ 314 u8 pad_0x4030_0x4034[0x4]; /* 0x4030 */
diff --git a/include/asm-powerpc/spu_csa.h b/include/asm-powerpc/spu_csa.h
index 964c2d38ccb7..bdbf906a767f 100644
--- a/include/asm-powerpc/spu_csa.h
+++ b/include/asm-powerpc/spu_csa.h
@@ -151,7 +151,6 @@ struct spu_priv1_collapsed {
151 u64 mfc_fir_chkstp_enable_RW; 151 u64 mfc_fir_chkstp_enable_RW;
152 u64 smf_sbi_signal_sel; 152 u64 smf_sbi_signal_sel;
153 u64 smf_ato_signal_sel; 153 u64 smf_ato_signal_sel;
154 u64 mfc_sdr_RW;
155 u64 tlb_index_hint_RO; 154 u64 tlb_index_hint_RO;
156 u64 tlb_index_W; 155 u64 tlb_index_W;
157 u64 tlb_vpn_RW; 156 u64 tlb_vpn_RW;
diff --git a/include/asm-powerpc/spu_info.h b/include/asm-powerpc/spu_info.h
new file mode 100644
index 000000000000..3545efbf9891
--- /dev/null
+++ b/include/asm-powerpc/spu_info.h
@@ -0,0 +1,54 @@
1/*
2 * SPU info structures
3 *
4 * (C) Copyright 2006 IBM Corp.
5 *
6 * Author: Dwayne Grant McConnell <decimal@us.ibm.com>
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2, or (at your option)
11 * any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
21 */
22
23#ifndef _SPU_INFO_H
24#define _SPU_INFO_H
25
26#ifdef __KERNEL__
27#include <asm/spu.h>
28#include <linux/types.h>
29#else
30struct mfc_cq_sr {
31 __u64 mfc_cq_data0_RW;
32 __u64 mfc_cq_data1_RW;
33 __u64 mfc_cq_data2_RW;
34 __u64 mfc_cq_data3_RW;
35};
36#endif /* __KERNEL__ */
37
38struct spu_dma_info {
39 __u64 dma_info_type;
40 __u64 dma_info_mask;
41 __u64 dma_info_status;
42 __u64 dma_info_stall_and_notify;
43 __u64 dma_info_atomic_command_status;
44 struct mfc_cq_sr dma_info_command_data[16];
45};
46
47struct spu_proxydma_info {
48 __u64 proxydma_info_type;
49 __u64 proxydma_info_mask;
50 __u64 proxydma_info_status;
51 struct mfc_cq_sr proxydma_info_command_data[8];
52};
53
54#endif
diff --git a/include/asm-powerpc/spu_priv1.h b/include/asm-powerpc/spu_priv1.h
index 300c458b6d06..69dcb0c53884 100644
--- a/include/asm-powerpc/spu_priv1.h
+++ b/include/asm-powerpc/spu_priv1.h
@@ -21,12 +21,13 @@
21#define _SPU_PRIV1_H 21#define _SPU_PRIV1_H
22#if defined(__KERNEL__) 22#if defined(__KERNEL__)
23 23
24#include <linux/types.h>
25
24struct spu; 26struct spu;
25 27
26/* access to priv1 registers */ 28/* access to priv1 registers */
27 29
28struct spu_priv1_ops 30struct spu_priv1_ops {
29{
30 void (*int_mask_and) (struct spu *spu, int class, u64 mask); 31 void (*int_mask_and) (struct spu *spu, int class, u64 mask);
31 void (*int_mask_or) (struct spu *spu, int class, u64 mask); 32 void (*int_mask_or) (struct spu *spu, int class, u64 mask);
32 void (*int_mask_set) (struct spu *spu, int class, u64 mask); 33 void (*int_mask_set) (struct spu *spu, int class, u64 mask);
@@ -37,7 +38,7 @@ struct spu_priv1_ops
37 u64 (*mfc_dar_get) (struct spu *spu); 38 u64 (*mfc_dar_get) (struct spu *spu);
38 u64 (*mfc_dsisr_get) (struct spu *spu); 39 u64 (*mfc_dsisr_get) (struct spu *spu);
39 void (*mfc_dsisr_set) (struct spu *spu, u64 dsisr); 40 void (*mfc_dsisr_set) (struct spu *spu, u64 dsisr);
40 void (*mfc_sdr_set) (struct spu *spu, u64 sdr); 41 void (*mfc_sdr_setup) (struct spu *spu);
41 void (*mfc_sr1_set) (struct spu *spu, u64 sr1); 42 void (*mfc_sr1_set) (struct spu *spu, u64 sr1);
42 u64 (*mfc_sr1_get) (struct spu *spu); 43 u64 (*mfc_sr1_get) (struct spu *spu);
43 void (*mfc_tclass_id_set) (struct spu *spu, u64 tclass_id); 44 void (*mfc_tclass_id_set) (struct spu *spu, u64 tclass_id);
@@ -112,9 +113,9 @@ spu_mfc_dsisr_set (struct spu *spu, u64 dsisr)
112} 113}
113 114
114static inline void 115static inline void
115spu_mfc_sdr_set (struct spu *spu, u64 sdr) 116spu_mfc_sdr_setup (struct spu *spu)
116{ 117{
117 spu_priv1_ops->mfc_sdr_set(spu, sdr); 118 spu_priv1_ops->mfc_sdr_setup(spu);
118} 119}
119 120
120static inline void 121static inline void
@@ -171,12 +172,41 @@ spu_resource_allocation_enable_get (struct spu *spu)
171 return spu_priv1_ops->resource_allocation_enable_get(spu); 172 return spu_priv1_ops->resource_allocation_enable_get(spu);
172} 173}
173 174
174/* The declarations folowing are put here for convenience 175/* spu management abstraction */
175 * and only intended to be used by the platform setup code 176
176 * for initializing spu_priv1_ops. 177struct spu_management_ops {
178 int (*enumerate_spus)(int (*fn)(void *data));
179 int (*create_spu)(struct spu *spu, void *data);
180 int (*destroy_spu)(struct spu *spu);
181};
182
183extern const struct spu_management_ops* spu_management_ops;
184
185static inline int
186spu_enumerate_spus (int (*fn)(void *data))
187{
188 return spu_management_ops->enumerate_spus(fn);
189}
190
191static inline int
192spu_create_spu (struct spu *spu, void *data)
193{
194 return spu_management_ops->create_spu(spu, data);
195}
196
197static inline int
198spu_destroy_spu (struct spu *spu)
199{
200 return spu_management_ops->destroy_spu(spu);
201}
202
203/*
204 * The declarations folowing are put here for convenience
205 * and only intended to be used by the platform setup code.
177 */ 206 */
178 207
179extern const struct spu_priv1_ops spu_priv1_mmio_ops; 208extern const struct spu_priv1_ops spu_priv1_mmio_ops;
209extern const struct spu_management_ops spu_management_of_ops;
180 210
181#endif /* __KERNEL__ */ 211#endif /* __KERNEL__ */
182#endif 212#endif
diff --git a/include/asm-powerpc/todc.h b/include/asm-powerpc/todc.h
deleted file mode 100644
index 60a8c39b8c11..000000000000
--- a/include/asm-powerpc/todc.h
+++ /dev/null
@@ -1,487 +0,0 @@
1/*
2 * Definitions for the M48Txx and mc146818 series of Time of day/Real Time
3 * Clock chips.
4 *
5 * Author: Mark A. Greer <mgreer@mvista.com>
6 *
7 * 2001 (c) MontaVista, Software, Inc. This file is licensed under
8 * the terms of the GNU General Public License version 2. This program
9 * is licensed "as is" without any warranty of any kind, whether express
10 * or implied.
11 */
12
13/*
14 * Support for the M48T37/M48T59/.../mc146818 Real Time Clock chips.
15 * Purpose is to make one generic file that handles all of these chips instead
16 * of every platform implementing the same code over & over again.
17 */
18
19#ifndef __PPC_KERNEL_TODC_H
20#define __PPC_KERNEL_TODC_H
21
22typedef struct {
23 uint rtc_type; /* your particular chip */
24
25 /*
26 * Following are the addresses of the AS0, AS1, and DATA registers
27 * of these chips. Note that these are board-specific.
28 */
29 unsigned int nvram_as0;
30 unsigned int nvram_as1;
31 unsigned int nvram_data;
32
33 /*
34 * Define bits to stop external set of regs from changing so
35 * the chip can be read/written reliably.
36 */
37 unsigned char enable_read;
38 unsigned char enable_write;
39
40 /*
41 * Following is the number of AS0 address bits. This is normally
42 * 8 but some bad hardware routes address lines incorrectly.
43 */
44 int as0_bits;
45
46 int nvram_size; /* Size of NVRAM on chip */
47 int sw_flags; /* Software control flags */
48
49 /* Following are the register offsets for the particular chip */
50 int year;
51 int month;
52 int day_of_month;
53 int day_of_week;
54 int hours;
55 int minutes;
56 int seconds;
57 int control_b;
58 int control_a;
59 int watchdog;
60 int interrupts;
61 int alarm_date;
62 int alarm_hour;
63 int alarm_minutes;
64 int alarm_seconds;
65 int century;
66 int flags;
67
68 /*
69 * Some RTC chips have their NVRAM buried behind a addr/data pair of
70 * regs on the first level/clock registers. The following fields
71 * are the addresses for those addr/data regs.
72 */
73 int nvram_addr_reg;
74 int nvram_data_reg;
75} todc_info_t;
76
77/*
78 * Define the types of TODC/RTC variants that are supported in
79 * arch/ppc/kernel/todc_time.c
80 * Make a new one of these for any chip somehow differs from what's already
81 * defined. That way, if you ever need to put in code to touch those
82 * bits/registers in todc_time.c, you can put it inside an
83 * 'if (todc_info->rtc_type == TODC_TYPE_XXX)' so you won't break
84 * anyone else.
85 */
86#define TODC_TYPE_MK48T35 1
87#define TODC_TYPE_MK48T37 2
88#define TODC_TYPE_MK48T59 3
89#define TODC_TYPE_DS1693 4 /* Dallas DS1693 RTC */
90#define TODC_TYPE_DS1743 5 /* Dallas DS1743 RTC */
91#define TODC_TYPE_DS1746 6 /* Dallas DS1746 RTC */
92#define TODC_TYPE_DS1747 7 /* Dallas DS1747 RTC */
93#define TODC_TYPE_DS1501 8 /* Dallas DS1501 RTC */
94#define TODC_TYPE_DS1643 9 /* Dallas DS1643 RTC */
95#define TODC_TYPE_PC97307 10 /* PC97307 internal RTC */
96#define TODC_TYPE_DS1557 11 /* Dallas DS1557 RTC */
97#define TODC_TYPE_DS17285 12 /* Dallas DS17285 RTC */
98#define TODC_TYPE_DS1553 13 /* Dallas DS1553 RTC */
99#define TODC_TYPE_MC146818 100 /* Leave room for m48txx's */
100
101/*
102 * Bit to clear/set to enable reads/writes to the chip
103 */
104#define TODC_MK48TXX_CNTL_A_R 0x40
105#define TODC_MK48TXX_CNTL_A_W 0x80
106#define TODC_MK48TXX_DAY_CB 0x80
107
108#define TODC_DS1501_CNTL_B_TE 0x80
109
110/*
111 * Define flag bits used by todc routines.
112 */
113#define TODC_FLAG_2_LEVEL_NVRAM 0x00000001
114
115/*
116 * Define the values for the various RTC's that should to into the todc_info
117 * table.
118 * Note: The XXX_NVRAM_SIZE, XXX_NVRAM_ADDR_REG, and XXX_NVRAM_DATA_REG only
119 * matter if XXX_SW_FLAGS has TODC_FLAG_2_LEVEL_NVRAM set.
120 */
121#define TODC_TYPE_MK48T35_NVRAM_SIZE 0x7ff8
122#define TODC_TYPE_MK48T35_SW_FLAGS 0
123#define TODC_TYPE_MK48T35_YEAR 0x7fff
124#define TODC_TYPE_MK48T35_MONTH 0x7ffe
125#define TODC_TYPE_MK48T35_DOM 0x7ffd /* Day of Month */
126#define TODC_TYPE_MK48T35_DOW 0x7ffc /* Day of Week */
127#define TODC_TYPE_MK48T35_HOURS 0x7ffb
128#define TODC_TYPE_MK48T35_MINUTES 0x7ffa
129#define TODC_TYPE_MK48T35_SECONDS 0x7ff9
130#define TODC_TYPE_MK48T35_CNTL_B 0x7ff9
131#define TODC_TYPE_MK48T35_CNTL_A 0x7ff8
132#define TODC_TYPE_MK48T35_WATCHDOG 0x0000
133#define TODC_TYPE_MK48T35_INTERRUPTS 0x0000
134#define TODC_TYPE_MK48T35_ALARM_DATE 0x0000
135#define TODC_TYPE_MK48T35_ALARM_HOUR 0x0000
136#define TODC_TYPE_MK48T35_ALARM_MINUTES 0x0000
137#define TODC_TYPE_MK48T35_ALARM_SECONDS 0x0000
138#define TODC_TYPE_MK48T35_CENTURY 0x0000
139#define TODC_TYPE_MK48T35_FLAGS 0x0000
140#define TODC_TYPE_MK48T35_NVRAM_ADDR_REG 0
141#define TODC_TYPE_MK48T35_NVRAM_DATA_REG 0
142
143#define TODC_TYPE_MK48T37_NVRAM_SIZE 0x7ff0
144#define TODC_TYPE_MK48T37_SW_FLAGS 0
145#define TODC_TYPE_MK48T37_YEAR 0x7fff
146#define TODC_TYPE_MK48T37_MONTH 0x7ffe
147#define TODC_TYPE_MK48T37_DOM 0x7ffd /* Day of Month */
148#define TODC_TYPE_MK48T37_DOW 0x7ffc /* Day of Week */
149#define TODC_TYPE_MK48T37_HOURS 0x7ffb
150#define TODC_TYPE_MK48T37_MINUTES 0x7ffa
151#define TODC_TYPE_MK48T37_SECONDS 0x7ff9
152#define TODC_TYPE_MK48T37_CNTL_B 0x7ff9
153#define TODC_TYPE_MK48T37_CNTL_A 0x7ff8
154#define TODC_TYPE_MK48T37_WATCHDOG 0x7ff7
155#define TODC_TYPE_MK48T37_INTERRUPTS 0x7ff6
156#define TODC_TYPE_MK48T37_ALARM_DATE 0x7ff5
157#define TODC_TYPE_MK48T37_ALARM_HOUR 0x7ff4
158#define TODC_TYPE_MK48T37_ALARM_MINUTES 0x7ff3
159#define TODC_TYPE_MK48T37_ALARM_SECONDS 0x7ff2
160#define TODC_TYPE_MK48T37_CENTURY 0x7ff1
161#define TODC_TYPE_MK48T37_FLAGS 0x7ff0
162#define TODC_TYPE_MK48T37_NVRAM_ADDR_REG 0
163#define TODC_TYPE_MK48T37_NVRAM_DATA_REG 0
164
165#define TODC_TYPE_MK48T59_NVRAM_SIZE 0x1ff0
166#define TODC_TYPE_MK48T59_SW_FLAGS 0
167#define TODC_TYPE_MK48T59_YEAR 0x1fff
168#define TODC_TYPE_MK48T59_MONTH 0x1ffe
169#define TODC_TYPE_MK48T59_DOM 0x1ffd /* Day of Month */
170#define TODC_TYPE_MK48T59_DOW 0x1ffc /* Day of Week */
171#define TODC_TYPE_MK48T59_HOURS 0x1ffb
172#define TODC_TYPE_MK48T59_MINUTES 0x1ffa
173#define TODC_TYPE_MK48T59_SECONDS 0x1ff9
174#define TODC_TYPE_MK48T59_CNTL_B 0x1ff9
175#define TODC_TYPE_MK48T59_CNTL_A 0x1ff8
176#define TODC_TYPE_MK48T59_WATCHDOG 0x1fff
177#define TODC_TYPE_MK48T59_INTERRUPTS 0x1fff
178#define TODC_TYPE_MK48T59_ALARM_DATE 0x1fff
179#define TODC_TYPE_MK48T59_ALARM_HOUR 0x1fff
180#define TODC_TYPE_MK48T59_ALARM_MINUTES 0x1fff
181#define TODC_TYPE_MK48T59_ALARM_SECONDS 0x1fff
182#define TODC_TYPE_MK48T59_CENTURY 0x1fff
183#define TODC_TYPE_MK48T59_FLAGS 0x1fff
184#define TODC_TYPE_MK48T59_NVRAM_ADDR_REG 0
185#define TODC_TYPE_MK48T59_NVRAM_DATA_REG 0
186
187#define TODC_TYPE_DS1501_NVRAM_SIZE 0x100
188#define TODC_TYPE_DS1501_SW_FLAGS TODC_FLAG_2_LEVEL_NVRAM
189#define TODC_TYPE_DS1501_YEAR (TODC_TYPE_DS1501_NVRAM_SIZE + 0x06)
190#define TODC_TYPE_DS1501_MONTH (TODC_TYPE_DS1501_NVRAM_SIZE + 0x05)
191#define TODC_TYPE_DS1501_DOM (TODC_TYPE_DS1501_NVRAM_SIZE + 0x04)
192#define TODC_TYPE_DS1501_DOW (TODC_TYPE_DS1501_NVRAM_SIZE + 0x03)
193#define TODC_TYPE_DS1501_HOURS (TODC_TYPE_DS1501_NVRAM_SIZE + 0x02)
194#define TODC_TYPE_DS1501_MINUTES (TODC_TYPE_DS1501_NVRAM_SIZE + 0x01)
195#define TODC_TYPE_DS1501_SECONDS (TODC_TYPE_DS1501_NVRAM_SIZE + 0x00)
196#define TODC_TYPE_DS1501_CNTL_B (TODC_TYPE_DS1501_NVRAM_SIZE + 0x0f)
197#define TODC_TYPE_DS1501_CNTL_A (TODC_TYPE_DS1501_NVRAM_SIZE + 0x0f)
198#define TODC_TYPE_DS1501_WATCHDOG (TODC_TYPE_DS1501_NVRAM_SIZE + 0xff)
199#define TODC_TYPE_DS1501_INTERRUPTS (TODC_TYPE_DS1501_NVRAM_SIZE + 0xff)
200#define TODC_TYPE_DS1501_ALARM_DATE (TODC_TYPE_DS1501_NVRAM_SIZE + 0x0b)
201#define TODC_TYPE_DS1501_ALARM_HOUR (TODC_TYPE_DS1501_NVRAM_SIZE + 0x0a)
202#define TODC_TYPE_DS1501_ALARM_MINUTES (TODC_TYPE_DS1501_NVRAM_SIZE + 0x09)
203#define TODC_TYPE_DS1501_ALARM_SECONDS (TODC_TYPE_DS1501_NVRAM_SIZE + 0x08)
204#define TODC_TYPE_DS1501_CENTURY (TODC_TYPE_DS1501_NVRAM_SIZE + 0x07)
205#define TODC_TYPE_DS1501_FLAGS (TODC_TYPE_DS1501_NVRAM_SIZE + 0xff)
206#define TODC_TYPE_DS1501_NVRAM_ADDR_REG 0x10
207#define TODC_TYPE_DS1501_NVRAM_DATA_REG 0x13
208
209#define TODC_TYPE_DS1553_NVRAM_SIZE 0x1ff0
210#define TODC_TYPE_DS1553_SW_FLAGS 0
211#define TODC_TYPE_DS1553_YEAR 0x1fff
212#define TODC_TYPE_DS1553_MONTH 0x1ffe
213#define TODC_TYPE_DS1553_DOM 0x1ffd /* Day of Month */
214#define TODC_TYPE_DS1553_DOW 0x1ffc /* Day of Week */
215#define TODC_TYPE_DS1553_HOURS 0x1ffb
216#define TODC_TYPE_DS1553_MINUTES 0x1ffa
217#define TODC_TYPE_DS1553_SECONDS 0x1ff9
218#define TODC_TYPE_DS1553_CNTL_B 0x1ff9
219#define TODC_TYPE_DS1553_CNTL_A 0x1ff8 /* control_a R/W regs */
220#define TODC_TYPE_DS1553_WATCHDOG 0x1ff7
221#define TODC_TYPE_DS1553_INTERRUPTS 0x1ff6
222#define TODC_TYPE_DS1553_ALARM_DATE 0x1ff5
223#define TODC_TYPE_DS1553_ALARM_HOUR 0x1ff4
224#define TODC_TYPE_DS1553_ALARM_MINUTES 0x1ff3
225#define TODC_TYPE_DS1553_ALARM_SECONDS 0x1ff2
226#define TODC_TYPE_DS1553_CENTURY 0x1ff8
227#define TODC_TYPE_DS1553_FLAGS 0x1ff0
228#define TODC_TYPE_DS1553_NVRAM_ADDR_REG 0
229#define TODC_TYPE_DS1553_NVRAM_DATA_REG 0
230
231#define TODC_TYPE_DS1557_NVRAM_SIZE 0x7fff0
232#define TODC_TYPE_DS1557_SW_FLAGS 0
233#define TODC_TYPE_DS1557_YEAR 0x7ffff
234#define TODC_TYPE_DS1557_MONTH 0x7fffe
235#define TODC_TYPE_DS1557_DOM 0x7fffd /* Day of Month */
236#define TODC_TYPE_DS1557_DOW 0x7fffc /* Day of Week */
237#define TODC_TYPE_DS1557_HOURS 0x7fffb
238#define TODC_TYPE_DS1557_MINUTES 0x7fffa
239#define TODC_TYPE_DS1557_SECONDS 0x7fff9
240#define TODC_TYPE_DS1557_CNTL_B 0x7fff9
241#define TODC_TYPE_DS1557_CNTL_A 0x7fff8 /* control_a R/W regs */
242#define TODC_TYPE_DS1557_WATCHDOG 0x7fff7
243#define TODC_TYPE_DS1557_INTERRUPTS 0x7fff6
244#define TODC_TYPE_DS1557_ALARM_DATE 0x7fff5
245#define TODC_TYPE_DS1557_ALARM_HOUR 0x7fff4
246#define TODC_TYPE_DS1557_ALARM_MINUTES 0x7fff3
247#define TODC_TYPE_DS1557_ALARM_SECONDS 0x7fff2
248#define TODC_TYPE_DS1557_CENTURY 0x7fff8
249#define TODC_TYPE_DS1557_FLAGS 0x7fff0
250#define TODC_TYPE_DS1557_NVRAM_ADDR_REG 0
251#define TODC_TYPE_DS1557_NVRAM_DATA_REG 0
252
253#define TODC_TYPE_DS1643_NVRAM_SIZE 0x1ff8
254#define TODC_TYPE_DS1643_SW_FLAGS 0
255#define TODC_TYPE_DS1643_YEAR 0x1fff
256#define TODC_TYPE_DS1643_MONTH 0x1ffe
257#define TODC_TYPE_DS1643_DOM 0x1ffd /* Day of Month */
258#define TODC_TYPE_DS1643_DOW 0x1ffc /* Day of Week */
259#define TODC_TYPE_DS1643_HOURS 0x1ffb
260#define TODC_TYPE_DS1643_MINUTES 0x1ffa
261#define TODC_TYPE_DS1643_SECONDS 0x1ff9
262#define TODC_TYPE_DS1643_CNTL_B 0x1ff9
263#define TODC_TYPE_DS1643_CNTL_A 0x1ff8 /* control_a R/W regs */
264#define TODC_TYPE_DS1643_WATCHDOG 0x1fff
265#define TODC_TYPE_DS1643_INTERRUPTS 0x1fff
266#define TODC_TYPE_DS1643_ALARM_DATE 0x1fff
267#define TODC_TYPE_DS1643_ALARM_HOUR 0x1fff
268#define TODC_TYPE_DS1643_ALARM_MINUTES 0x1fff
269#define TODC_TYPE_DS1643_ALARM_SECONDS 0x1fff
270#define TODC_TYPE_DS1643_CENTURY 0x1ff8
271#define TODC_TYPE_DS1643_FLAGS 0x1fff
272#define TODC_TYPE_DS1643_NVRAM_ADDR_REG 0
273#define TODC_TYPE_DS1643_NVRAM_DATA_REG 0
274
275#define TODC_TYPE_DS1693_NVRAM_SIZE 0 /* Not handled yet */
276#define TODC_TYPE_DS1693_SW_FLAGS 0
277#define TODC_TYPE_DS1693_YEAR 0x09
278#define TODC_TYPE_DS1693_MONTH 0x08
279#define TODC_TYPE_DS1693_DOM 0x07 /* Day of Month */
280#define TODC_TYPE_DS1693_DOW 0x06 /* Day of Week */
281#define TODC_TYPE_DS1693_HOURS 0x04
282#define TODC_TYPE_DS1693_MINUTES 0x02
283#define TODC_TYPE_DS1693_SECONDS 0x00
284#define TODC_TYPE_DS1693_CNTL_B 0x0b
285#define TODC_TYPE_DS1693_CNTL_A 0x0a
286#define TODC_TYPE_DS1693_WATCHDOG 0xff
287#define TODC_TYPE_DS1693_INTERRUPTS 0xff
288#define TODC_TYPE_DS1693_ALARM_DATE 0x49
289#define TODC_TYPE_DS1693_ALARM_HOUR 0x05
290#define TODC_TYPE_DS1693_ALARM_MINUTES 0x03
291#define TODC_TYPE_DS1693_ALARM_SECONDS 0x01
292#define TODC_TYPE_DS1693_CENTURY 0x48
293#define TODC_TYPE_DS1693_FLAGS 0xff
294#define TODC_TYPE_DS1693_NVRAM_ADDR_REG 0
295#define TODC_TYPE_DS1693_NVRAM_DATA_REG 0
296
297#define TODC_TYPE_DS1743_NVRAM_SIZE 0x1ff8
298#define TODC_TYPE_DS1743_SW_FLAGS 0
299#define TODC_TYPE_DS1743_YEAR 0x1fff
300#define TODC_TYPE_DS1743_MONTH 0x1ffe
301#define TODC_TYPE_DS1743_DOM 0x1ffd /* Day of Month */
302#define TODC_TYPE_DS1743_DOW 0x1ffc /* Day of Week */
303#define TODC_TYPE_DS1743_HOURS 0x1ffb
304#define TODC_TYPE_DS1743_MINUTES 0x1ffa
305#define TODC_TYPE_DS1743_SECONDS 0x1ff9
306#define TODC_TYPE_DS1743_CNTL_B 0x1ff9
307#define TODC_TYPE_DS1743_CNTL_A 0x1ff8 /* control_a R/W regs */
308#define TODC_TYPE_DS1743_WATCHDOG 0x1fff
309#define TODC_TYPE_DS1743_INTERRUPTS 0x1fff
310#define TODC_TYPE_DS1743_ALARM_DATE 0x1fff
311#define TODC_TYPE_DS1743_ALARM_HOUR 0x1fff
312#define TODC_TYPE_DS1743_ALARM_MINUTES 0x1fff
313#define TODC_TYPE_DS1743_ALARM_SECONDS 0x1fff
314#define TODC_TYPE_DS1743_CENTURY 0x1ff8
315#define TODC_TYPE_DS1743_FLAGS 0x1fff
316#define TODC_TYPE_DS1743_NVRAM_ADDR_REG 0
317#define TODC_TYPE_DS1743_NVRAM_DATA_REG 0
318
319#define TODC_TYPE_DS1746_NVRAM_SIZE 0x1fff8
320#define TODC_TYPE_DS1746_SW_FLAGS 0
321#define TODC_TYPE_DS1746_YEAR 0x1ffff
322#define TODC_TYPE_DS1746_MONTH 0x1fffe
323#define TODC_TYPE_DS1746_DOM 0x1fffd /* Day of Month */
324#define TODC_TYPE_DS1746_DOW 0x1fffc /* Day of Week */
325#define TODC_TYPE_DS1746_HOURS 0x1fffb
326#define TODC_TYPE_DS1746_MINUTES 0x1fffa
327#define TODC_TYPE_DS1746_SECONDS 0x1fff9
328#define TODC_TYPE_DS1746_CNTL_B 0x1fff9
329#define TODC_TYPE_DS1746_CNTL_A 0x1fff8 /* control_a R/W regs */
330#define TODC_TYPE_DS1746_WATCHDOG 0x00000
331#define TODC_TYPE_DS1746_INTERRUPTS 0x00000
332#define TODC_TYPE_DS1746_ALARM_DATE 0x00000
333#define TODC_TYPE_DS1746_ALARM_HOUR 0x00000
334#define TODC_TYPE_DS1746_ALARM_MINUTES 0x00000
335#define TODC_TYPE_DS1746_ALARM_SECONDS 0x00000
336#define TODC_TYPE_DS1746_CENTURY 0x00000
337#define TODC_TYPE_DS1746_FLAGS 0x00000
338#define TODC_TYPE_DS1746_NVRAM_ADDR_REG 0
339#define TODC_TYPE_DS1746_NVRAM_DATA_REG 0
340
341#define TODC_TYPE_DS1747_NVRAM_SIZE 0x7fff8
342#define TODC_TYPE_DS1747_SW_FLAGS 0
343#define TODC_TYPE_DS1747_YEAR 0x7ffff
344#define TODC_TYPE_DS1747_MONTH 0x7fffe
345#define TODC_TYPE_DS1747_DOM 0x7fffd /* Day of Month */
346#define TODC_TYPE_DS1747_DOW 0x7fffc /* Day of Week */
347#define TODC_TYPE_DS1747_HOURS 0x7fffb
348#define TODC_TYPE_DS1747_MINUTES 0x7fffa
349#define TODC_TYPE_DS1747_SECONDS 0x7fff9
350#define TODC_TYPE_DS1747_CNTL_B 0x7fff9
351#define TODC_TYPE_DS1747_CNTL_A 0x7fff8 /* control_a R/W regs */
352#define TODC_TYPE_DS1747_WATCHDOG 0x00000
353#define TODC_TYPE_DS1747_INTERRUPTS 0x00000
354#define TODC_TYPE_DS1747_ALARM_DATE 0x00000
355#define TODC_TYPE_DS1747_ALARM_HOUR 0x00000
356#define TODC_TYPE_DS1747_ALARM_MINUTES 0x00000
357#define TODC_TYPE_DS1747_ALARM_SECONDS 0x00000
358#define TODC_TYPE_DS1747_CENTURY 0x00000
359#define TODC_TYPE_DS1747_FLAGS 0x00000
360#define TODC_TYPE_DS1747_NVRAM_ADDR_REG 0
361#define TODC_TYPE_DS1747_NVRAM_DATA_REG 0
362
363#define TODC_TYPE_DS17285_NVRAM_SIZE (0x1000-0x80) /* 4Kx8 NVRAM (minus RTC regs) */
364#define TODC_TYPE_DS17285_SW_FLAGS TODC_FLAG_2_LEVEL_NVRAM
365#define TODC_TYPE_DS17285_SECONDS (TODC_TYPE_DS17285_NVRAM_SIZE + 0x00)
366#define TODC_TYPE_DS17285_ALARM_SECONDS (TODC_TYPE_DS17285_NVRAM_SIZE + 0x01)
367#define TODC_TYPE_DS17285_MINUTES (TODC_TYPE_DS17285_NVRAM_SIZE + 0x02)
368#define TODC_TYPE_DS17285_ALARM_MINUTES (TODC_TYPE_DS17285_NVRAM_SIZE + 0x03)
369#define TODC_TYPE_DS17285_HOURS (TODC_TYPE_DS17285_NVRAM_SIZE + 0x04)
370#define TODC_TYPE_DS17285_ALARM_HOUR (TODC_TYPE_DS17285_NVRAM_SIZE + 0x05)
371#define TODC_TYPE_DS17285_DOW (TODC_TYPE_DS17285_NVRAM_SIZE + 0x06)
372#define TODC_TYPE_DS17285_DOM (TODC_TYPE_DS17285_NVRAM_SIZE + 0x07)
373#define TODC_TYPE_DS17285_MONTH (TODC_TYPE_DS17285_NVRAM_SIZE + 0x08)
374#define TODC_TYPE_DS17285_YEAR (TODC_TYPE_DS17285_NVRAM_SIZE + 0x09)
375#define TODC_TYPE_DS17285_CNTL_A (TODC_TYPE_DS17285_NVRAM_SIZE + 0x0A)
376#define TODC_TYPE_DS17285_CNTL_B (TODC_TYPE_DS17285_NVRAM_SIZE + 0x0B)
377#define TODC_TYPE_DS17285_CNTL_C (TODC_TYPE_DS17285_NVRAM_SIZE + 0x0C)
378#define TODC_TYPE_DS17285_CNTL_D (TODC_TYPE_DS17285_NVRAM_SIZE + 0x0D)
379#define TODC_TYPE_DS17285_WATCHDOG 0
380#define TODC_TYPE_DS17285_INTERRUPTS 0
381#define TODC_TYPE_DS17285_ALARM_DATE 0
382#define TODC_TYPE_DS17285_CENTURY 0
383#define TODC_TYPE_DS17285_FLAGS 0
384#define TODC_TYPE_DS17285_NVRAM_ADDR_REG 0x50
385#define TODC_TYPE_DS17285_NVRAM_DATA_REG 0x53
386
387#define TODC_TYPE_MC146818_NVRAM_SIZE 0 /* XXXX */
388#define TODC_TYPE_MC146818_SW_FLAGS 0
389#define TODC_TYPE_MC146818_YEAR 0x09
390#define TODC_TYPE_MC146818_MONTH 0x08
391#define TODC_TYPE_MC146818_DOM 0x07 /* Day of Month */
392#define TODC_TYPE_MC146818_DOW 0x06 /* Day of Week */
393#define TODC_TYPE_MC146818_HOURS 0x04
394#define TODC_TYPE_MC146818_MINUTES 0x02
395#define TODC_TYPE_MC146818_SECONDS 0x00
396#define TODC_TYPE_MC146818_CNTL_B 0x0a
397#define TODC_TYPE_MC146818_CNTL_A 0x0b /* control_a R/W regs */
398#define TODC_TYPE_MC146818_WATCHDOG 0
399#define TODC_TYPE_MC146818_INTERRUPTS 0x0c
400#define TODC_TYPE_MC146818_ALARM_DATE 0xff
401#define TODC_TYPE_MC146818_ALARM_HOUR 0x05
402#define TODC_TYPE_MC146818_ALARM_MINUTES 0x03
403#define TODC_TYPE_MC146818_ALARM_SECONDS 0x01
404#define TODC_TYPE_MC146818_CENTURY 0xff
405#define TODC_TYPE_MC146818_FLAGS 0xff
406#define TODC_TYPE_MC146818_NVRAM_ADDR_REG 0
407#define TODC_TYPE_MC146818_NVRAM_DATA_REG 0
408
409#define TODC_TYPE_PC97307_NVRAM_SIZE 0 /* No NVRAM? */
410#define TODC_TYPE_PC97307_SW_FLAGS 0
411#define TODC_TYPE_PC97307_YEAR 0x09
412#define TODC_TYPE_PC97307_MONTH 0x08
413#define TODC_TYPE_PC97307_DOM 0x07 /* Day of Month */
414#define TODC_TYPE_PC97307_DOW 0x06 /* Day of Week */
415#define TODC_TYPE_PC97307_HOURS 0x04
416#define TODC_TYPE_PC97307_MINUTES 0x02
417#define TODC_TYPE_PC97307_SECONDS 0x00
418#define TODC_TYPE_PC97307_CNTL_B 0x0a
419#define TODC_TYPE_PC97307_CNTL_A 0x0b /* control_a R/W regs */
420#define TODC_TYPE_PC97307_WATCHDOG 0x0c
421#define TODC_TYPE_PC97307_INTERRUPTS 0x0d
422#define TODC_TYPE_PC97307_ALARM_DATE 0xff
423#define TODC_TYPE_PC97307_ALARM_HOUR 0x05
424#define TODC_TYPE_PC97307_ALARM_MINUTES 0x03
425#define TODC_TYPE_PC97307_ALARM_SECONDS 0x01
426#define TODC_TYPE_PC97307_CENTURY 0xff
427#define TODC_TYPE_PC97307_FLAGS 0xff
428#define TODC_TYPE_PC97307_NVRAM_ADDR_REG 0
429#define TODC_TYPE_PC97307_NVRAM_DATA_REG 0
430
431/*
432 * Define macros to allocate and init the todc_info_t table that will
433 * be used by the todc_time.c routines.
434 */
435#define TODC_ALLOC() \
436 static todc_info_t todc_info_alloc; \
437 todc_info_t *todc_info = &todc_info_alloc;
438
439#define TODC_INIT(clock_type, as0, as1, data, bits) { \
440 todc_info->rtc_type = clock_type; \
441 \
442 todc_info->nvram_as0 = (unsigned int)(as0); \
443 todc_info->nvram_as1 = (unsigned int)(as1); \
444 todc_info->nvram_data = (unsigned int)(data); \
445 \
446 todc_info->as0_bits = (bits); \
447 \
448 todc_info->nvram_size = clock_type ##_NVRAM_SIZE; \
449 todc_info->sw_flags = clock_type ##_SW_FLAGS; \
450 \
451 todc_info->year = clock_type ##_YEAR; \
452 todc_info->month = clock_type ##_MONTH; \
453 todc_info->day_of_month = clock_type ##_DOM; \
454 todc_info->day_of_week = clock_type ##_DOW; \
455 todc_info->hours = clock_type ##_HOURS; \
456 todc_info->minutes = clock_type ##_MINUTES; \
457 todc_info->seconds = clock_type ##_SECONDS; \
458 todc_info->control_b = clock_type ##_CNTL_B; \
459 todc_info->control_a = clock_type ##_CNTL_A; \
460 todc_info->watchdog = clock_type ##_WATCHDOG; \
461 todc_info->interrupts = clock_type ##_INTERRUPTS; \
462 todc_info->alarm_date = clock_type ##_ALARM_DATE; \
463 todc_info->alarm_hour = clock_type ##_ALARM_HOUR; \
464 todc_info->alarm_minutes = clock_type ##_ALARM_MINUTES; \
465 todc_info->alarm_seconds = clock_type ##_ALARM_SECONDS; \
466 todc_info->century = clock_type ##_CENTURY; \
467 todc_info->flags = clock_type ##_FLAGS; \
468 \
469 todc_info->nvram_addr_reg = clock_type ##_NVRAM_ADDR_REG; \
470 todc_info->nvram_data_reg = clock_type ##_NVRAM_DATA_REG; \
471}
472
473extern todc_info_t *todc_info;
474
475unsigned char todc_direct_read_val(int addr);
476void todc_direct_write_val(int addr, unsigned char val);
477unsigned char todc_m48txx_read_val(int addr);
478void todc_m48txx_write_val(int addr, unsigned char val);
479unsigned char todc_mc146818_read_val(int addr);
480void todc_mc146818_write_val(int addr, unsigned char val);
481
482long todc_time_init(void);
483void todc_get_rtc_time(struct rtc_time *);
484int todc_set_rtc_time(struct rtc_time *);
485void todc_calibrate_decr(void);
486
487#endif /* __PPC_KERNEL_TODC_H */
diff --git a/include/asm-powerpc/topology.h b/include/asm-powerpc/topology.h
index 9fe7894ee035..50c014007de7 100644
--- a/include/asm-powerpc/topology.h
+++ b/include/asm-powerpc/topology.h
@@ -32,7 +32,14 @@ static inline int node_to_first_cpu(int node)
32int of_node_to_nid(struct device_node *device); 32int of_node_to_nid(struct device_node *device);
33 33
34struct pci_bus; 34struct pci_bus;
35#ifdef CONFIG_PCI
35extern int pcibus_to_node(struct pci_bus *bus); 36extern int pcibus_to_node(struct pci_bus *bus);
37#else
38static inline int pcibus_to_node(struct pci_bus *bus)
39{
40 return -1;
41}
42#endif
36 43
37#define pcibus_to_cpumask(bus) (pcibus_to_node(bus) == -1 ? \ 44#define pcibus_to_cpumask(bus) (pcibus_to_node(bus) == -1 ? \
38 CPU_MASK_ALL : \ 45 CPU_MASK_ALL : \
diff --git a/include/asm-powerpc/tsi108.h b/include/asm-powerpc/tsi108.h
index 2c702d35a7cf..4e95d153be84 100644
--- a/include/asm-powerpc/tsi108.h
+++ b/include/asm-powerpc/tsi108.h
@@ -98,12 +98,12 @@ typedef struct {
98extern u32 get_vir_csrbase(void); 98extern u32 get_vir_csrbase(void);
99extern u32 tsi108_csr_vir_base; 99extern u32 tsi108_csr_vir_base;
100 100
101extern inline u32 tsi108_read_reg(u32 reg_offset) 101static inline u32 tsi108_read_reg(u32 reg_offset)
102{ 102{
103 return in_be32((volatile u32 *)(tsi108_csr_vir_base + reg_offset)); 103 return in_be32((volatile u32 *)(tsi108_csr_vir_base + reg_offset));
104} 104}
105 105
106extern inline void tsi108_write_reg(u32 reg_offset, u32 val) 106static inline void tsi108_write_reg(u32 reg_offset, u32 val)
107{ 107{
108 out_be32((volatile u32 *)(tsi108_csr_vir_base + reg_offset), val); 108 out_be32((volatile u32 *)(tsi108_csr_vir_base + reg_offset), val);
109} 109}
diff --git a/include/asm-powerpc/types.h b/include/asm-powerpc/types.h
index d6fb56b80453..3b363757a2bb 100644
--- a/include/asm-powerpc/types.h
+++ b/include/asm-powerpc/types.h
@@ -97,16 +97,6 @@ typedef struct {
97 unsigned long env; 97 unsigned long env;
98} func_descr_t; 98} func_descr_t;
99 99
100#ifdef CONFIG_LBD
101typedef u64 sector_t;
102#define HAVE_SECTOR_T
103#endif
104
105#ifdef CONFIG_LSF
106typedef u64 blkcnt_t;
107#define HAVE_BLKCNT_T
108#endif
109
110#endif /* __ASSEMBLY__ */ 100#endif /* __ASSEMBLY__ */
111 101
112#endif /* __KERNEL__ */ 102#endif /* __KERNEL__ */
diff --git a/include/asm-powerpc/uaccess.h b/include/asm-powerpc/uaccess.h
index d83fc29c2bbf..adbf16b8cfbb 100644
--- a/include/asm-powerpc/uaccess.h
+++ b/include/asm-powerpc/uaccess.h
@@ -304,7 +304,7 @@ extern unsigned long __copy_tofrom_user(void __user *to,
304 304
305#ifndef __powerpc64__ 305#ifndef __powerpc64__
306 306
307extern inline unsigned long copy_from_user(void *to, 307static inline unsigned long copy_from_user(void *to,
308 const void __user *from, unsigned long n) 308 const void __user *from, unsigned long n)
309{ 309{
310 unsigned long over; 310 unsigned long over;
@@ -319,7 +319,7 @@ extern inline unsigned long copy_from_user(void *to,
319 return n; 319 return n;
320} 320}
321 321
322extern inline unsigned long copy_to_user(void __user *to, 322static inline unsigned long copy_to_user(void __user *to,
323 const void *from, unsigned long n) 323 const void *from, unsigned long n)
324{ 324{
325 unsigned long over; 325 unsigned long over;
diff --git a/include/asm-powerpc/unistd.h b/include/asm-powerpc/unistd.h
index 0e4ea37f6466..04b6c17cc59b 100644
--- a/include/asm-powerpc/unistd.h
+++ b/include/asm-powerpc/unistd.h
@@ -446,7 +446,6 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
446#include <linux/types.h> 446#include <linux/types.h>
447#include <linux/compiler.h> 447#include <linux/compiler.h>
448#include <linux/linkage.h> 448#include <linux/linkage.h>
449#include <asm/syscalls.h>
450 449
451#define __ARCH_WANT_IPC_PARSE_VERSION 450#define __ARCH_WANT_IPC_PARSE_VERSION
452#define __ARCH_WANT_OLD_READDIR 451#define __ARCH_WANT_OLD_READDIR
@@ -481,16 +480,9 @@ type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, type5 arg5, type6 arg6
481 480
482/* 481/*
483 * "Conditional" syscalls 482 * "Conditional" syscalls
484 *
485 * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
486 * but it doesn't work on all toolchains, so we just do it by hand
487 */ 483 */
488#ifdef CONFIG_PPC32 484#define cond_syscall(x) \
489#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") 485 asmlinkage long x (void) __attribute__((weak,alias("sys_ni_syscall")))
490#else
491#define cond_syscall(x) asm(".weak\t." #x "\n\t.set\t." #x ",.sys_ni_syscall")
492#endif
493
494 486
495#endif /* __ASSEMBLY__ */ 487#endif /* __ASSEMBLY__ */
496#endif /* __KERNEL__ */ 488#endif /* __KERNEL__ */
diff --git a/include/asm-powerpc/vio.h b/include/asm-powerpc/vio.h
index 4b51d42e1419..0117b544ecbc 100644
--- a/include/asm-powerpc/vio.h
+++ b/include/asm-powerpc/vio.h
@@ -45,7 +45,6 @@ struct iommu_table;
45 * The vio_dev structure is used to describe virtual I/O devices. 45 * The vio_dev structure is used to describe virtual I/O devices.
46 */ 46 */
47struct vio_dev { 47struct vio_dev {
48 struct iommu_table *iommu_table; /* vio_map_* uses this */
49 const char *name; 48 const char *name;
50 const char *type; 49 const char *type;
51 uint32_t unit_address; 50 uint32_t unit_address;
diff --git a/include/asm-powerpc/xmon.h b/include/asm-powerpc/xmon.h
index f1d337ed68d5..88320a05f0a8 100644
--- a/include/asm-powerpc/xmon.h
+++ b/include/asm-powerpc/xmon.h
@@ -14,8 +14,10 @@
14 14
15#ifdef CONFIG_XMON 15#ifdef CONFIG_XMON
16extern void xmon_setup(void); 16extern void xmon_setup(void);
17extern void xmon_register_spus(struct list_head *list);
17#else 18#else
18static inline void xmon_setup(void) { }; 19static inline void xmon_setup(void) { };
20static inline void xmon_register_spus(struct list_head *list) { };
19#endif 21#endif
20 22
21#endif /* __KERNEL __ */ 23#endif /* __KERNEL __ */
diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h
index a4c411b753ef..ccf1a9bb2e43 100644
--- a/include/asm-ppc/io.h
+++ b/include/asm-ppc/io.h
@@ -26,17 +26,11 @@
26 26
27#if defined(CONFIG_4xx) 27#if defined(CONFIG_4xx)
28#include <asm/ibm4xx.h> 28#include <asm/ibm4xx.h>
29#elif defined(CONFIG_PPC_MPC52xx)
30#include <asm/mpc52xx.h>
31#elif defined(CONFIG_8xx) 29#elif defined(CONFIG_8xx)
32#include <asm/mpc8xx.h> 30#include <asm/mpc8xx.h>
33#elif defined(CONFIG_8260) 31#elif defined(CONFIG_8260)
34#include <asm/mpc8260.h> 32#include <asm/mpc8260.h>
35#elif defined(CONFIG_83xx) 33#elif defined(CONFIG_APUS) || !defined(CONFIG_PCI)
36#include <asm/mpc83xx.h>
37#elif defined(CONFIG_85xx)
38#include <asm/mpc85xx.h>
39#elif defined(CONFIG_APUS)
40#define _IO_BASE 0 34#define _IO_BASE 0
41#define _ISA_MEM_BASE 0 35#define _ISA_MEM_BASE 0
42#define PCI_DRAM_OFFSET 0 36#define PCI_DRAM_OFFSET 0
@@ -237,6 +231,14 @@ static inline void __raw_writel(__u32 b, volatile void __iomem *addr)
237#define insl(port, buf, nl) _insl_ns((port)+___IO_BASE, (buf), (nl)) 231#define insl(port, buf, nl) _insl_ns((port)+___IO_BASE, (buf), (nl))
238#define outsl(port, buf, nl) _outsl_ns((port)+___IO_BASE, (buf), (nl)) 232#define outsl(port, buf, nl) _outsl_ns((port)+___IO_BASE, (buf), (nl))
239 233
234#define readsb(a, b, n) _insb((a), (b), (n))
235#define readsw(a, b, n) _insw_ns((a), (b), (n))
236#define readsl(a, b, n) _insl_ns((a), (b), (n))
237#define writesb(a, b, n) _outsb((a),(b),(n))
238#define writesw(a, b, n) _outsw_ns((a),(b),(n))
239#define writesl(a, b, n) _outsl_ns((a),(b),(n))
240
241
240/* 242/*
241 * On powermacs and 8xx we will get a machine check exception 243 * On powermacs and 8xx we will get a machine check exception
242 * if we try to read data from a non-existent I/O port. Because 244 * if we try to read data from a non-existent I/O port. Because
@@ -327,12 +329,12 @@ __do_out_asm(outl, "stwbrx")
327#define inl_p(port) inl((port)) 329#define inl_p(port) inl((port))
328#define outl_p(val, port) outl((val), (port)) 330#define outl_p(val, port) outl((val), (port))
329 331
330extern void _insb(volatile u8 __iomem *port, void *buf, long count); 332extern void _insb(const volatile u8 __iomem *addr, void *buf, long count);
331extern void _outsb(volatile u8 __iomem *port, const void *buf, long count); 333extern void _outsb(volatile u8 __iomem *addr,const void *buf,long count);
332extern void _insw_ns(volatile u16 __iomem *port, void *buf, long count); 334extern void _insw_ns(const volatile u16 __iomem *addr, void *buf, long count);
333extern void _outsw_ns(volatile u16 __iomem *port, const void *buf, long count); 335extern void _outsw_ns(volatile u16 __iomem *addr, const void *buf, long count);
334extern void _insl_ns(volatile u32 __iomem *port, void *buf, long count); 336extern void _insl_ns(const volatile u32 __iomem *addr, void *buf, long count);
335extern void _outsl_ns(volatile u32 __iomem *port, const void *buf, long count); 337extern void _outsl_ns(volatile u32 __iomem *addr, const void *buf, long count);
336 338
337 339
338#define IO_SPACE_LIMIT ~0 340#define IO_SPACE_LIMIT ~0
diff --git a/include/asm-ppc/m48t35.h b/include/asm-ppc/m48t35.h
index f3c5e5dfa986..a5277ea4b194 100644
--- a/include/asm-ppc/m48t35.h
+++ b/include/asm-ppc/m48t35.h
@@ -39,7 +39,7 @@
39#define M48T35_RTC_WATCHDOG_RB 0x03 39#define M48T35_RTC_WATCHDOG_RB 0x03
40#define M48T35_RTC_WATCHDOG_BMB 0x7c 40#define M48T35_RTC_WATCHDOG_BMB 0x7c
41#define M48T35_RTC_WATCHDOG_WDS 0x80 41#define M48T35_RTC_WATCHDOG_WDS 0x80
42#define M48T35_RTC_WATCHDOG_ALL (M48T35_RTC_WATCHDOG_RB|M48T35_RTC_WATCHDOG_BMB|M48T35_RTC_W 42#define M48T35_RTC_WATCHDOG_ALL (M48T35_RTC_WATCHDOG_RB|M48T35_RTC_WATCHDOG_BMB|M48T35_RTC_W)
43 43
44#define M48T35_RTC_CONTROL_WRITE 0x80 44#define M48T35_RTC_CONTROL_WRITE 0x80
45#define M48T35_RTC_CONTROL_READ 0x40 45#define M48T35_RTC_CONTROL_READ 0x40
diff --git a/include/asm-ppc/mpc52xx.h b/include/asm-ppc/mpc52xx.h
index 64c8874618dc..d9d21aa68ba3 100644
--- a/include/asm-ppc/mpc52xx.h
+++ b/include/asm-ppc/mpc52xx.h
@@ -29,17 +29,6 @@ struct pt_regs;
29#endif /* __ASSEMBLY__ */ 29#endif /* __ASSEMBLY__ */
30 30
31 31
32#ifdef CONFIG_PCI
33#define _IO_BASE isa_io_base
34#define _ISA_MEM_BASE isa_mem_base
35#define PCI_DRAM_OFFSET pci_dram_offset
36#else
37#define _IO_BASE 0
38#define _ISA_MEM_BASE 0
39#define PCI_DRAM_OFFSET 0
40#endif
41
42
43/* ======================================================================== */ 32/* ======================================================================== */
44/* PPC Sys devices definition */ 33/* PPC Sys devices definition */
45/* ======================================================================== */ 34/* ======================================================================== */
diff --git a/include/asm-ppc/mpc83xx.h b/include/asm-ppc/mpc83xx.h
index 02ed2c325714..c3061972309b 100644
--- a/include/asm-ppc/mpc83xx.h
+++ b/include/asm-ppc/mpc83xx.h
@@ -25,14 +25,6 @@
25#include <platforms/83xx/mpc834x_sys.h> 25#include <platforms/83xx/mpc834x_sys.h>
26#endif 26#endif
27 27
28#define _IO_BASE isa_io_base
29#define _ISA_MEM_BASE isa_mem_base
30#ifdef CONFIG_PCI
31#define PCI_DRAM_OFFSET pci_dram_offset
32#else
33#define PCI_DRAM_OFFSET 0
34#endif
35
36/* 28/*
37 * The "residual" board information structure the boot loader passes 29 * The "residual" board information structure the boot loader passes
38 * into the kernel. 30 * into the kernel.
diff --git a/include/asm-ppc/mpc85xx.h b/include/asm-ppc/mpc85xx.h
index 9b4851199c76..d7e4a79d77fb 100644
--- a/include/asm-ppc/mpc85xx.h
+++ b/include/asm-ppc/mpc85xx.h
@@ -44,14 +44,6 @@
44#include <platforms/85xx/tqm85xx.h> 44#include <platforms/85xx/tqm85xx.h>
45#endif 45#endif
46 46
47#define _IO_BASE isa_io_base
48#define _ISA_MEM_BASE isa_mem_base
49#ifdef CONFIG_PCI
50#define PCI_DRAM_OFFSET pci_dram_offset
51#else
52#define PCI_DRAM_OFFSET 0
53#endif
54
55/* 47/*
56 * The "residual" board information structure the boot loader passes 48 * The "residual" board information structure the boot loader passes
57 * into the kernel. 49 * into the kernel.
diff --git a/include/asm-ppc/pci-bridge.h b/include/asm-ppc/pci-bridge.h
index 9d5230689b31..6c955d0c1ef0 100644
--- a/include/asm-ppc/pci-bridge.h
+++ b/include/asm-ppc/pci-bridge.h
@@ -43,6 +43,7 @@ struct pci_controller {
43 struct pci_controller *next; 43 struct pci_controller *next;
44 struct pci_bus *bus; 44 struct pci_bus *bus;
45 void *arch_data; 45 void *arch_data;
46 struct device *parent;
46 47
47 int first_busno; 48 int first_busno;
48 int last_busno; 49 int last_busno;
diff --git a/include/asm-s390/cio.h b/include/asm-s390/cio.h
index 81287d86329d..d92785030980 100644
--- a/include/asm-s390/cio.h
+++ b/include/asm-s390/cio.h
@@ -278,17 +278,16 @@ struct ccw_dev_id {
278static inline int ccw_dev_id_is_equal(struct ccw_dev_id *dev_id1, 278static inline int ccw_dev_id_is_equal(struct ccw_dev_id *dev_id1,
279 struct ccw_dev_id *dev_id2) 279 struct ccw_dev_id *dev_id2)
280{ 280{
281 return !memcmp(dev_id1, dev_id2, sizeof(struct ccw_dev_id)); 281 if ((dev_id1->ssid == dev_id2->ssid) &&
282 (dev_id1->devno == dev_id2->devno))
283 return 1;
284 return 0;
282} 285}
283 286
284extern int diag210(struct diag210 *addr); 287extern int diag210(struct diag210 *addr);
285 288
286extern void wait_cons_dev(void); 289extern void wait_cons_dev(void);
287 290
288extern void clear_all_subchannels(void);
289
290extern void cio_reset_channel_paths(void);
291
292extern void css_schedule_reprobe(void); 291extern void css_schedule_reprobe(void);
293 292
294extern void reipl_ccw_dev(struct ccw_dev_id *id); 293extern void reipl_ccw_dev(struct ccw_dev_id *id);
diff --git a/include/asm-s390/cpcmd.h b/include/asm-s390/cpcmd.h
index 1fcf65be7a23..48a9eab16429 100644
--- a/include/asm-s390/cpcmd.h
+++ b/include/asm-s390/cpcmd.h
@@ -7,8 +7,8 @@
7 * Christian Borntraeger (cborntra@de.ibm.com), 7 * Christian Borntraeger (cborntra@de.ibm.com),
8 */ 8 */
9 9
10#ifndef __CPCMD__ 10#ifndef _ASM_S390_CPCMD_H
11#define __CPCMD__ 11#define _ASM_S390_CPCMD_H
12 12
13/* 13/*
14 * the lowlevel function for cpcmd 14 * the lowlevel function for cpcmd
@@ -16,9 +16,6 @@
16 */ 16 */
17extern int __cpcmd(const char *cmd, char *response, int rlen, int *response_code); 17extern int __cpcmd(const char *cmd, char *response, int rlen, int *response_code);
18 18
19#ifndef __s390x__
20#define cpcmd __cpcmd
21#else
22/* 19/*
23 * cpcmd is the in-kernel interface for issuing CP commands 20 * cpcmd is the in-kernel interface for issuing CP commands
24 * 21 *
@@ -33,6 +30,5 @@ extern int __cpcmd(const char *cmd, char *response, int rlen, int *response_code
33 * NOTE: If the response buffer is not below 2 GB, cpcmd can sleep 30 * NOTE: If the response buffer is not below 2 GB, cpcmd can sleep
34 */ 31 */
35extern int cpcmd(const char *cmd, char *response, int rlen, int *response_code); 32extern int cpcmd(const char *cmd, char *response, int rlen, int *response_code);
36#endif /*__s390x__*/
37 33
38#endif 34#endif /* _ASM_S390_CPCMD_H */
diff --git a/include/asm-s390/kexec.h b/include/asm-s390/kexec.h
index ce28ddda0f50..9c35c8ad1afd 100644
--- a/include/asm-s390/kexec.h
+++ b/include/asm-s390/kexec.h
@@ -26,7 +26,7 @@
26 26
27/* Maximum address we can use for the control pages */ 27/* Maximum address we can use for the control pages */
28/* Not more than 2GB */ 28/* Not more than 2GB */
29#define KEXEC_CONTROL_MEMORY_LIMIT (1<<31) 29#define KEXEC_CONTROL_MEMORY_LIMIT (1UL<<31)
30 30
31/* Allocate one page for the pdp and the second for the code */ 31/* Allocate one page for the pdp and the second for the code */
32#define KEXEC_CONTROL_CODE_SIZE 4096 32#define KEXEC_CONTROL_CODE_SIZE 4096
diff --git a/include/asm-s390/lowcore.h b/include/asm-s390/lowcore.h
index 06583ed0bde7..74f7389bd3ee 100644
--- a/include/asm-s390/lowcore.h
+++ b/include/asm-s390/lowcore.h
@@ -362,6 +362,14 @@ static inline void set_prefix(__u32 address)
362 asm volatile("spx %0" : : "m" (address) : "memory"); 362 asm volatile("spx %0" : : "m" (address) : "memory");
363} 363}
364 364
365static inline __u32 store_prefix(void)
366{
367 __u32 address;
368
369 asm volatile("stpx %0" : "=m" (address));
370 return address;
371}
372
365#define __PANIC_MAGIC 0xDEADC0DE 373#define __PANIC_MAGIC 0xDEADC0DE
366 374
367#endif 375#endif
diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h
index 36bb6dacf008..2d968a69ed1f 100644
--- a/include/asm-s390/pgtable.h
+++ b/include/asm-s390/pgtable.h
@@ -110,13 +110,22 @@ extern char empty_zero_page[PAGE_SIZE];
110#define VMALLOC_OFFSET (8*1024*1024) 110#define VMALLOC_OFFSET (8*1024*1024)
111#define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) \ 111#define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) \
112 & ~(VMALLOC_OFFSET-1)) 112 & ~(VMALLOC_OFFSET-1))
113
114/*
115 * We need some free virtual space to be able to do vmalloc.
116 * VMALLOC_MIN_SIZE defines the minimum size of the vmalloc
117 * area. On a machine with 2GB memory we make sure that we
118 * have at least 128MB free space for vmalloc. On a machine
119 * with 4TB we make sure we have at least 1GB.
120 */
113#ifndef __s390x__ 121#ifndef __s390x__
114# define VMALLOC_END (0x7fffffffL) 122#define VMALLOC_MIN_SIZE 0x8000000UL
123#define VMALLOC_END 0x80000000UL
115#else /* __s390x__ */ 124#else /* __s390x__ */
116# define VMALLOC_END (0x40000000000L) 125#define VMALLOC_MIN_SIZE 0x40000000UL
126#define VMALLOC_END 0x40000000000UL
117#endif /* __s390x__ */ 127#endif /* __s390x__ */
118 128
119
120/* 129/*
121 * A 31 bit pagetable entry of S390 has following format: 130 * A 31 bit pagetable entry of S390 has following format:
122 * | PFRA | | OS | 131 * | PFRA | | OS |
diff --git a/include/asm-s390/reset.h b/include/asm-s390/reset.h
new file mode 100644
index 000000000000..9b439cf67800
--- /dev/null
+++ b/include/asm-s390/reset.h
@@ -0,0 +1,23 @@
1/*
2 * include/asm-s390/reset.h
3 *
4 * Copyright IBM Corp. 2006
5 * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com>
6 */
7
8#ifndef _ASM_S390_RESET_H
9#define _ASM_S390_RESET_H
10
11#include <linux/list.h>
12
13struct reset_call {
14 struct list_head list;
15 void (*fn)(void);
16};
17
18extern void register_reset_call(struct reset_call *reset);
19extern void unregister_reset_call(struct reset_call *reset);
20extern void s390_reset_system(void);
21extern void (*s390_reset_mcck_handler)(void);
22
23#endif /* _ASM_S390_RESET_H */
diff --git a/include/asm-s390/setup.h b/include/asm-s390/setup.h
index 5d72eda8a11b..7664bacdd832 100644
--- a/include/asm-s390/setup.h
+++ b/include/asm-s390/setup.h
@@ -2,7 +2,7 @@
2 * include/asm-s390/setup.h 2 * include/asm-s390/setup.h
3 * 3 *
4 * S390 version 4 * S390 version
5 * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation 5 * Copyright IBM Corp. 1999,2006
6 */ 6 */
7 7
8#ifndef _ASM_S390_SETUP_H 8#ifndef _ASM_S390_SETUP_H
@@ -30,6 +30,17 @@
30#endif /* __s390x__ */ 30#endif /* __s390x__ */
31#define COMMAND_LINE ((char *) (0x10480)) 31#define COMMAND_LINE ((char *) (0x10480))
32 32
33#define CHUNK_READ_WRITE 0
34#define CHUNK_READ_ONLY 1
35
36struct mem_chunk {
37 unsigned long addr;
38 unsigned long size;
39 unsigned long type;
40};
41
42extern struct mem_chunk memory_chunk[];
43
33/* 44/*
34 * Machine features detected in head.S 45 * Machine features detected in head.S
35 */ 46 */
@@ -53,7 +64,6 @@ extern unsigned long machine_flags;
53#define MACHINE_HAS_MVCOS (machine_flags & 512) 64#define MACHINE_HAS_MVCOS (machine_flags & 512)
54#endif /* __s390x__ */ 65#endif /* __s390x__ */
55 66
56
57#define MACHINE_HAS_SCLP (!MACHINE_IS_P390) 67#define MACHINE_HAS_SCLP (!MACHINE_IS_P390)
58 68
59/* 69/*
@@ -71,7 +81,6 @@ extern unsigned int console_irq;
71#define SET_CONSOLE_3215 do { console_mode = 2; } while (0) 81#define SET_CONSOLE_3215 do { console_mode = 2; } while (0)
72#define SET_CONSOLE_3270 do { console_mode = 3; } while (0) 82#define SET_CONSOLE_3270 do { console_mode = 3; } while (0)
73 83
74
75struct ipl_list_hdr { 84struct ipl_list_hdr {
76 u32 len; 85 u32 len;
77 u8 reserved1[3]; 86 u8 reserved1[3];
diff --git a/include/asm-s390/smp.h b/include/asm-s390/smp.h
index c3cf030ada4d..7097c96ed026 100644
--- a/include/asm-s390/smp.h
+++ b/include/asm-s390/smp.h
@@ -18,6 +18,7 @@
18 18
19#include <asm/lowcore.h> 19#include <asm/lowcore.h>
20#include <asm/sigp.h> 20#include <asm/sigp.h>
21#include <asm/ptrace.h>
21 22
22/* 23/*
23 s390 specific smp.c headers 24 s390 specific smp.c headers
@@ -101,6 +102,13 @@ smp_call_function_on(void (*func) (void *info), void *info,
101 func(info); 102 func(info);
102 return 0; 103 return 0;
103} 104}
105
106static inline void smp_send_stop(void)
107{
108 /* Disable all interrupts/machine checks */
109 __load_psw_mask(PSW_KERNEL_BITS & ~PSW_MASK_MCHECK);
110}
111
104#define smp_cpu_not_running(cpu) 1 112#define smp_cpu_not_running(cpu) 1
105#define smp_get_cpu(cpu) ({ 0; }) 113#define smp_get_cpu(cpu) ({ 0; })
106#define smp_put_cpu(cpu) ({ 0; }) 114#define smp_put_cpu(cpu) ({ 0; })
diff --git a/include/asm-s390/system.h b/include/asm-s390/system.h
index ccbafe4bf2cb..bd0b05ae87d2 100644
--- a/include/asm-s390/system.h
+++ b/include/asm-s390/system.h
@@ -115,6 +115,16 @@ extern void account_system_vtime(struct task_struct *);
115#define account_vtime(x) do { /* empty */ } while (0) 115#define account_vtime(x) do { /* empty */ } while (0)
116#endif 116#endif
117 117
118#ifdef CONFIG_PFAULT
119extern void pfault_irq_init(void);
120extern int pfault_init(void);
121extern void pfault_fini(void);
122#else /* CONFIG_PFAULT */
123#define pfault_irq_init() do { } while (0)
124#define pfault_init() ({-1;})
125#define pfault_fini() do { } while (0)
126#endif /* CONFIG_PFAULT */
127
118#define finish_arch_switch(prev) do { \ 128#define finish_arch_switch(prev) do { \
119 set_fs(current->thread.mm_segment); \ 129 set_fs(current->thread.mm_segment); \
120 account_vtime(prev); \ 130 account_vtime(prev); \
diff --git a/include/asm-s390/termios.h b/include/asm-s390/termios.h
index d1e29cca54c9..62b23caf370e 100644
--- a/include/asm-s390/termios.h
+++ b/include/asm-s390/termios.h
@@ -75,39 +75,7 @@ struct termio {
75*/ 75*/
76#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" 76#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0"
77 77
78/* 78#include <asm-generic/termios.h>
79 * Translate a "termio" structure into a "termios". Ugh.
80 */
81#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \
82 unsigned short __tmp; \
83 get_user(__tmp,&(termio)->x); \
84 (termios)->x = (0xffff0000 & ((termios)->x)) | __tmp; \
85}
86
87#define user_termio_to_kernel_termios(termios, termio) \
88({ \
89 SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \
90 SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \
91 SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \
92 SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \
93 copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \
94})
95
96/*
97 * Translate a "termios" structure into a "termio". Ugh.
98 */
99#define kernel_termios_to_user_termio(termio, termios) \
100({ \
101 put_user((termios)->c_iflag, &(termio)->c_iflag); \
102 put_user((termios)->c_oflag, &(termio)->c_oflag); \
103 put_user((termios)->c_cflag, &(termio)->c_cflag); \
104 put_user((termios)->c_lflag, &(termio)->c_lflag); \
105 put_user((termios)->c_line, &(termio)->c_line); \
106 copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \
107})
108
109#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios))
110#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios))
111 79
112#endif /* __KERNEL__ */ 80#endif /* __KERNEL__ */
113 81
diff --git a/include/asm-s390/types.h b/include/asm-s390/types.h
index ae2951cc83ac..fc5d7cf19324 100644
--- a/include/asm-s390/types.h
+++ b/include/asm-s390/types.h
@@ -87,16 +87,6 @@ typedef union {
87 } subreg; 87 } subreg;
88} register_pair; 88} register_pair;
89 89
90#ifdef CONFIG_LBD
91typedef u64 sector_t;
92#define HAVE_SECTOR_T
93#endif
94
95#ifdef CONFIG_LSF
96typedef u64 blkcnt_t;
97#define HAVE_BLKCNT_T
98#endif
99
100#endif /* ! __s390x__ */ 90#endif /* ! __s390x__ */
101#endif /* __ASSEMBLY__ */ 91#endif /* __ASSEMBLY__ */
102#endif /* __KERNEL__ */ 92#endif /* __KERNEL__ */
diff --git a/include/asm-s390/uaccess.h b/include/asm-s390/uaccess.h
index 72ae4efddb49..73ac4e82217b 100644
--- a/include/asm-s390/uaccess.h
+++ b/include/asm-s390/uaccess.h
@@ -201,7 +201,7 @@ extern int __get_user_bad(void) __attribute__((noreturn));
201 * Returns number of bytes that could not be copied. 201 * Returns number of bytes that could not be copied.
202 * On success, this will be zero. 202 * On success, this will be zero.
203 */ 203 */
204static inline unsigned long 204static inline unsigned long __must_check
205__copy_to_user(void __user *to, const void *from, unsigned long n) 205__copy_to_user(void __user *to, const void *from, unsigned long n)
206{ 206{
207 if (__builtin_constant_p(n) && (n <= 256)) 207 if (__builtin_constant_p(n) && (n <= 256))
@@ -226,7 +226,7 @@ __copy_to_user(void __user *to, const void *from, unsigned long n)
226 * Returns number of bytes that could not be copied. 226 * Returns number of bytes that could not be copied.
227 * On success, this will be zero. 227 * On success, this will be zero.
228 */ 228 */
229static inline unsigned long 229static inline unsigned long __must_check
230copy_to_user(void __user *to, const void *from, unsigned long n) 230copy_to_user(void __user *to, const void *from, unsigned long n)
231{ 231{
232 might_sleep(); 232 might_sleep();
@@ -252,7 +252,7 @@ copy_to_user(void __user *to, const void *from, unsigned long n)
252 * If some data could not be copied, this function will pad the copied 252 * If some data could not be copied, this function will pad the copied
253 * data to the requested size using zero bytes. 253 * data to the requested size using zero bytes.
254 */ 254 */
255static inline unsigned long 255static inline unsigned long __must_check
256__copy_from_user(void *to, const void __user *from, unsigned long n) 256__copy_from_user(void *to, const void __user *from, unsigned long n)
257{ 257{
258 if (__builtin_constant_p(n) && (n <= 256)) 258 if (__builtin_constant_p(n) && (n <= 256))
@@ -277,7 +277,7 @@ __copy_from_user(void *to, const void __user *from, unsigned long n)
277 * If some data could not be copied, this function will pad the copied 277 * If some data could not be copied, this function will pad the copied
278 * data to the requested size using zero bytes. 278 * data to the requested size using zero bytes.
279 */ 279 */
280static inline unsigned long 280static inline unsigned long __must_check
281copy_from_user(void *to, const void __user *from, unsigned long n) 281copy_from_user(void *to, const void __user *from, unsigned long n)
282{ 282{
283 might_sleep(); 283 might_sleep();
@@ -288,13 +288,13 @@ copy_from_user(void *to, const void __user *from, unsigned long n)
288 return n; 288 return n;
289} 289}
290 290
291static inline unsigned long 291static inline unsigned long __must_check
292__copy_in_user(void __user *to, const void __user *from, unsigned long n) 292__copy_in_user(void __user *to, const void __user *from, unsigned long n)
293{ 293{
294 return uaccess.copy_in_user(n, to, from); 294 return uaccess.copy_in_user(n, to, from);
295} 295}
296 296
297static inline unsigned long 297static inline unsigned long __must_check
298copy_in_user(void __user *to, const void __user *from, unsigned long n) 298copy_in_user(void __user *to, const void __user *from, unsigned long n)
299{ 299{
300 might_sleep(); 300 might_sleep();
@@ -306,7 +306,7 @@ copy_in_user(void __user *to, const void __user *from, unsigned long n)
306/* 306/*
307 * Copy a null terminated string from userspace. 307 * Copy a null terminated string from userspace.
308 */ 308 */
309static inline long 309static inline long __must_check
310strncpy_from_user(char *dst, const char __user *src, long count) 310strncpy_from_user(char *dst, const char __user *src, long count)
311{ 311{
312 long res = -EFAULT; 312 long res = -EFAULT;
@@ -343,13 +343,13 @@ strnlen_user(const char __user * src, unsigned long n)
343 * Zero Userspace 343 * Zero Userspace
344 */ 344 */
345 345
346static inline unsigned long 346static inline unsigned long __must_check
347__clear_user(void __user *to, unsigned long n) 347__clear_user(void __user *to, unsigned long n)
348{ 348{
349 return uaccess.clear_user(n, to); 349 return uaccess.clear_user(n, to);
350} 350}
351 351
352static inline unsigned long 352static inline unsigned long __must_check
353clear_user(void __user *to, unsigned long n) 353clear_user(void __user *to, unsigned long n)
354{ 354{
355 might_sleep(); 355 might_sleep();
diff --git a/include/asm-s390/zcrypt.h b/include/asm-s390/zcrypt.h
index 7244c68464f2..b90e55888a55 100644
--- a/include/asm-s390/zcrypt.h
+++ b/include/asm-s390/zcrypt.h
@@ -180,40 +180,8 @@ struct ica_xcRB {
180 * for the implementation details for the contents of the 180 * for the implementation details for the contents of the
181 * block 181 * block
182 * 182 *
183 * Z90STAT_TOTALCOUNT 183 * ZSECSENDCPRB
184 * Return an integer count of all device types together. 184 * Send an arbitrary CPRB to a crypto card.
185 *
186 * Z90STAT_PCICACOUNT
187 * Return an integer count of all PCICAs.
188 *
189 * Z90STAT_PCICCCOUNT
190 * Return an integer count of all PCICCs.
191 *
192 * Z90STAT_PCIXCCMCL2COUNT
193 * Return an integer count of all MCL2 PCIXCCs.
194 *
195 * Z90STAT_PCIXCCMCL3COUNT
196 * Return an integer count of all MCL3 PCIXCCs.
197 *
198 * Z90STAT_CEX2CCOUNT
199 * Return an integer count of all CEX2Cs.
200 *
201 * Z90STAT_CEX2ACOUNT
202 * Return an integer count of all CEX2As.
203 *
204 * Z90STAT_REQUESTQ_COUNT
205 * Return an integer count of the number of entries waiting to be
206 * sent to a device.
207 *
208 * Z90STAT_PENDINGQ_COUNT
209 * Return an integer count of the number of entries sent to a
210 * device awaiting the reply.
211 *
212 * Z90STAT_TOTALOPEN_COUNT
213 * Return an integer count of the number of open file handles.
214 *
215 * Z90STAT_DOMAIN_INDEX
216 * Return the integer value of the Cryptographic Domain.
217 * 185 *
218 * Z90STAT_STATUS_MASK 186 * Z90STAT_STATUS_MASK
219 * Return an 64 element array of unsigned chars for the status of 187 * Return an 64 element array of unsigned chars for the status of
@@ -235,28 +203,51 @@ struct ica_xcRB {
235 * of successfully completed requests per device since the device 203 * of successfully completed requests per device since the device
236 * was detected and made available. 204 * was detected and made available.
237 * 205 *
238 * ICAZ90STATUS (deprecated) 206 * Z90STAT_REQUESTQ_COUNT
207 * Return an integer count of the number of entries waiting to be
208 * sent to a device.
209 *
210 * Z90STAT_PENDINGQ_COUNT
211 * Return an integer count of the number of entries sent to all
212 * devices awaiting the reply.
213 *
214 * Z90STAT_TOTALOPEN_COUNT
215 * Return an integer count of the number of open file handles.
216 *
217 * Z90STAT_DOMAIN_INDEX
218 * Return the integer value of the Cryptographic Domain.
219 *
220 * The following ioctls are deprecated and should be no longer used:
221 *
222 * Z90STAT_TOTALCOUNT
223 * Return an integer count of all device types together.
224 *
225 * Z90STAT_PCICACOUNT
226 * Return an integer count of all PCICAs.
227 *
228 * Z90STAT_PCICCCOUNT
229 * Return an integer count of all PCICCs.
230 *
231 * Z90STAT_PCIXCCMCL2COUNT
232 * Return an integer count of all MCL2 PCIXCCs.
233 *
234 * Z90STAT_PCIXCCMCL3COUNT
235 * Return an integer count of all MCL3 PCIXCCs.
236 *
237 * Z90STAT_CEX2CCOUNT
238 * Return an integer count of all CEX2Cs.
239 *
240 * Z90STAT_CEX2ACOUNT
241 * Return an integer count of all CEX2As.
242 *
243 * ICAZ90STATUS
239 * Return some device driver status in a ica_z90_status struct 244 * Return some device driver status in a ica_z90_status struct
240 * This takes an ica_z90_status struct as its arg. 245 * This takes an ica_z90_status struct as its arg.
241 * 246 *
242 * NOTE: this ioctl() is deprecated, and has been replaced with 247 * Z90STAT_PCIXCCCOUNT
243 * single ioctl()s for each type of status being requested
244 *
245 * Z90STAT_PCIXCCCOUNT (deprecated)
246 * Return an integer count of all PCIXCCs (MCL2 + MCL3). 248 * Return an integer count of all PCIXCCs (MCL2 + MCL3).
247 * This is DEPRECATED now that MCL3 PCIXCCs are treated differently from 249 * This is DEPRECATED now that MCL3 PCIXCCs are treated differently from
248 * MCL2 PCIXCCs. 250 * MCL2 PCIXCCs.
249 *
250 * Z90QUIESCE (not recommended)
251 * Quiesce the driver. This is intended to stop all new
252 * requests from being processed. Its use is NOT recommended,
253 * except in circumstances where there is no other way to stop
254 * callers from accessing the driver. Its original use was to
255 * allow the driver to be "drained" of work in preparation for
256 * a system shutdown.
257 *
258 * NOTE: once issued, this ban on new work cannot be undone
259 * except by unloading and reloading the driver.
260 */ 251 */
261 252
262/** 253/**
diff --git a/include/asm-sh/types.h b/include/asm-sh/types.h
index 3c09dd4ca31c..fd00dbb82f84 100644
--- a/include/asm-sh/types.h
+++ b/include/asm-sh/types.h
@@ -52,16 +52,6 @@ typedef unsigned long long u64;
52 52
53typedef u32 dma_addr_t; 53typedef u32 dma_addr_t;
54 54
55#ifdef CONFIG_LBD
56typedef u64 sector_t;
57#define HAVE_SECTOR_T
58#endif
59
60#ifdef CONFIG_LSF
61typedef u64 blkcnt_t;
62#define HAVE_BLKCNT_T
63#endif
64
65#endif /* __ASSEMBLY__ */ 55#endif /* __ASSEMBLY__ */
66 56
67#endif /* __KERNEL__ */ 57#endif /* __KERNEL__ */
diff --git a/include/asm-x86_64/elf.h b/include/asm-x86_64/elf.h
index a406fcb1e924..6d24ea7c4d9d 100644
--- a/include/asm-x86_64/elf.h
+++ b/include/asm-x86_64/elf.h
@@ -45,7 +45,6 @@ typedef struct user_i387_struct elf_fpregset_t;
45 45
46#ifdef __KERNEL__ 46#ifdef __KERNEL__
47#include <asm/processor.h> 47#include <asm/processor.h>
48#include <asm/compat.h>
49 48
50/* 49/*
51 * This is used to ensure we don't load something for the wrong architecture. 50 * This is used to ensure we don't load something for the wrong architecture.
diff --git a/include/asm-x86_64/types.h b/include/asm-x86_64/types.h
index c86c2e6793e2..2d4491aae281 100644
--- a/include/asm-x86_64/types.h
+++ b/include/asm-x86_64/types.h
@@ -48,9 +48,6 @@ typedef unsigned long long u64;
48typedef u64 dma64_addr_t; 48typedef u64 dma64_addr_t;
49typedef u64 dma_addr_t; 49typedef u64 dma_addr_t;
50 50
51typedef u64 sector_t;
52#define HAVE_SECTOR_T
53
54#endif /* __ASSEMBLY__ */ 51#endif /* __ASSEMBLY__ */
55 52
56#endif /* __KERNEL__ */ 53#endif /* __KERNEL__ */
diff --git a/include/asm-x86_64/uaccess.h b/include/asm-x86_64/uaccess.h
index 19f99178fe83..d5dbc87274f8 100644
--- a/include/asm-x86_64/uaccess.h
+++ b/include/asm-x86_64/uaccess.h
@@ -6,7 +6,6 @@
6 */ 6 */
7#include <linux/compiler.h> 7#include <linux/compiler.h>
8#include <linux/errno.h> 8#include <linux/errno.h>
9#include <linux/sched.h>
10#include <linux/prefetch.h> 9#include <linux/prefetch.h>
11#include <asm/page.h> 10#include <asm/page.h>
12 11
diff --git a/include/linux/acct.h b/include/linux/acct.h
index 0496d1f09952..302eb727ecb8 100644
--- a/include/linux/acct.h
+++ b/include/linux/acct.h
@@ -119,6 +119,7 @@ struct acct_v3
119#ifdef CONFIG_BSD_PROCESS_ACCT 119#ifdef CONFIG_BSD_PROCESS_ACCT
120struct vfsmount; 120struct vfsmount;
121struct super_block; 121struct super_block;
122struct pacct_struct;
122extern void acct_auto_close_mnt(struct vfsmount *m); 123extern void acct_auto_close_mnt(struct vfsmount *m);
123extern void acct_auto_close(struct super_block *sb); 124extern void acct_auto_close(struct super_block *sb);
124extern void acct_init_pacct(struct pacct_struct *pacct); 125extern void acct_init_pacct(struct pacct_struct *pacct);
diff --git a/include/linux/ata.h b/include/linux/ata.h
index d89441907024..1df941648a57 100644
--- a/include/linux/ata.h
+++ b/include/linux/ata.h
@@ -200,8 +200,9 @@ enum {
200 ATA_CBL_NONE = 0, 200 ATA_CBL_NONE = 0,
201 ATA_CBL_PATA40 = 1, 201 ATA_CBL_PATA40 = 1,
202 ATA_CBL_PATA80 = 2, 202 ATA_CBL_PATA80 = 2,
203 ATA_CBL_PATA_UNK = 3, 203 ATA_CBL_PATA40_SHORT = 3, /* 40 wire cable to high UDMA spec */
204 ATA_CBL_SATA = 4, 204 ATA_CBL_PATA_UNK = 4,
205 ATA_CBL_SATA = 5,
205 206
206 /* SATA Status and Control Registers */ 207 /* SATA Status and Control Registers */
207 SCR_STATUS = 0, 208 SCR_STATUS = 0,
@@ -342,6 +343,15 @@ static inline int ata_id_is_cfa(const u16 *id)
342 return 0; 343 return 0;
343} 344}
344 345
346static inline int ata_drive_40wire(const u16 *dev_id)
347{
348 if (ata_id_major_version(dev_id) >= 5 && ata_id_is_sata(dev_id))
349 return 0; /* SATA */
350 if (dev_id[93] & 0x4000)
351 return 0; /* 80 wire */
352 return 1;
353}
354
345static inline int atapi_cdb_len(const u16 *dev_id) 355static inline int atapi_cdb_len(const u16 *dev_id)
346{ 356{
347 u16 tmp = dev_id[0] & 0x3; 357 u16 tmp = dev_id[0] & 0x3;
diff --git a/include/linux/cpu.h b/include/linux/cpu.h
index 3fef7d67aedc..f02d71bf6894 100644
--- a/include/linux/cpu.h
+++ b/include/linux/cpu.h
@@ -33,6 +33,14 @@ struct cpu {
33 33
34extern int register_cpu(struct cpu *cpu, int num); 34extern int register_cpu(struct cpu *cpu, int num);
35extern struct sys_device *get_cpu_sysdev(unsigned cpu); 35extern struct sys_device *get_cpu_sysdev(unsigned cpu);
36
37extern int cpu_add_sysdev_attr(struct sysdev_attribute *attr);
38extern void cpu_remove_sysdev_attr(struct sysdev_attribute *attr);
39
40extern int cpu_add_sysdev_attr_group(struct attribute_group *attrs);
41extern void cpu_remove_sysdev_attr_group(struct attribute_group *attrs);
42
43
36#ifdef CONFIG_HOTPLUG_CPU 44#ifdef CONFIG_HOTPLUG_CPU
37extern void unregister_cpu(struct cpu *cpu); 45extern void unregister_cpu(struct cpu *cpu);
38#endif 46#endif
diff --git a/include/linux/elf.h b/include/linux/elf.h
index b70d1d2c8d28..743d5c8e6d36 100644
--- a/include/linux/elf.h
+++ b/include/linux/elf.h
@@ -368,5 +368,12 @@ extern Elf64_Dyn _DYNAMIC [];
368 368
369#endif 369#endif
370 370
371#ifndef ARCH_HAVE_EXTRA_ELF_NOTES
372static inline int arch_notes_size(void) { return 0; }
373static inline void arch_write_notes(struct file *file) { }
374
375#define ELF_CORE_EXTRA_NOTES_SIZE arch_notes_size()
376#define ELF_CORE_WRITE_EXTRA_NOTES arch_write_notes(file)
377#endif /* ARCH_HAVE_EXTRA_ELF_NOTES */
371 378
372#endif /* _LINUX_ELF_H */ 379#endif /* _LINUX_ELF_H */
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 2fe6e3f900ba..cac7b1ef9543 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -276,7 +276,7 @@ extern int dir_notify_enable;
276#include <linux/radix-tree.h> 276#include <linux/radix-tree.h>
277#include <linux/prio_tree.h> 277#include <linux/prio_tree.h>
278#include <linux/init.h> 278#include <linux/init.h>
279#include <linux/sched.h> 279#include <linux/pid.h>
280#include <linux/mutex.h> 280#include <linux/mutex.h>
281 281
282#include <asm/atomic.h> 282#include <asm/atomic.h>
@@ -977,36 +977,13 @@ enum {
977#define vfs_check_frozen(sb, level) \ 977#define vfs_check_frozen(sb, level) \
978 wait_event((sb)->s_wait_unfrozen, ((sb)->s_frozen < (level))) 978 wait_event((sb)->s_wait_unfrozen, ((sb)->s_frozen < (level)))
979 979
980static inline void get_fs_excl(void) 980#define get_fs_excl() atomic_inc(&current->fs_excl)
981{ 981#define put_fs_excl() atomic_dec(&current->fs_excl)
982 atomic_inc(&current->fs_excl); 982#define has_fs_excl() atomic_read(&current->fs_excl)
983}
984
985static inline void put_fs_excl(void)
986{
987 atomic_dec(&current->fs_excl);
988}
989
990static inline int has_fs_excl(void)
991{
992 return atomic_read(&current->fs_excl);
993}
994 983
995 984/* not quite ready to be deprecated, but... */
996/* 985extern void lock_super(struct super_block *);
997 * Superblock locking. 986extern void unlock_super(struct super_block *);
998 */
999static inline void lock_super(struct super_block * sb)
1000{
1001 get_fs_excl();
1002 mutex_lock(&sb->s_lock);
1003}
1004
1005static inline void unlock_super(struct super_block * sb)
1006{
1007 put_fs_excl();
1008 mutex_unlock(&sb->s_lock);
1009}
1010 987
1011/* 988/*
1012 * VFS helper functions.. 989 * VFS helper functions..
diff --git a/include/linux/igmp.h b/include/linux/igmp.h
index 6e7ea2f0a57c..9dbb525c5178 100644
--- a/include/linux/igmp.h
+++ b/include/linux/igmp.h
@@ -127,6 +127,7 @@ struct igmpv3_query {
127 127
128#ifdef __KERNEL__ 128#ifdef __KERNEL__
129#include <linux/skbuff.h> 129#include <linux/skbuff.h>
130#include <linux/timer.h>
130#include <linux/in.h> 131#include <linux/in.h>
131 132
132extern int sysctl_igmp_max_memberships; 133extern int sysctl_igmp_max_memberships;
diff --git a/include/linux/kernelcapi.h b/include/linux/kernelcapi.h
index 891bb2cf0aa8..aea34e74c496 100644
--- a/include/linux/kernelcapi.h
+++ b/include/linux/kernelcapi.h
@@ -47,6 +47,8 @@ typedef struct kcapi_carddef {
47 47
48#include <linux/list.h> 48#include <linux/list.h>
49#include <linux/skbuff.h> 49#include <linux/skbuff.h>
50#include <linux/workqueue.h>
51#include <asm/semaphore.h>
50 52
51#define KCI_CONTRUP 0 /* arg: struct capi_profile */ 53#define KCI_CONTRUP 0 /* arg: struct capi_profile */
52#define KCI_CONTRDOWN 1 /* arg: NULL */ 54#define KCI_CONTRDOWN 1 /* arg: NULL */
diff --git a/include/linux/libata.h b/include/linux/libata.h
index b3f32eadbef5..ab2754830322 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -140,6 +140,7 @@ enum {
140 ATA_DFLAG_LBA48 = (1 << 1), /* device supports LBA48 */ 140 ATA_DFLAG_LBA48 = (1 << 1), /* device supports LBA48 */
141 ATA_DFLAG_CDB_INTR = (1 << 2), /* device asserts INTRQ when ready for CDB */ 141 ATA_DFLAG_CDB_INTR = (1 << 2), /* device asserts INTRQ when ready for CDB */
142 ATA_DFLAG_NCQ = (1 << 3), /* device supports NCQ */ 142 ATA_DFLAG_NCQ = (1 << 3), /* device supports NCQ */
143 ATA_DFLAG_FLUSH_EXT = (1 << 4), /* do FLUSH_EXT instead of FLUSH */
143 ATA_DFLAG_CFG_MASK = (1 << 8) - 1, 144 ATA_DFLAG_CFG_MASK = (1 << 8) - 1,
144 145
145 ATA_DFLAG_PIO = (1 << 8), /* device limited to PIO mode */ 146 ATA_DFLAG_PIO = (1 << 8), /* device limited to PIO mode */
@@ -175,6 +176,7 @@ enum {
175 ATA_FLAG_SKIP_D2H_BSY = (1 << 12), /* can't wait for the first D2H 176 ATA_FLAG_SKIP_D2H_BSY = (1 << 12), /* can't wait for the first D2H
176 * Register FIS clearing BSY */ 177 * Register FIS clearing BSY */
177 ATA_FLAG_DEBUGMSG = (1 << 13), 178 ATA_FLAG_DEBUGMSG = (1 << 13),
179 ATA_FLAG_SETXFER_POLLING= (1 << 14), /* use polling for SETXFER */
178 180
179 /* The following flag belongs to ap->pflags but is kept in 181 /* The following flag belongs to ap->pflags but is kept in
180 * ap->flags because it's referenced in many LLDs and will be 182 * ap->flags because it's referenced in many LLDs and will be
@@ -283,6 +285,9 @@ enum {
283 ATA_EHI_QUIET = (1 << 3), /* be quiet */ 285 ATA_EHI_QUIET = (1 << 3), /* be quiet */
284 286
285 ATA_EHI_DID_RESET = (1 << 16), /* already reset this port */ 287 ATA_EHI_DID_RESET = (1 << 16), /* already reset this port */
288 ATA_EHI_PRINTINFO = (1 << 17), /* print configuration info */
289 ATA_EHI_SETMODE = (1 << 18), /* configure transfer mode */
290 ATA_EHI_POST_SETMODE = (1 << 19), /* revaildating after setmode */
286 291
287 ATA_EHI_RESET_MODIFIER_MASK = ATA_EHI_RESUME_LINK, 292 ATA_EHI_RESET_MODIFIER_MASK = ATA_EHI_RESUME_LINK,
288 293
@@ -307,10 +312,11 @@ enum {
307 (some horkage may be drive/controller pair dependant */ 312 (some horkage may be drive/controller pair dependant */
308 313
309 ATA_HORKAGE_DIAGNOSTIC = (1 << 0), /* Failed boot diag */ 314 ATA_HORKAGE_DIAGNOSTIC = (1 << 0), /* Failed boot diag */
315 ATA_HORKAGE_NODMA = (1 << 1), /* DMA problems */
316 ATA_HORKAGE_NONCQ = (1 << 2), /* Don't use NCQ */
310}; 317};
311 318
312enum hsm_task_states { 319enum hsm_task_states {
313 HSM_ST_UNKNOWN, /* state unknown */
314 HSM_ST_IDLE, /* no command on going */ 320 HSM_ST_IDLE, /* no command on going */
315 HSM_ST, /* (waiting the device to) transfer data */ 321 HSM_ST, /* (waiting the device to) transfer data */
316 HSM_ST_LAST, /* (waiting the device to) complete command */ 322 HSM_ST_LAST, /* (waiting the device to) complete command */
@@ -329,6 +335,7 @@ enum ata_completion_errors {
329 AC_ERR_SYSTEM = (1 << 6), /* system error */ 335 AC_ERR_SYSTEM = (1 << 6), /* system error */
330 AC_ERR_INVALID = (1 << 7), /* invalid argument */ 336 AC_ERR_INVALID = (1 << 7), /* invalid argument */
331 AC_ERR_OTHER = (1 << 8), /* unknown */ 337 AC_ERR_OTHER = (1 << 8), /* unknown */
338 AC_ERR_NODEV_HINT = (1 << 9), /* polling device detection hint */
332}; 339};
333 340
334/* forward declarations */ 341/* forward declarations */
@@ -701,6 +708,8 @@ extern int sata_phy_debounce(struct ata_port *ap, const unsigned long *param);
701extern int sata_phy_resume(struct ata_port *ap, const unsigned long *param); 708extern int sata_phy_resume(struct ata_port *ap, const unsigned long *param);
702extern int ata_std_prereset(struct ata_port *ap); 709extern int ata_std_prereset(struct ata_port *ap);
703extern int ata_std_softreset(struct ata_port *ap, unsigned int *classes); 710extern int ata_std_softreset(struct ata_port *ap, unsigned int *classes);
711extern int sata_port_hardreset(struct ata_port *ap,
712 const unsigned long *timing);
704extern int sata_std_hardreset(struct ata_port *ap, unsigned int *class); 713extern int sata_std_hardreset(struct ata_port *ap, unsigned int *class);
705extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes); 714extern void ata_std_postreset(struct ata_port *ap, unsigned int *classes);
706extern void ata_port_disable(struct ata_port *); 715extern void ata_port_disable(struct ata_port *);
@@ -745,9 +754,8 @@ extern int ata_scsi_device_suspend(struct scsi_device *, pm_message_t mesg);
745extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg); 754extern int ata_host_suspend(struct ata_host *host, pm_message_t mesg);
746extern void ata_host_resume(struct ata_host *host); 755extern void ata_host_resume(struct ata_host *host);
747extern int ata_ratelimit(void); 756extern int ata_ratelimit(void);
748extern unsigned int ata_busy_sleep(struct ata_port *ap, 757extern int ata_busy_sleep(struct ata_port *ap,
749 unsigned long timeout_pat, 758 unsigned long timeout_pat, unsigned long timeout);
750 unsigned long timeout);
751extern void ata_port_queue_task(struct ata_port *ap, work_func_t fn, 759extern void ata_port_queue_task(struct ata_port *ap, work_func_t fn,
752 void *data, unsigned long delay); 760 void *data, unsigned long delay);
753extern u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val, 761extern u32 ata_wait_register(void __iomem *reg, u32 mask, u32 val,
@@ -788,6 +796,7 @@ extern void ata_id_string(const u16 *id, unsigned char *s,
788 unsigned int ofs, unsigned int len); 796 unsigned int ofs, unsigned int len);
789extern void ata_id_c_string(const u16 *id, unsigned char *s, 797extern void ata_id_c_string(const u16 *id, unsigned char *s,
790 unsigned int ofs, unsigned int len); 798 unsigned int ofs, unsigned int len);
799extern unsigned long ata_device_blacklisted(const struct ata_device *dev);
791extern void ata_bmdma_setup (struct ata_queued_cmd *qc); 800extern void ata_bmdma_setup (struct ata_queued_cmd *qc);
792extern void ata_bmdma_start (struct ata_queued_cmd *qc); 801extern void ata_bmdma_start (struct ata_queued_cmd *qc);
793extern void ata_bmdma_stop(struct ata_queued_cmd *qc); 802extern void ata_bmdma_stop(struct ata_queued_cmd *qc);
@@ -1062,7 +1071,7 @@ static inline u8 ata_busy_wait(struct ata_port *ap, unsigned int bits,
1062 udelay(10); 1071 udelay(10);
1063 status = ata_chk_status(ap); 1072 status = ata_chk_status(ap);
1064 max--; 1073 max--;
1065 } while ((status & bits) && (max > 0)); 1074 } while (status != 0xff && (status & bits) && (max > 0));
1066 1075
1067 return status; 1076 return status;
1068} 1077}
@@ -1083,7 +1092,7 @@ static inline u8 ata_wait_idle(struct ata_port *ap)
1083{ 1092{
1084 u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000); 1093 u8 status = ata_busy_wait(ap, ATA_BUSY | ATA_DRQ, 1000);
1085 1094
1086 if (status & (ATA_BUSY | ATA_DRQ)) { 1095 if (status != 0xff && (status & (ATA_BUSY | ATA_DRQ))) {
1087 unsigned long l = ap->ioaddr.status_addr; 1096 unsigned long l = ap->ioaddr.status_addr;
1088 if (ata_msg_warn(ap)) 1097 if (ata_msg_warn(ap))
1089 printk(KERN_WARNING "ATA: abnormal status 0x%X on port 0x%lX\n", 1098 printk(KERN_WARNING "ATA: abnormal status 0x%X on port 0x%lX\n",
@@ -1149,37 +1158,6 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc)
1149} 1158}
1150 1159
1151/** 1160/**
1152 * ata_irq_on - Enable interrupts on a port.
1153 * @ap: Port on which interrupts are enabled.
1154 *
1155 * Enable interrupts on a legacy IDE device using MMIO or PIO,
1156 * wait for idle, clear any pending interrupts.
1157 *
1158 * LOCKING:
1159 * Inherited from caller.
1160 */
1161
1162static inline u8 ata_irq_on(struct ata_port *ap)
1163{
1164 struct ata_ioports *ioaddr = &ap->ioaddr;
1165 u8 tmp;
1166
1167 ap->ctl &= ~ATA_NIEN;
1168 ap->last_ctl = ap->ctl;
1169
1170 if (ap->flags & ATA_FLAG_MMIO)
1171 writeb(ap->ctl, (void __iomem *) ioaddr->ctl_addr);
1172 else
1173 outb(ap->ctl, ioaddr->ctl_addr);
1174 tmp = ata_wait_idle(ap);
1175
1176 ap->ops->irq_clear(ap);
1177
1178 return tmp;
1179}
1180
1181
1182/**
1183 * ata_irq_ack - Acknowledge a device interrupt. 1161 * ata_irq_ack - Acknowledge a device interrupt.
1184 * @ap: Port on which interrupts are enabled. 1162 * @ap: Port on which interrupts are enabled.
1185 * 1163 *
diff --git a/include/linux/module.h b/include/linux/module.h
index 9258ffd8a7f0..d33df2408e05 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -6,7 +6,6 @@
6 * Rewritten by Richard Henderson <rth@tamu.edu> Dec 1996 6 * Rewritten by Richard Henderson <rth@tamu.edu> Dec 1996
7 * Rewritten again by Rusty Russell, 2002 7 * Rewritten again by Rusty Russell, 2002
8 */ 8 */
9#include <linux/sched.h>
10#include <linux/spinlock.h> 9#include <linux/spinlock.h>
11#include <linux/list.h> 10#include <linux/list.h>
12#include <linux/stat.h> 11#include <linux/stat.h>
@@ -411,17 +410,7 @@ static inline int try_module_get(struct module *module)
411 return ret; 410 return ret;
412} 411}
413 412
414static inline void module_put(struct module *module) 413extern void module_put(struct module *module);
415{
416 if (module) {
417 unsigned int cpu = get_cpu();
418 local_dec(&module->ref[cpu].count);
419 /* Maybe they're waiting for us to drop reference? */
420 if (unlikely(!module_is_live(module)))
421 wake_up_process(module->waiter);
422 put_cpu();
423 }
424}
425 414
426#else /*!CONFIG_MODULE_UNLOAD*/ 415#else /*!CONFIG_MODULE_UNLOAD*/
427static inline int try_module_get(struct module *module) 416static inline int try_module_get(struct module *module)
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 949eada46ce1..c57088f575a3 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -30,6 +30,7 @@
30#include <linux/if_packet.h> 30#include <linux/if_packet.h>
31 31
32#ifdef __KERNEL__ 32#ifdef __KERNEL__
33#include <linux/timer.h>
33#include <asm/atomic.h> 34#include <asm/atomic.h>
34#include <asm/cache.h> 35#include <asm/cache.h>
35#include <asm/byteorder.h> 36#include <asm/byteorder.h>
diff --git a/include/linux/netfilter_ipv4/ip_conntrack.h b/include/linux/netfilter_ipv4/ip_conntrack.h
index 61da56941dce..33581c13d947 100644
--- a/include/linux/netfilter_ipv4/ip_conntrack.h
+++ b/include/linux/netfilter_ipv4/ip_conntrack.h
@@ -9,6 +9,7 @@
9#include <linux/compiler.h> 9#include <linux/compiler.h>
10#include <asm/atomic.h> 10#include <asm/atomic.h>
11 11
12#include <linux/timer.h>
12#include <linux/netfilter_ipv4/ip_conntrack_tcp.h> 13#include <linux/netfilter_ipv4/ip_conntrack_tcp.h>
13#include <linux/netfilter_ipv4/ip_conntrack_icmp.h> 14#include <linux/netfilter_ipv4/ip_conntrack_icmp.h>
14#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h> 15#include <linux/netfilter_ipv4/ip_conntrack_proto_gre.h>
diff --git a/include/linux/pata_platform.h b/include/linux/pata_platform.h
new file mode 100644
index 000000000000..2d5fd647e0e9
--- /dev/null
+++ b/include/linux/pata_platform.h
@@ -0,0 +1,13 @@
1#ifndef __LINUX_PATA_PLATFORM_H
2#define __LINUX_PATA_PLATFORM_H
3
4struct pata_platform_info {
5 /*
6 * I/O port shift, for platforms with ports that are
7 * constantly spaced and need larger than the 1-byte
8 * spacing used by ata_std_ports().
9 */
10 unsigned int ioport_shift;
11};
12
13#endif /* __LINUX_PATA_PLATFORM_H */
diff --git a/include/linux/poll.h b/include/linux/poll.h
index 51e1b56741fb..27690798623f 100644
--- a/include/linux/poll.h
+++ b/include/linux/poll.h
@@ -8,7 +8,8 @@
8#include <linux/compiler.h> 8#include <linux/compiler.h>
9#include <linux/wait.h> 9#include <linux/wait.h>
10#include <linux/string.h> 10#include <linux/string.h>
11#include <linux/mm.h> 11#include <linux/fs.h>
12#include <linux/sched.h>
12#include <asm/uaccess.h> 13#include <asm/uaccess.h>
13 14
14/* ~832 bytes of stack space used max in sys_select/sys_poll before allocating 15/* ~832 bytes of stack space used max in sys_select/sys_poll before allocating
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
index 9158a68140c9..cbfa11537421 100644
--- a/include/linux/radix-tree.h
+++ b/include/linux/radix-tree.h
@@ -19,7 +19,6 @@
19#ifndef _LINUX_RADIX_TREE_H 19#ifndef _LINUX_RADIX_TREE_H
20#define _LINUX_RADIX_TREE_H 20#define _LINUX_RADIX_TREE_H
21 21
22#include <linux/sched.h>
23#include <linux/preempt.h> 22#include <linux/preempt.h>
24#include <linux/types.h> 23#include <linux/types.h>
25 24
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index 14ec16d2d9ba..a05a5f7c0b73 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -22,12 +22,10 @@
22#include <asm/atomic.h> 22#include <asm/atomic.h>
23#include <asm/types.h> 23#include <asm/types.h>
24#include <linux/spinlock.h> 24#include <linux/spinlock.h>
25#include <linux/mm.h>
26#include <linux/highmem.h>
27#include <linux/poll.h>
28#include <linux/net.h> 25#include <linux/net.h>
29#include <linux/textsearch.h> 26#include <linux/textsearch.h>
30#include <net/checksum.h> 27#include <net/checksum.h>
28#include <linux/rcupdate.h>
31#include <linux/dmaengine.h> 29#include <linux/dmaengine.h>
32 30
33#define HAVE_ALLOC_SKB /* For the drivers to know */ 31#define HAVE_ALLOC_SKB /* For the drivers to know */
@@ -1295,24 +1293,6 @@ static inline int pskb_trim_rcsum(struct sk_buff *skb, unsigned int len)
1295 return __pskb_trim(skb, len); 1293 return __pskb_trim(skb, len);
1296} 1294}
1297 1295
1298static inline void *kmap_skb_frag(const skb_frag_t *frag)
1299{
1300#ifdef CONFIG_HIGHMEM
1301 BUG_ON(in_irq());
1302
1303 local_bh_disable();
1304#endif
1305 return kmap_atomic(frag->page, KM_SKB_DATA_SOFTIRQ);
1306}
1307
1308static inline void kunmap_skb_frag(void *vaddr)
1309{
1310 kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ);
1311#ifdef CONFIG_HIGHMEM
1312 local_bh_enable();
1313#endif
1314}
1315
1316#define skb_queue_walk(queue, skb) \ 1296#define skb_queue_walk(queue, skb) \
1317 for (skb = (queue)->next; \ 1297 for (skb = (queue)->next; \
1318 prefetch(skb->next), (skb != (struct sk_buff *)(queue)); \ 1298 prefetch(skb->next), (skb != (struct sk_buff *)(queue)); \
diff --git a/include/linux/types.h b/include/linux/types.h
index 745c409ebbb5..0351bf2fac85 100644
--- a/include/linux/types.h
+++ b/include/linux/types.h
@@ -136,15 +136,19 @@ typedef __s64 int64_t;
136 * 136 *
137 * Linux always considers sectors to be 512 bytes long independently 137 * Linux always considers sectors to be 512 bytes long independently
138 * of the devices real block size. 138 * of the devices real block size.
139 *
140 * If required, asm/types.h can override it and define
141 * HAVE_SECTOR_T
142 */ 139 */
143#ifndef HAVE_SECTOR_T 140#ifdef CONFIG_LBD
141typedef u64 sector_t;
142#else
144typedef unsigned long sector_t; 143typedef unsigned long sector_t;
145#endif 144#endif
146 145
147#ifndef HAVE_BLKCNT_T 146/*
147 * The type of the inode's block count.
148 */
149#ifdef CONFIG_LSF
150typedef u64 blkcnt_t;
151#else
148typedef unsigned long blkcnt_t; 152typedef unsigned long blkcnt_t;
149#endif 153#endif
150 154
diff --git a/include/net/inet_connection_sock.h b/include/net/inet_connection_sock.h
index cccea051e922..bf16d98d372c 100644
--- a/include/net/inet_connection_sock.h
+++ b/include/net/inet_connection_sock.h
@@ -18,6 +18,7 @@
18#include <linux/compiler.h> 18#include <linux/compiler.h>
19#include <linux/string.h> 19#include <linux/string.h>
20#include <linux/timer.h> 20#include <linux/timer.h>
21#include <linux/poll.h>
21 22
22#include <net/inet_sock.h> 23#include <net/inet_sock.h>
23#include <net/request_sock.h> 24#include <net/request_sock.h>
diff --git a/include/net/irda/timer.h b/include/net/irda/timer.h
index 2c5d8864ab77..cb61568547d1 100644
--- a/include/net/irda/timer.h
+++ b/include/net/irda/timer.h
@@ -28,6 +28,7 @@
28#define TIMER_H 28#define TIMER_H
29 29
30#include <linux/timer.h> 30#include <linux/timer.h>
31#include <linux/jiffies.h>
31 32
32#include <asm/param.h> /* for HZ */ 33#include <asm/param.h> /* for HZ */
33 34
diff --git a/include/net/netfilter/nf_conntrack.h b/include/net/netfilter/nf_conntrack.h
index 032b36a0e378..bd01b4633ee2 100644
--- a/include/net/netfilter/nf_conntrack.h
+++ b/include/net/netfilter/nf_conntrack.h
@@ -56,6 +56,7 @@ union nf_conntrack_help {
56 56
57#include <linux/types.h> 57#include <linux/types.h>
58#include <linux/skbuff.h> 58#include <linux/skbuff.h>
59#include <linux/timer.h>
59 60
60#ifdef CONFIG_NETFILTER_DEBUG 61#ifdef CONFIG_NETFILTER_DEBUG
61#define NF_CT_ASSERT(x) \ 62#define NF_CT_ASSERT(x) \
diff --git a/include/net/netlink.h b/include/net/netlink.h
index fd75fd65d59e..bcaf67b7a19d 100644
--- a/include/net/netlink.h
+++ b/include/net/netlink.h
@@ -3,6 +3,7 @@
3 3
4#include <linux/types.h> 4#include <linux/types.h>
5#include <linux/netlink.h> 5#include <linux/netlink.h>
6#include <linux/jiffies.h>
6 7
7/* ======================================================================== 8/* ========================================================================
8 * Netlink Messages and Attributes Interface (As Seen On TV) 9 * Netlink Messages and Attributes Interface (As Seen On TV)
diff --git a/include/net/sock.h b/include/net/sock.h
index 26fc0b16bc0c..fe3a33fad03f 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -47,6 +47,7 @@
47#include <linux/lockdep.h> 47#include <linux/lockdep.h>
48#include <linux/netdevice.h> 48#include <linux/netdevice.h>
49#include <linux/skbuff.h> /* struct sk_buff */ 49#include <linux/skbuff.h> /* struct sk_buff */
50#include <linux/mm.h>
50#include <linux/security.h> 51#include <linux/security.h>
51 52
52#include <linux/filter.h> 53#include <linux/filter.h>
diff --git a/include/net/udp.h b/include/net/udp.h
index 1548d68d45da..1b921fa81474 100644
--- a/include/net/udp.h
+++ b/include/net/udp.h
@@ -29,6 +29,7 @@
29#include <net/ip.h> 29#include <net/ip.h>
30#include <linux/ipv6.h> 30#include <linux/ipv6.h>
31#include <linux/seq_file.h> 31#include <linux/seq_file.h>
32#include <linux/poll.h>
32 33
33/** 34/**
34 * struct udp_skb_cb - UDP(-Lite) private variables 35 * struct udp_skb_cb - UDP(-Lite) private variables
diff --git a/include/scsi/libiscsi.h b/include/scsi/libiscsi.h
index 61eebec00a7b..ea0816d4904d 100644
--- a/include/scsi/libiscsi.h
+++ b/include/scsi/libiscsi.h
@@ -25,6 +25,8 @@
25 25
26#include <linux/types.h> 26#include <linux/types.h>
27#include <linux/mutex.h> 27#include <linux/mutex.h>
28#include <linux/timer.h>
29#include <linux/workqueue.h>
28#include <scsi/iscsi_proto.h> 30#include <scsi/iscsi_proto.h>
29#include <scsi/iscsi_if.h> 31#include <scsi/iscsi_if.h>
30 32
diff --git a/include/sound/pcm.h b/include/sound/pcm.h
index afaf3e88e086..2f645dfd7f70 100644
--- a/include/sound/pcm.h
+++ b/include/sound/pcm.h
@@ -26,6 +26,7 @@
26#include <sound/asound.h> 26#include <sound/asound.h>
27#include <sound/memalloc.h> 27#include <sound/memalloc.h>
28#include <linux/poll.h> 28#include <linux/poll.h>
29#include <linux/mm.h>
29#include <linux/bitops.h> 30#include <linux/bitops.h>
30 31
31#define snd_pcm_substream_chip(substream) ((substream)->private_data) 32#define snd_pcm_substream_chip(substream) ((substream)->private_data)
diff --git a/kernel/auditsc.c b/kernel/auditsc.c
index 42f2f1179711..ab97e5101232 100644
--- a/kernel/auditsc.c
+++ b/kernel/auditsc.c
@@ -64,6 +64,7 @@
64#include <linux/tty.h> 64#include <linux/tty.h>
65#include <linux/selinux.h> 65#include <linux/selinux.h>
66#include <linux/binfmts.h> 66#include <linux/binfmts.h>
67#include <linux/highmem.h>
67#include <linux/syscalls.h> 68#include <linux/syscalls.h>
68 69
69#include "audit.h" 70#include "audit.h"
diff --git a/kernel/latency.c b/kernel/latency.c
index 258f2555abbc..e63fcacb61a7 100644
--- a/kernel/latency.c
+++ b/kernel/latency.c
@@ -36,6 +36,7 @@
36#include <linux/slab.h> 36#include <linux/slab.h>
37#include <linux/module.h> 37#include <linux/module.h>
38#include <linux/notifier.h> 38#include <linux/notifier.h>
39#include <linux/jiffies.h>
39#include <asm/atomic.h> 40#include <asm/atomic.h>
40 41
41struct latency_info { 42struct latency_info {
diff --git a/kernel/module.c b/kernel/module.c
index 45e01cb60101..e2d09d604ca0 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -34,10 +34,10 @@
34#include <linux/err.h> 34#include <linux/err.h>
35#include <linux/vermagic.h> 35#include <linux/vermagic.h>
36#include <linux/notifier.h> 36#include <linux/notifier.h>
37#include <linux/sched.h>
37#include <linux/stop_machine.h> 38#include <linux/stop_machine.h>
38#include <linux/device.h> 39#include <linux/device.h>
39#include <linux/string.h> 40#include <linux/string.h>
40#include <linux/sched.h>
41#include <linux/mutex.h> 41#include <linux/mutex.h>
42#include <linux/unwind.h> 42#include <linux/unwind.h>
43#include <asm/uaccess.h> 43#include <asm/uaccess.h>
@@ -790,6 +790,19 @@ static struct module_attribute refcnt = {
790 .show = show_refcnt, 790 .show = show_refcnt,
791}; 791};
792 792
793void module_put(struct module *module)
794{
795 if (module) {
796 unsigned int cpu = get_cpu();
797 local_dec(&module->ref[cpu].count);
798 /* Maybe they're waiting for us to drop reference? */
799 if (unlikely(!module_is_live(module)))
800 wake_up_process(module->waiter);
801 put_cpu();
802 }
803}
804EXPORT_SYMBOL(module_put);
805
793#else /* !CONFIG_MODULE_UNLOAD */ 806#else /* !CONFIG_MODULE_UNLOAD */
794static void print_unload_info(struct seq_file *m, struct module *mod) 807static void print_unload_info(struct seq_file *m, struct module *mod)
795{ 808{
diff --git a/lib/iomap.c b/lib/iomap.c
index 55689c5d3379..d6ccdd85df53 100644
--- a/lib/iomap.c
+++ b/lib/iomap.c
@@ -50,6 +50,16 @@
50 } \ 50 } \
51} while (0) 51} while (0)
52 52
53#ifndef pio_read16be
54#define pio_read16be(port) swab16(inw(port))
55#define pio_read32be(port) swab32(inl(port))
56#endif
57
58#ifndef mmio_read16be
59#define mmio_read16be(addr) be16_to_cpu(__raw_readw(addr))
60#define mmio_read32be(addr) be32_to_cpu(__raw_readl(addr))
61#endif
62
53unsigned int fastcall ioread8(void __iomem *addr) 63unsigned int fastcall ioread8(void __iomem *addr)
54{ 64{
55 IO_COND(addr, return inb(port), return readb(addr)); 65 IO_COND(addr, return inb(port), return readb(addr));
@@ -60,7 +70,7 @@ unsigned int fastcall ioread16(void __iomem *addr)
60} 70}
61unsigned int fastcall ioread16be(void __iomem *addr) 71unsigned int fastcall ioread16be(void __iomem *addr)
62{ 72{
63 IO_COND(addr, return inw(port), return be16_to_cpu(__raw_readw(addr))); 73 IO_COND(addr, return pio_read16be(port), return mmio_read16be(addr));
64} 74}
65unsigned int fastcall ioread32(void __iomem *addr) 75unsigned int fastcall ioread32(void __iomem *addr)
66{ 76{
@@ -68,7 +78,7 @@ unsigned int fastcall ioread32(void __iomem *addr)
68} 78}
69unsigned int fastcall ioread32be(void __iomem *addr) 79unsigned int fastcall ioread32be(void __iomem *addr)
70{ 80{
71 IO_COND(addr, return inl(port), return be32_to_cpu(__raw_readl(addr))); 81 IO_COND(addr, return pio_read32be(port), return mmio_read32be(addr));
72} 82}
73EXPORT_SYMBOL(ioread8); 83EXPORT_SYMBOL(ioread8);
74EXPORT_SYMBOL(ioread16); 84EXPORT_SYMBOL(ioread16);
@@ -76,6 +86,16 @@ EXPORT_SYMBOL(ioread16be);
76EXPORT_SYMBOL(ioread32); 86EXPORT_SYMBOL(ioread32);
77EXPORT_SYMBOL(ioread32be); 87EXPORT_SYMBOL(ioread32be);
78 88
89#ifndef pio_write16be
90#define pio_write16be(val,port) outw(swab16(val),port)
91#define pio_write32be(val,port) outl(swab32(val),port)
92#endif
93
94#ifndef mmio_write16be
95#define mmio_write16be(val,port) __raw_writew(be16_to_cpu(val),port)
96#define mmio_write32be(val,port) __raw_writel(be32_to_cpu(val),port)
97#endif
98
79void fastcall iowrite8(u8 val, void __iomem *addr) 99void fastcall iowrite8(u8 val, void __iomem *addr)
80{ 100{
81 IO_COND(addr, outb(val,port), writeb(val, addr)); 101 IO_COND(addr, outb(val,port), writeb(val, addr));
@@ -86,7 +106,7 @@ void fastcall iowrite16(u16 val, void __iomem *addr)
86} 106}
87void fastcall iowrite16be(u16 val, void __iomem *addr) 107void fastcall iowrite16be(u16 val, void __iomem *addr)
88{ 108{
89 IO_COND(addr, outw(val,port), __raw_writew(cpu_to_be16(val), addr)); 109 IO_COND(addr, pio_write16be(val,port), mmio_write16be(val, addr));
90} 110}
91void fastcall iowrite32(u32 val, void __iomem *addr) 111void fastcall iowrite32(u32 val, void __iomem *addr)
92{ 112{
@@ -94,7 +114,7 @@ void fastcall iowrite32(u32 val, void __iomem *addr)
94} 114}
95void fastcall iowrite32be(u32 val, void __iomem *addr) 115void fastcall iowrite32be(u32 val, void __iomem *addr)
96{ 116{
97 IO_COND(addr, outl(val,port), __raw_writel(cpu_to_be32(val), addr)); 117 IO_COND(addr, pio_write32be(val,port), mmio_write32be(val, addr));
98} 118}
99EXPORT_SYMBOL(iowrite8); 119EXPORT_SYMBOL(iowrite8);
100EXPORT_SYMBOL(iowrite16); 120EXPORT_SYMBOL(iowrite16);
@@ -108,6 +128,7 @@ EXPORT_SYMBOL(iowrite32be);
108 * convert to CPU byte order. We write in "IO byte 128 * convert to CPU byte order. We write in "IO byte
109 * order" (we also don't have IO barriers). 129 * order" (we also don't have IO barriers).
110 */ 130 */
131#ifndef mmio_insb
111static inline void mmio_insb(void __iomem *addr, u8 *dst, int count) 132static inline void mmio_insb(void __iomem *addr, u8 *dst, int count)
112{ 133{
113 while (--count >= 0) { 134 while (--count >= 0) {
@@ -132,7 +153,9 @@ static inline void mmio_insl(void __iomem *addr, u32 *dst, int count)
132 dst++; 153 dst++;
133 } 154 }
134} 155}
156#endif
135 157
158#ifndef mmio_outsb
136static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count) 159static inline void mmio_outsb(void __iomem *addr, const u8 *src, int count)
137{ 160{
138 while (--count >= 0) { 161 while (--count >= 0) {
@@ -154,6 +177,7 @@ static inline void mmio_outsl(void __iomem *addr, const u32 *src, int count)
154 src++; 177 src++;
155 } 178 }
156} 179}
180#endif
157 181
158void fastcall ioread8_rep(void __iomem *addr, void *dst, unsigned long count) 182void fastcall ioread8_rep(void __iomem *addr, void *dst, unsigned long count)
159{ 183{
diff --git a/lib/random32.c b/lib/random32.c
index 4a15ce51cea7..ec7f81d3fb18 100644
--- a/lib/random32.c
+++ b/lib/random32.c
@@ -36,6 +36,7 @@
36#include <linux/types.h> 36#include <linux/types.h>
37#include <linux/percpu.h> 37#include <linux/percpu.h>
38#include <linux/module.h> 38#include <linux/module.h>
39#include <linux/jiffies.h>
39#include <linux/random.h> 40#include <linux/random.h>
40 41
41struct rnd_state { 42struct rnd_state {
diff --git a/mm/filemap.c b/mm/filemap.c
index 7b84dc814347..13df01c50479 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -1893,6 +1893,7 @@ int should_remove_suid(struct dentry *dentry)
1893 1893
1894 return 0; 1894 return 0;
1895} 1895}
1896EXPORT_SYMBOL(should_remove_suid);
1896 1897
1897int __remove_suid(struct dentry *dentry, int kill) 1898int __remove_suid(struct dentry *dentry, int kill)
1898{ 1899{
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index 485e35c3b28b..3a7052207708 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -61,6 +61,7 @@
61#include <net/tcp_states.h> 61#include <net/tcp_states.h>
62#include <net/route.h> 62#include <net/route.h>
63#include <linux/atalk.h> 63#include <linux/atalk.h>
64#include "../core/kmap_skb.h"
64 65
65struct datalink_proto *ddp_dl, *aarp_dl; 66struct datalink_proto *ddp_dl, *aarp_dl;
66static const struct proto_ops atalk_dgram_ops; 67static const struct proto_ops atalk_dgram_ops;
diff --git a/net/core/kmap_skb.h b/net/core/kmap_skb.h
new file mode 100644
index 000000000000..283c2b993fb8
--- /dev/null
+++ b/net/core/kmap_skb.h
@@ -0,0 +1,19 @@
1#include <linux/highmem.h>
2
3static inline void *kmap_skb_frag(const skb_frag_t *frag)
4{
5#ifdef CONFIG_HIGHMEM
6 BUG_ON(in_irq());
7
8 local_bh_disable();
9#endif
10 return kmap_atomic(frag->page, KM_SKB_DATA_SOFTIRQ);
11}
12
13static inline void kunmap_skb_frag(void *vaddr)
14{
15 kunmap_atomic(vaddr, KM_SKB_DATA_SOFTIRQ);
16#ifdef CONFIG_HIGHMEM
17 local_bh_enable();
18#endif
19}
diff --git a/net/core/skbuff.c b/net/core/skbuff.c
index a90bc439488e..8e1c385e5ba9 100644
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -56,7 +56,6 @@
56#include <linux/cache.h> 56#include <linux/cache.h>
57#include <linux/rtnetlink.h> 57#include <linux/rtnetlink.h>
58#include <linux/init.h> 58#include <linux/init.h>
59#include <linux/highmem.h>
60 59
61#include <net/protocol.h> 60#include <net/protocol.h>
62#include <net/dst.h> 61#include <net/dst.h>
@@ -67,6 +66,8 @@
67#include <asm/uaccess.h> 66#include <asm/uaccess.h>
68#include <asm/system.h> 67#include <asm/system.h>
69 68
69#include "kmap_skb.h"
70
70static kmem_cache_t *skbuff_head_cache __read_mostly; 71static kmem_cache_t *skbuff_head_cache __read_mostly;
71static kmem_cache_t *skbuff_fclone_cache __read_mostly; 72static kmem_cache_t *skbuff_fclone_cache __read_mostly;
72 73
diff --git a/net/core/sock.c b/net/core/sock.c
index ab8fafadb4ba..419c7d3289c7 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -111,6 +111,7 @@
111#include <linux/poll.h> 111#include <linux/poll.h>
112#include <linux/tcp.h> 112#include <linux/tcp.h>
113#include <linux/init.h> 113#include <linux/init.h>
114#include <linux/highmem.h>
114 115
115#include <asm/uaccess.h> 116#include <asm/uaccess.h>
116#include <asm/system.h> 117#include <asm/system.h>
diff --git a/net/dccp/ccids/Kconfig b/net/dccp/ccids/Kconfig
index dac89166eb18..80f469887691 100644
--- a/net/dccp/ccids/Kconfig
+++ b/net/dccp/ccids/Kconfig
@@ -89,4 +89,37 @@ config IP_DCCP_CCID3_DEBUG
89 parameter to 0 or 1. 89 parameter to 0 or 1.
90 90
91 If in doubt, say N. 91 If in doubt, say N.
92
93config IP_DCCP_CCID3_RTO
94 int "Use higher bound for nofeedback timer"
95 default 100
96 depends on IP_DCCP_CCID3 && EXPERIMENTAL
97 ---help---
98 Use higher lower bound for nofeedback timer expiration.
99
100 The TFRC nofeedback timer normally expires after the maximum of 4
101 RTTs and twice the current send interval (RFC 3448, 4.3). On LANs
102 with a small RTT this can mean a high processing load and reduced
103 performance, since then the nofeedback timer is triggered very
104 frequently.
105
106 This option enables to set a higher lower bound for the nofeedback
107 value. Values in units of milliseconds can be set here.
108
109 A value of 0 disables this feature by enforcing the value specified
110 in RFC 3448. The following values have been suggested as bounds for
111 experimental use:
112 * 16-20ms to match the typical multimedia inter-frame interval
113 * 100ms as a reasonable compromise [default]
114 * 1000ms corresponds to the lower TCP RTO bound (RFC 2988, 2.4)
115
116 The default of 100ms is a compromise between a large value for
117 efficient DCCP implementations, and a small value to avoid disrupting
118 the network in times of congestion.
119
120 The purpose of the nofeedback timer is to slow DCCP down when there
121 is serious network congestion: experimenting with larger values should
122 therefore not be performed on WANs.
123
124
92endmenu 125endmenu
diff --git a/net/dccp/ccids/ccid3.c b/net/dccp/ccids/ccid3.c
index 70ebe705eb75..cf8c07b2704f 100644
--- a/net/dccp/ccids/ccid3.c
+++ b/net/dccp/ccids/ccid3.c
@@ -121,12 +121,15 @@ static inline void ccid3_update_send_time(struct ccid3_hc_tx_sock *hctx)
121/* 121/*
122 * Update X by 122 * Update X by
123 * If (p > 0) 123 * If (p > 0)
124 * x_calc = calcX(s, R, p); 124 * X_calc = calcX(s, R, p);
125 * X = max(min(X_calc, 2 * X_recv), s / t_mbi); 125 * X = max(min(X_calc, 2 * X_recv), s / t_mbi);
126 * Else 126 * Else
127 * If (now - tld >= R) 127 * If (now - tld >= R)
128 * X = max(min(2 * X, 2 * X_recv), s / R); 128 * X = max(min(2 * X, 2 * X_recv), s / R);
129 * tld = now; 129 * tld = now;
130 *
131 * If X has changed, we also update the scheduled send time t_now,
132 * the inter-packet interval t_ipi, and the delta value.
130 */ 133 */
131static void ccid3_hc_tx_update_x(struct sock *sk, struct timeval *now) 134static void ccid3_hc_tx_update_x(struct sock *sk, struct timeval *now)
132 135
@@ -134,8 +137,7 @@ static void ccid3_hc_tx_update_x(struct sock *sk, struct timeval *now)
134 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk); 137 struct ccid3_hc_tx_sock *hctx = ccid3_hc_tx_sk(sk);
135 const __u32 old_x = hctx->ccid3hctx_x; 138 const __u32 old_x = hctx->ccid3hctx_x;
136 139
137 /* To avoid large error in calcX */ 140 if (hctx->ccid3hctx_p > 0) {
138 if (hctx->ccid3hctx_p >= TFRC_SMALLEST_P) {
139 hctx->ccid3hctx_x_calc = tfrc_calc_x(hctx->ccid3hctx_s, 141 hctx->ccid3hctx_x_calc = tfrc_calc_x(hctx->ccid3hctx_s,
140 hctx->ccid3hctx_rtt, 142 hctx->ccid3hctx_rtt,
141 hctx->ccid3hctx_p); 143 hctx->ccid3hctx_p);
@@ -223,16 +225,14 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
223 ccid3_tx_state_name(hctx->ccid3hctx_state)); 225 ccid3_tx_state_name(hctx->ccid3hctx_state));
224 /* Halve sending rate */ 226 /* Halve sending rate */
225 227
226 /* If (X_calc > 2 * X_recv) 228 /* If (p == 0 || X_calc > 2 * X_recv)
227 * X_recv = max(X_recv / 2, s / (2 * t_mbi)); 229 * X_recv = max(X_recv / 2, s / (2 * t_mbi));
228 * Else 230 * Else
229 * X_recv = X_calc / 4; 231 * X_recv = X_calc / 4;
230 */ 232 */
231 BUG_ON(hctx->ccid3hctx_p >= TFRC_SMALLEST_P && 233 BUG_ON(hctx->ccid3hctx_p && !hctx->ccid3hctx_x_calc);
232 hctx->ccid3hctx_x_calc == 0);
233 234
234 /* check also if p is zero -> x_calc is infinity? */ 235 if (hctx->ccid3hctx_p == 0 ||
235 if (hctx->ccid3hctx_p < TFRC_SMALLEST_P ||
236 hctx->ccid3hctx_x_calc > 2 * hctx->ccid3hctx_x_recv) 236 hctx->ccid3hctx_x_calc > 2 * hctx->ccid3hctx_x_recv)
237 hctx->ccid3hctx_x_recv = max_t(u32, hctx->ccid3hctx_x_recv / 2, 237 hctx->ccid3hctx_x_recv = max_t(u32, hctx->ccid3hctx_x_recv / 2,
238 hctx->ccid3hctx_s / (2 * TFRC_T_MBI)); 238 hctx->ccid3hctx_s / (2 * TFRC_T_MBI));
@@ -245,9 +245,10 @@ static void ccid3_hc_tx_no_feedback_timer(unsigned long data)
245 } 245 }
246 /* 246 /*
247 * Schedule no feedback timer to expire in 247 * Schedule no feedback timer to expire in
248 * max(4 * R, 2 * s/X) = max(4 * R, 2 * t_ipi) 248 * max(t_RTO, 2 * s/X) = max(t_RTO, 2 * t_ipi)
249 * See comments in packet_recv() regarding the value of t_RTO.
249 */ 250 */
250 t_nfb = max(4 * hctx->ccid3hctx_rtt, 2 * hctx->ccid3hctx_t_ipi); 251 t_nfb = max(hctx->ccid3hctx_t_rto, 2 * hctx->ccid3hctx_t_ipi);
251 break; 252 break;
252 case TFRC_SSTATE_NO_SENT: 253 case TFRC_SSTATE_NO_SENT:
253 DCCP_BUG("Illegal %s state NO_SENT, sk=%p", dccp_role(sk), sk); 254 DCCP_BUG("Illegal %s state NO_SENT, sk=%p", dccp_role(sk), sk);
@@ -338,7 +339,7 @@ static int ccid3_hc_tx_send_packet(struct sock *sk, struct sk_buff *skb)
338 * else 339 * else
339 * // send the packet in (t_nom - t_now) milliseconds. 340 * // send the packet in (t_nom - t_now) milliseconds.
340 */ 341 */
341 if (delay >= hctx->ccid3hctx_delta) 342 if (delay - (long)hctx->ccid3hctx_delta >= 0)
342 return delay / 1000L; 343 return delay / 1000L;
343 break; 344 break;
344 case TFRC_SSTATE_TERM: 345 case TFRC_SSTATE_TERM:
@@ -412,10 +413,8 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
412 struct dccp_tx_hist_entry *packet; 413 struct dccp_tx_hist_entry *packet;
413 struct timeval now; 414 struct timeval now;
414 unsigned long t_nfb; 415 unsigned long t_nfb;
415 u32 t_elapsed;
416 u32 pinv; 416 u32 pinv;
417 u32 x_recv; 417 long r_sample, t_elapsed;
418 u32 r_sample;
419 418
420 BUG_ON(hctx == NULL); 419 BUG_ON(hctx == NULL);
421 420
@@ -426,31 +425,44 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
426 425
427 opt_recv = &hctx->ccid3hctx_options_received; 426 opt_recv = &hctx->ccid3hctx_options_received;
428 427
429 t_elapsed = dp->dccps_options_received.dccpor_elapsed_time * 10;
430 x_recv = opt_recv->ccid3or_receive_rate;
431 pinv = opt_recv->ccid3or_loss_event_rate;
432
433 switch (hctx->ccid3hctx_state) { 428 switch (hctx->ccid3hctx_state) {
434 case TFRC_SSTATE_NO_FBACK: 429 case TFRC_SSTATE_NO_FBACK:
435 case TFRC_SSTATE_FBACK: 430 case TFRC_SSTATE_FBACK:
436 /* Calculate new round trip sample by 431 /* get packet from history to look up t_recvdata */
437 * R_sample = (now - t_recvdata) - t_delay */
438 /* get t_recvdata from history */
439 packet = dccp_tx_hist_find_entry(&hctx->ccid3hctx_hist, 432 packet = dccp_tx_hist_find_entry(&hctx->ccid3hctx_hist,
440 DCCP_SKB_CB(skb)->dccpd_ack_seq); 433 DCCP_SKB_CB(skb)->dccpd_ack_seq);
441 if (unlikely(packet == NULL)) { 434 if (unlikely(packet == NULL)) {
442 DCCP_WARN("%s, sk=%p, seqno %llu(%s) does't exist " 435 DCCP_WARN("%s(%p), seqno %llu(%s) doesn't exist "
443 "in history!\n", dccp_role(sk), sk, 436 "in history!\n", dccp_role(sk), sk,
444 (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq, 437 (unsigned long long)DCCP_SKB_CB(skb)->dccpd_ack_seq,
445 dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type)); 438 dccp_packet_name(DCCP_SKB_CB(skb)->dccpd_type));
446 return; 439 return;
447 } 440 }
448 441
449 /* Update RTT */ 442 /* Update receive rate */
443 hctx->ccid3hctx_x_recv = opt_recv->ccid3or_receive_rate;
444
445 /* Update loss event rate */
446 pinv = opt_recv->ccid3or_loss_event_rate;
447 if (pinv == ~0U || pinv == 0)
448 hctx->ccid3hctx_p = 0;
449 else
450 hctx->ccid3hctx_p = 1000000 / pinv;
451
450 dccp_timestamp(sk, &now); 452 dccp_timestamp(sk, &now);
451 r_sample = timeval_delta(&now, &packet->dccphtx_tstamp); 453
452 if (unlikely(r_sample <= t_elapsed)) 454 /*
453 DCCP_WARN("r_sample=%uus,t_elapsed=%uus\n", 455 * Calculate new round trip sample as per [RFC 3448, 4.3] by
456 * R_sample = (now - t_recvdata) - t_elapsed
457 */
458 r_sample = timeval_delta(&now, &packet->dccphtx_tstamp);
459 t_elapsed = dp->dccps_options_received.dccpor_elapsed_time * 10;
460
461 if (unlikely(r_sample <= 0)) {
462 DCCP_WARN("WARNING: R_sample (%ld) <= 0!\n", r_sample);
463 r_sample = 0;
464 } else if (unlikely(r_sample <= t_elapsed))
465 DCCP_WARN("WARNING: r_sample=%ldus <= t_elapsed=%ldus\n",
454 r_sample, t_elapsed); 466 r_sample, t_elapsed);
455 else 467 else
456 r_sample -= t_elapsed; 468 r_sample -= t_elapsed;
@@ -473,31 +485,25 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
473 hctx->ccid3hctx_t_ld = now; 485 hctx->ccid3hctx_t_ld = now;
474 486
475 ccid3_update_send_time(hctx); 487 ccid3_update_send_time(hctx);
476 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK);
477 } else {
478 hctx->ccid3hctx_rtt = (hctx->ccid3hctx_rtt * 9) / 10 +
479 r_sample / 10;
480 ccid3_hc_tx_update_x(sk, &now);
481 }
482 488
483 ccid3_pr_debug("%s, sk=%p, New RTT estimate=%uus, " 489 ccid3_pr_debug("%s(%p), s=%u, w_init=%u, "
484 "r_sample=%us\n", dccp_role(sk), sk, 490 "R_sample=%ldus, X=%u\n", dccp_role(sk),
485 hctx->ccid3hctx_rtt, r_sample); 491 sk, hctx->ccid3hctx_s, w_init, r_sample,
492 hctx->ccid3hctx_x);
486 493
487 /* Update receive rate */ 494 ccid3_hc_tx_set_state(sk, TFRC_SSTATE_FBACK);
488 hctx->ccid3hctx_x_recv = x_recv;/* X_recv in bytes per sec */ 495 } else {
496 hctx->ccid3hctx_rtt = (9 * hctx->ccid3hctx_rtt +
497 (u32)r_sample ) / 10;
489 498
490 /* Update loss event rate */ 499 ccid3_hc_tx_update_x(sk, &now);
491 if (pinv == ~0 || pinv == 0)
492 hctx->ccid3hctx_p = 0;
493 else {
494 hctx->ccid3hctx_p = 1000000 / pinv;
495 500
496 if (hctx->ccid3hctx_p < TFRC_SMALLEST_P) { 501 ccid3_pr_debug("%s(%p), RTT=%uus (sample=%ldus), s=%u, "
497 hctx->ccid3hctx_p = TFRC_SMALLEST_P; 502 "p=%u, X_calc=%u, X=%u\n", dccp_role(sk),
498 ccid3_pr_debug("%s, sk=%p, Smallest p used!\n", 503 sk, hctx->ccid3hctx_rtt, r_sample,
499 dccp_role(sk), sk); 504 hctx->ccid3hctx_s, hctx->ccid3hctx_p,
500 } 505 hctx->ccid3hctx_x_calc,
506 hctx->ccid3hctx_x);
501 } 507 }
502 508
503 /* unschedule no feedback timer */ 509 /* unschedule no feedback timer */
@@ -512,16 +518,20 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
512 */ 518 */
513 sk->sk_write_space(sk); 519 sk->sk_write_space(sk);
514 520
515 /* Update timeout interval. We use the alternative variant of 521 /*
516 * [RFC 3448, 3.1] which sets the upper bound of t_rto to one 522 * Update timeout interval for the nofeedback timer.
517 * second, as it is suggested for TCP (see RFC 2988, 2.4). */ 523 * We use a configuration option to increase the lower bound.
524 * This can help avoid triggering the nofeedback timer too often
525 * ('spinning') on LANs with small RTTs.
526 */
518 hctx->ccid3hctx_t_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt, 527 hctx->ccid3hctx_t_rto = max_t(u32, 4 * hctx->ccid3hctx_rtt,
519 USEC_PER_SEC ); 528 CONFIG_IP_DCCP_CCID3_RTO *
529 (USEC_PER_SEC/1000) );
520 /* 530 /*
521 * Schedule no feedback timer to expire in 531 * Schedule no feedback timer to expire in
522 * max(4 * R, 2 * s/X) = max(4 * R, 2 * t_ipi) 532 * max(t_RTO, 2 * s/X) = max(t_RTO, 2 * t_ipi)
523 */ 533 */
524 t_nfb = max(4 * hctx->ccid3hctx_rtt, 2 * hctx->ccid3hctx_t_ipi); 534 t_nfb = max(hctx->ccid3hctx_t_rto, 2 * hctx->ccid3hctx_t_ipi);
525 535
526 ccid3_pr_debug("%s, sk=%p, Scheduled no feedback timer to " 536 ccid3_pr_debug("%s, sk=%p, Scheduled no feedback timer to "
527 "expire in %lu jiffies (%luus)\n", 537 "expire in %lu jiffies (%luus)\n",
@@ -535,7 +545,8 @@ static void ccid3_hc_tx_packet_recv(struct sock *sk, struct sk_buff *skb)
535 hctx->ccid3hctx_idle = 1; 545 hctx->ccid3hctx_idle = 1;
536 break; 546 break;
537 case TFRC_SSTATE_NO_SENT: 547 case TFRC_SSTATE_NO_SENT:
538 DCCP_WARN("Illegal ACK received - no packet has been sent\n"); 548 if (dccp_sk(sk)->dccps_role == DCCP_ROLE_CLIENT)
549 DCCP_WARN("Illegal ACK received - no packet sent\n");
539 /* fall through */ 550 /* fall through */
540 case TFRC_SSTATE_TERM: /* ignore feedback when closing */ 551 case TFRC_SSTATE_TERM: /* ignore feedback when closing */
541 break; 552 break;
diff --git a/net/dccp/ccids/ccid3.h b/net/dccp/ccids/ccid3.h
index 27cb20ae1da8..07596d704ef9 100644
--- a/net/dccp/ccids/ccid3.h
+++ b/net/dccp/ccids/ccid3.h
@@ -51,8 +51,6 @@
51/* Parameter t_mbi from [RFC 3448, 4.3]: backoff interval in seconds */ 51/* Parameter t_mbi from [RFC 3448, 4.3]: backoff interval in seconds */
52#define TFRC_T_MBI 64 52#define TFRC_T_MBI 64
53 53
54#define TFRC_SMALLEST_P 40
55
56enum ccid3_options { 54enum ccid3_options {
57 TFRC_OPT_LOSS_EVENT_RATE = 192, 55 TFRC_OPT_LOSS_EVENT_RATE = 192,
58 TFRC_OPT_LOSS_INTERVALS = 193, 56 TFRC_OPT_LOSS_INTERVALS = 193,
diff --git a/net/dccp/ccids/lib/tfrc_equation.c b/net/dccp/ccids/lib/tfrc_equation.c
index 2601012383fb..ddac2c511e2f 100644
--- a/net/dccp/ccids/lib/tfrc_equation.c
+++ b/net/dccp/ccids/lib/tfrc_equation.c
@@ -18,10 +18,79 @@
18#include "tfrc.h" 18#include "tfrc.h"
19 19
20#define TFRC_CALC_X_ARRSIZE 500 20#define TFRC_CALC_X_ARRSIZE 500
21#define TFRC_CALC_X_SPLIT 50000 /* 0.05 * 1000000, details below */
22#define TFRC_SMALLEST_P (TFRC_CALC_X_SPLIT/TFRC_CALC_X_ARRSIZE)
21 23
22#define TFRC_CALC_X_SPLIT 50000 24/*
23/* equivalent to 0.05 */ 25 TFRC TCP Reno Throughput Equation Lookup Table for f(p)
24 26
27 The following two-column lookup table implements a part of the TCP throughput
28 equation from [RFC 3448, sec. 3.1]:
29
30 s
31 X_calc = --------------------------------------------------------------
32 R * sqrt(2*b*p/3) + (3 * t_RTO * sqrt(3*b*p/8) * (p + 32*p^3))
33
34 Where:
35 X is the transmit rate in bytes/second
36 s is the packet size in bytes
37 R is the round trip time in seconds
38 p is the loss event rate, between 0 and 1.0, of the number of loss
39 events as a fraction of the number of packets transmitted
40 t_RTO is the TCP retransmission timeout value in seconds
41 b is the number of packets acknowledged by a single TCP ACK
42
43 We can assume that b = 1 and t_RTO is 4 * R. The equation now becomes:
44
45 s
46 X_calc = -------------------------------------------------------
47 R * sqrt(p*2/3) + (12 * R * sqrt(p*3/8) * (p + 32*p^3))
48
49 which we can break down into:
50
51 s
52 X_calc = ---------
53 R * f(p)
54
55 where f(p) is given for 0 < p <= 1 by:
56
57 f(p) = sqrt(2*p/3) + 12 * sqrt(3*p/8) * (p + 32*p^3)
58
59 Since this is kernel code, floating-point arithmetic is avoided in favour of
60 integer arithmetic. This means that nearly all fractional parameters are
61 scaled by 1000000:
62 * the parameters p and R
63 * the return result f(p)
64 The lookup table therefore actually tabulates the following function g(q):
65
66 g(q) = 1000000 * f(q/1000000)
67
68 Hence, when p <= 1, q must be less than or equal to 1000000. To achieve finer
69 granularity for the practically more relevant case of small values of p (up to
70 5%), the second column is used; the first one ranges up to 100%. This split
71 corresponds to the value of q = TFRC_CALC_X_SPLIT. At the same time this also
72 determines the smallest resolution possible with this lookup table:
73
74 TFRC_SMALLEST_P = TFRC_CALC_X_SPLIT / TFRC_CALC_X_ARRSIZE
75
76 The entire table is generated by:
77 for(i=0; i < TFRC_CALC_X_ARRSIZE; i++) {
78 lookup[i][0] = g((i+1) * 1000000/TFRC_CALC_X_ARRSIZE);
79 lookup[i][1] = g((i+1) * TFRC_CALC_X_SPLIT/TFRC_CALC_X_ARRSIZE);
80 }
81
82 With the given configuration, we have, with M = TFRC_CALC_X_ARRSIZE-1,
83 lookup[0][0] = g(1000000/(M+1)) = 1000000 * f(0.2%)
84 lookup[M][0] = g(1000000) = 1000000 * f(100%)
85 lookup[0][1] = g(TFRC_SMALLEST_P) = 1000000 * f(0.01%)
86 lookup[M][1] = g(TFRC_CALC_X_SPLIT) = 1000000 * f(5%)
87
88 In summary, the two columns represent f(p) for the following ranges:
89 * The first column is for 0.002 <= p <= 1.0
90 * The second column is for 0.0001 <= p <= 0.05
91 Where the columns overlap, the second (finer-grained) is given preference,
92 i.e. the first column is used only for p >= 0.05.
93 */
25static const u32 tfrc_calc_x_lookup[TFRC_CALC_X_ARRSIZE][2] = { 94static const u32 tfrc_calc_x_lookup[TFRC_CALC_X_ARRSIZE][2] = {
26 { 37172, 8172 }, 95 { 37172, 8172 },
27 { 53499, 11567 }, 96 { 53499, 11567 },
@@ -525,85 +594,69 @@ static const u32 tfrc_calc_x_lookup[TFRC_CALC_X_ARRSIZE][2] = {
525 { 243315981, 271305 } 594 { 243315981, 271305 }
526}; 595};
527 596
528/* Calculate the send rate as per section 3.1 of RFC3448 597/* return largest index i such that fval <= lookup[i][small] */
529 598static inline u32 tfrc_binsearch(u32 fval, u8 small)
530Returns send rate in bytes per second 599{
531 600 u32 try, low = 0, high = TFRC_CALC_X_ARRSIZE - 1;
532Integer maths and lookups are used as not allowed floating point in kernel 601
533 602 while (low < high) {
534The function for Xcalc as per section 3.1 of RFC3448 is: 603 try = (low + high) / 2;
535 604 if (fval <= tfrc_calc_x_lookup[try][small])
536X = s 605 high = try;
537 ------------------------------------------------------------- 606 else
538 R*sqrt(2*b*p/3) + (t_RTO * (3*sqrt(3*b*p/8) * p * (1+32*p^2))) 607 low = try + 1;
539 608 }
540where 609 return high;
541X is the trasmit rate in bytes/second 610}
542s is the packet size in bytes
543R is the round trip time in seconds
544p is the loss event rate, between 0 and 1.0, of the number of loss events
545 as a fraction of the number of packets transmitted
546t_RTO is the TCP retransmission timeout value in seconds
547b is the number of packets acknowledged by a single TCP acknowledgement
548
549we can assume that b = 1 and t_RTO is 4 * R. With this the equation becomes:
550
551X = s
552 -----------------------------------------------------------------------
553 R * sqrt(2 * p / 3) + (12 * R * (sqrt(3 * p / 8) * p * (1 + 32 * p^2)))
554
555
556which we can break down into:
557
558X = s
559 --------
560 R * f(p)
561
562where f(p) = sqrt(2 * p / 3) + (12 * sqrt(3 * p / 8) * p * (1 + 32 * p * p))
563
564Function parameters:
565s - bytes
566R - RTT in usecs
567p - loss rate (decimal fraction multiplied by 1,000,000)
568
569Returns Xcalc in bytes per second
570
571DON'T alter this code unless you run test cases against it as the code
572has been manipulated to stop underflow/overlow.
573 611
574*/ 612/**
613 * tfrc_calc_x - Calculate the send rate as per section 3.1 of RFC3448
614 *
615 * @s: packet size in bytes
616 * @R: RTT scaled by 1000000 (i.e., microseconds)
617 * @p: loss ratio estimate scaled by 1000000
618 * Returns X_calc in bytes per second (not scaled).
619 *
620 * Note: DO NOT alter this code unless you run test cases against it,
621 * as the code has been optimized to stop underflow/overflow.
622 */
575u32 tfrc_calc_x(u16 s, u32 R, u32 p) 623u32 tfrc_calc_x(u16 s, u32 R, u32 p)
576{ 624{
577 int index; 625 int index;
578 u32 f; 626 u32 f;
579 u64 tmp1, tmp2; 627 u64 tmp1, tmp2;
580 628
581 if (p < TFRC_CALC_X_SPLIT) 629 /* check against invalid parameters and divide-by-zero */
582 index = (p / (TFRC_CALC_X_SPLIT / TFRC_CALC_X_ARRSIZE)) - 1; 630 BUG_ON(p > 1000000); /* p must not exceed 100% */
583 else 631 BUG_ON(p == 0); /* f(0) = 0, divide by zero */
584 index = (p / (1000000 / TFRC_CALC_X_ARRSIZE)) - 1; 632 if (R == 0) { /* possible divide by zero */
633 DCCP_CRIT("WARNING: RTT is 0, returning maximum X_calc.");
634 return ~0U;
635 }
585 636
586 if (index < 0) 637 if (p <= TFRC_CALC_X_SPLIT) { /* 0.0000 < p <= 0.05 */
587 /* p should be 0 unless there is a bug in my code */ 638 if (p < TFRC_SMALLEST_P) { /* 0.0000 < p < 0.0001 */
588 index = 0; 639 DCCP_WARN("Value of p (%d) below resolution. "
640 "Substituting %d\n", p, TFRC_SMALLEST_P);
641 index = 0;
642 } else /* 0.0001 <= p <= 0.05 */
643 index = p/TFRC_SMALLEST_P - 1;
589 644
590 if (R == 0) { 645 f = tfrc_calc_x_lookup[index][1];
591 DCCP_WARN("RTT==0, setting to 1\n");
592 R = 1; /* RTT can't be zero or else divide by zero */
593 }
594 646
595 BUG_ON(index >= TFRC_CALC_X_ARRSIZE); 647 } else { /* 0.05 < p <= 1.00 */
648 index = p/(1000000/TFRC_CALC_X_ARRSIZE) - 1;
596 649
597 if (p >= TFRC_CALC_X_SPLIT)
598 f = tfrc_calc_x_lookup[index][0]; 650 f = tfrc_calc_x_lookup[index][0];
599 else 651 }
600 f = tfrc_calc_x_lookup[index][1];
601 652
653 /* The following computes X = s/(R*f(p)) in bytes per second. Since f(p)
654 * and R are both scaled by 1000000, we need to multiply by 1000000^2.
655 * ==> DO NOT alter this unless you test against overflow on 32 bit */
602 tmp1 = ((u64)s * 100000000); 656 tmp1 = ((u64)s * 100000000);
603 tmp2 = ((u64)R * (u64)f); 657 tmp2 = ((u64)R * (u64)f);
604 do_div(tmp2, 10000); 658 do_div(tmp2, 10000);
605 do_div(tmp1, tmp2); 659 do_div(tmp1, tmp2);
606 /* Don't alter above math unless you test due to overflow on 32 bit */
607 660
608 return (u32)tmp1; 661 return (u32)tmp1;
609} 662}
@@ -611,33 +664,36 @@ u32 tfrc_calc_x(u16 s, u32 R, u32 p)
611EXPORT_SYMBOL_GPL(tfrc_calc_x); 664EXPORT_SYMBOL_GPL(tfrc_calc_x);
612 665
613/* 666/*
614 * args: fvalue - function value to match 667 * tfrc_calc_x_reverse_lookup - try to find p given f(p)
615 * returns: p closest to that value
616 * 668 *
617 * both fvalue and p are multiplied by 1,000,000 to use ints 669 * @fvalue: function value to match, scaled by 1000000
670 * Returns closest match for p, also scaled by 1000000
618 */ 671 */
619u32 tfrc_calc_x_reverse_lookup(u32 fvalue) 672u32 tfrc_calc_x_reverse_lookup(u32 fvalue)
620{ 673{
621 int ctr = 0; 674 int index;
622 int small;
623 675
624 if (fvalue < tfrc_calc_x_lookup[0][1]) 676 if (fvalue == 0) /* f(p) = 0 whenever p = 0 */
625 return 0; 677 return 0;
626 678
627 if (fvalue <= tfrc_calc_x_lookup[TFRC_CALC_X_ARRSIZE - 1][1]) 679 /* Error cases. */
628 small = 1; 680 if (fvalue < tfrc_calc_x_lookup[0][1]) {
629 else if (fvalue > tfrc_calc_x_lookup[TFRC_CALC_X_ARRSIZE - 1][0]) 681 DCCP_WARN("fvalue %d smaller than resolution\n", fvalue);
682 return tfrc_calc_x_lookup[0][1];
683 }
684 if (fvalue > tfrc_calc_x_lookup[TFRC_CALC_X_ARRSIZE - 1][0]) {
685 DCCP_WARN("fvalue %d exceeds bounds!\n", fvalue);
630 return 1000000; 686 return 1000000;
631 else 687 }
632 small = 0;
633
634 while (fvalue > tfrc_calc_x_lookup[ctr][small])
635 ctr++;
636 688
637 if (small) 689 if (fvalue <= tfrc_calc_x_lookup[TFRC_CALC_X_ARRSIZE - 1][1]) {
638 return TFRC_CALC_X_SPLIT * ctr / TFRC_CALC_X_ARRSIZE; 690 index = tfrc_binsearch(fvalue, 1);
639 else 691 return (index + 1) * TFRC_CALC_X_SPLIT / TFRC_CALC_X_ARRSIZE;
640 return 1000000 * ctr / TFRC_CALC_X_ARRSIZE; 692 }
693
694 /* else ... it must be in the coarse-grained column */
695 index = tfrc_binsearch(fvalue, 0);
696 return (index + 1) * 1000000 / TFRC_CALC_X_ARRSIZE;
641} 697}
642 698
643EXPORT_SYMBOL_GPL(tfrc_calc_x_reverse_lookup); 699EXPORT_SYMBOL_GPL(tfrc_calc_x_reverse_lookup);
diff --git a/net/ieee80211/ieee80211_crypt_tkip.c b/net/ieee80211/ieee80211_crypt_tkip.c
index 4200ec509866..fc1f99a59732 100644
--- a/net/ieee80211/ieee80211_crypt_tkip.c
+++ b/net/ieee80211/ieee80211_crypt_tkip.c
@@ -16,6 +16,7 @@
16#include <linux/random.h> 16#include <linux/random.h>
17#include <linux/skbuff.h> 17#include <linux/skbuff.h>
18#include <linux/netdevice.h> 18#include <linux/netdevice.h>
19#include <linux/mm.h>
19#include <linux/if_ether.h> 20#include <linux/if_ether.h>
20#include <linux/if_arp.h> 21#include <linux/if_arp.h>
21#include <asm/string.h> 22#include <asm/string.h>
diff --git a/net/ieee80211/ieee80211_crypt_wep.c b/net/ieee80211/ieee80211_crypt_wep.c
index 1b2efff11d39..7a95c3d81314 100644
--- a/net/ieee80211/ieee80211_crypt_wep.c
+++ b/net/ieee80211/ieee80211_crypt_wep.c
@@ -15,6 +15,7 @@
15#include <linux/slab.h> 15#include <linux/slab.h>
16#include <linux/random.h> 16#include <linux/random.h>
17#include <linux/skbuff.h> 17#include <linux/skbuff.h>
18#include <linux/mm.h>
18#include <asm/string.h> 19#include <asm/string.h>
19 20
20#include <net/ieee80211.h> 21#include <net/ieee80211.h>
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 1da3d32f8289..a35209d517ad 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -53,6 +53,7 @@
53#include <linux/mm.h> 53#include <linux/mm.h>
54#include <linux/string.h> 54#include <linux/string.h>
55#include <linux/errno.h> 55#include <linux/errno.h>
56#include <linux/highmem.h>
56 57
57#include <linux/socket.h> 58#include <linux/socket.h>
58#include <linux/sockios.h> 59#include <linux/sockios.h>
diff --git a/net/ipv4/ipvs/ip_vs_lblc.c b/net/ipv4/ipvs/ip_vs_lblc.c
index 524751e031de..a4385a2180ee 100644
--- a/net/ipv4/ipvs/ip_vs_lblc.c
+++ b/net/ipv4/ipvs/ip_vs_lblc.c
@@ -45,6 +45,7 @@
45#include <linux/module.h> 45#include <linux/module.h>
46#include <linux/kernel.h> 46#include <linux/kernel.h>
47#include <linux/skbuff.h> 47#include <linux/skbuff.h>
48#include <linux/jiffies.h>
48 49
49/* for sysctl */ 50/* for sysctl */
50#include <linux/fs.h> 51#include <linux/fs.h>
diff --git a/net/ipv4/ipvs/ip_vs_lblcr.c b/net/ipv4/ipvs/ip_vs_lblcr.c
index 08990192b6ec..fe1af5d079af 100644
--- a/net/ipv4/ipvs/ip_vs_lblcr.c
+++ b/net/ipv4/ipvs/ip_vs_lblcr.c
@@ -43,6 +43,7 @@
43#include <linux/module.h> 43#include <linux/module.h>
44#include <linux/kernel.h> 44#include <linux/kernel.h>
45#include <linux/skbuff.h> 45#include <linux/skbuff.h>
46#include <linux/jiffies.h>
46 47
47/* for sysctl */ 48/* for sysctl */
48#include <linux/fs.h> 49#include <linux/fs.h>
diff --git a/net/irda/discovery.c b/net/irda/discovery.c
index 3fefc822c1c0..89fd2a2cbca6 100644
--- a/net/irda/discovery.c
+++ b/net/irda/discovery.c
@@ -32,6 +32,7 @@
32 32
33#include <linux/string.h> 33#include <linux/string.h>
34#include <linux/socket.h> 34#include <linux/socket.h>
35#include <linux/fs.h>
35#include <linux/seq_file.h> 36#include <linux/seq_file.h>
36 37
37#include <net/irda/irda.h> 38#include <net/irda/irda.h>
diff --git a/net/irda/iriap.c b/net/irda/iriap.c
index 8cfd076c4c12..8f1c6d65b247 100644
--- a/net/irda/iriap.c
+++ b/net/irda/iriap.c
@@ -27,6 +27,7 @@
27#include <linux/module.h> 27#include <linux/module.h>
28#include <linux/types.h> 28#include <linux/types.h>
29#include <linux/skbuff.h> 29#include <linux/skbuff.h>
30#include <linux/fs.h>
30#include <linux/string.h> 31#include <linux/string.h>
31#include <linux/init.h> 32#include <linux/init.h>
32#include <linux/seq_file.h> 33#include <linux/seq_file.h>
diff --git a/net/irda/irttp.c b/net/irda/irttp.c
index 9c446a72ff1f..252f11012566 100644
--- a/net/irda/irttp.c
+++ b/net/irda/irttp.c
@@ -26,6 +26,7 @@
26 26
27#include <linux/skbuff.h> 27#include <linux/skbuff.h>
28#include <linux/init.h> 28#include <linux/init.h>
29#include <linux/fs.h>
29#include <linux/seq_file.h> 30#include <linux/seq_file.h>
30 31
31#include <asm/byteorder.h> 32#include <asm/byteorder.h>
diff --git a/net/netfilter/nf_conntrack_core.c b/net/netfilter/nf_conntrack_core.c
index 93d97d9f9da8..eaa0f8a1adb6 100644
--- a/net/netfilter/nf_conntrack_core.c
+++ b/net/netfilter/nf_conntrack_core.c
@@ -46,6 +46,7 @@
46#include <linux/kernel.h> 46#include <linux/kernel.h>
47#include <linux/netdevice.h> 47#include <linux/netdevice.h>
48#include <linux/socket.h> 48#include <linux/socket.h>
49#include <linux/mm.h>
49 50
50#include <net/netfilter/nf_conntrack.h> 51#include <net/netfilter/nf_conntrack.h>
51#include <net/netfilter/nf_conntrack_l3proto.h> 52#include <net/netfilter/nf_conntrack_l3proto.h>
diff --git a/net/netfilter/x_tables.c b/net/netfilter/x_tables.c
index 58522fc65d33..8996584b8499 100644
--- a/net/netfilter/x_tables.c
+++ b/net/netfilter/x_tables.c
@@ -21,6 +21,7 @@
21#include <linux/string.h> 21#include <linux/string.h>
22#include <linux/vmalloc.h> 22#include <linux/vmalloc.h>
23#include <linux/mutex.h> 23#include <linux/mutex.h>
24#include <linux/mm.h>
24 25
25#include <linux/netfilter/x_tables.h> 26#include <linux/netfilter/x_tables.h>
26#include <linux/netfilter_arp.h> 27#include <linux/netfilter_arp.h>
diff --git a/net/netfilter/xt_hashlimit.c b/net/netfilter/xt_hashlimit.c
index 501c564e247f..a98de0b54d65 100644
--- a/net/netfilter/xt_hashlimit.c
+++ b/net/netfilter/xt_hashlimit.c
@@ -17,6 +17,7 @@
17#include <linux/seq_file.h> 17#include <linux/seq_file.h>
18#include <linux/list.h> 18#include <linux/list.h>
19#include <linux/skbuff.h> 19#include <linux/skbuff.h>
20#include <linux/mm.h>
20#include <linux/in.h> 21#include <linux/in.h>
21#include <linux/ip.h> 22#include <linux/ip.h>
22#include <linux/ipv6.h> 23#include <linux/ipv6.h>
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index 271d2eed0699..08e68b67bbf6 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -71,6 +71,7 @@
71#include <asm/uaccess.h> 71#include <asm/uaccess.h>
72#include <asm/ioctls.h> 72#include <asm/ioctls.h>
73#include <asm/page.h> 73#include <asm/page.h>
74#include <asm/cacheflush.h>
74#include <asm/io.h> 75#include <asm/io.h>
75#include <linux/proc_fs.h> 76#include <linux/proc_fs.h>
76#include <linux/seq_file.h> 77#include <linux/seq_file.h>
diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c
index 6f97665983d2..311205ffa775 100644
--- a/net/xfrm/xfrm_user.c
+++ b/net/xfrm/xfrm_user.c
@@ -858,7 +858,6 @@ static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut,
858 int i; 858 int i;
859 859
860 xp->xfrm_nr = nr; 860 xp->xfrm_nr = nr;
861 xp->family = ut->family;
862 for (i = 0; i < nr; i++, ut++) { 861 for (i = 0; i < nr; i++, ut++) {
863 struct xfrm_tmpl *t = &xp->xfrm_vec[i]; 862 struct xfrm_tmpl *t = &xp->xfrm_vec[i];
864 863
@@ -876,19 +875,53 @@ static void copy_templates(struct xfrm_policy *xp, struct xfrm_user_tmpl *ut,
876 } 875 }
877} 876}
878 877
878static int validate_tmpl(int nr, struct xfrm_user_tmpl *ut, u16 family)
879{
880 int i;
881
882 if (nr > XFRM_MAX_DEPTH)
883 return -EINVAL;
884
885 for (i = 0; i < nr; i++) {
886 /* We never validated the ut->family value, so many
887 * applications simply leave it at zero. The check was
888 * never made and ut->family was ignored because all
889 * templates could be assumed to have the same family as
890 * the policy itself. Now that we will have ipv4-in-ipv6
891 * and ipv6-in-ipv4 tunnels, this is no longer true.
892 */
893 if (!ut[i].family)
894 ut[i].family = family;
895
896 switch (ut[i].family) {
897 case AF_INET:
898 break;
899#if defined(CONFIG_IPV6) || defined(CONFIG_IPV6_MODULE)
900 case AF_INET6:
901 break;
902#endif
903 default:
904 return -EINVAL;
905 };
906 }
907
908 return 0;
909}
910
879static int copy_from_user_tmpl(struct xfrm_policy *pol, struct rtattr **xfrma) 911static int copy_from_user_tmpl(struct xfrm_policy *pol, struct rtattr **xfrma)
880{ 912{
881 struct rtattr *rt = xfrma[XFRMA_TMPL-1]; 913 struct rtattr *rt = xfrma[XFRMA_TMPL-1];
882 struct xfrm_user_tmpl *utmpl;
883 int nr;
884 914
885 if (!rt) { 915 if (!rt) {
886 pol->xfrm_nr = 0; 916 pol->xfrm_nr = 0;
887 } else { 917 } else {
888 nr = (rt->rta_len - sizeof(*rt)) / sizeof(*utmpl); 918 struct xfrm_user_tmpl *utmpl = RTA_DATA(rt);
919 int nr = (rt->rta_len - sizeof(*rt)) / sizeof(*utmpl);
920 int err;
889 921
890 if (nr > XFRM_MAX_DEPTH) 922 err = validate_tmpl(nr, utmpl, pol->family);
891 return -EINVAL; 923 if (err)
924 return err;
892 925
893 copy_templates(pol, RTA_DATA(rt), nr); 926 copy_templates(pol, RTA_DATA(rt), nr);
894 } 927 }
@@ -1530,7 +1563,8 @@ static int xfrm_add_acquire(struct sk_buff *skb, struct nlmsghdr *nlh, void **xf
1530 } 1563 }
1531 1564
1532 /* build an XP */ 1565 /* build an XP */
1533 xp = xfrm_policy_construct(&ua->policy, (struct rtattr **) xfrma, &err); if (!xp) { 1566 xp = xfrm_policy_construct(&ua->policy, (struct rtattr **) xfrma, &err);
1567 if (!xp) {
1534 kfree(x); 1568 kfree(x);
1535 return err; 1569 return err;
1536 } 1570 }
@@ -1979,7 +2013,7 @@ static struct xfrm_policy *xfrm_compile_policy(struct sock *sk, int opt,
1979 return NULL; 2013 return NULL;
1980 2014
1981 nr = ((len - sizeof(*p)) / sizeof(*ut)); 2015 nr = ((len - sizeof(*p)) / sizeof(*ut));
1982 if (nr > XFRM_MAX_DEPTH) 2016 if (validate_tmpl(nr, ut, p->sel.family))
1983 return NULL; 2017 return NULL;
1984 2018
1985 if (p->dir > XFRM_POLICY_OUT) 2019 if (p->dir > XFRM_POLICY_OUT)
diff --git a/security/selinux/avc.c b/security/selinux/avc.c
index 74c0319c417e..e73ac1ab7cfd 100644
--- a/security/selinux/avc.c
+++ b/security/selinux/avc.c
@@ -496,7 +496,7 @@ static inline void avc_print_ipv6_addr(struct audit_buffer *ab,
496 audit_log_format(ab, " %s=%d", name2, ntohs(port)); 496 audit_log_format(ab, " %s=%d", name2, ntohs(port));
497} 497}
498 498
499static inline void avc_print_ipv4_addr(struct audit_buffer *ab, u32 addr, 499static inline void avc_print_ipv4_addr(struct audit_buffer *ab, __be32 addr,
500 __be16 port, char *name1, char *name2) 500 __be16 port, char *name1, char *name2)
501{ 501{
502 if (addr) 502 if (addr)
diff --git a/security/selinux/hooks.c b/security/selinux/hooks.c
index a29d78d3f44c..78f98fe084eb 100644
--- a/security/selinux/hooks.c
+++ b/security/selinux/hooks.c
@@ -3537,7 +3537,7 @@ static int selinux_socket_sock_rcv_skb(struct sock *sk, struct sk_buff *skb)
3537 goto out; 3537 goto out;
3538 3538
3539 /* Handle mapped IPv4 packets arriving via IPv6 sockets */ 3539 /* Handle mapped IPv4 packets arriving via IPv6 sockets */
3540 if (family == PF_INET6 && skb->protocol == ntohs(ETH_P_IP)) 3540 if (family == PF_INET6 && skb->protocol == htons(ETH_P_IP))
3541 family = PF_INET; 3541 family = PF_INET;
3542 3542
3543 AVC_AUDIT_DATA_INIT(&ad, NET); 3543 AVC_AUDIT_DATA_INIT(&ad, NET);
diff --git a/security/selinux/include/avc.h b/security/selinux/include/avc.h
index 960ef18ddc41..6ed10c3d3339 100644
--- a/security/selinux/include/avc.h
+++ b/security/selinux/include/avc.h
@@ -54,12 +54,12 @@ struct avc_audit_data {
54 char *netif; 54 char *netif;
55 struct sock *sk; 55 struct sock *sk;
56 u16 family; 56 u16 family;
57 u16 dport; 57 __be16 dport;
58 u16 sport; 58 __be16 sport;
59 union { 59 union {
60 struct { 60 struct {
61 u32 daddr; 61 __be32 daddr;
62 u32 saddr; 62 __be32 saddr;
63 } v4; 63 } v4;
64 struct { 64 struct {
65 struct in6_addr daddr; 65 struct in6_addr daddr;
diff --git a/sound/oss/cs46xx.c b/sound/oss/cs46xx.c
index b1c5d8286e40..147c8a951137 100644
--- a/sound/oss/cs46xx.c
+++ b/sound/oss/cs46xx.c
@@ -91,6 +91,7 @@
91#include <linux/poll.h> 91#include <linux/poll.h>
92#include <linux/ac97_codec.h> 92#include <linux/ac97_codec.h>
93#include <linux/mutex.h> 93#include <linux/mutex.h>
94#include <linux/mm.h>
94 95
95#include <asm/io.h> 96#include <asm/io.h>
96#include <asm/dma.h> 97#include <asm/dma.h>
diff --git a/sound/oss/dmabuf.c b/sound/oss/dmabuf.c
index b256c0401161..eaf69971bf92 100644
--- a/sound/oss/dmabuf.c
+++ b/sound/oss/dmabuf.c
@@ -25,6 +25,7 @@
25#define BE_CONSERVATIVE 25#define BE_CONSERVATIVE
26#define SAMPLE_ROUNDUP 0 26#define SAMPLE_ROUNDUP 0
27 27
28#include <linux/mm.h>
28#include "sound_config.h" 29#include "sound_config.h"
29 30
30#define DMAP_FREE_ON_CLOSE 0 31#define DMAP_FREE_ON_CLOSE 0
diff --git a/sound/oss/emu10k1/audio.c b/sound/oss/emu10k1/audio.c
index cde4d59d5430..86dd23974e05 100644
--- a/sound/oss/emu10k1/audio.c
+++ b/sound/oss/emu10k1/audio.c
@@ -36,6 +36,7 @@
36#include <linux/bitops.h> 36#include <linux/bitops.h>
37#include <asm/io.h> 37#include <asm/io.h>
38#include <linux/sched.h> 38#include <linux/sched.h>
39#include <linux/mm.h>
39#include <linux/smp_lock.h> 40#include <linux/smp_lock.h>
40 41
41#include "hwaccess.h" 42#include "hwaccess.h"
diff --git a/sound/oss/es1371.c b/sound/oss/es1371.c
index ddf6b0a0bca5..cc282a0cd539 100644
--- a/sound/oss/es1371.c
+++ b/sound/oss/es1371.c
@@ -130,6 +130,7 @@
130#include <linux/wait.h> 130#include <linux/wait.h>
131#include <linux/dma-mapping.h> 131#include <linux/dma-mapping.h>
132#include <linux/mutex.h> 132#include <linux/mutex.h>
133#include <linux/mm.h>
133 134
134#include <asm/io.h> 135#include <asm/io.h>
135#include <asm/page.h> 136#include <asm/page.h>
diff --git a/sound/oss/i810_audio.c b/sound/oss/i810_audio.c
index 240cc7939b69..c3c8a720d555 100644
--- a/sound/oss/i810_audio.c
+++ b/sound/oss/i810_audio.c
@@ -101,6 +101,7 @@
101#include <linux/ac97_codec.h> 101#include <linux/ac97_codec.h>
102#include <linux/bitops.h> 102#include <linux/bitops.h>
103#include <linux/mutex.h> 103#include <linux/mutex.h>
104#include <linux/mm.h>
104 105
105#include <asm/uaccess.h> 106#include <asm/uaccess.h>
106 107
diff --git a/sound/oss/soundcard.c b/sound/oss/soundcard.c
index 75c5e745705f..8fb8e7f99556 100644
--- a/sound/oss/soundcard.c
+++ b/sound/oss/soundcard.c
@@ -42,6 +42,7 @@
42#include <linux/proc_fs.h> 42#include <linux/proc_fs.h>
43#include <linux/smp_lock.h> 43#include <linux/smp_lock.h>
44#include <linux/module.h> 44#include <linux/module.h>
45#include <linux/mm.h>
45 46
46/* 47/*
47 * This ought to be moved into include/asm/dma.h 48 * This ought to be moved into include/asm/dma.h
diff --git a/sound/oss/sscape.c b/sound/oss/sscape.c
index 51f2fa615413..30c36d1f35d7 100644
--- a/sound/oss/sscape.c
+++ b/sound/oss/sscape.c
@@ -39,6 +39,7 @@
39#include <linux/ioport.h> 39#include <linux/ioport.h>
40#include <linux/delay.h> 40#include <linux/delay.h>
41#include <linux/proc_fs.h> 41#include <linux/proc_fs.h>
42#include <linux/mm.h>
42#include <linux/spinlock.h> 43#include <linux/spinlock.h>
43 44
44#include "coproc.h" 45#include "coproc.h"
diff --git a/sound/oss/trident.c b/sound/oss/trident.c
index 7a363a178afd..6b1f8c9cdcf8 100644
--- a/sound/oss/trident.c
+++ b/sound/oss/trident.c
@@ -216,6 +216,7 @@
216#include <linux/gameport.h> 216#include <linux/gameport.h>
217#include <linux/kernel.h> 217#include <linux/kernel.h>
218#include <linux/mutex.h> 218#include <linux/mutex.h>
219#include <linux/mm.h>
219 220
220#include <asm/uaccess.h> 221#include <asm/uaccess.h>
221#include <asm/io.h> 222#include <asm/io.h>