aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Documentation/acpi-hotkey.txt38
-rw-r--r--Documentation/arm/Samsung-S3C24XX/DMA.txt46
-rw-r--r--Documentation/arm/Samsung-S3C24XX/Overview.txt21
-rw-r--r--Documentation/feature-removal-schedule.txt23
-rw-r--r--Documentation/kernel-parameters.txt6
-rw-r--r--Documentation/pci.txt4
-rw-r--r--Documentation/powerpc/booting-without-of.txt14
-rw-r--r--Documentation/sony-laptop.txt106
-rw-r--r--MAINTAINERS9
-rw-r--r--arch/arm/Kconfig40
-rw-r--r--arch/arm/Makefile18
-rw-r--r--arch/arm/boot/.gitignore2
-rw-r--r--arch/arm/boot/compressed/.gitignore1
-rw-r--r--arch/arm/common/dmabounce.c87
-rw-r--r--arch/arm/common/gic.c109
-rw-r--r--arch/arm/configs/at91sam9263ek_defconfig1184
-rw-r--r--arch/arm/configs/ateb9200_defconfig2
-rw-r--r--arch/arm/configs/csb337_defconfig8
-rw-r--r--arch/arm/configs/csb637_defconfig6
-rw-r--r--arch/arm/configs/kafa_defconfig2
-rw-r--r--arch/arm/configs/ns9xxx_defconfig621
-rw-r--r--arch/arm/configs/s3c2410_defconfig142
-rw-r--r--arch/arm/kernel/Makefile1
-rw-r--r--arch/arm/kernel/calls.S1
-rw-r--r--arch/arm/kernel/crunch.c1
-rw-r--r--arch/arm/kernel/ecard.c2
-rw-r--r--arch/arm/kernel/entry-armv.S1
-rw-r--r--arch/arm/kernel/machine_kexec.c78
-rw-r--r--arch/arm/kernel/process.c8
-rw-r--r--arch/arm/kernel/relocate_kernel.S74
-rw-r--r--arch/arm/kernel/setup.c3
-rw-r--r--arch/arm/kernel/time.c4
-rw-r--r--arch/arm/kernel/traps.c17
-rw-r--r--arch/arm/mach-at91/Kconfig (renamed from arch/arm/mach-at91rm9200/Kconfig)39
-rw-r--r--arch/arm/mach-at91/Makefile (renamed from arch/arm/mach-at91rm9200/Makefile)4
-rw-r--r--arch/arm/mach-at91/Makefile.boot (renamed from arch/arm/mach-at91rm9200/Makefile.boot)0
-rw-r--r--arch/arm/mach-at91/at91rm9200.c (renamed from arch/arm/mach-at91rm9200/at91rm9200.c)39
-rw-r--r--arch/arm/mach-at91/at91rm9200_devices.c (renamed from arch/arm/mach-at91rm9200/at91rm9200_devices.c)10
-rw-r--r--arch/arm/mach-at91/at91rm9200_time.c (renamed from arch/arm/mach-at91rm9200/at91rm9200_time.c)2
-rw-r--r--arch/arm/mach-at91/at91sam9260.c (renamed from arch/arm/mach-at91rm9200/at91sam9260.c)90
-rw-r--r--arch/arm/mach-at91/at91sam9260_devices.c (renamed from arch/arm/mach-at91rm9200/at91sam9260_devices.c)16
-rw-r--r--arch/arm/mach-at91/at91sam9261.c (renamed from arch/arm/mach-at91rm9200/at91sam9261.c)23
-rw-r--r--arch/arm/mach-at91/at91sam9261_devices.c (renamed from arch/arm/mach-at91rm9200/at91sam9261_devices.c)10
-rw-r--r--arch/arm/mach-at91/at91sam9263.c313
-rw-r--r--arch/arm/mach-at91/at91sam9263_devices.c818
-rw-r--r--arch/arm/mach-at91/at91sam926x_time.c (renamed from arch/arm/mach-at91rm9200/at91sam926x_time.c)5
-rw-r--r--arch/arm/mach-at91/board-1arm.c (renamed from arch/arm/mach-at91rm9200/board-1arm.c)2
-rw-r--r--arch/arm/mach-at91/board-carmeva.c (renamed from arch/arm/mach-at91rm9200/board-carmeva.c)4
-rw-r--r--arch/arm/mach-at91/board-csb337.c (renamed from arch/arm/mach-at91rm9200/board-csb337.c)43
-rw-r--r--arch/arm/mach-at91/board-csb637.c (renamed from arch/arm/mach-at91rm9200/board-csb637.c)41
-rw-r--r--arch/arm/mach-at91/board-dk.c (renamed from arch/arm/mach-at91rm9200/board-dk.c)4
-rw-r--r--arch/arm/mach-at91/board-eb9200.c (renamed from arch/arm/mach-at91rm9200/board-eb9200.c)4
-rw-r--r--arch/arm/mach-at91/board-ek.c (renamed from arch/arm/mach-at91rm9200/board-ek.c)4
-rw-r--r--arch/arm/mach-at91/board-kafa.c (renamed from arch/arm/mach-at91rm9200/board-kafa.c)2
-rw-r--r--arch/arm/mach-at91/board-kb9202.c (renamed from arch/arm/mach-at91rm9200/board-kb9202.c)4
-rw-r--r--arch/arm/mach-at91/board-sam9260ek.c (renamed from arch/arm/mach-at91rm9200/board-sam9260ek.c)6
-rw-r--r--arch/arm/mach-at91/board-sam9261ek.c (renamed from arch/arm/mach-at91rm9200/board-sam9261ek.c)4
-rw-r--r--arch/arm/mach-at91/board-sam9263ek.c176
-rw-r--r--arch/arm/mach-at91/clock.c (renamed from arch/arm/mach-at91rm9200/clock.c)64
-rw-r--r--arch/arm/mach-at91/clock.h (renamed from arch/arm/mach-at91rm9200/clock.h)2
-rw-r--r--arch/arm/mach-at91/generic.h (renamed from arch/arm/mach-at91rm9200/generic.h)4
-rw-r--r--arch/arm/mach-at91/gpio.c (renamed from arch/arm/mach-at91rm9200/gpio.c)2
-rw-r--r--arch/arm/mach-at91/irq.c (renamed from arch/arm/mach-at91rm9200/irq.c)2
-rw-r--r--arch/arm/mach-at91/leds.c (renamed from arch/arm/mach-at91rm9200/leds.c)4
-rw-r--r--arch/arm/mach-at91/pm.c (renamed from arch/arm/mach-at91rm9200/pm.c)4
-rw-r--r--arch/arm/mach-ep93xx/Kconfig25
-rw-r--r--arch/arm/mach-ep93xx/Makefile1
-rw-r--r--arch/arm/mach-ep93xx/clock.c6
-rw-r--r--arch/arm/mach-ep93xx/core.c115
-rw-r--r--arch/arm/mach-ep93xx/micro9.c157
-rw-r--r--arch/arm/mach-iop13xx/irq.c3
-rw-r--r--arch/arm/mach-iop32x/irq.c2
-rw-r--r--arch/arm/mach-iop32x/n2100.c14
-rw-r--r--arch/arm/mach-iop33x/irq.c2
-rw-r--r--arch/arm/mach-ixp4xx/Kconfig12
-rw-r--r--arch/arm/mach-ixp4xx/Makefile2
-rw-r--r--arch/arm/mach-ixp4xx/avila-pci.c78
-rw-r--r--arch/arm/mach-ixp4xx/avila-setup.c192
-rw-r--r--arch/arm/mach-ixp4xx/ixdp425-pci.c2
-rw-r--r--arch/arm/mach-ixp4xx/ixdp425-setup.c20
-rw-r--r--arch/arm/mach-ns9xxx/Kconfig21
-rw-r--r--arch/arm/mach-ns9xxx/Makefile5
-rw-r--r--arch/arm/mach-ns9xxx/Makefile.boot2
-rw-r--r--arch/arm/mach-ns9xxx/board-a9m9750dev.c199
-rw-r--r--arch/arm/mach-ns9xxx/board-a9m9750dev.h15
-rw-r--r--arch/arm/mach-ns9xxx/generic.c42
-rw-r--r--arch/arm/mach-ns9xxx/generic.h19
-rw-r--r--arch/arm/mach-ns9xxx/irq.c94
-rw-r--r--arch/arm/mach-ns9xxx/mach-cc9p9360dev.c41
-rw-r--r--arch/arm/mach-ns9xxx/time.c88
-rw-r--r--arch/arm/mach-pxa/generic.c24
-rw-r--r--arch/arm/mach-realview/Kconfig11
-rw-r--r--arch/arm/mach-realview/platsmp.c4
-rw-r--r--arch/arm/mach-realview/realview_eb.c38
-rw-r--r--arch/arm/mach-s3c2400/Kconfig13
-rw-r--r--arch/arm/mach-s3c2400/Makefile15
-rw-r--r--arch/arm/mach-s3c2400/gpio.c (renamed from arch/arm/mach-s3c2410/s3c2400-gpio.c)2
-rw-r--r--arch/arm/mach-s3c2410/Kconfig338
-rw-r--r--arch/arm/mach-s3c2410/Makefile103
-rw-r--r--arch/arm/mach-s3c2410/bast-irq.c2
-rw-r--r--arch/arm/mach-s3c2410/bast.h2
-rw-r--r--arch/arm/mach-s3c2410/clock.c565
-rw-r--r--arch/arm/mach-s3c2410/dma.c1546
-rw-r--r--arch/arm/mach-s3c2410/gpio.c165
-rw-r--r--arch/arm/mach-s3c2410/irq.c775
-rw-r--r--arch/arm/mach-s3c2410/mach-amlm5900.c14
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c6
-rw-r--r--arch/arm/mach-s3c2410/mach-h1940.c64
-rw-r--r--arch/arm/mach-s3c2410/mach-n30.c9
-rw-r--r--arch/arm/mach-s3c2410/mach-otom.c8
-rw-r--r--arch/arm/mach-s3c2410/mach-qt2410.c448
-rw-r--r--arch/arm/mach-s3c2410/mach-smdk2410.c8
-rw-r--r--arch/arm/mach-s3c2410/mach-vr1000.c6
-rw-r--r--arch/arm/mach-s3c2410/pm.c653
-rw-r--r--arch/arm/mach-s3c2410/s3c2410-clock.c276
-rw-r--r--arch/arm/mach-s3c2410/s3c2410-dma.c161
-rw-r--r--arch/arm/mach-s3c2410/s3c2410-gpio.c71
-rw-r--r--arch/arm/mach-s3c2410/s3c2410-irq.c48
-rw-r--r--arch/arm/mach-s3c2410/s3c2410-pm.c156
-rw-r--r--arch/arm/mach-s3c2410/s3c2410-sleep.S68
-rw-r--r--arch/arm/mach-s3c2410/s3c2410.c10
-rw-r--r--arch/arm/mach-s3c2410/sleep.S151
-rw-r--r--arch/arm/mach-s3c2410/usb-simtec.c2
-rw-r--r--arch/arm/mach-s3c2412/Kconfig58
-rw-r--r--arch/arm/mach-s3c2412/Makefile21
-rw-r--r--arch/arm/mach-s3c2412/clock.c (renamed from arch/arm/mach-s3c2410/s3c2412-clock.c)8
-rw-r--r--arch/arm/mach-s3c2412/dma.c (renamed from arch/arm/mach-s3c2410/s3c2412-dma.c)7
-rw-r--r--arch/arm/mach-s3c2412/irq.c (renamed from arch/arm/mach-s3c2410/s3c2412-irq.c)8
-rw-r--r--arch/arm/mach-s3c2412/mach-smdk2413.c (renamed from arch/arm/mach-s3c2410/mach-smdk2413.c)68
-rw-r--r--arch/arm/mach-s3c2412/mach-vstms.c (renamed from arch/arm/mach-s3c2410/mach-vstms.c)13
-rw-r--r--arch/arm/mach-s3c2412/pm.c (renamed from arch/arm/mach-s3c2410/s3c2412-pm.c)8
-rw-r--r--arch/arm/mach-s3c2412/s3c2412.c (renamed from arch/arm/mach-s3c2410/s3c2412.c)12
-rw-r--r--arch/arm/mach-s3c2440/Kconfig71
-rw-r--r--arch/arm/mach-s3c2440/Makefile23
-rw-r--r--arch/arm/mach-s3c2440/clock.c (renamed from arch/arm/mach-s3c2410/s3c2440-clock.c)6
-rw-r--r--arch/arm/mach-s3c2440/dma.c (renamed from arch/arm/mach-s3c2410/s3c2440-dma.c)51
-rw-r--r--arch/arm/mach-s3c2440/dsc.c (renamed from arch/arm/mach-s3c2410/s3c2440-dsc.c)6
-rw-r--r--arch/arm/mach-s3c2440/irq.c (renamed from arch/arm/mach-s3c2410/s3c2440-irq.c)8
-rw-r--r--arch/arm/mach-s3c2440/mach-anubis.c (renamed from arch/arm/mach-s3c2410/mach-anubis.c)8
-rw-r--r--arch/arm/mach-s3c2440/mach-nexcoder.c (renamed from arch/arm/mach-s3c2410/mach-nexcoder.c)12
-rw-r--r--arch/arm/mach-s3c2440/mach-osiris.c (renamed from arch/arm/mach-s3c2410/mach-osiris.c)8
-rw-r--r--arch/arm/mach-s3c2440/mach-rx3715.c (renamed from arch/arm/mach-s3c2410/mach-rx3715.c)11
-rw-r--r--arch/arm/mach-s3c2440/mach-smdk2440.c (renamed from arch/arm/mach-s3c2410/mach-smdk2440.c)17
-rw-r--r--arch/arm/mach-s3c2440/s3c2440.c (renamed from arch/arm/mach-s3c2410/s3c2440.c)8
-rw-r--r--arch/arm/mach-s3c2442/Kconfig27
-rw-r--r--arch/arm/mach-s3c2442/Makefile16
-rw-r--r--arch/arm/mach-s3c2442/clock.c (renamed from arch/arm/mach-s3c2410/s3c2442-clock.c)6
-rw-r--r--arch/arm/mach-s3c2442/s3c2442.c (renamed from arch/arm/mach-s3c2410/s3c2442.c)6
-rw-r--r--arch/arm/mach-s3c2443/Kconfig29
-rw-r--r--arch/arm/mach-s3c2443/Makefile20
-rw-r--r--arch/arm/mach-s3c2443/clock.c1007
-rw-r--r--arch/arm/mach-s3c2443/dma.c180
-rw-r--r--arch/arm/mach-s3c2443/irq.c290
-rw-r--r--arch/arm/mach-s3c2443/mach-smdk2443.c137
-rw-r--r--arch/arm/mach-s3c2443/s3c2443.c97
-rw-r--r--arch/arm/mm/Kconfig11
-rw-r--r--arch/arm/mm/Makefile2
-rw-r--r--arch/arm/mm/cache-l2x0.c104
-rw-r--r--arch/arm/mm/consistent.c17
-rw-r--r--arch/arm/mm/context.c12
-rw-r--r--arch/arm/mm/fault-armv.c2
-rw-r--r--arch/arm/mm/mmu.c3
-rw-r--r--arch/arm/mm/proc-v6.S22
-rw-r--r--arch/arm/mm/proc-xsc3.S151
-rw-r--r--arch/arm/mm/tlb-v6.S4
-rw-r--r--arch/arm/oprofile/Kconfig19
-rw-r--r--arch/arm/oprofile/Makefile4
-rw-r--r--arch/arm/oprofile/common.c8
-rw-r--r--arch/arm/oprofile/op_arm_model.h3
-rw-r--r--arch/arm/oprofile/op_model_arm11_core.c162
-rw-r--r--arch/arm/oprofile/op_model_arm11_core.h45
-rw-r--r--arch/arm/oprofile/op_model_mpcore.c296
-rw-r--r--arch/arm/oprofile/op_model_mpcore.h61
-rw-r--r--arch/arm/oprofile/op_model_v6.c67
-rw-r--r--arch/arm/plat-iop/Makefile30
-rw-r--r--arch/arm/plat-iop/cp6.c50
-rw-r--r--arch/arm/plat-iop/io.c58
-rw-r--r--arch/arm/plat-iop/pci.c6
-rw-r--r--arch/arm/plat-s3c24xx/Kconfig99
-rw-r--r--arch/arm/plat-s3c24xx/Makefile30
-rw-r--r--arch/arm/plat-s3c24xx/clock.c449
-rw-r--r--arch/arm/plat-s3c24xx/common-smdk.c (renamed from arch/arm/mach-s3c2410/common-smdk.c)8
-rw-r--r--arch/arm/plat-s3c24xx/cpu.c (renamed from arch/arm/mach-s3c2410/cpu.c)29
-rw-r--r--arch/arm/plat-s3c24xx/devs.c (renamed from arch/arm/mach-s3c2410/devs.c)21
-rw-r--r--arch/arm/plat-s3c24xx/dma.c1499
-rw-r--r--arch/arm/plat-s3c24xx/gpio.c188
-rw-r--r--arch/arm/plat-s3c24xx/irq.c801
-rw-r--r--arch/arm/plat-s3c24xx/pm-simtec.c (renamed from arch/arm/mach-s3c2410/pm-simtec.c)4
-rw-r--r--arch/arm/plat-s3c24xx/pm.c659
-rw-r--r--arch/arm/plat-s3c24xx/s3c244x-irq.c (renamed from arch/arm/mach-s3c2410/s3c244x-irq.c)8
-rw-r--r--arch/arm/plat-s3c24xx/s3c244x.c (renamed from arch/arm/mach-s3c2410/s3c244x.c)16
-rw-r--r--arch/arm/plat-s3c24xx/s3c244x.h (renamed from arch/arm/mach-s3c2410/s3c244x.h)2
-rw-r--r--arch/arm/plat-s3c24xx/sleep.S157
-rw-r--r--arch/arm/plat-s3c24xx/time.c (renamed from arch/arm/mach-s3c2410/time.c)6
-rw-r--r--arch/avr32/mach-at32ap/clock.c2
-rw-r--r--arch/avr32/mach-at32ap/clock.h2
-rw-r--r--arch/i386/kernel/acpi/boot.c5
-rw-r--r--arch/i386/pci/common.c88
-rw-r--r--arch/ia64/kernel/acpi.c4
-rw-r--r--arch/powerpc/Kconfig9
-rw-r--r--arch/powerpc/boot/dts/kuroboxHD.dts1
-rw-r--r--arch/powerpc/boot/dts/kuroboxHG.dts1
-rw-r--r--arch/powerpc/boot/dts/mpc7448hpc2.dts1
-rw-r--r--arch/powerpc/boot/dts/mpc8272ads.dts1
-rw-r--r--arch/powerpc/boot/dts/mpc8313erdb.dts62
-rw-r--r--arch/powerpc/boot/dts/mpc832x_mds.dts (renamed from arch/powerpc/boot/dts/mpc8323emds.dts)120
-rw-r--r--arch/powerpc/boot/dts/mpc8349emitx.dts60
-rw-r--r--arch/powerpc/boot/dts/mpc8349emitxgp.dts39
-rw-r--r--arch/powerpc/boot/dts/mpc834x_mds.dts164
-rw-r--r--arch/powerpc/boot/dts/mpc836x_mds.dts (renamed from arch/powerpc/boot/dts/mpc8360emds.dts)124
-rw-r--r--arch/powerpc/boot/dts/mpc8540ads.dts142
-rw-r--r--arch/powerpc/boot/dts/mpc8541cds.dts108
-rw-r--r--arch/powerpc/boot/dts/mpc8548cds.dts129
-rw-r--r--arch/powerpc/boot/dts/mpc8555cds.dts108
-rw-r--r--arch/powerpc/boot/dts/mpc8560ads.dts158
-rw-r--r--arch/powerpc/boot/dts/mpc8568mds.dts96
-rw-r--r--arch/powerpc/boot/dts/mpc8641_hpcn.dts194
-rw-r--r--arch/powerpc/boot/dts/mpc866ads.dts1
-rw-r--r--arch/powerpc/boot/dts/mpc885ads.dts1
-rw-r--r--arch/powerpc/configs/cell_defconfig1
-rw-r--r--arch/powerpc/configs/mpc832x_mds_defconfig (renamed from arch/powerpc/configs/mpc832xemds_defconfig)0
-rw-r--r--arch/powerpc/configs/mpc836x_mds_defconfig (renamed from arch/powerpc/configs/mpc8360emds_defconfig)29
-rw-r--r--arch/powerpc/configs/mpc8568mds_defconfig32
-rw-r--r--arch/powerpc/configs/ppc64_defconfig4
-rw-r--r--arch/powerpc/configs/pseries_defconfig4
-rw-r--r--arch/powerpc/kernel/prom.c1
-rw-r--r--arch/powerpc/kernel/prom_parse.c40
-rw-r--r--arch/powerpc/mm/pgtable_64.c2
-rw-r--r--arch/powerpc/platforms/83xx/Kconfig8
-rw-r--r--arch/powerpc/platforms/83xx/Makefile2
-rw-r--r--arch/powerpc/platforms/83xx/mpc8313_rdb.c11
-rw-r--r--arch/powerpc/platforms/83xx/mpc832x_mds.c65
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_itx.c23
-rw-r--r--arch/powerpc/platforms/83xx/mpc834x_mds.c27
-rw-r--r--arch/powerpc/platforms/83xx/mpc836x_mds.c (renamed from arch/powerpc/platforms/83xx/mpc8360e_pb.c)97
-rw-r--r--arch/powerpc/platforms/85xx/Kconfig8
-rw-r--r--arch/powerpc/platforms/85xx/Makefile2
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_ads.c14
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_cds.c15
-rw-r--r--arch/powerpc/platforms/85xx/mpc85xx_mds.c (renamed from arch/powerpc/platforms/85xx/mpc8568_mds.c)46
-rw-r--r--arch/powerpc/platforms/86xx/mpc86xx_hpcn.c9
-rw-r--r--arch/powerpc/platforms/celleb/Makefile3
-rw-r--r--arch/powerpc/platforms/celleb/setup.c2
-rw-r--r--arch/powerpc/platforms/ps3/Kconfig10
-rw-r--r--arch/powerpc/platforms/ps3/setup.c27
-rw-r--r--arch/powerpc/platforms/pseries/Makefile2
-rw-r--r--arch/powerpc/platforms/pseries/power.c87
-rw-r--r--arch/powerpc/platforms/pseries/pseries.h7
-rw-r--r--arch/powerpc/platforms/pseries/setup.c30
-rw-r--r--arch/powerpc/sysdev/Makefile1
-rw-r--r--arch/powerpc/sysdev/fsl_soc.c19
-rw-r--r--arch/powerpc/sysdev/mpic.c2
-rw-r--r--arch/powerpc/sysdev/pmi.c305
-rw-r--r--arch/powerpc/sysdev/qe_lib/ucc_fast.c163
-rw-r--r--arch/powerpc/sysdev/qe_lib/ucc_slow.c137
-rw-r--r--arch/x86_64/kernel/early-quirks.c4
-rw-r--r--drivers/acpi/Kconfig10
-rw-r--r--drivers/acpi/Makefile1
-rw-r--r--drivers/acpi/ac.c9
-rw-r--r--drivers/acpi/acpi_memhotplug.c9
-rw-r--r--drivers/acpi/asus_acpi.c20
-rw-r--r--drivers/acpi/battery.c24
-rw-r--r--drivers/acpi/bay.c107
-rw-r--r--drivers/acpi/bus.c30
-rw-r--r--drivers/acpi/button.c7
-rw-r--r--drivers/acpi/cm_sbs.c2
-rw-r--r--drivers/acpi/container.c9
-rw-r--r--drivers/acpi/debug.c2
-rw-r--r--drivers/acpi/dispatcher/dsmethod.c12
-rw-r--r--drivers/acpi/dock.c8
-rw-r--r--drivers/acpi/ec.c9
-rw-r--r--drivers/acpi/event.c2
-rw-r--r--drivers/acpi/events/evgpe.c11
-rw-r--r--drivers/acpi/events/evmisc.c11
-rw-r--r--drivers/acpi/executer/exdump.c2
-rw-r--r--drivers/acpi/executer/exmutex.c36
-rw-r--r--drivers/acpi/fan.c9
-rw-r--r--drivers/acpi/glue.c62
-rw-r--r--drivers/acpi/hardware/hwsleep.c13
-rw-r--r--drivers/acpi/hotkey.c1042
-rw-r--r--drivers/acpi/i2c_ec.c5
-rw-r--r--drivers/acpi/ibm_acpi.c18
-rw-r--r--drivers/acpi/numa.c18
-rw-r--r--drivers/acpi/osl.c35
-rw-r--r--drivers/acpi/pci_bind.c2
-rw-r--r--drivers/acpi/pci_irq.c2
-rw-r--r--drivers/acpi/pci_link.c5
-rw-r--r--drivers/acpi/pci_root.c5
-rw-r--r--drivers/acpi/power.c156
-rw-r--r--drivers/acpi/processor_core.c13
-rw-r--r--drivers/acpi/processor_idle.c11
-rw-r--r--drivers/acpi/processor_perflib.c3
-rw-r--r--drivers/acpi/processor_thermal.c3
-rw-r--r--drivers/acpi/processor_throttling.c3
-rw-r--r--drivers/acpi/sbs.c25
-rw-r--r--drivers/acpi/scan.c3
-rw-r--r--drivers/acpi/sleep/main.c3
-rw-r--r--drivers/acpi/system.c3
-rw-r--r--drivers/acpi/tables.c41
-rw-r--r--drivers/acpi/tables/tbxface.c9
-rw-r--r--drivers/acpi/thermal.c37
-rw-r--r--drivers/acpi/toshiba_acpi.c6
-rw-r--r--drivers/acpi/utilities/utdelete.c1
-rw-r--r--drivers/acpi/utils.c2
-rw-r--r--drivers/acpi/video.c9
-rw-r--r--drivers/base/bus.c22
-rw-r--r--drivers/base/class.c3
-rw-r--r--drivers/i2c/busses/i2c-iop3xx.c2
-rw-r--r--drivers/i2c/busses/i2c-pxa.c241
-rw-r--r--drivers/ide/Kconfig8
-rw-r--r--drivers/ide/Makefile1
-rw-r--r--drivers/ide/arm/icside.c25
-rw-r--r--drivers/ide/arm/rapide.c2
-rw-r--r--drivers/ide/cris/ide-cris.c34
-rw-r--r--drivers/ide/h8300/ide-h8300.c4
-rw-r--r--drivers/ide/ide-cd.c44
-rw-r--r--drivers/ide/ide-disk.c14
-rw-r--r--drivers/ide/ide-dma.c105
-rw-r--r--drivers/ide/ide-floppy.c29
-rw-r--r--drivers/ide/ide-io.c15
-rw-r--r--drivers/ide/ide-iops.c34
-rw-r--r--drivers/ide/ide-lib.c20
-rw-r--r--drivers/ide/ide-probe.c4
-rw-r--r--drivers/ide/ide-tape.c12
-rw-r--r--drivers/ide/ide.c24
-rw-r--r--drivers/ide/legacy/buddha.c2
-rw-r--r--drivers/ide/legacy/gayle.c2
-rw-r--r--drivers/ide/legacy/ht6560b.c14
-rw-r--r--drivers/ide/legacy/macide.c2
-rw-r--r--drivers/ide/legacy/q40ide.c2
-rw-r--r--drivers/ide/mips/au1xxx-ide.c41
-rw-r--r--drivers/ide/mips/swarm.c2
-rw-r--r--drivers/ide/pci/aec62xx.c32
-rw-r--r--drivers/ide/pci/alim15x3.c15
-rw-r--r--drivers/ide/pci/amd74xx.c5
-rw-r--r--drivers/ide/pci/atiixp.c41
-rw-r--r--drivers/ide/pci/cmd64x.c47
-rw-r--r--drivers/ide/pci/cs5520.c5
-rw-r--r--drivers/ide/pci/cs5530.c41
-rw-r--r--drivers/ide/pci/cs5535.c19
-rw-r--r--drivers/ide/pci/cy82c693.c33
-rw-r--r--drivers/ide/pci/hpt34x.c42
-rw-r--r--drivers/ide/pci/hpt366.c24
-rw-r--r--drivers/ide/pci/it8213.c14
-rw-r--r--drivers/ide/pci/it821x.c14
-rw-r--r--drivers/ide/pci/jmicron.c14
-rw-r--r--drivers/ide/pci/ns87415.c13
-rw-r--r--drivers/ide/pci/opti621.c63
-rw-r--r--drivers/ide/pci/pdc202xx_new.c28
-rw-r--r--drivers/ide/pci/pdc202xx_old.c104
-rw-r--r--drivers/ide/pci/piix.c119
-rw-r--r--drivers/ide/pci/sc1200.c11
-rw-r--r--drivers/ide/pci/serverworks.c59
-rw-r--r--drivers/ide/pci/sgiioc4.c125
-rw-r--r--drivers/ide/pci/siimage.c113
-rw-r--r--drivers/ide/pci/sis5513.c59
-rw-r--r--drivers/ide/pci/sl82c105.c39
-rw-r--r--drivers/ide/pci/slc90e66.c22
-rw-r--r--drivers/ide/pci/tc86c001.c46
-rw-r--r--drivers/ide/pci/triflex.c24
-rw-r--r--drivers/ide/pci/trm290.c42
-rw-r--r--drivers/ide/pci/via82cxxx.c5
-rw-r--r--drivers/ide/ppc/pmac.c16
-rw-r--r--drivers/ide/ppc/scc_pata.c831
-rw-r--r--drivers/ieee1394/ieee1394-ioctl.h2
-rw-r--r--drivers/ieee1394/ieee1394_core.c43
-rw-r--r--drivers/ieee1394/ieee1394_core.h3
-rw-r--r--drivers/ieee1394/nodemgr.c3
-rw-r--r--drivers/ieee1394/raw1394.c20
-rw-r--r--drivers/ieee1394/raw1394.h10
-rw-r--r--drivers/infiniband/core/Makefile2
-rw-r--r--drivers/infiniband/core/cma.c359
-rw-r--r--drivers/infiniband/core/fmr_pool.c4
-rw-r--r--drivers/infiniband/core/iwcm.c47
-rw-r--r--drivers/infiniband/core/multicast.c837
-rw-r--r--drivers/infiniband/core/sa.h66
-rw-r--r--drivers/infiniband/core/sa_query.c30
-rw-r--r--drivers/infiniband/core/sysfs.c2
-rw-r--r--drivers/infiniband/core/ucma.c204
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_dbg.c1
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_hal.c1
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_hal.h1
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_resource.c1
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_resource.h1
-rw-r--r--drivers/infiniband/hw/cxgb3/cxio_wr.h1
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch.c1
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch.h1
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_cm.c1
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_cm.h1
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_cq.c1
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_ev.c1
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_mem.c1
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_provider.c1
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_provider.h1
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_qp.c3
-rw-r--r--drivers/infiniband/hw/cxgb3/iwch_user.h1
-rw-r--r--drivers/infiniband/hw/ehca/Kconfig8
-rw-r--r--drivers/infiniband/hw/ehca/ehca_classes.h19
-rw-r--r--drivers/infiniband/hw/ehca/ehca_eq.c1
-rw-r--r--drivers/infiniband/hw/ehca/ehca_hca.c3
-rw-r--r--drivers/infiniband/hw/ehca/ehca_irq.c307
-rw-r--r--drivers/infiniband/hw/ehca/ehca_irq.h1
-rw-r--r--drivers/infiniband/hw/ehca/ehca_main.c32
-rw-r--r--drivers/infiniband/hw/ehca/ipz_pt_fn.h11
-rw-r--r--drivers/infiniband/hw/ipath/ipath_dma.c4
-rw-r--r--drivers/infiniband/hw/mthca/mthca_memfree.c4
-rw-r--r--drivers/infiniband/hw/mthca/mthca_qp.c5
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_cm.c4
-rw-r--r--drivers/infiniband/ulp/ipoib/ipoib_multicast.c195
-rw-r--r--drivers/misc/Kconfig15
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/asus-laptop.c5
-rw-r--r--drivers/misc/sony-laptop.c562
-rw-r--r--drivers/mmc/at91_mci.c46
-rw-r--r--drivers/pci/pci-driver.c1
-rw-r--r--drivers/pci/pci-sysfs.c11
-rw-r--r--drivers/pci/pci.c12
-rw-r--r--drivers/pci/setup-bus.c27
-rw-r--r--drivers/pci/setup-irq.c18
-rw-r--r--drivers/pcmcia/at91_cf.c2
-rw-r--r--drivers/pcmcia/soc_common.c8
-rw-r--r--drivers/pnp/pnpacpi/Kconfig16
-rw-r--r--drivers/ps3/Makefile1
-rw-r--r--drivers/ps3/sys-manager.c604
-rw-r--r--drivers/ps3/vuart.c398
-rw-r--r--drivers/ps3/vuart.h59
-rw-r--r--drivers/scsi/ide-scsi.c8
-rw-r--r--drivers/scsi/sd.c11
-rw-r--r--drivers/serial/Kconfig3
-rw-r--r--drivers/serial/atmel_serial.c3
-rw-r--r--drivers/serial/cpm_uart/cpm_uart_cpm2.c2
-rw-r--r--drivers/serial/imx.c14
-rw-r--r--drivers/serial/mpc52xx_uart.c4
-rw-r--r--drivers/serial/serial_cs.c5
-rw-r--r--drivers/usb/Makefile1
-rw-r--r--drivers/usb/atm/ueagle-atm.c1
-rw-r--r--drivers/usb/class/cdc-acm.c33
-rw-r--r--drivers/usb/core/devices.c9
-rw-r--r--drivers/usb/core/devio.c4
-rw-r--r--drivers/usb/core/driver.c1
-rw-r--r--drivers/usb/core/endpoint.c2
-rw-r--r--drivers/usb/core/generic.c2
-rw-r--r--drivers/usb/core/hub.c31
-rw-r--r--drivers/usb/core/message.c22
-rw-r--r--drivers/usb/core/otg_whitelist.h2
-rw-r--r--drivers/usb/core/sysfs.c2
-rw-r--r--drivers/usb/gadget/at91_udc.c19
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.c16
-rw-r--r--drivers/usb/gadget/pxa2xx_udc.h15
-rw-r--r--drivers/usb/gadget/serial.c1
-rw-r--r--drivers/usb/host/ehci-hcd.c36
-rw-r--r--drivers/usb/host/ehci-hub.c2
-rw-r--r--drivers/usb/host/isp116x-hcd.c2
-rw-r--r--drivers/usb/host/ohci-at91.c50
-rw-r--r--drivers/usb/host/ohci-hcd.c18
-rw-r--r--drivers/usb/input/hid-core.c8
-rw-r--r--drivers/usb/misc/Kconfig11
-rw-r--r--drivers/usb/misc/Makefile1
-rw-r--r--drivers/usb/misc/appledisplay.c4
-rw-r--r--drivers/usb/misc/berry_charge.c140
-rw-r--r--drivers/usb/net/Kconfig11
-rw-r--r--drivers/usb/net/asix.c2
-rw-r--r--drivers/usb/net/cdc_subset.c21
-rw-r--r--drivers/usb/net/usbnet.c29
-rw-r--r--drivers/usb/serial/airprime.c35
-rw-r--r--drivers/usb/serial/cp2101.c1
-rw-r--r--drivers/usb/serial/generic.c102
-rw-r--r--drivers/usb/serial/option.c4
-rw-r--r--drivers/usb/serial/pl2303.c1
-rw-r--r--drivers/usb/serial/pl2303.h5
-rw-r--r--drivers/usb/storage/scsiglue.c6
-rw-r--r--drivers/usb/storage/unusual_devs.h26
-rw-r--r--drivers/usb/usb-skeleton.c10
-rw-r--r--fs/debugfs/file.c12
-rw-r--r--fs/debugfs/inode.c82
-rw-r--r--fs/partitions/check.c9
-rw-r--r--fs/sysfs/file.c2
-rw-r--r--include/acpi/acinterp.h3
-rw-r--r--include/acpi/acobject.h2
-rw-r--r--include/acpi/acpi_drivers.h40
-rw-r--r--include/acpi/acpiosxf.h6
-rw-r--r--include/asm-arm/.gitignore2
-rw-r--r--include/asm-arm/arch-at91/at91_aic.h (renamed from include/asm-arm/arch-at91rm9200/at91_aic.h)2
-rw-r--r--include/asm-arm/arch-at91/at91_dbgu.h (renamed from include/asm-arm/arch-at91rm9200/at91_dbgu.h)16
-rw-r--r--include/asm-arm/arch-at91/at91_ecc.h (renamed from include/asm-arm/arch-at91rm9200/at91_ecc.h)2
-rw-r--r--include/asm-arm/arch-at91/at91_lcdc.h (renamed from include/asm-arm/arch-at91rm9200/at91_lcdc.h)2
-rw-r--r--include/asm-arm/arch-at91/at91_mci.h (renamed from include/asm-arm/arch-at91rm9200/at91_mci.h)2
-rw-r--r--include/asm-arm/arch-at91/at91_pio.h (renamed from include/asm-arm/arch-at91rm9200/at91_pio.h)2
-rw-r--r--include/asm-arm/arch-at91/at91_pit.h (renamed from include/asm-arm/arch-at91rm9200/at91_pit.h)2
-rw-r--r--include/asm-arm/arch-at91/at91_pmc.h (renamed from include/asm-arm/arch-at91rm9200/at91_pmc.h)2
-rw-r--r--include/asm-arm/arch-at91/at91_rstc.h (renamed from include/asm-arm/arch-at91rm9200/at91_rstc.h)5
-rw-r--r--include/asm-arm/arch-at91/at91_rtc.h (renamed from include/asm-arm/arch-at91rm9200/at91_rtc.h)2
-rw-r--r--include/asm-arm/arch-at91/at91_rtt.h (renamed from include/asm-arm/arch-at91rm9200/at91_rtt.h)2
-rw-r--r--include/asm-arm/arch-at91/at91_shdwc.h (renamed from include/asm-arm/arch-at91rm9200/at91_shdwc.h)2
-rw-r--r--include/asm-arm/arch-at91/at91_spi.h (renamed from include/asm-arm/arch-at91rm9200/at91_spi.h)2
-rw-r--r--include/asm-arm/arch-at91/at91_ssc.h (renamed from include/asm-arm/arch-at91rm9200/at91_ssc.h)2
-rw-r--r--include/asm-arm/arch-at91/at91_st.h (renamed from include/asm-arm/arch-at91rm9200/at91_st.h)2
-rw-r--r--include/asm-arm/arch-at91/at91_tc.h (renamed from include/asm-arm/arch-at91rm9200/at91_tc.h)2
-rw-r--r--include/asm-arm/arch-at91/at91_twi.h (renamed from include/asm-arm/arch-at91rm9200/at91_twi.h)2
-rw-r--r--include/asm-arm/arch-at91/at91_wdt.h (renamed from include/asm-arm/arch-at91rm9200/at91_wdt.h)2
-rw-r--r--include/asm-arm/arch-at91/at91rm9200.h (renamed from include/asm-arm/arch-at91rm9200/at91rm9200.h)2
-rw-r--r--include/asm-arm/arch-at91/at91rm9200_emac.h (renamed from include/asm-arm/arch-at91rm9200/at91rm9200_emac.h)2
-rw-r--r--include/asm-arm/arch-at91/at91rm9200_mc.h (renamed from include/asm-arm/arch-at91rm9200/at91rm9200_mc.h)2
-rw-r--r--include/asm-arm/arch-at91/at91sam9260.h (renamed from include/asm-arm/arch-at91rm9200/at91sam9260.h)6
-rw-r--r--include/asm-arm/arch-at91/at91sam9260_matrix.h (renamed from include/asm-arm/arch-at91rm9200/at91sam9260_matrix.h)4
-rw-r--r--include/asm-arm/arch-at91/at91sam9261.h (renamed from include/asm-arm/arch-at91rm9200/at91sam9261.h)2
-rw-r--r--include/asm-arm/arch-at91/at91sam9261_matrix.h (renamed from include/asm-arm/arch-at91rm9200/at91sam9261_matrix.h)2
-rw-r--r--include/asm-arm/arch-at91/at91sam9263.h131
-rw-r--r--include/asm-arm/arch-at91/at91sam9263_matrix.h129
-rw-r--r--include/asm-arm/arch-at91/at91sam926x_mc.h (renamed from include/asm-arm/arch-at91rm9200/at91sam926x_mc.h)9
-rw-r--r--include/asm-arm/arch-at91/board.h (renamed from include/asm-arm/arch-at91rm9200/board.h)9
-rw-r--r--include/asm-arm/arch-at91/cpu.h (renamed from include/asm-arm/arch-at91rm9200/cpu.h)26
-rw-r--r--include/asm-arm/arch-at91/debug-macro.S39
-rw-r--r--include/asm-arm/arch-at91/dma.h (renamed from include/asm-arm/arch-at91rm9200/dma.h)2
-rw-r--r--include/asm-arm/arch-at91/entry-macro.S26
-rw-r--r--include/asm-arm/arch-at91/gpio.h (renamed from include/asm-arm/arch-at91rm9200/gpio.h)61
-rw-r--r--include/asm-arm/arch-at91/hardware.h (renamed from include/asm-arm/arch-at91rm9200/hardware.h)12
-rw-r--r--include/asm-arm/arch-at91/io.h (renamed from include/asm-arm/arch-at91rm9200/io.h)2
-rw-r--r--include/asm-arm/arch-at91/irqs.h (renamed from include/asm-arm/arch-at91rm9200/irqs.h)6
-rw-r--r--include/asm-arm/arch-at91/memory.h (renamed from include/asm-arm/arch-at91rm9200/memory.h)2
-rw-r--r--include/asm-arm/arch-at91/system.h (renamed from include/asm-arm/arch-at91rm9200/system.h)2
-rw-r--r--include/asm-arm/arch-at91/timex.h (renamed from include/asm-arm/arch-at91rm9200/timex.h)7
-rw-r--r--include/asm-arm/arch-at91/uncompress.h (renamed from include/asm-arm/arch-at91rm9200/uncompress.h)2
-rw-r--r--include/asm-arm/arch-at91/vmalloc.h (renamed from include/asm-arm/arch-at91rm9200/vmalloc.h)2
-rw-r--r--include/asm-arm/arch-at91rm9200/at91_pdc.h36
-rw-r--r--include/asm-arm/arch-at91rm9200/debug-macro.S39
-rw-r--r--include/asm-arm/arch-at91rm9200/entry-macro.S26
-rw-r--r--include/asm-arm/arch-ep93xx/ep93xx-regs.h5
-rw-r--r--include/asm-arm/arch-ep93xx/irqs.h8
-rw-r--r--include/asm-arm/arch-ep93xx/platform.h1
-rw-r--r--include/asm-arm/arch-imx/entry-macro.S18
-rw-r--r--include/asm-arm/arch-iop32x/io.h10
-rw-r--r--include/asm-arm/arch-iop33x/io.h9
-rw-r--r--include/asm-arm/arch-ixp4xx/avila.h39
-rw-r--r--include/asm-arm/arch-ixp4xx/hardware.h1
-rw-r--r--include/asm-arm/arch-ixp4xx/irqs.h9
-rw-r--r--include/asm-arm/arch-ixp4xx/udc.h22
-rw-r--r--include/asm-arm/arch-ns9xxx/board.h18
-rw-r--r--include/asm-arm/arch-ns9xxx/clock.h37
-rw-r--r--include/asm-arm/arch-ns9xxx/debug-macro.S22
-rw-r--r--include/asm-arm/arch-ns9xxx/dma.h14
-rw-r--r--include/asm-arm/arch-ns9xxx/entry-macro.S22
-rw-r--r--include/asm-arm/arch-ns9xxx/hardware.h67
-rw-r--r--include/asm-arm/arch-ns9xxx/io.h20
-rw-r--r--include/asm-arm/arch-ns9xxx/irqs.h85
-rw-r--r--include/asm-arm/arch-ns9xxx/memory.h27
-rw-r--r--include/asm-arm/arch-ns9xxx/processor.h18
-rw-r--r--include/asm-arm/arch-ns9xxx/regs-bbu.h21
-rw-r--r--include/asm-arm/arch-ns9xxx/regs-board-a9m9750dev.h24
-rw-r--r--include/asm-arm/arch-ns9xxx/regs-mem.h135
-rw-r--r--include/asm-arm/arch-ns9xxx/regs-sys.h157
-rw-r--r--include/asm-arm/arch-ns9xxx/system.h34
-rw-r--r--include/asm-arm/arch-ns9xxx/timex.h20
-rw-r--r--include/asm-arm/arch-ns9xxx/uncompress.h35
-rw-r--r--include/asm-arm/arch-ns9xxx/vmalloc.h16
-rw-r--r--include/asm-arm/arch-pxa/pxa-regs.h24
-rw-r--r--include/asm-arm/arch-pxa/udc.h30
-rw-r--r--include/asm-arm/arch-realview/hardware.h2
-rw-r--r--include/asm-arm/arch-realview/irqs.h17
-rw-r--r--include/asm-arm/arch-realview/platform.h18
-rw-r--r--include/asm-arm/arch-realview/scu.h8
-rw-r--r--include/asm-arm/arch-s3c2410/dma.h36
-rw-r--r--include/asm-arm/arch-s3c2410/irqs.h74
-rw-r--r--include/asm-arm/arch-s3c2410/regs-adc.h2
-rw-r--r--include/asm-arm/arch-s3c2410/regs-gpio.h32
-rw-r--r--include/asm-arm/arch-s3c2410/regs-s3c2443-clock.h194
-rw-r--r--include/asm-arm/arch-s3c2410/regs-serial.h13
-rw-r--r--include/asm-arm/arch-s3c2410/reset.h22
-rw-r--r--include/asm-arm/arch-s3c2410/system.h15
-rw-r--r--include/asm-arm/arch-s3c2410/udc.h36
-rw-r--r--include/asm-arm/cacheflush.h49
-rw-r--r--include/asm-arm/checksum.h56
-rw-r--r--include/asm-arm/device.h10
-rw-r--r--include/asm-arm/dma-mapping.h18
-rw-r--r--include/asm-arm/domain.h1
-rw-r--r--include/asm-arm/hardware/arm_scu.h2
-rw-r--r--include/asm-arm/hardware/cache-l2x0.h56
-rw-r--r--include/asm-arm/hardware/gic.h5
-rw-r--r--include/asm-arm/hardware/iop3xx.h15
-rw-r--r--include/asm-arm/hardware/sa1111.h93
-rw-r--r--include/asm-arm/kexec.h30
-rw-r--r--include/asm-arm/pgtable.h54
-rw-r--r--include/asm-arm/plat-s3c24xx/clock.h (renamed from arch/arm/mach-s3c2410/clock.h)2
-rw-r--r--include/asm-arm/plat-s3c24xx/common-smdk.h (renamed from arch/arm/mach-s3c2410/common-smdk.h)2
-rw-r--r--include/asm-arm/plat-s3c24xx/cpu.h (renamed from arch/arm/mach-s3c2410/cpu.h)3
-rw-r--r--include/asm-arm/plat-s3c24xx/devs.h (renamed from arch/arm/mach-s3c2410/devs.h)2
-rw-r--r--include/asm-arm/plat-s3c24xx/dma.h (renamed from arch/arm/mach-s3c2410/dma.h)34
-rw-r--r--include/asm-arm/plat-s3c24xx/irq.h (renamed from arch/arm/mach-s3c2410/irq.h)2
-rw-r--r--include/asm-arm/plat-s3c24xx/pm.h (renamed from arch/arm/mach-s3c2410/pm.h)2
-rw-r--r--include/asm-arm/plat-s3c24xx/s3c2400.h (renamed from arch/arm/mach-s3c2410/s3c2400.h)2
-rw-r--r--include/asm-arm/plat-s3c24xx/s3c2410.h (renamed from arch/arm/mach-s3c2410/s3c2410.h)2
-rw-r--r--include/asm-arm/plat-s3c24xx/s3c2412.h (renamed from arch/arm/mach-s3c2410/s3c2412.h)2
-rw-r--r--include/asm-arm/plat-s3c24xx/s3c2440.h (renamed from arch/arm/mach-s3c2410/s3c2440.h)2
-rw-r--r--include/asm-arm/plat-s3c24xx/s3c2442.h (renamed from arch/arm/mach-s3c2410/s3c2442.h)2
-rw-r--r--include/asm-arm/plat-s3c24xx/s3c2443.h32
-rw-r--r--include/asm-arm/system.h62
-rw-r--r--include/asm-arm/tlbflush.h50
-rw-r--r--include/asm-arm/unistd.h1
-rw-r--r--include/asm-avr32/arch-at32ap/at91_pdc.h36
-rw-r--r--include/asm-i386/acpi.h1
-rw-r--r--include/asm-powerpc/atomic.h40
-rw-r--r--include/asm-powerpc/dcr-native.h4
-rw-r--r--include/asm-powerpc/pmi.h67
-rw-r--r--include/asm-powerpc/prom.h2
-rw-r--r--include/asm-powerpc/ps3.h27
-rw-r--r--include/asm-powerpc/ucc_slow.h8
-rw-r--r--include/linux/acpi.h8
-rw-r--r--include/linux/atmel_pdc.h36
-rw-r--r--include/linux/debugfs.h10
-rw-r--r--include/linux/device.h1
-rw-r--r--include/linux/ide.h28
-rw-r--r--include/linux/kexec.h1
-rw-r--r--include/linux/kmod.h2
-rw-r--r--include/linux/module.h53
-rw-r--r--include/linux/moduleparam.h12
-rw-r--r--include/linux/pci.h3
-rw-r--r--include/linux/usb.h2
-rw-r--r--include/linux/usb/cdc.h7
-rw-r--r--include/linux/usb/ch9.h20
-rw-r--r--include/linux/usb/serial.h6
-rw-r--r--include/linux/usb_usual.h4
-rw-r--r--include/linux/usbdevice_fs.h4
-rw-r--r--include/pcmcia/ciscode.h1
-rw-r--r--include/rdma/ib_addr.h6
-rw-r--r--include/rdma/ib_sa.h159
-rw-r--r--include/rdma/rdma_cm.h21
-rw-r--r--include/rdma/rdma_cm_ib.h4
-rw-r--r--include/rdma/rdma_user_cm.h13
-rw-r--r--include/scsi/scsi_device.h1
-rw-r--r--kernel/kmod.c120
-rw-r--r--kernel/module.c47
-rw-r--r--kernel/params.c29
-rw-r--r--lib/kobject.c3
-rw-r--r--sound/arm/aaci.c315
-rw-r--r--sound/arm/aaci.h41
635 files changed, 24386 insertions, 10530 deletions
diff --git a/Documentation/acpi-hotkey.txt b/Documentation/acpi-hotkey.txt
deleted file mode 100644
index 38040fa37649..000000000000
--- a/Documentation/acpi-hotkey.txt
+++ /dev/null
@@ -1,38 +0,0 @@
1driver/acpi/hotkey.c implement:
21. /proc/acpi/hotkey/event_config
3(event based hotkey or event config interface):
4a. add a event based hotkey(event) :
5echo "0:bus::action:method:num:num" > event_config
6
7b. delete a event based hotkey(event):
8echo "1:::::num:num" > event_config
9
10c. modify a event based hotkey(event):
11echo "2:bus::action:method:num:num" > event_config
12
132. /proc/acpi/hotkey/poll_config
14(polling based hotkey or event config interface):
15a.add a polling based hotkey(event) :
16echo "0:bus:method:action:method:num" > poll_config
17this adding command will create a proc file
18/proc/acpi/hotkey/method, which is used to get
19result of polling.
20
21b.delete a polling based hotkey(event):
22echo "1:::::num" > event_config
23
24c.modify a polling based hotkey(event):
25echo "2:bus:method:action:method:num" > poll_config
26
273./proc/acpi/hotkey/action
28(interface to call aml method associated with a
29specific hotkey(event))
30echo "event_num:event_type:event_argument" >
31 /proc/acpi/hotkey/action.
32The result of the execution of this aml method is
33attached to /proc/acpi/hotkey/poll_method, which is dynamically
34created. Please use command "cat /proc/acpi/hotkey/polling_method"
35to retrieve it.
36
37Note: Use cmdline "acpi_generic_hotkey" to over-ride
38platform-specific with generic driver.
diff --git a/Documentation/arm/Samsung-S3C24XX/DMA.txt b/Documentation/arm/Samsung-S3C24XX/DMA.txt
new file mode 100644
index 000000000000..37f4edcc5d87
--- /dev/null
+++ b/Documentation/arm/Samsung-S3C24XX/DMA.txt
@@ -0,0 +1,46 @@
1 S3C2410 DMA
2 ===========
3
4Introduction
5------------
6
7 The kernel provides an interface to manage DMA transfers
8 using the DMA channels in the cpu, so that the central
9 duty of managing channel mappings, and programming the
10 channel generators is in one place.
11
12
13DMA Channel Ordering
14--------------------
15
16 Many of the range do not have connections for the DMA
17 channels to all sources, which means that some devices
18 have a restricted number of channels that can be used.
19
20 To allow flexibilty for each cpu type and board, the
21 dma code can be given an dma ordering structure which
22 allows the order of channel search to be specified, as
23 well as allowing the prohibition of certain claims.
24
25 struct s3c24xx_dma_order has a list of channels, and
26 each channel within has a slot for a list of dma
27 channel numbers. The slots are searched in order, for
28 the presence of a dma channel number with DMA_CH_VALID
29 orred in.
30
31 If the order has the flag DMA_CH_NEVER set, then after
32 checking the channel list, the system will return no
33 found channel, thus denying the request.
34
35 A board support file can call s3c24xx_dma_order_set()
36 to register an complete ordering set. The routine will
37 copy the data, so the original can be discared with
38 __initdata.
39
40
41Authour
42-------
43
44Ben Dooks,
45Copyright (c) 2007 Ben Dooks, Simtec Electronics
46Licensed under the GPL v2
diff --git a/Documentation/arm/Samsung-S3C24XX/Overview.txt b/Documentation/arm/Samsung-S3C24XX/Overview.txt
index 28d014714ab8..c31b76fa66c4 100644
--- a/Documentation/arm/Samsung-S3C24XX/Overview.txt
+++ b/Documentation/arm/Samsung-S3C24XX/Overview.txt
@@ -8,13 +8,10 @@ Introduction
8 8
9 The Samsung S3C24XX range of ARM9 System-on-Chip CPUs are supported 9 The Samsung S3C24XX range of ARM9 System-on-Chip CPUs are supported
10 by the 's3c2410' architecture of ARM Linux. Currently the S3C2410, 10 by the 's3c2410' architecture of ARM Linux. Currently the S3C2410,
11 S3C2440 and S3C2442 devices are supported. 11 S3C2412, S3C2413, S3C2440 and S3C2442 devices are supported.
12 12
13 Support for the S3C2400 series is in progress. 13 Support for the S3C2400 series is in progress.
14 14
15 Support for the S3C2412 and S3C2413 CPUs is being merged.
16
17
18Configuration 15Configuration
19------------- 16-------------
20 17
@@ -26,6 +23,22 @@ Configuration
26 please check the machine specific documentation. 23 please check the machine specific documentation.
27 24
28 25
26Layout
27------
28
29 The core support files are located in the platform code contained in
30 arch/arm/plat-s3c24xx with headers in include/asm-arm/plat-s3c24xx.
31 This directory should be kept to items shared between the platform
32 code (arch/arm/plat-s3c24xx) and the arch/arm/mach-s3c24* code.
33
34 Each cpu has a directory with the support files for it, and the
35 machines that carry the device. For example S3C2410 is contained
36 in arch/arm/mach-s3c2410 and S3C2440 in arch/arm/mach-s3c2440
37
38 Register, kernel and platform data definitions are held in the
39 include/asm-arm/arch-s3c2410 directory.
40
41
29Machines 42Machines
30-------- 43--------
31 44
diff --git a/Documentation/feature-removal-schedule.txt b/Documentation/feature-removal-schedule.txt
index c585aa8d62b4..28f897fd3674 100644
--- a/Documentation/feature-removal-schedule.txt
+++ b/Documentation/feature-removal-schedule.txt
@@ -253,29 +253,6 @@ Who: Venkatesh Pallipadi <venkatesh.pallipadi@intel.com>
253 253
254--------------------------- 254---------------------------
255 255
256<<<<<<< test:Documentation/feature-removal-schedule.txt
257What: ACPI hotkey driver (CONFIG_ACPI_HOTKEY)
258When: 2.6.21
259Why: hotkey.c was an attempt to consolidate multiple drivers that use
260 ACPI to implement hotkeys. However, hotkeys are not documented
261 in the ACPI specification, so the drivers used undocumented
262 vendor-specific hooks and turned out to be more different than
263 the same.
264
265 Further, the keys and the features supplied by each platform
266 are different, so there will always be a need for
267 platform-specific drivers.
268
269 So the new plan is to delete hotkey.c and instead, work on the
270 platform specific drivers to try to make them look the same
271 to the user when they supply the same features.
272
273 hotkey.c has always depended on CONFIG_EXPERIMENTAL
274
275Who: Len Brown <len.brown@intel.com>
276
277---------------------------
278
279What: /sys/firmware/acpi/namespace 256What: /sys/firmware/acpi/namespace
280When: 2.6.21 257When: 2.6.21
281Why: The ACPI namespace is effectively the symbol list for 258Why: The ACPI namespace is effectively the symbol list for
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index abd575cfc759..ce1f2c85e20f 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -1275,6 +1275,12 @@ and is between 256 and 4096 characters. It is defined in the file
1275 This sorting is done to get a device 1275 This sorting is done to get a device
1276 order compatible with older (<= 2.4) kernels. 1276 order compatible with older (<= 2.4) kernels.
1277 nobfsort Don't sort PCI devices into breadth-first order. 1277 nobfsort Don't sort PCI devices into breadth-first order.
1278 cbiosize=nn[KMG] The fixed amount of bus space which is
1279 reserved for the CardBus bridge's IO window.
1280 The default value is 256 bytes.
1281 cbmemsize=nn[KMG] The fixed amount of bus space which is
1282 reserved for the CardBus bridge's memory
1283 window. The default value is 64 megabytes.
1278 1284
1279 pcmv= [HW,PCMCIA] BadgePAD 4 1285 pcmv= [HW,PCMCIA] BadgePAD 4
1280 1286
diff --git a/Documentation/pci.txt b/Documentation/pci.txt
index fd5028eca13e..cdf2f3c0ab14 100644
--- a/Documentation/pci.txt
+++ b/Documentation/pci.txt
@@ -205,8 +205,8 @@ Tips on when/where to use the above attributes:
205 exclusively called by the probe() routine, can be marked __devinit. 205 exclusively called by the probe() routine, can be marked __devinit.
206 Ditto for remove() and __devexit. 206 Ditto for remove() and __devexit.
207 207
208 o If mydriver_probe() is marked with __devinit(), then all address 208 o If mydriver_remove() is marked with __devexit(), then all address
209 references to mydriver_probe must use __devexit_p(mydriver_probe) 209 references to mydriver_remove must use __devexit_p(mydriver_remove)
210 (in the struct pci_driver declaration for example). 210 (in the struct pci_driver declaration for example).
211 __devexit_p() will generate the function name _or_ NULL if the 211 __devexit_p() will generate the function name _or_ NULL if the
212 function will be discarded. For an example, see drivers/net/tg3.c. 212 function will be discarded. For an example, see drivers/net/tg3.c.
diff --git a/Documentation/powerpc/booting-without-of.txt b/Documentation/powerpc/booting-without-of.txt
index 3b514672b80e..b41397d6430a 100644
--- a/Documentation/powerpc/booting-without-of.txt
+++ b/Documentation/powerpc/booting-without-of.txt
@@ -497,7 +497,7 @@ looks like in practice.
497 | |- device_type = "cpu" 497 | |- device_type = "cpu"
498 | |- reg = <0> 498 | |- reg = <0>
499 | |- clock-frequency = <5f5e1000> 499 | |- clock-frequency = <5f5e1000>
500 | |- linux,boot-cpu 500 | |- 64-bit
501 | |- linux,phandle = <2> 501 | |- linux,phandle = <2>
502 | 502 |
503 o memory@0 503 o memory@0
@@ -509,7 +509,6 @@ looks like in practice.
509 o chosen 509 o chosen
510 |- name = "chosen" 510 |- name = "chosen"
511 |- bootargs = "root=/dev/sda2" 511 |- bootargs = "root=/dev/sda2"
512 |- linux,platform = <00000600>
513 |- linux,phandle = <4> 512 |- linux,phandle = <4>
514 513
515This tree is almost a minimal tree. It pretty much contains the 514This tree is almost a minimal tree. It pretty much contains the
@@ -519,7 +518,7 @@ physical memory layout. It also includes misc information passed
519through /chosen, like in this example, the platform type (mandatory) 518through /chosen, like in this example, the platform type (mandatory)
520and the kernel command line arguments (optional). 519and the kernel command line arguments (optional).
521 520
522The /cpus/PowerPC,970@0/linux,boot-cpu property is an example of a 521The /cpus/PowerPC,970@0/64-bit property is an example of a
523property without a value. All other properties have a value. The 522property without a value. All other properties have a value. The
524significance of the #address-cells and #size-cells properties will be 523significance of the #address-cells and #size-cells properties will be
525explained in chapter IV which defines precisely the required nodes and 524explained in chapter IV which defines precisely the required nodes and
@@ -733,8 +732,7 @@ address which can extend beyond that limit.
733 that typically get driven by the same platform code in the 732 that typically get driven by the same platform code in the
734 kernel, you would use a different "model" property but put a 733 kernel, you would use a different "model" property but put a
735 value in "compatible". The kernel doesn't directly use that 734 value in "compatible". The kernel doesn't directly use that
736 value (see /chosen/linux,platform for how the kernel chooses a 735 value but it is generally useful.
737 platform type) but it is generally useful.
738 736
739 The root node is also generally where you add additional properties 737 The root node is also generally where you add additional properties
740 specific to your board like the serial number if any, that sort of 738 specific to your board like the serial number if any, that sort of
@@ -778,7 +776,6 @@ address which can extend beyond that limit.
778 bytes 776 bytes
779 - d-cache-size : one cell, size of L1 data cache in bytes 777 - d-cache-size : one cell, size of L1 data cache in bytes
780 - i-cache-size : one cell, size of L1 instruction cache in bytes 778 - i-cache-size : one cell, size of L1 instruction cache in bytes
781 - linux, boot-cpu : Should be defined if this cpu is the boot cpu.
782 779
783 Recommended properties: 780 Recommended properties:
784 781
@@ -843,11 +840,6 @@ address which can extend beyond that limit.
843 the prom_init() trampoline when booting with an OF client interface, 840 the prom_init() trampoline when booting with an OF client interface,
844 but that you have to provide yourself when using the flattened format. 841 but that you have to provide yourself when using the flattened format.
845 842
846 Required properties:
847
848 - linux,platform : This is your platform number as assigned by the
849 architecture maintainers
850
851 Recommended properties: 843 Recommended properties:
852 844
853 - bootargs : This zero-terminated string is passed as the kernel 845 - bootargs : This zero-terminated string is passed as the kernel
diff --git a/Documentation/sony-laptop.txt b/Documentation/sony-laptop.txt
new file mode 100644
index 000000000000..dfd26df056f4
--- /dev/null
+++ b/Documentation/sony-laptop.txt
@@ -0,0 +1,106 @@
1Sony Notebook Control Driver (SNC) Readme
2-----------------------------------------
3 Copyright (C) 2004- 2005 Stelian Pop <stelian@popies.net>
4 Copyright (C) 2007 Mattia Dongili <malattia@linux.it>
5
6This mini-driver drives the SNC device present in the ACPI BIOS of
7the Sony Vaio laptops.
8
9It gives access to some extra laptop functionalities. In its current
10form, this driver let the user set or query the screen brightness
11through the backlight subsystem and remove/apply power to some devices.
12
13Backlight control:
14------------------
15If your laptop model supports it, you will find sysfs files in the
16/sys/class/backlight/sony/
17directory. You will be able to query and set the current screen
18brightness:
19 brightness get/set screen brightness (an iteger
20 between 0 and 7)
21 actual_brightness reading from this file will query the HW
22 to get real brightness value
23 max_brightness the maximum brightness value
24
25
26Platform specific:
27------------------
28Loading the sony-laptop module will create a
29/sys/devices/platform/sony-laptop/
30directory populated with some files.
31
32You then read/write integer values from/to those files by using
33standard UNIX tools.
34
35The files are:
36 brightness_default screen brightness which will be set
37 when the laptop will be rebooted
38 cdpower power on/off the internal CD drive
39 audiopower power on/off the internal sound card
40 lanpower power on/off the internal ethernet card
41 (only in debug mode)
42
43Note that some files may be missing if they are not supported
44by your particular laptop model.
45
46Example usage:
47 # echo "1" > /sys/devices/platform/sony-laptop/brightness_default
48sets the lowest screen brightness for the next and later reboots,
49 # echo "8" > /sys/devices/platform/sony-laptop/brightness_default
50sets the highest screen brightness for the next and later reboots,
51 # cat /sys/devices/platform/sony-laptop/brightness_default
52retrieves the value.
53
54 # echo "0" > /sys/devices/platform/sony-laptop/audiopower
55powers off the sound card,
56 # echo "1" > /sys/devices/platform/sony-laptop/audiopower
57powers on the sound card.
58
59Development:
60------------
61
62If you want to help with the development of this driver (and
63you are not afraid of any side effects doing strange things with
64your ACPI BIOS could have on your laptop), load the driver and
65pass the option 'debug=1'.
66
67REPEAT: DON'T DO THIS IF YOU DON'T LIKE RISKY BUSINESS.
68
69In your kernel logs you will find the list of all ACPI methods
70the SNC device has on your laptop. You can see the GCDP/GCDP methods
71used to pwer on/off the CD drive, but there are others.
72
73I HAVE NO IDEA WHAT THOSE METHODS DO.
74
75The sony-laptop driver creates, for some of those methods (the most
76current ones found on several Vaio models), an entry under
77/sys/devices/platform/sony-laptop, just like the 'cdpower' one.
78You can create other entries corresponding to your own laptop methods by
79further editing the source (see the 'sony_acpi_values' table, and add a new
80entry to this table with your get/set method names using the
81HANDLE_NAMES macro).
82
83Your mission, should you accept it, is to try finding out what
84those entries are for, by reading/writing random values from/to those
85files and find out what is the impact on your laptop.
86
87Should you find anything interesting, please report it back to me,
88I will not disavow all knowledge of your actions :)
89
90Bugs/Limitations:
91-----------------
92
93* This driver is not based on official documentation from Sony
94 (because there is none), so there is no guarantee this driver
95 will work at all, or do the right thing. Although this hasn't
96 happened to me, this driver could do very bad things to your
97 laptop, including permanent damage.
98
99* The sony-laptop and sonypi drivers do not interact at all. In the
100 future, sonypi could use sony-laptop to do (part of) its business.
101
102* spicctrl, which is the userspace tool used to communicate with the
103 sonypi driver (through /dev/sonypi) does not try to use the
104 sony-laptop driver. In the future, spicctrl could try sonypi first,
105 and if it isn't present, try sony-laptop instead.
106
diff --git a/MAINTAINERS b/MAINTAINERS
index c0f9a1ad361e..270c6b006b91 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -247,6 +247,13 @@ L: linux-acpi@vger.kernel.org
247W: http://acpi.sourceforge.net/ 247W: http://acpi.sourceforge.net/
248S: Supported 248S: Supported
249 249
250ACPI VIDEO DRIVER
251P: Luming Yu
252M: luming.yu@intel.com
253L: linux-acpi@vger.kernel.org
254W: http://acpi.sourceforge.net/
255S: Supported
256
250AD1816 SOUND DRIVER 257AD1816 SOUND DRIVER
251P: Thorsten Knabe 258P: Thorsten Knabe
252M: Thorsten Knabe <linux@thorsten-knabe.de> 259M: Thorsten Knabe <linux@thorsten-knabe.de>
@@ -3061,6 +3068,8 @@ S: Maintained
3061SONY VAIO CONTROL DEVICE DRIVER 3068SONY VAIO CONTROL DEVICE DRIVER
3062P: Stelian Pop 3069P: Stelian Pop
3063M: stelian@popies.net 3070M: stelian@popies.net
3071P: Mattia Dongili
3072M: malattia@linux.it
3064W: http://popies.net/sonypi/ 3073W: http://popies.net/sonypi/
3065S: Maintained 3074S: Maintained
3066 3075
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 5c795193ebba..8bf97e0eacdb 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -245,6 +245,8 @@ config ARCH_IOP33X
245 245
246config ARCH_IOP13XX 246config ARCH_IOP13XX
247 bool "IOP13xx-based" 247 bool "IOP13xx-based"
248 depends on MMU
249 select PLAT_IOP
248 select PCI 250 select PCI
249 help 251 help
250 Support for Intel's IOP13XX (XScale) family of processors. 252 Support for Intel's IOP13XX (XScale) family of processors.
@@ -283,6 +285,14 @@ config ARCH_L7200
283 If you have any questions or comments about the Linux kernel port 285 If you have any questions or comments about the Linux kernel port
284 to this board, send e-mail to <sjhill@cotw.com>. 286 to this board, send e-mail to <sjhill@cotw.com>.
285 287
288config ARCH_NS9XXX
289 bool "NetSilicon NS9xxx"
290 help
291 Say Y here if you intend to run this kernel on a NetSilicon NS9xxx
292 System.
293
294 <http://www.digi.com/products/microprocessors/index.jsp>
295
286config ARCH_PNX4008 296config ARCH_PNX4008
287 bool "Philips Nexperia PNX4008 Mobile" 297 bool "Philips Nexperia PNX4008 Mobile"
288 help 298 help
@@ -292,6 +302,7 @@ config ARCH_PXA
292 bool "PXA2xx-based" 302 bool "PXA2xx-based"
293 depends on MMU 303 depends on MMU
294 select ARCH_MTD_XIP 304 select ARCH_MTD_XIP
305 select GENERIC_TIME
295 help 306 help
296 Support for Intel's PXA2XX processor line. 307 Support for Intel's PXA2XX processor line.
297 308
@@ -316,7 +327,7 @@ config ARCH_SA1100
316 Support for StrongARM 11x0 based boards. 327 Support for StrongARM 11x0 based boards.
317 328
318config ARCH_S3C2410 329config ARCH_S3C2410
319 bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442" 330 bool "Samsung S3C2410, S3C2412, S3C2413, S3C2440, S3C2442, S3C2443"
320 help 331 help
321 Samsung S3C2410X CPU based systems, such as the Simtec Electronics 332 Samsung S3C2410X CPU based systems, such as the Simtec Electronics
322 BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or 333 BAST (<http://www.simtec.co.uk/products/EB110ITX/>), the IPAQ 1940 or
@@ -376,7 +387,16 @@ source "arch/arm/mach-omap1/Kconfig"
376 387
377source "arch/arm/mach-omap2/Kconfig" 388source "arch/arm/mach-omap2/Kconfig"
378 389
390source "arch/arm/plat-s3c24xx/Kconfig"
391
392if ARCH_S3C2410
393source "arch/arm/mach-s3c2400/Kconfig"
379source "arch/arm/mach-s3c2410/Kconfig" 394source "arch/arm/mach-s3c2410/Kconfig"
395source "arch/arm/mach-s3c2412/Kconfig"
396source "arch/arm/mach-s3c2440/Kconfig"
397source "arch/arm/mach-s3c2442/Kconfig"
398source "arch/arm/mach-s3c2443/Kconfig"
399endif
380 400
381source "arch/arm/mach-lh7a40x/Kconfig" 401source "arch/arm/mach-lh7a40x/Kconfig"
382 402
@@ -390,10 +410,12 @@ source "arch/arm/mach-aaec2000/Kconfig"
390 410
391source "arch/arm/mach-realview/Kconfig" 411source "arch/arm/mach-realview/Kconfig"
392 412
393source "arch/arm/mach-at91rm9200/Kconfig" 413source "arch/arm/mach-at91/Kconfig"
394 414
395source "arch/arm/mach-netx/Kconfig" 415source "arch/arm/mach-netx/Kconfig"
396 416
417source "arch/arm/mach-ns9xxx/Kconfig"
418
397# Definitions to make life easier 419# Definitions to make life easier
398config ARCH_ACORN 420config ARCH_ACORN
399 bool 421 bool
@@ -751,6 +773,20 @@ config XIP_PHYS_ADDR
751 be linked for and stored to. This address is dependent on your 773 be linked for and stored to. This address is dependent on your
752 own flash usage. 774 own flash usage.
753 775
776config KEXEC
777 bool "Kexec system call (EXPERIMENTAL)"
778 depends on EXPERIMENTAL
779 help
780 kexec is a system call that implements the ability to shutdown your
781 current kernel, and to start another kernel. It is like a reboot
782 but it is indepedent of the system firmware. And like a reboot
783 you can start any kernel with it, not just Linux.
784
785 It is an ongoing process to be certain the hardware in a machine
786 is properly shutdown, so do not be surprised if this code does not
787 initially work for you. It may help to enable device hotplugging
788 support.
789
754endmenu 790endmenu
755 791
756if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX ) 792if (ARCH_SA1100 || ARCH_INTEGRATOR || ARCH_OMAP || ARCH_IMX )
diff --git a/arch/arm/Makefile b/arch/arm/Makefile
index 000f1100b553..1320418b5d6f 100644
--- a/arch/arm/Makefile
+++ b/arch/arm/Makefile
@@ -124,10 +124,12 @@ endif
124 machine-$(CONFIG_ARCH_H720X) := h720x 124 machine-$(CONFIG_ARCH_H720X) := h720x
125 machine-$(CONFIG_ARCH_AAEC2000) := aaec2000 125 machine-$(CONFIG_ARCH_AAEC2000) := aaec2000
126 machine-$(CONFIG_ARCH_REALVIEW) := realview 126 machine-$(CONFIG_ARCH_REALVIEW) := realview
127 machine-$(CONFIG_ARCH_AT91) := at91rm9200 127 machine-$(CONFIG_ARCH_AT91) := at91rm9200
128 machine-$(CONFIG_ARCH_EP93XX) := ep93xx 128 machine-$(CONFIG_ARCH_EP93XX) := ep93xx
129 machine-$(CONFIG_ARCH_PNX4008) := pnx4008 129 machine-$(CONFIG_ARCH_PNX4008) := pnx4008
130 machine-$(CONFIG_ARCH_NETX) := netx 130 machine-$(CONFIG_ARCH_NETX) := netx
131 machine-$(CONFIG_ARCH_NS9XXX) := ns9xxx
132 textofs-$(CONFIG_ARCH_NS9XXX) := 0x00108000
131 133
132ifeq ($(CONFIG_ARCH_EBSA110),y) 134ifeq ($(CONFIG_ARCH_EBSA110),y)
133# This is what happens if you forget the IOCS16 line. 135# This is what happens if you forget the IOCS16 line.
@@ -149,7 +151,7 @@ MACHINE := arch/arm/mach-$(machine-y)/
149else 151else
150MACHINE := 152MACHINE :=
151endif 153endif
152 154
153export TEXT_OFFSET GZFLAGS MMUEXT 155export TEXT_OFFSET GZFLAGS MMUEXT
154 156
155# Do we have FASTFPE? 157# Do we have FASTFPE?
@@ -161,6 +163,11 @@ endif
161# If we have a machine-specific directory, then include it in the build. 163# If we have a machine-specific directory, then include it in the build.
162core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/ 164core-y += arch/arm/kernel/ arch/arm/mm/ arch/arm/common/
163core-y += $(MACHINE) 165core-y += $(MACHINE)
166core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2400/
167core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2412/
168core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2440/
169core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2442/
170core-$(CONFIG_ARCH_S3C2410) += arch/arm/mach-s3c2443/
164core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/ 171core-$(CONFIG_FPE_NWFPE) += arch/arm/nwfpe/
165core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ) 172core-$(CONFIG_FPE_FASTFPE) += $(FASTFPE_OBJ)
166core-$(CONFIG_VFP) += arch/arm/vfp/ 173core-$(CONFIG_VFP) += arch/arm/vfp/
@@ -168,6 +175,7 @@ core-$(CONFIG_VFP) += arch/arm/vfp/
168# If we have a common platform directory, then include it in the build. 175# If we have a common platform directory, then include it in the build.
169core-$(CONFIG_PLAT_IOP) += arch/arm/plat-iop/ 176core-$(CONFIG_PLAT_IOP) += arch/arm/plat-iop/
170core-$(CONFIG_ARCH_OMAP) += arch/arm/plat-omap/ 177core-$(CONFIG_ARCH_OMAP) += arch/arm/plat-omap/
178core-$(CONFIG_PLAT_S3C24XX) += arch/arm/plat-s3c24xx/
171 179
172drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/ 180drivers-$(CONFIG_OPROFILE) += arch/arm/oprofile/
173drivers-$(CONFIG_ARCH_CLPS7500) += drivers/acorn/char/ 181drivers-$(CONFIG_ARCH_CLPS7500) += drivers/acorn/char/
diff --git a/arch/arm/boot/.gitignore b/arch/arm/boot/.gitignore
new file mode 100644
index 000000000000..171a0853caf8
--- /dev/null
+++ b/arch/arm/boot/.gitignore
@@ -0,0 +1,2 @@
1Image
2zImage
diff --git a/arch/arm/boot/compressed/.gitignore b/arch/arm/boot/compressed/.gitignore
new file mode 100644
index 000000000000..aefee20cbf98
--- /dev/null
+++ b/arch/arm/boot/compressed/.gitignore
@@ -0,0 +1 @@
piggy.gz
diff --git a/arch/arm/common/dmabounce.c b/arch/arm/common/dmabounce.c
index 2e635b814c14..6fbe7722aa44 100644
--- a/arch/arm/common/dmabounce.c
+++ b/arch/arm/common/dmabounce.c
@@ -32,7 +32,6 @@
32 32
33#include <asm/cacheflush.h> 33#include <asm/cacheflush.h>
34 34
35#undef DEBUG
36#undef STATS 35#undef STATS
37 36
38#ifdef STATS 37#ifdef STATS
@@ -66,14 +65,13 @@ struct dmabounce_pool {
66}; 65};
67 66
68struct dmabounce_device_info { 67struct dmabounce_device_info {
69 struct list_head node;
70
71 struct device *dev; 68 struct device *dev;
72 struct list_head safe_buffers; 69 struct list_head safe_buffers;
73#ifdef STATS 70#ifdef STATS
74 unsigned long total_allocs; 71 unsigned long total_allocs;
75 unsigned long map_op_count; 72 unsigned long map_op_count;
76 unsigned long bounce_count; 73 unsigned long bounce_count;
74 int attr_res;
77#endif 75#endif
78 struct dmabounce_pool small; 76 struct dmabounce_pool small;
79 struct dmabounce_pool large; 77 struct dmabounce_pool large;
@@ -81,33 +79,23 @@ struct dmabounce_device_info {
81 rwlock_t lock; 79 rwlock_t lock;
82}; 80};
83 81
84static LIST_HEAD(dmabounce_devs);
85
86#ifdef STATS 82#ifdef STATS
87static void print_alloc_stats(struct dmabounce_device_info *device_info) 83static ssize_t dmabounce_show(struct device *dev, struct device_attribute *attr,
84 char *buf)
88{ 85{
89 printk(KERN_INFO 86 struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
90 "%s: dmabounce: sbp: %lu, lbp: %lu, other: %lu, total: %lu\n", 87 return sprintf(buf, "%lu %lu %lu %lu %lu %lu\n",
91 device_info->dev->bus_id, 88 device_info->small.allocs,
92 device_info->small.allocs, device_info->large.allocs, 89 device_info->large.allocs,
93 device_info->total_allocs - device_info->small.allocs - 90 device_info->total_allocs - device_info->small.allocs -
94 device_info->large.allocs, 91 device_info->large.allocs,
95 device_info->total_allocs); 92 device_info->total_allocs,
93 device_info->map_op_count,
94 device_info->bounce_count);
96} 95}
97#endif
98
99/* find the given device in the dmabounce device list */
100static inline struct dmabounce_device_info *
101find_dmabounce_dev(struct device *dev)
102{
103 struct dmabounce_device_info *d;
104 96
105 list_for_each_entry(d, &dmabounce_devs, node) 97static DEVICE_ATTR(dmabounce_stats, 0400, dmabounce_show, NULL);
106 if (d->dev == dev) 98#endif
107 return d;
108
109 return NULL;
110}
111 99
112 100
113/* allocate a 'safe' buffer and keep track of it */ 101/* allocate a 'safe' buffer and keep track of it */
@@ -162,8 +150,6 @@ alloc_safe_buffer(struct dmabounce_device_info *device_info, void *ptr,
162 if (pool) 150 if (pool)
163 pool->allocs++; 151 pool->allocs++;
164 device_info->total_allocs++; 152 device_info->total_allocs++;
165 if (device_info->total_allocs % 1000 == 0)
166 print_alloc_stats(device_info);
167#endif 153#endif
168 154
169 write_lock_irqsave(&device_info->lock, flags); 155 write_lock_irqsave(&device_info->lock, flags);
@@ -218,20 +204,11 @@ free_safe_buffer(struct dmabounce_device_info *device_info, struct safe_buffer *
218 204
219/* ************************************************** */ 205/* ************************************************** */
220 206
221#ifdef STATS
222static void print_map_stats(struct dmabounce_device_info *device_info)
223{
224 dev_info(device_info->dev,
225 "dmabounce: map_op_count=%lu, bounce_count=%lu\n",
226 device_info->map_op_count, device_info->bounce_count);
227}
228#endif
229
230static inline dma_addr_t 207static inline dma_addr_t
231map_single(struct device *dev, void *ptr, size_t size, 208map_single(struct device *dev, void *ptr, size_t size,
232 enum dma_data_direction dir) 209 enum dma_data_direction dir)
233{ 210{
234 struct dmabounce_device_info *device_info = find_dmabounce_dev(dev); 211 struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
235 dma_addr_t dma_addr; 212 dma_addr_t dma_addr;
236 int needs_bounce = 0; 213 int needs_bounce = 0;
237 214
@@ -281,10 +258,14 @@ map_single(struct device *dev, void *ptr, size_t size,
281 ptr = buf->safe; 258 ptr = buf->safe;
282 259
283 dma_addr = buf->safe_dma_addr; 260 dma_addr = buf->safe_dma_addr;
261 } else {
262 /*
263 * We don't need to sync the DMA buffer since
264 * it was allocated via the coherent allocators.
265 */
266 consistent_sync(ptr, size, dir);
284 } 267 }
285 268
286 consistent_sync(ptr, size, dir);
287
288 return dma_addr; 269 return dma_addr;
289} 270}
290 271
@@ -292,7 +273,7 @@ static inline void
292unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, 273unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
293 enum dma_data_direction dir) 274 enum dma_data_direction dir)
294{ 275{
295 struct dmabounce_device_info *device_info = find_dmabounce_dev(dev); 276 struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
296 struct safe_buffer *buf = NULL; 277 struct safe_buffer *buf = NULL;
297 278
298 /* 279 /*
@@ -317,12 +298,12 @@ unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
317 DO_STATS ( device_info->bounce_count++ ); 298 DO_STATS ( device_info->bounce_count++ );
318 299
319 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) { 300 if (dir == DMA_FROM_DEVICE || dir == DMA_BIDIRECTIONAL) {
320 unsigned long ptr; 301 void *ptr = buf->ptr;
321 302
322 dev_dbg(dev, 303 dev_dbg(dev,
323 "%s: copy back safe %p to unsafe %p size %d\n", 304 "%s: copy back safe %p to unsafe %p size %d\n",
324 __func__, buf->safe, buf->ptr, size); 305 __func__, buf->safe, ptr, size);
325 memcpy(buf->ptr, buf->safe, size); 306 memcpy(ptr, buf->safe, size);
326 307
327 /* 308 /*
328 * DMA buffers must have the same cache properties 309 * DMA buffers must have the same cache properties
@@ -332,8 +313,8 @@ unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
332 * bidirectional case because we know the cache 313 * bidirectional case because we know the cache
333 * lines will be coherent with the data written. 314 * lines will be coherent with the data written.
334 */ 315 */
335 ptr = (unsigned long)buf->ptr;
336 dmac_clean_range(ptr, ptr + size); 316 dmac_clean_range(ptr, ptr + size);
317 outer_clean_range(__pa(ptr), __pa(ptr) + size);
337 } 318 }
338 free_safe_buffer(device_info, buf); 319 free_safe_buffer(device_info, buf);
339 } 320 }
@@ -343,7 +324,7 @@ static inline void
343sync_single(struct device *dev, dma_addr_t dma_addr, size_t size, 324sync_single(struct device *dev, dma_addr_t dma_addr, size_t size,
344 enum dma_data_direction dir) 325 enum dma_data_direction dir)
345{ 326{
346 struct dmabounce_device_info *device_info = find_dmabounce_dev(dev); 327 struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
347 struct safe_buffer *buf = NULL; 328 struct safe_buffer *buf = NULL;
348 329
349 if (device_info) 330 if (device_info)
@@ -397,7 +378,10 @@ sync_single(struct device *dev, dma_addr_t dma_addr, size_t size,
397 default: 378 default:
398 BUG(); 379 BUG();
399 } 380 }
400 consistent_sync(buf->safe, size, dir); 381 /*
382 * No need to sync the safe buffer - it was allocated
383 * via the coherent allocators.
384 */
401 } else { 385 } else {
402 consistent_sync(dma_to_virt(dev, dma_addr), size, dir); 386 consistent_sync(dma_to_virt(dev, dma_addr), size, dir);
403 } 387 }
@@ -604,9 +588,10 @@ dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
604 device_info->total_allocs = 0; 588 device_info->total_allocs = 0;
605 device_info->map_op_count = 0; 589 device_info->map_op_count = 0;
606 device_info->bounce_count = 0; 590 device_info->bounce_count = 0;
591 device_info->attr_res = device_create_file(dev, &dev_attr_dmabounce_stats);
607#endif 592#endif
608 593
609 list_add(&device_info->node, &dmabounce_devs); 594 dev->archdata.dmabounce = device_info;
610 595
611 printk(KERN_INFO "dmabounce: registered device %s on %s bus\n", 596 printk(KERN_INFO "dmabounce: registered device %s on %s bus\n",
612 dev->bus_id, dev->bus->name); 597 dev->bus_id, dev->bus->name);
@@ -623,7 +608,9 @@ dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size,
623void 608void
624dmabounce_unregister_dev(struct device *dev) 609dmabounce_unregister_dev(struct device *dev)
625{ 610{
626 struct dmabounce_device_info *device_info = find_dmabounce_dev(dev); 611 struct dmabounce_device_info *device_info = dev->archdata.dmabounce;
612
613 dev->archdata.dmabounce = NULL;
627 614
628 if (!device_info) { 615 if (!device_info) {
629 printk(KERN_WARNING 616 printk(KERN_WARNING
@@ -645,12 +632,10 @@ dmabounce_unregister_dev(struct device *dev)
645 dma_pool_destroy(device_info->large.pool); 632 dma_pool_destroy(device_info->large.pool);
646 633
647#ifdef STATS 634#ifdef STATS
648 print_alloc_stats(device_info); 635 if (device_info->attr_res == 0)
649 print_map_stats(device_info); 636 device_remove_file(dev, &dev_attr_dmabounce_stats);
650#endif 637#endif
651 638
652 list_del(&device_info->node);
653
654 kfree(device_info); 639 kfree(device_info);
655 640
656 printk(KERN_INFO "dmabounce: device %s on %s bus unregistered\n", 641 printk(KERN_INFO "dmabounce: device %s on %s bus unregistered\n",
diff --git a/arch/arm/common/gic.c b/arch/arm/common/gic.c
index 09b9d1b6844c..4deece5fbdf4 100644
--- a/arch/arm/common/gic.c
+++ b/arch/arm/common/gic.c
@@ -14,7 +14,9 @@
14 * 14 *
15 * o There is one CPU Interface per CPU, which sends interrupts sent 15 * o There is one CPU Interface per CPU, which sends interrupts sent
16 * by the Distributor, and interrupts generated locally, to the 16 * by the Distributor, and interrupts generated locally, to the
17 * associated CPU. 17 * associated CPU. The base address of the CPU interface is usually
18 * aliased so that the same address points to different chips depending
19 * on the CPU it is accessed from.
18 * 20 *
19 * Note that IRQs 0-31 are special - they are local to each CPU. 21 * Note that IRQs 0-31 are special - they are local to each CPU.
20 * As such, the enable set/clear, pending set/clear and active bit 22 * As such, the enable set/clear, pending set/clear and active bit
@@ -31,10 +33,38 @@
31#include <asm/mach/irq.h> 33#include <asm/mach/irq.h>
32#include <asm/hardware/gic.h> 34#include <asm/hardware/gic.h>
33 35
34static void __iomem *gic_dist_base;
35static void __iomem *gic_cpu_base;
36static DEFINE_SPINLOCK(irq_controller_lock); 36static DEFINE_SPINLOCK(irq_controller_lock);
37 37
38struct gic_chip_data {
39 unsigned int irq_offset;
40 void __iomem *dist_base;
41 void __iomem *cpu_base;
42};
43
44#ifndef MAX_GIC_NR
45#define MAX_GIC_NR 1
46#endif
47
48static struct gic_chip_data gic_data[MAX_GIC_NR];
49
50static inline void __iomem *gic_dist_base(unsigned int irq)
51{
52 struct gic_chip_data *gic_data = get_irq_chip_data(irq);
53 return gic_data->dist_base;
54}
55
56static inline void __iomem *gic_cpu_base(unsigned int irq)
57{
58 struct gic_chip_data *gic_data = get_irq_chip_data(irq);
59 return gic_data->cpu_base;
60}
61
62static inline unsigned int gic_irq(unsigned int irq)
63{
64 struct gic_chip_data *gic_data = get_irq_chip_data(irq);
65 return irq - gic_data->irq_offset;
66}
67
38/* 68/*
39 * Routines to acknowledge, disable and enable interrupts 69 * Routines to acknowledge, disable and enable interrupts
40 * 70 *
@@ -55,8 +85,8 @@ static void gic_ack_irq(unsigned int irq)
55 u32 mask = 1 << (irq % 32); 85 u32 mask = 1 << (irq % 32);
56 86
57 spin_lock(&irq_controller_lock); 87 spin_lock(&irq_controller_lock);
58 writel(mask, gic_dist_base + GIC_DIST_ENABLE_CLEAR + (irq / 32) * 4); 88 writel(mask, gic_dist_base(irq) + GIC_DIST_ENABLE_CLEAR + (gic_irq(irq) / 32) * 4);
59 writel(irq, gic_cpu_base + GIC_CPU_EOI); 89 writel(gic_irq(irq), gic_cpu_base(irq) + GIC_CPU_EOI);
60 spin_unlock(&irq_controller_lock); 90 spin_unlock(&irq_controller_lock);
61} 91}
62 92
@@ -65,7 +95,7 @@ static void gic_mask_irq(unsigned int irq)
65 u32 mask = 1 << (irq % 32); 95 u32 mask = 1 << (irq % 32);
66 96
67 spin_lock(&irq_controller_lock); 97 spin_lock(&irq_controller_lock);
68 writel(mask, gic_dist_base + GIC_DIST_ENABLE_CLEAR + (irq / 32) * 4); 98 writel(mask, gic_dist_base(irq) + GIC_DIST_ENABLE_CLEAR + (gic_irq(irq) / 32) * 4);
69 spin_unlock(&irq_controller_lock); 99 spin_unlock(&irq_controller_lock);
70} 100}
71 101
@@ -74,14 +104,14 @@ static void gic_unmask_irq(unsigned int irq)
74 u32 mask = 1 << (irq % 32); 104 u32 mask = 1 << (irq % 32);
75 105
76 spin_lock(&irq_controller_lock); 106 spin_lock(&irq_controller_lock);
77 writel(mask, gic_dist_base + GIC_DIST_ENABLE_SET + (irq / 32) * 4); 107 writel(mask, gic_dist_base(irq) + GIC_DIST_ENABLE_SET + (gic_irq(irq) / 32) * 4);
78 spin_unlock(&irq_controller_lock); 108 spin_unlock(&irq_controller_lock);
79} 109}
80 110
81#ifdef CONFIG_SMP 111#ifdef CONFIG_SMP
82static void gic_set_cpu(unsigned int irq, cpumask_t mask_val) 112static void gic_set_cpu(unsigned int irq, cpumask_t mask_val)
83{ 113{
84 void __iomem *reg = gic_dist_base + GIC_DIST_TARGET + (irq & ~3); 114 void __iomem *reg = gic_dist_base(irq) + GIC_DIST_TARGET + (gic_irq(irq) & ~3);
85 unsigned int shift = (irq % 4) * 8; 115 unsigned int shift = (irq % 4) * 8;
86 unsigned int cpu = first_cpu(mask_val); 116 unsigned int cpu = first_cpu(mask_val);
87 u32 val; 117 u32 val;
@@ -95,6 +125,37 @@ static void gic_set_cpu(unsigned int irq, cpumask_t mask_val)
95} 125}
96#endif 126#endif
97 127
128static void fastcall gic_handle_cascade_irq(unsigned int irq,
129 struct irq_desc *desc)
130{
131 struct gic_chip_data *chip_data = get_irq_data(irq);
132 struct irq_chip *chip = get_irq_chip(irq);
133 unsigned int cascade_irq;
134 unsigned long status;
135
136 /* primary controller ack'ing */
137 chip->ack(irq);
138
139 spin_lock(&irq_controller_lock);
140 status = readl(chip_data->cpu_base + GIC_CPU_INTACK);
141 spin_unlock(&irq_controller_lock);
142
143 cascade_irq = (status & 0x3ff);
144 if (cascade_irq > 1020)
145 goto out;
146 if (cascade_irq < 32 || cascade_irq >= NR_IRQS) {
147 do_bad_IRQ(cascade_irq, desc);
148 goto out;
149 }
150
151 cascade_irq += chip_data->irq_offset;
152 generic_handle_irq(cascade_irq);
153
154 out:
155 /* primary controller unmasking */
156 chip->unmask(irq);
157}
158
98static struct irq_chip gic_chip = { 159static struct irq_chip gic_chip = {
99 .name = "GIC", 160 .name = "GIC",
100 .ack = gic_ack_irq, 161 .ack = gic_ack_irq,
@@ -105,15 +166,29 @@ static struct irq_chip gic_chip = {
105#endif 166#endif
106}; 167};
107 168
108void __init gic_dist_init(void __iomem *base) 169void __init gic_cascade_irq(unsigned int gic_nr, unsigned int irq)
170{
171 if (gic_nr >= MAX_GIC_NR)
172 BUG();
173 if (set_irq_data(irq, &gic_data[gic_nr]) != 0)
174 BUG();
175 set_irq_chained_handler(irq, gic_handle_cascade_irq);
176}
177
178void __init gic_dist_init(unsigned int gic_nr, void __iomem *base,
179 unsigned int irq_start)
109{ 180{
110 unsigned int max_irq, i; 181 unsigned int max_irq, i;
111 u32 cpumask = 1 << smp_processor_id(); 182 u32 cpumask = 1 << smp_processor_id();
112 183
184 if (gic_nr >= MAX_GIC_NR)
185 BUG();
186
113 cpumask |= cpumask << 8; 187 cpumask |= cpumask << 8;
114 cpumask |= cpumask << 16; 188 cpumask |= cpumask << 16;
115 189
116 gic_dist_base = base; 190 gic_data[gic_nr].dist_base = base;
191 gic_data[gic_nr].irq_offset = (irq_start - 1) & ~31;
117 192
118 writel(0, base + GIC_DIST_CTRL); 193 writel(0, base + GIC_DIST_CTRL);
119 194
@@ -158,8 +233,9 @@ void __init gic_dist_init(void __iomem *base)
158 /* 233 /*
159 * Setup the Linux IRQ subsystem. 234 * Setup the Linux IRQ subsystem.
160 */ 235 */
161 for (i = 29; i < max_irq; i++) { 236 for (i = irq_start; i < gic_data[gic_nr].irq_offset + max_irq; i++) {
162 set_irq_chip(i, &gic_chip); 237 set_irq_chip(i, &gic_chip);
238 set_irq_chip_data(i, &gic_data[gic_nr]);
163 set_irq_handler(i, handle_level_irq); 239 set_irq_handler(i, handle_level_irq);
164 set_irq_flags(i, IRQF_VALID | IRQF_PROBE); 240 set_irq_flags(i, IRQF_VALID | IRQF_PROBE);
165 } 241 }
@@ -167,9 +243,13 @@ void __init gic_dist_init(void __iomem *base)
167 writel(1, base + GIC_DIST_CTRL); 243 writel(1, base + GIC_DIST_CTRL);
168} 244}
169 245
170void __cpuinit gic_cpu_init(void __iomem *base) 246void __cpuinit gic_cpu_init(unsigned int gic_nr, void __iomem *base)
171{ 247{
172 gic_cpu_base = base; 248 if (gic_nr >= MAX_GIC_NR)
249 BUG();
250
251 gic_data[gic_nr].cpu_base = base;
252
173 writel(0xf0, base + GIC_CPU_PRIMASK); 253 writel(0xf0, base + GIC_CPU_PRIMASK);
174 writel(1, base + GIC_CPU_CTRL); 254 writel(1, base + GIC_CPU_CTRL);
175} 255}
@@ -179,6 +259,7 @@ void gic_raise_softirq(cpumask_t cpumask, unsigned int irq)
179{ 259{
180 unsigned long map = *cpus_addr(cpumask); 260 unsigned long map = *cpus_addr(cpumask);
181 261
182 writel(map << 16 | irq, gic_dist_base + GIC_DIST_SOFTINT); 262 /* this always happens on GIC0 */
263 writel(map << 16 | irq, gic_data[0].dist_base + GIC_DIST_SOFTINT);
183} 264}
184#endif 265#endif
diff --git a/arch/arm/configs/at91sam9263ek_defconfig b/arch/arm/configs/at91sam9263ek_defconfig
new file mode 100644
index 000000000000..c72ab82873d5
--- /dev/null
+++ b/arch/arm/configs/at91sam9263ek_defconfig
@@ -0,0 +1,1184 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.20-rc1
4# Mon Jan 8 16:06:54 2007
5#
6CONFIG_ARM=y
7# CONFIG_GENERIC_TIME is not set
8CONFIG_MMU=y
9CONFIG_GENERIC_HARDIRQS=y
10CONFIG_TRACE_IRQFLAGS_SUPPORT=y
11CONFIG_HARDIRQS_SW_RESEND=y
12CONFIG_GENERIC_IRQ_PROBE=y
13CONFIG_RWSEM_GENERIC_SPINLOCK=y
14# CONFIG_ARCH_HAS_ILOG2_U32 is not set
15# CONFIG_ARCH_HAS_ILOG2_U64 is not set
16CONFIG_GENERIC_HWEIGHT=y
17CONFIG_GENERIC_CALIBRATE_DELAY=y
18CONFIG_VECTORS_BASE=0xffff0000
19CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
20
21#
22# Code maturity level options
23#
24CONFIG_EXPERIMENTAL=y
25CONFIG_BROKEN_ON_SMP=y
26CONFIG_INIT_ENV_ARG_LIMIT=32
27
28#
29# General setup
30#
31CONFIG_LOCALVERSION=""
32# CONFIG_LOCALVERSION_AUTO is not set
33# CONFIG_SWAP is not set
34CONFIG_SYSVIPC=y
35# CONFIG_IPC_NS is not set
36# CONFIG_POSIX_MQUEUE is not set
37# CONFIG_BSD_PROCESS_ACCT is not set
38# CONFIG_TASKSTATS is not set
39# CONFIG_UTS_NS is not set
40# CONFIG_AUDIT is not set
41# CONFIG_IKCONFIG is not set
42CONFIG_SYSFS_DEPRECATED=y
43# CONFIG_RELAY is not set
44CONFIG_INITRAMFS_SOURCE=""
45CONFIG_CC_OPTIMIZE_FOR_SIZE=y
46CONFIG_SYSCTL=y
47# CONFIG_EMBEDDED is not set
48CONFIG_UID16=y
49CONFIG_SYSCTL_SYSCALL=y
50CONFIG_KALLSYMS=y
51# CONFIG_KALLSYMS_ALL is not set
52# CONFIG_KALLSYMS_EXTRA_PASS is not set
53CONFIG_HOTPLUG=y
54CONFIG_PRINTK=y
55CONFIG_BUG=y
56CONFIG_ELF_CORE=y
57CONFIG_BASE_FULL=y
58CONFIG_FUTEX=y
59CONFIG_EPOLL=y
60CONFIG_SHMEM=y
61CONFIG_SLAB=y
62CONFIG_VM_EVENT_COUNTERS=y
63CONFIG_RT_MUTEXES=y
64# CONFIG_TINY_SHMEM is not set
65CONFIG_BASE_SMALL=0
66# CONFIG_SLOB is not set
67
68#
69# Loadable module support
70#
71CONFIG_MODULES=y
72CONFIG_MODULE_UNLOAD=y
73# CONFIG_MODULE_FORCE_UNLOAD is not set
74# CONFIG_MODVERSIONS is not set
75# CONFIG_MODULE_SRCVERSION_ALL is not set
76CONFIG_KMOD=y
77
78#
79# Block layer
80#
81CONFIG_BLOCK=y
82# CONFIG_LBD is not set
83# CONFIG_BLK_DEV_IO_TRACE is not set
84# CONFIG_LSF is not set
85
86#
87# IO Schedulers
88#
89CONFIG_IOSCHED_NOOP=y
90CONFIG_IOSCHED_AS=y
91# CONFIG_IOSCHED_DEADLINE is not set
92# CONFIG_IOSCHED_CFQ is not set
93CONFIG_DEFAULT_AS=y
94# CONFIG_DEFAULT_DEADLINE is not set
95# CONFIG_DEFAULT_CFQ is not set
96# CONFIG_DEFAULT_NOOP is not set
97CONFIG_DEFAULT_IOSCHED="anticipatory"
98
99#
100# System Type
101#
102# CONFIG_ARCH_AAEC2000 is not set
103# CONFIG_ARCH_INTEGRATOR is not set
104# CONFIG_ARCH_REALVIEW is not set
105# CONFIG_ARCH_VERSATILE is not set
106CONFIG_ARCH_AT91=y
107# CONFIG_ARCH_CLPS7500 is not set
108# CONFIG_ARCH_CLPS711X is not set
109# CONFIG_ARCH_CO285 is not set
110# CONFIG_ARCH_EBSA110 is not set
111# CONFIG_ARCH_EP93XX is not set
112# CONFIG_ARCH_FOOTBRIDGE is not set
113# CONFIG_ARCH_NETX is not set
114# CONFIG_ARCH_H720X is not set
115# CONFIG_ARCH_IMX is not set
116# CONFIG_ARCH_IOP32X is not set
117# CONFIG_ARCH_IOP33X is not set
118# CONFIG_ARCH_IOP13XX is not set
119# CONFIG_ARCH_IXP4XX is not set
120# CONFIG_ARCH_IXP2000 is not set
121# CONFIG_ARCH_IXP23XX is not set
122# CONFIG_ARCH_L7200 is not set
123# CONFIG_ARCH_PNX4008 is not set
124# CONFIG_ARCH_PXA is not set
125# CONFIG_ARCH_RPC is not set
126# CONFIG_ARCH_SA1100 is not set
127# CONFIG_ARCH_S3C2410 is not set
128# CONFIG_ARCH_SHARK is not set
129# CONFIG_ARCH_LH7A40X is not set
130# CONFIG_ARCH_OMAP is not set
131
132#
133# Atmel AT91 System-on-Chip
134#
135# CONFIG_ARCH_AT91RM9200 is not set
136# CONFIG_ARCH_AT91SAM9260 is not set
137# CONFIG_ARCH_AT91SAM9261 is not set
138CONFIG_ARCH_AT91SAM9263=y
139
140#
141# AT91SAM9263 Board Type
142#
143CONFIG_MACH_AT91SAM9263EK=y
144
145#
146# AT91 Board Options
147#
148CONFIG_MTD_AT91_DATAFLASH_CARD=y
149# CONFIG_MTD_NAND_AT91_BUSWIDTH_16 is not set
150
151#
152# AT91 Feature Selections
153#
154# CONFIG_AT91_PROGRAMMABLE_CLOCKS is not set
155
156#
157# Processor Type
158#
159CONFIG_CPU_32=y
160CONFIG_CPU_ARM926T=y
161CONFIG_CPU_32v5=y
162CONFIG_CPU_ABRT_EV5TJ=y
163CONFIG_CPU_CACHE_VIVT=y
164CONFIG_CPU_COPY_V4WB=y
165CONFIG_CPU_TLB_V4WBI=y
166CONFIG_CPU_CP15=y
167CONFIG_CPU_CP15_MMU=y
168
169#
170# Processor Features
171#
172# CONFIG_ARM_THUMB is not set
173# CONFIG_CPU_ICACHE_DISABLE is not set
174# CONFIG_CPU_DCACHE_DISABLE is not set
175# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
176# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
177
178#
179# Bus support
180#
181
182#
183# PCCARD (PCMCIA/CardBus) support
184#
185# CONFIG_PCCARD is not set
186
187#
188# Kernel Features
189#
190# CONFIG_PREEMPT is not set
191# CONFIG_NO_IDLE_HZ is not set
192CONFIG_HZ=100
193# CONFIG_AEABI is not set
194# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
195CONFIG_SELECT_MEMORY_MODEL=y
196CONFIG_FLATMEM_MANUAL=y
197# CONFIG_DISCONTIGMEM_MANUAL is not set
198# CONFIG_SPARSEMEM_MANUAL is not set
199CONFIG_FLATMEM=y
200CONFIG_FLAT_NODE_MEM_MAP=y
201# CONFIG_SPARSEMEM_STATIC is not set
202CONFIG_SPLIT_PTLOCK_CPUS=4096
203# CONFIG_RESOURCES_64BIT is not set
204# CONFIG_LEDS is not set
205CONFIG_ALIGNMENT_TRAP=y
206
207#
208# Boot options
209#
210CONFIG_ZBOOT_ROM_TEXT=0x0
211CONFIG_ZBOOT_ROM_BSS=0x0
212CONFIG_CMDLINE="mem=64M console=ttyS0,115200 initrd=0x21100000,3145728 root=/dev/ram0 rw"
213# CONFIG_XIP_KERNEL is not set
214
215#
216# Floating point emulation
217#
218
219#
220# At least one emulation must be selected
221#
222CONFIG_FPE_NWFPE=y
223# CONFIG_FPE_NWFPE_XP is not set
224# CONFIG_FPE_FASTFPE is not set
225# CONFIG_VFP is not set
226
227#
228# Userspace binary formats
229#
230CONFIG_BINFMT_ELF=y
231# CONFIG_BINFMT_AOUT is not set
232# CONFIG_BINFMT_MISC is not set
233# CONFIG_ARTHUR is not set
234
235#
236# Power management options
237#
238# CONFIG_PM is not set
239# CONFIG_APM is not set
240
241#
242# Networking
243#
244CONFIG_NET=y
245
246#
247# Networking options
248#
249# CONFIG_NETDEBUG is not set
250CONFIG_PACKET=y
251# CONFIG_PACKET_MMAP is not set
252CONFIG_UNIX=y
253# CONFIG_NET_KEY is not set
254CONFIG_INET=y
255# CONFIG_IP_MULTICAST is not set
256# CONFIG_IP_ADVANCED_ROUTER is not set
257CONFIG_IP_FIB_HASH=y
258CONFIG_IP_PNP=y
259# CONFIG_IP_PNP_DHCP is not set
260CONFIG_IP_PNP_BOOTP=y
261CONFIG_IP_PNP_RARP=y
262# CONFIG_NET_IPIP is not set
263# CONFIG_NET_IPGRE is not set
264# CONFIG_ARPD is not set
265# CONFIG_SYN_COOKIES is not set
266# CONFIG_INET_AH is not set
267# CONFIG_INET_ESP is not set
268# CONFIG_INET_IPCOMP is not set
269# CONFIG_INET_XFRM_TUNNEL is not set
270# CONFIG_INET_TUNNEL is not set
271# CONFIG_INET_XFRM_MODE_TRANSPORT is not set
272# CONFIG_INET_XFRM_MODE_TUNNEL is not set
273# CONFIG_INET_XFRM_MODE_BEET is not set
274# CONFIG_INET_DIAG is not set
275# CONFIG_TCP_CONG_ADVANCED is not set
276CONFIG_TCP_CONG_CUBIC=y
277CONFIG_DEFAULT_TCP_CONG="cubic"
278# CONFIG_TCP_MD5SIG is not set
279# CONFIG_IPV6 is not set
280# CONFIG_INET6_XFRM_TUNNEL is not set
281# CONFIG_INET6_TUNNEL is not set
282# CONFIG_NETWORK_SECMARK is not set
283# CONFIG_NETFILTER is not set
284
285#
286# DCCP Configuration (EXPERIMENTAL)
287#
288# CONFIG_IP_DCCP is not set
289
290#
291# SCTP Configuration (EXPERIMENTAL)
292#
293# CONFIG_IP_SCTP is not set
294
295#
296# TIPC Configuration (EXPERIMENTAL)
297#
298# CONFIG_TIPC is not set
299# CONFIG_ATM is not set
300# CONFIG_BRIDGE is not set
301# CONFIG_VLAN_8021Q is not set
302# CONFIG_DECNET is not set
303# CONFIG_LLC2 is not set
304# CONFIG_IPX is not set
305# CONFIG_ATALK is not set
306# CONFIG_X25 is not set
307# CONFIG_LAPB is not set
308# CONFIG_ECONET is not set
309# CONFIG_WAN_ROUTER is not set
310
311#
312# QoS and/or fair queueing
313#
314# CONFIG_NET_SCHED is not set
315
316#
317# Network testing
318#
319# CONFIG_NET_PKTGEN is not set
320# CONFIG_HAMRADIO is not set
321# CONFIG_IRDA is not set
322# CONFIG_BT is not set
323# CONFIG_IEEE80211 is not set
324
325#
326# Device Drivers
327#
328
329#
330# Generic Driver Options
331#
332CONFIG_STANDALONE=y
333CONFIG_PREVENT_FIRMWARE_BUILD=y
334# CONFIG_FW_LOADER is not set
335# CONFIG_DEBUG_DRIVER is not set
336# CONFIG_SYS_HYPERVISOR is not set
337
338#
339# Connector - unified userspace <-> kernelspace linker
340#
341# CONFIG_CONNECTOR is not set
342
343#
344# Memory Technology Devices (MTD)
345#
346CONFIG_MTD=y
347# CONFIG_MTD_DEBUG is not set
348# CONFIG_MTD_CONCAT is not set
349CONFIG_MTD_PARTITIONS=y
350# CONFIG_MTD_REDBOOT_PARTS is not set
351CONFIG_MTD_CMDLINE_PARTS=y
352# CONFIG_MTD_AFS_PARTS is not set
353
354#
355# User Modules And Translation Layers
356#
357CONFIG_MTD_CHAR=y
358CONFIG_MTD_BLKDEVS=y
359CONFIG_MTD_BLOCK=y
360# CONFIG_FTL is not set
361# CONFIG_NFTL is not set
362# CONFIG_INFTL is not set
363# CONFIG_RFD_FTL is not set
364# CONFIG_SSFDC is not set
365
366#
367# RAM/ROM/Flash chip drivers
368#
369# CONFIG_MTD_CFI is not set
370# CONFIG_MTD_JEDECPROBE is not set
371CONFIG_MTD_MAP_BANK_WIDTH_1=y
372CONFIG_MTD_MAP_BANK_WIDTH_2=y
373CONFIG_MTD_MAP_BANK_WIDTH_4=y
374# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set
375# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set
376# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set
377CONFIG_MTD_CFI_I1=y
378CONFIG_MTD_CFI_I2=y
379# CONFIG_MTD_CFI_I4 is not set
380# CONFIG_MTD_CFI_I8 is not set
381# CONFIG_MTD_RAM is not set
382# CONFIG_MTD_ROM is not set
383# CONFIG_MTD_ABSENT is not set
384# CONFIG_MTD_OBSOLETE_CHIPS is not set
385
386#
387# Mapping drivers for chip access
388#
389# CONFIG_MTD_COMPLEX_MAPPINGS is not set
390# CONFIG_MTD_PLATRAM is not set
391
392#
393# Self-contained MTD device drivers
394#
395CONFIG_MTD_DATAFLASH=y
396# CONFIG_MTD_M25P80 is not set
397# CONFIG_MTD_SLRAM is not set
398# CONFIG_MTD_PHRAM is not set
399# CONFIG_MTD_MTDRAM is not set
400# CONFIG_MTD_BLOCK2MTD is not set
401
402#
403# Disk-On-Chip Device Drivers
404#
405# CONFIG_MTD_DOC2000 is not set
406# CONFIG_MTD_DOC2001 is not set
407# CONFIG_MTD_DOC2001PLUS is not set
408
409#
410# NAND Flash Device Drivers
411#
412CONFIG_MTD_NAND=y
413# CONFIG_MTD_NAND_VERIFY_WRITE is not set
414# CONFIG_MTD_NAND_ECC_SMC is not set
415CONFIG_MTD_NAND_IDS=y
416# CONFIG_MTD_NAND_DISKONCHIP is not set
417CONFIG_MTD_NAND_AT91=y
418# CONFIG_MTD_NAND_NANDSIM is not set
419
420#
421# OneNAND Flash Device Drivers
422#
423# CONFIG_MTD_ONENAND is not set
424
425#
426# Parallel port support
427#
428# CONFIG_PARPORT is not set
429
430#
431# Plug and Play support
432#
433
434#
435# Block devices
436#
437# CONFIG_BLK_DEV_COW_COMMON is not set
438CONFIG_BLK_DEV_LOOP=y
439# CONFIG_BLK_DEV_CRYPTOLOOP is not set
440# CONFIG_BLK_DEV_NBD is not set
441# CONFIG_BLK_DEV_UB is not set
442CONFIG_BLK_DEV_RAM=y
443CONFIG_BLK_DEV_RAM_COUNT=16
444CONFIG_BLK_DEV_RAM_SIZE=8192
445CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
446CONFIG_BLK_DEV_INITRD=y
447# CONFIG_CDROM_PKTCDVD is not set
448# CONFIG_ATA_OVER_ETH is not set
449
450#
451# SCSI device support
452#
453# CONFIG_RAID_ATTRS is not set
454CONFIG_SCSI=y
455# CONFIG_SCSI_TGT is not set
456# CONFIG_SCSI_NETLINK is not set
457CONFIG_SCSI_PROC_FS=y
458
459#
460# SCSI support type (disk, tape, CD-ROM)
461#
462CONFIG_BLK_DEV_SD=y
463# CONFIG_CHR_DEV_ST is not set
464# CONFIG_CHR_DEV_OSST is not set
465# CONFIG_BLK_DEV_SR is not set
466# CONFIG_CHR_DEV_SG is not set
467# CONFIG_CHR_DEV_SCH is not set
468
469#
470# Some SCSI devices (e.g. CD jukebox) support multiple LUNs
471#
472CONFIG_SCSI_MULTI_LUN=y
473# CONFIG_SCSI_CONSTANTS is not set
474# CONFIG_SCSI_LOGGING is not set
475# CONFIG_SCSI_SCAN_ASYNC is not set
476
477#
478# SCSI Transports
479#
480# CONFIG_SCSI_SPI_ATTRS is not set
481# CONFIG_SCSI_FC_ATTRS is not set
482# CONFIG_SCSI_ISCSI_ATTRS is not set
483# CONFIG_SCSI_SAS_ATTRS is not set
484# CONFIG_SCSI_SAS_LIBSAS is not set
485
486#
487# SCSI low-level drivers
488#
489# CONFIG_ISCSI_TCP is not set
490# CONFIG_SCSI_DEBUG is not set
491
492#
493# Serial ATA (prod) and Parallel ATA (experimental) drivers
494#
495# CONFIG_ATA is not set
496
497#
498# Multi-device support (RAID and LVM)
499#
500# CONFIG_MD is not set
501
502#
503# Fusion MPT device support
504#
505# CONFIG_FUSION is not set
506
507#
508# IEEE 1394 (FireWire) support
509#
510
511#
512# I2O device support
513#
514
515#
516# Network device support
517#
518CONFIG_NETDEVICES=y
519# CONFIG_DUMMY is not set
520# CONFIG_BONDING is not set
521# CONFIG_EQUALIZER is not set
522# CONFIG_TUN is not set
523
524#
525# PHY device support
526#
527# CONFIG_PHYLIB is not set
528
529#
530# Ethernet (10 or 100Mbit)
531#
532CONFIG_NET_ETHERNET=y
533CONFIG_MII=y
534# CONFIG_SMC91X is not set
535# CONFIG_DM9000 is not set
536
537#
538# Ethernet (1000 Mbit)
539#
540
541#
542# Ethernet (10000 Mbit)
543#
544
545#
546# Token Ring devices
547#
548
549#
550# Wireless LAN (non-hamradio)
551#
552# CONFIG_NET_RADIO is not set
553
554#
555# Wan interfaces
556#
557# CONFIG_WAN is not set
558# CONFIG_PPP is not set
559# CONFIG_SLIP is not set
560# CONFIG_SHAPER is not set
561# CONFIG_NETCONSOLE is not set
562# CONFIG_NETPOLL is not set
563# CONFIG_NET_POLL_CONTROLLER is not set
564
565#
566# ISDN subsystem
567#
568# CONFIG_ISDN is not set
569
570#
571# Input device support
572#
573CONFIG_INPUT=y
574# CONFIG_INPUT_FF_MEMLESS is not set
575
576#
577# Userland interfaces
578#
579CONFIG_INPUT_MOUSEDEV=y
580# CONFIG_INPUT_MOUSEDEV_PSAUX is not set
581CONFIG_INPUT_MOUSEDEV_SCREEN_X=1024
582CONFIG_INPUT_MOUSEDEV_SCREEN_Y=768
583# CONFIG_INPUT_JOYDEV is not set
584CONFIG_INPUT_TSDEV=y
585CONFIG_INPUT_TSDEV_SCREEN_X=240
586CONFIG_INPUT_TSDEV_SCREEN_Y=320
587CONFIG_INPUT_EVDEV=y
588# CONFIG_INPUT_EVBUG is not set
589
590#
591# Input Device Drivers
592#
593# CONFIG_INPUT_KEYBOARD is not set
594# CONFIG_INPUT_MOUSE is not set
595# CONFIG_INPUT_JOYSTICK is not set
596CONFIG_INPUT_TOUCHSCREEN=y
597CONFIG_TOUCHSCREEN_ADS7846=y
598# CONFIG_TOUCHSCREEN_GUNZE is not set
599# CONFIG_TOUCHSCREEN_ELO is not set
600# CONFIG_TOUCHSCREEN_MTOUCH is not set
601# CONFIG_TOUCHSCREEN_MK712 is not set
602# CONFIG_TOUCHSCREEN_PENMOUNT is not set
603# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set
604# CONFIG_TOUCHSCREEN_TOUCHWIN is not set
605# CONFIG_TOUCHSCREEN_UCB1400 is not set
606# CONFIG_INPUT_MISC is not set
607
608#
609# Hardware I/O ports
610#
611# CONFIG_SERIO is not set
612# CONFIG_GAMEPORT is not set
613
614#
615# Character devices
616#
617CONFIG_VT=y
618CONFIG_VT_CONSOLE=y
619CONFIG_HW_CONSOLE=y
620# CONFIG_VT_HW_CONSOLE_BINDING is not set
621# CONFIG_SERIAL_NONSTANDARD is not set
622
623#
624# Serial drivers
625#
626# CONFIG_SERIAL_8250 is not set
627
628#
629# Non-8250 serial port support
630#
631CONFIG_SERIAL_ATMEL=y
632CONFIG_SERIAL_ATMEL_CONSOLE=y
633# CONFIG_SERIAL_ATMEL_TTYAT is not set
634CONFIG_SERIAL_CORE=y
635CONFIG_SERIAL_CORE_CONSOLE=y
636CONFIG_UNIX98_PTYS=y
637CONFIG_LEGACY_PTYS=y
638CONFIG_LEGACY_PTY_COUNT=256
639
640#
641# IPMI
642#
643# CONFIG_IPMI_HANDLER is not set
644
645#
646# Watchdog Cards
647#
648CONFIG_WATCHDOG=y
649CONFIG_WATCHDOG_NOWAYOUT=y
650
651#
652# Watchdog Device Drivers
653#
654# CONFIG_SOFT_WATCHDOG is not set
655
656#
657# USB-based Watchdog Cards
658#
659# CONFIG_USBPCWATCHDOG is not set
660CONFIG_HW_RANDOM=y
661# CONFIG_NVRAM is not set
662# CONFIG_DTLK is not set
663# CONFIG_R3964 is not set
664# CONFIG_RAW_DRIVER is not set
665
666#
667# TPM devices
668#
669# CONFIG_TCG_TPM is not set
670
671#
672# I2C support
673#
674CONFIG_I2C=y
675CONFIG_I2C_CHARDEV=y
676
677#
678# I2C Algorithms
679#
680# CONFIG_I2C_ALGOBIT is not set
681# CONFIG_I2C_ALGOPCF is not set
682# CONFIG_I2C_ALGOPCA is not set
683
684#
685# I2C Hardware Bus support
686#
687CONFIG_I2C_AT91=y
688# CONFIG_I2C_OCORES is not set
689# CONFIG_I2C_PARPORT_LIGHT is not set
690# CONFIG_I2C_STUB is not set
691# CONFIG_I2C_PCA is not set
692# CONFIG_I2C_PCA_ISA is not set
693
694#
695# Miscellaneous I2C Chip support
696#
697# CONFIG_SENSORS_DS1337 is not set
698# CONFIG_SENSORS_DS1374 is not set
699# CONFIG_SENSORS_EEPROM is not set
700# CONFIG_SENSORS_PCF8574 is not set
701# CONFIG_SENSORS_PCA9539 is not set
702# CONFIG_SENSORS_PCF8591 is not set
703# CONFIG_SENSORS_MAX6875 is not set
704# CONFIG_I2C_DEBUG_CORE is not set
705# CONFIG_I2C_DEBUG_ALGO is not set
706# CONFIG_I2C_DEBUG_BUS is not set
707# CONFIG_I2C_DEBUG_CHIP is not set
708
709#
710# SPI support
711#
712CONFIG_SPI=y
713# CONFIG_SPI_DEBUG is not set
714CONFIG_SPI_MASTER=y
715
716#
717# SPI Master Controller Drivers
718#
719CONFIG_SPI_ATMEL=y
720# CONFIG_SPI_BITBANG is not set
721
722#
723# SPI Protocol Masters
724#
725
726#
727# Dallas's 1-wire bus
728#
729# CONFIG_W1 is not set
730
731#
732# Hardware Monitoring support
733#
734# CONFIG_HWMON is not set
735# CONFIG_HWMON_VID is not set
736
737#
738# Misc devices
739#
740# CONFIG_TIFM_CORE is not set
741
742#
743# LED devices
744#
745# CONFIG_NEW_LEDS is not set
746
747#
748# LED drivers
749#
750
751#
752# LED Triggers
753#
754
755#
756# Multimedia devices
757#
758# CONFIG_VIDEO_DEV is not set
759
760#
761# Digital Video Broadcasting Devices
762#
763# CONFIG_DVB is not set
764# CONFIG_USB_DABUSB is not set
765
766#
767# Graphics support
768#
769# CONFIG_FIRMWARE_EDID is not set
770CONFIG_FB=y
771# CONFIG_FB_CFB_FILLRECT is not set
772# CONFIG_FB_CFB_COPYAREA is not set
773# CONFIG_FB_CFB_IMAGEBLIT is not set
774# CONFIG_FB_MACMODES is not set
775# CONFIG_FB_BACKLIGHT is not set
776# CONFIG_FB_MODE_HELPERS is not set
777# CONFIG_FB_TILEBLITTING is not set
778# CONFIG_FB_S1D13XXX is not set
779# CONFIG_FB_VIRTUAL is not set
780
781#
782# Console display driver support
783#
784# CONFIG_VGA_CONSOLE is not set
785CONFIG_DUMMY_CONSOLE=y
786# CONFIG_FRAMEBUFFER_CONSOLE is not set
787
788#
789# Logo configuration
790#
791# CONFIG_LOGO is not set
792# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
793
794#
795# Sound
796#
797# CONFIG_SOUND is not set
798
799#
800# HID Devices
801#
802CONFIG_HID=y
803
804#
805# USB support
806#
807CONFIG_USB_ARCH_HAS_HCD=y
808CONFIG_USB_ARCH_HAS_OHCI=y
809# CONFIG_USB_ARCH_HAS_EHCI is not set
810CONFIG_USB=y
811# CONFIG_USB_DEBUG is not set
812
813#
814# Miscellaneous USB options
815#
816CONFIG_USB_DEVICEFS=y
817# CONFIG_USB_BANDWIDTH is not set
818# CONFIG_USB_DYNAMIC_MINORS is not set
819# CONFIG_USB_MULTITHREAD_PROBE is not set
820# CONFIG_USB_OTG is not set
821
822#
823# USB Host Controller Drivers
824#
825# CONFIG_USB_ISP116X_HCD is not set
826CONFIG_USB_OHCI_HCD=y
827# CONFIG_USB_OHCI_BIG_ENDIAN is not set
828CONFIG_USB_OHCI_LITTLE_ENDIAN=y
829# CONFIG_USB_SL811_HCD is not set
830
831#
832# USB Device Class drivers
833#
834# CONFIG_USB_ACM is not set
835# CONFIG_USB_PRINTER is not set
836
837#
838# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
839#
840
841#
842# may also be needed; see USB_STORAGE Help for more information
843#
844CONFIG_USB_STORAGE=y
845# CONFIG_USB_STORAGE_DEBUG is not set
846# CONFIG_USB_STORAGE_DATAFAB is not set
847# CONFIG_USB_STORAGE_FREECOM is not set
848# CONFIG_USB_STORAGE_DPCM is not set
849# CONFIG_USB_STORAGE_USBAT is not set
850# CONFIG_USB_STORAGE_SDDR09 is not set
851# CONFIG_USB_STORAGE_SDDR55 is not set
852# CONFIG_USB_STORAGE_JUMPSHOT is not set
853# CONFIG_USB_STORAGE_ALAUDA is not set
854# CONFIG_USB_STORAGE_ONETOUCH is not set
855# CONFIG_USB_STORAGE_KARMA is not set
856# CONFIG_USB_LIBUSUAL is not set
857
858#
859# USB Input Devices
860#
861# CONFIG_USB_HID is not set
862
863#
864# USB HID Boot Protocol drivers
865#
866# CONFIG_USB_KBD is not set
867# CONFIG_USB_MOUSE is not set
868# CONFIG_USB_AIPTEK is not set
869# CONFIG_USB_WACOM is not set
870# CONFIG_USB_ACECAD is not set
871# CONFIG_USB_KBTAB is not set
872# CONFIG_USB_POWERMATE is not set
873# CONFIG_USB_TOUCHSCREEN is not set
874# CONFIG_USB_YEALINK is not set
875# CONFIG_USB_XPAD is not set
876# CONFIG_USB_ATI_REMOTE is not set
877# CONFIG_USB_ATI_REMOTE2 is not set
878# CONFIG_USB_KEYSPAN_REMOTE is not set
879# CONFIG_USB_APPLETOUCH is not set
880
881#
882# USB Imaging devices
883#
884# CONFIG_USB_MDC800 is not set
885# CONFIG_USB_MICROTEK is not set
886
887#
888# USB Network Adapters
889#
890# CONFIG_USB_CATC is not set
891# CONFIG_USB_KAWETH is not set
892# CONFIG_USB_PEGASUS is not set
893# CONFIG_USB_RTL8150 is not set
894# CONFIG_USB_USBNET_MII is not set
895# CONFIG_USB_USBNET is not set
896CONFIG_USB_MON=y
897
898#
899# USB port drivers
900#
901
902#
903# USB Serial Converter support
904#
905# CONFIG_USB_SERIAL is not set
906
907#
908# USB Miscellaneous drivers
909#
910# CONFIG_USB_EMI62 is not set
911# CONFIG_USB_EMI26 is not set
912# CONFIG_USB_ADUTUX is not set
913# CONFIG_USB_AUERSWALD is not set
914# CONFIG_USB_RIO500 is not set
915# CONFIG_USB_LEGOTOWER is not set
916# CONFIG_USB_LCD is not set
917# CONFIG_USB_LED is not set
918# CONFIG_USB_CYPRESS_CY7C63 is not set
919# CONFIG_USB_CYTHERM is not set
920# CONFIG_USB_PHIDGET is not set
921# CONFIG_USB_IDMOUSE is not set
922# CONFIG_USB_FTDI_ELAN is not set
923# CONFIG_USB_APPLEDISPLAY is not set
924# CONFIG_USB_LD is not set
925# CONFIG_USB_TRANCEVIBRATOR is not set
926# CONFIG_USB_TEST is not set
927
928#
929# USB DSL modem support
930#
931
932#
933# USB Gadget Support
934#
935CONFIG_USB_GADGET=y
936# CONFIG_USB_GADGET_DEBUG_FILES is not set
937CONFIG_USB_GADGET_SELECTED=y
938# CONFIG_USB_GADGET_NET2280 is not set
939# CONFIG_USB_GADGET_PXA2XX is not set
940# CONFIG_USB_GADGET_GOKU is not set
941# CONFIG_USB_GADGET_LH7A40X is not set
942# CONFIG_USB_GADGET_OMAP is not set
943CONFIG_USB_GADGET_AT91=y
944CONFIG_USB_AT91=y
945# CONFIG_USB_GADGET_DUMMY_HCD is not set
946# CONFIG_USB_GADGET_DUALSPEED is not set
947CONFIG_USB_ZERO=m
948# CONFIG_USB_ETH is not set
949CONFIG_USB_GADGETFS=m
950CONFIG_USB_FILE_STORAGE=m
951# CONFIG_USB_FILE_STORAGE_TEST is not set
952CONFIG_USB_G_SERIAL=m
953# CONFIG_USB_MIDI_GADGET is not set
954
955#
956# MMC/SD Card support
957#
958CONFIG_MMC=y
959# CONFIG_MMC_DEBUG is not set
960CONFIG_MMC_BLOCK=y
961CONFIG_MMC_AT91=m
962# CONFIG_MMC_TIFM_SD is not set
963
964#
965# Real Time Clock
966#
967CONFIG_RTC_LIB=y
968# CONFIG_RTC_CLASS is not set
969
970#
971# File systems
972#
973CONFIG_EXT2_FS=y
974# CONFIG_EXT2_FS_XATTR is not set
975# CONFIG_EXT2_FS_XIP is not set
976# CONFIG_EXT3_FS is not set
977# CONFIG_EXT4DEV_FS is not set
978# CONFIG_REISERFS_FS is not set
979# CONFIG_JFS_FS is not set
980# CONFIG_FS_POSIX_ACL is not set
981# CONFIG_XFS_FS is not set
982# CONFIG_GFS2_FS is not set
983# CONFIG_OCFS2_FS is not set
984# CONFIG_MINIX_FS is not set
985# CONFIG_ROMFS_FS is not set
986CONFIG_INOTIFY=y
987CONFIG_INOTIFY_USER=y
988# CONFIG_QUOTA is not set
989CONFIG_DNOTIFY=y
990# CONFIG_AUTOFS_FS is not set
991# CONFIG_AUTOFS4_FS is not set
992# CONFIG_FUSE_FS is not set
993
994#
995# CD-ROM/DVD Filesystems
996#
997# CONFIG_ISO9660_FS is not set
998# CONFIG_UDF_FS is not set
999
1000#
1001# DOS/FAT/NT Filesystems
1002#
1003CONFIG_FAT_FS=y
1004# CONFIG_MSDOS_FS is not set
1005CONFIG_VFAT_FS=y
1006CONFIG_FAT_DEFAULT_CODEPAGE=437
1007CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1"
1008# CONFIG_NTFS_FS is not set
1009
1010#
1011# Pseudo filesystems
1012#
1013CONFIG_PROC_FS=y
1014CONFIG_PROC_SYSCTL=y
1015CONFIG_SYSFS=y
1016CONFIG_TMPFS=y
1017# CONFIG_TMPFS_POSIX_ACL is not set
1018# CONFIG_HUGETLB_PAGE is not set
1019CONFIG_RAMFS=y
1020# CONFIG_CONFIGFS_FS is not set
1021
1022#
1023# Miscellaneous filesystems
1024#
1025# CONFIG_ADFS_FS is not set
1026# CONFIG_AFFS_FS is not set
1027# CONFIG_HFS_FS is not set
1028# CONFIG_HFSPLUS_FS is not set
1029# CONFIG_BEFS_FS is not set
1030# CONFIG_BFS_FS is not set
1031# CONFIG_EFS_FS is not set
1032CONFIG_JFFS2_FS=y
1033CONFIG_JFFS2_FS_DEBUG=0
1034CONFIG_JFFS2_FS_WRITEBUFFER=y
1035# CONFIG_JFFS2_SUMMARY is not set
1036# CONFIG_JFFS2_FS_XATTR is not set
1037# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set
1038CONFIG_JFFS2_ZLIB=y
1039CONFIG_JFFS2_RTIME=y
1040# CONFIG_JFFS2_RUBIN is not set
1041CONFIG_CRAMFS=y
1042# CONFIG_VXFS_FS is not set
1043# CONFIG_HPFS_FS is not set
1044# CONFIG_QNX4FS_FS is not set
1045# CONFIG_SYSV_FS is not set
1046# CONFIG_UFS_FS is not set
1047
1048#
1049# Network File Systems
1050#
1051CONFIG_NFS_FS=y
1052# CONFIG_NFS_V3 is not set
1053# CONFIG_NFS_V4 is not set
1054# CONFIG_NFS_DIRECTIO is not set
1055# CONFIG_NFSD is not set
1056CONFIG_ROOT_NFS=y
1057CONFIG_LOCKD=y
1058CONFIG_NFS_COMMON=y
1059CONFIG_SUNRPC=y
1060# CONFIG_RPCSEC_GSS_KRB5 is not set
1061# CONFIG_RPCSEC_GSS_SPKM3 is not set
1062# CONFIG_SMB_FS is not set
1063# CONFIG_CIFS is not set
1064# CONFIG_NCP_FS is not set
1065# CONFIG_CODA_FS is not set
1066# CONFIG_AFS_FS is not set
1067# CONFIG_9P_FS is not set
1068
1069#
1070# Partition Types
1071#
1072# CONFIG_PARTITION_ADVANCED is not set
1073CONFIG_MSDOS_PARTITION=y
1074
1075#
1076# Native Language Support
1077#
1078CONFIG_NLS=y
1079CONFIG_NLS_DEFAULT="iso8859-1"
1080CONFIG_NLS_CODEPAGE_437=y
1081# CONFIG_NLS_CODEPAGE_737 is not set
1082# CONFIG_NLS_CODEPAGE_775 is not set
1083CONFIG_NLS_CODEPAGE_850=y
1084# CONFIG_NLS_CODEPAGE_852 is not set
1085# CONFIG_NLS_CODEPAGE_855 is not set
1086# CONFIG_NLS_CODEPAGE_857 is not set
1087# CONFIG_NLS_CODEPAGE_860 is not set
1088# CONFIG_NLS_CODEPAGE_861 is not set
1089# CONFIG_NLS_CODEPAGE_862 is not set
1090# CONFIG_NLS_CODEPAGE_863 is not set
1091# CONFIG_NLS_CODEPAGE_864 is not set
1092# CONFIG_NLS_CODEPAGE_865 is not set
1093# CONFIG_NLS_CODEPAGE_866 is not set
1094# CONFIG_NLS_CODEPAGE_869 is not set
1095# CONFIG_NLS_CODEPAGE_936 is not set
1096# CONFIG_NLS_CODEPAGE_950 is not set
1097# CONFIG_NLS_CODEPAGE_932 is not set
1098# CONFIG_NLS_CODEPAGE_949 is not set
1099# CONFIG_NLS_CODEPAGE_874 is not set
1100# CONFIG_NLS_ISO8859_8 is not set
1101# CONFIG_NLS_CODEPAGE_1250 is not set
1102# CONFIG_NLS_CODEPAGE_1251 is not set
1103# CONFIG_NLS_ASCII is not set
1104CONFIG_NLS_ISO8859_1=y
1105# CONFIG_NLS_ISO8859_2 is not set
1106# CONFIG_NLS_ISO8859_3 is not set
1107# CONFIG_NLS_ISO8859_4 is not set
1108# CONFIG_NLS_ISO8859_5 is not set
1109# CONFIG_NLS_ISO8859_6 is not set
1110# CONFIG_NLS_ISO8859_7 is not set
1111# CONFIG_NLS_ISO8859_9 is not set
1112# CONFIG_NLS_ISO8859_13 is not set
1113# CONFIG_NLS_ISO8859_14 is not set
1114# CONFIG_NLS_ISO8859_15 is not set
1115# CONFIG_NLS_KOI8_R is not set
1116# CONFIG_NLS_KOI8_U is not set
1117# CONFIG_NLS_UTF8 is not set
1118
1119#
1120# Distributed Lock Manager
1121#
1122# CONFIG_DLM is not set
1123
1124#
1125# Profiling support
1126#
1127# CONFIG_PROFILING is not set
1128
1129#
1130# Kernel hacking
1131#
1132# CONFIG_PRINTK_TIME is not set
1133CONFIG_ENABLE_MUST_CHECK=y
1134# CONFIG_MAGIC_SYSRQ is not set
1135# CONFIG_UNUSED_SYMBOLS is not set
1136# CONFIG_DEBUG_FS is not set
1137# CONFIG_HEADERS_CHECK is not set
1138CONFIG_DEBUG_KERNEL=y
1139CONFIG_LOG_BUF_SHIFT=14
1140CONFIG_DETECT_SOFTLOCKUP=y
1141# CONFIG_SCHEDSTATS is not set
1142# CONFIG_DEBUG_SLAB is not set
1143# CONFIG_DEBUG_RT_MUTEXES is not set
1144# CONFIG_RT_MUTEX_TESTER is not set
1145# CONFIG_DEBUG_SPINLOCK is not set
1146# CONFIG_DEBUG_MUTEXES is not set
1147# CONFIG_DEBUG_RWSEMS is not set
1148# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
1149# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
1150# CONFIG_DEBUG_KOBJECT is not set
1151CONFIG_DEBUG_BUGVERBOSE=y
1152# CONFIG_DEBUG_INFO is not set
1153# CONFIG_DEBUG_VM is not set
1154# CONFIG_DEBUG_LIST is not set
1155CONFIG_FRAME_POINTER=y
1156CONFIG_FORCED_INLINING=y
1157# CONFIG_RCU_TORTURE_TEST is not set
1158CONFIG_DEBUG_USER=y
1159# CONFIG_DEBUG_ERRORS is not set
1160CONFIG_DEBUG_LL=y
1161# CONFIG_DEBUG_ICEDCC is not set
1162
1163#
1164# Security options
1165#
1166# CONFIG_KEYS is not set
1167# CONFIG_SECURITY is not set
1168
1169#
1170# Cryptographic options
1171#
1172# CONFIG_CRYPTO is not set
1173
1174#
1175# Library routines
1176#
1177CONFIG_BITREVERSE=y
1178# CONFIG_CRC_CCITT is not set
1179# CONFIG_CRC16 is not set
1180CONFIG_CRC32=y
1181# CONFIG_LIBCRC32C is not set
1182CONFIG_ZLIB_INFLATE=y
1183CONFIG_PLIST=y
1184CONFIG_IOMAP_COPY=y
diff --git a/arch/arm/configs/ateb9200_defconfig b/arch/arm/configs/ateb9200_defconfig
index 3de5c643848c..baa97698c744 100644
--- a/arch/arm/configs/ateb9200_defconfig
+++ b/arch/arm/configs/ateb9200_defconfig
@@ -1066,7 +1066,7 @@ CONFIG_RTC_INTF_DEV=y
1066# CONFIG_RTC_DRV_PCF8563 is not set 1066# CONFIG_RTC_DRV_PCF8563 is not set
1067# CONFIG_RTC_DRV_RS5C372 is not set 1067# CONFIG_RTC_DRV_RS5C372 is not set
1068# CONFIG_RTC_DRV_M48T86 is not set 1068# CONFIG_RTC_DRV_M48T86 is not set
1069CONFIG_RTC_DRV_AT91=y 1069CONFIG_RTC_DRV_AT91RM9200=y
1070# CONFIG_RTC_DRV_TEST is not set 1070# CONFIG_RTC_DRV_TEST is not set
1071 1071
1072# 1072#
diff --git a/arch/arm/configs/csb337_defconfig b/arch/arm/configs/csb337_defconfig
index 2cadd51506bb..88e5d28aeec7 100644
--- a/arch/arm/configs/csb337_defconfig
+++ b/arch/arm/configs/csb337_defconfig
@@ -355,10 +355,12 @@ CONFIG_MTD_CFI_UTIL=y
355# Mapping drivers for chip access 355# Mapping drivers for chip access
356# 356#
357# CONFIG_MTD_COMPLEX_MAPPINGS is not set 357# CONFIG_MTD_COMPLEX_MAPPINGS is not set
358# CONFIG_MTD_PHYSMAP is not set 358CONFIG_MTD_PHYSMAP=y
359CONFIG_MTD_PHYSMAP_START=0
360CONFIG_MTD_PHYSMAP_LEN=0
361CONFIG_MTD_PHYSMAP_BANKWIDTH=0
359# CONFIG_MTD_ARM_INTEGRATOR is not set 362# CONFIG_MTD_ARM_INTEGRATOR is not set
360# CONFIG_MTD_PLATRAM is not set 363# CONFIG_MTD_PLATRAM is not set
361CONFIG_MTD_CSB337=y
362 364
363# 365#
364# Self-contained MTD device drivers 366# Self-contained MTD device drivers
@@ -986,7 +988,7 @@ CONFIG_RTC_DRV_DS1307=y
986# CONFIG_RTC_DRV_PCF8583 is not set 988# CONFIG_RTC_DRV_PCF8583 is not set
987# CONFIG_RTC_DRV_RS5C372 is not set 989# CONFIG_RTC_DRV_RS5C372 is not set
988# CONFIG_RTC_DRV_M48T86 is not set 990# CONFIG_RTC_DRV_M48T86 is not set
989CONFIG_RTC_DRV_AT91=y 991CONFIG_RTC_DRV_AT91RM9200=y
990# CONFIG_RTC_DRV_TEST is not set 992# CONFIG_RTC_DRV_TEST is not set
991# CONFIG_RTC_DRV_V3020 is not set 993# CONFIG_RTC_DRV_V3020 is not set
992 994
diff --git a/arch/arm/configs/csb637_defconfig b/arch/arm/configs/csb637_defconfig
index 94908c1df4cf..669f035896f9 100644
--- a/arch/arm/configs/csb637_defconfig
+++ b/arch/arm/configs/csb637_defconfig
@@ -355,10 +355,12 @@ CONFIG_MTD_CFI_UTIL=y
355# Mapping drivers for chip access 355# Mapping drivers for chip access
356# 356#
357# CONFIG_MTD_COMPLEX_MAPPINGS is not set 357# CONFIG_MTD_COMPLEX_MAPPINGS is not set
358# CONFIG_MTD_PHYSMAP is not set 358CONFIG_MTD_PHYSMAP=y
359CONFIG_MTD_PHYSMAP_START=0
360CONFIG_MTD_PHYSMAP_LEN=0
361CONFIG_MTD_PHYSMAP_BANKWIDTH=0
359# CONFIG_MTD_ARM_INTEGRATOR is not set 362# CONFIG_MTD_ARM_INTEGRATOR is not set
360# CONFIG_MTD_PLATRAM is not set 363# CONFIG_MTD_PLATRAM is not set
361CONFIG_MTD_CSB637=y
362 364
363# 365#
364# Self-contained MTD device drivers 366# Self-contained MTD device drivers
diff --git a/arch/arm/configs/kafa_defconfig b/arch/arm/configs/kafa_defconfig
index a4cdafc1548a..a0f48d54fbcc 100644
--- a/arch/arm/configs/kafa_defconfig
+++ b/arch/arm/configs/kafa_defconfig
@@ -718,7 +718,7 @@ CONFIG_RTC_INTF_DEV=y
718# CONFIG_RTC_DRV_PCF8563 is not set 718# CONFIG_RTC_DRV_PCF8563 is not set
719# CONFIG_RTC_DRV_RS5C372 is not set 719# CONFIG_RTC_DRV_RS5C372 is not set
720# CONFIG_RTC_DRV_M48T86 is not set 720# CONFIG_RTC_DRV_M48T86 is not set
721CONFIG_RTC_DRV_AT91=y 721CONFIG_RTC_DRV_AT91RM9200=y
722# CONFIG_RTC_DRV_TEST is not set 722# CONFIG_RTC_DRV_TEST is not set
723 723
724# 724#
diff --git a/arch/arm/configs/ns9xxx_defconfig b/arch/arm/configs/ns9xxx_defconfig
new file mode 100644
index 000000000000..0e5794c6a48e
--- /dev/null
+++ b/arch/arm/configs/ns9xxx_defconfig
@@ -0,0 +1,621 @@
1#
2# Automatically generated make config: don't edit
3# Linux kernel version: 2.6.20
4# Thu Feb 15 20:51:47 2007
5#
6CONFIG_ARM=y
7# CONFIG_GENERIC_TIME is not set
8CONFIG_MMU=y
9CONFIG_GENERIC_HARDIRQS=y
10CONFIG_TRACE_IRQFLAGS_SUPPORT=y
11CONFIG_HARDIRQS_SW_RESEND=y
12CONFIG_GENERIC_IRQ_PROBE=y
13CONFIG_RWSEM_GENERIC_SPINLOCK=y
14# CONFIG_ARCH_HAS_ILOG2_U32 is not set
15# CONFIG_ARCH_HAS_ILOG2_U64 is not set
16CONFIG_GENERIC_HWEIGHT=y
17CONFIG_GENERIC_CALIBRATE_DELAY=y
18CONFIG_VECTORS_BASE=0xffff0000
19CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
20
21#
22# Code maturity level options
23#
24CONFIG_EXPERIMENTAL=y
25CONFIG_BROKEN_ON_SMP=y
26CONFIG_INIT_ENV_ARG_LIMIT=32
27
28#
29# General setup
30#
31CONFIG_LOCALVERSION=""
32CONFIG_LOCALVERSION_AUTO=y
33CONFIG_SWAP=y
34CONFIG_SYSVIPC=y
35# CONFIG_IPC_NS is not set
36# CONFIG_BSD_PROCESS_ACCT is not set
37# CONFIG_UTS_NS is not set
38CONFIG_IKCONFIG=y
39CONFIG_IKCONFIG_PROC=y
40CONFIG_SYSFS_DEPRECATED=y
41# CONFIG_RELAY is not set
42CONFIG_INITRAMFS_SOURCE=""
43# CONFIG_CC_OPTIMIZE_FOR_SIZE is not set
44CONFIG_SYSCTL=y
45CONFIG_EMBEDDED=y
46CONFIG_UID16=y
47# CONFIG_SYSCTL_SYSCALL is not set
48CONFIG_KALLSYMS=y
49# CONFIG_KALLSYMS_ALL is not set
50# CONFIG_KALLSYMS_EXTRA_PASS is not set
51CONFIG_HOTPLUG=y
52CONFIG_PRINTK=y
53CONFIG_BUG=y
54CONFIG_ELF_CORE=y
55CONFIG_BASE_FULL=y
56CONFIG_FUTEX=y
57CONFIG_EPOLL=y
58CONFIG_SHMEM=y
59CONFIG_SLAB=y
60# CONFIG_VM_EVENT_COUNTERS is not set
61CONFIG_RT_MUTEXES=y
62# CONFIG_TINY_SHMEM is not set
63CONFIG_BASE_SMALL=0
64# CONFIG_SLOB is not set
65
66#
67# Loadable module support
68#
69CONFIG_MODULES=y
70CONFIG_MODULE_UNLOAD=y
71CONFIG_MODULE_FORCE_UNLOAD=y
72CONFIG_MODVERSIONS=y
73CONFIG_MODULE_SRCVERSION_ALL=y
74CONFIG_KMOD=y
75
76#
77# Block layer
78#
79CONFIG_BLOCK=y
80# CONFIG_LBD is not set
81# CONFIG_BLK_DEV_IO_TRACE is not set
82# CONFIG_LSF is not set
83
84#
85# IO Schedulers
86#
87CONFIG_IOSCHED_NOOP=y
88# CONFIG_IOSCHED_AS is not set
89# CONFIG_IOSCHED_DEADLINE is not set
90# CONFIG_IOSCHED_CFQ is not set
91# CONFIG_DEFAULT_AS is not set
92# CONFIG_DEFAULT_DEADLINE is not set
93# CONFIG_DEFAULT_CFQ is not set
94CONFIG_DEFAULT_NOOP=y
95CONFIG_DEFAULT_IOSCHED="noop"
96
97#
98# System Type
99#
100# CONFIG_ARCH_AAEC2000 is not set
101# CONFIG_ARCH_INTEGRATOR is not set
102# CONFIG_ARCH_REALVIEW is not set
103# CONFIG_ARCH_VERSATILE is not set
104# CONFIG_ARCH_AT91 is not set
105# CONFIG_ARCH_CLPS7500 is not set
106# CONFIG_ARCH_CLPS711X is not set
107# CONFIG_ARCH_CO285 is not set
108# CONFIG_ARCH_EBSA110 is not set
109# CONFIG_ARCH_EP93XX is not set
110# CONFIG_ARCH_FOOTBRIDGE is not set
111# CONFIG_ARCH_NETX is not set
112# CONFIG_ARCH_H720X is not set
113# CONFIG_ARCH_IMX is not set
114# CONFIG_ARCH_IOP32X is not set
115# CONFIG_ARCH_IOP33X is not set
116# CONFIG_ARCH_IOP13XX is not set
117# CONFIG_ARCH_IXP4XX is not set
118# CONFIG_ARCH_IXP2000 is not set
119# CONFIG_ARCH_IXP23XX is not set
120# CONFIG_ARCH_L7200 is not set
121CONFIG_ARCH_NS9XXX=y
122# CONFIG_ARCH_PNX4008 is not set
123# CONFIG_ARCH_PXA is not set
124# CONFIG_ARCH_RPC is not set
125# CONFIG_ARCH_SA1100 is not set
126# CONFIG_ARCH_S3C2410 is not set
127# CONFIG_ARCH_SHARK is not set
128# CONFIG_ARCH_LH7A40X is not set
129# CONFIG_ARCH_OMAP is not set
130
131#
132# NS9xxx Implementations
133#
134CONFIG_MACH_CC9P9360DEV=y
135CONFIG_PROCESSOR_NS9360=y
136CONFIG_BOARD_A9M9750DEV=y
137
138#
139# Processor Type
140#
141CONFIG_CPU_32=y
142CONFIG_CPU_ARM926T=y
143CONFIG_CPU_32v5=y
144CONFIG_CPU_ABRT_EV5TJ=y
145CONFIG_CPU_CACHE_VIVT=y
146CONFIG_CPU_COPY_V4WB=y
147CONFIG_CPU_TLB_V4WBI=y
148CONFIG_CPU_CP15=y
149CONFIG_CPU_CP15_MMU=y
150
151#
152# Processor Features
153#
154# CONFIG_ARM_THUMB is not set
155# CONFIG_CPU_ICACHE_DISABLE is not set
156# CONFIG_CPU_DCACHE_DISABLE is not set
157# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
158# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
159
160#
161# Bus support
162#
163
164#
165# PCCARD (PCMCIA/CardBus) support
166#
167# CONFIG_PCCARD is not set
168
169#
170# Kernel Features
171#
172# CONFIG_PREEMPT is not set
173# CONFIG_NO_IDLE_HZ is not set
174CONFIG_HZ=100
175# CONFIG_AEABI is not set
176# CONFIG_ARCH_DISCONTIGMEM_ENABLE is not set
177CONFIG_SELECT_MEMORY_MODEL=y
178CONFIG_FLATMEM_MANUAL=y
179# CONFIG_DISCONTIGMEM_MANUAL is not set
180# CONFIG_SPARSEMEM_MANUAL is not set
181CONFIG_FLATMEM=y
182CONFIG_FLAT_NODE_MEM_MAP=y
183# CONFIG_SPARSEMEM_STATIC is not set
184CONFIG_SPLIT_PTLOCK_CPUS=4096
185# CONFIG_RESOURCES_64BIT is not set
186CONFIG_ALIGNMENT_TRAP=y
187
188#
189# Boot options
190#
191CONFIG_ZBOOT_ROM_TEXT=0x0
192CONFIG_ZBOOT_ROM_BSS=0x0
193CONFIG_CMDLINE=""
194# CONFIG_XIP_KERNEL is not set
195
196#
197# Floating point emulation
198#
199
200#
201# At least one emulation must be selected
202#
203CONFIG_FPE_NWFPE=y
204# CONFIG_FPE_NWFPE_XP is not set
205# CONFIG_FPE_FASTFPE is not set
206# CONFIG_VFP is not set
207
208#
209# Userspace binary formats
210#
211CONFIG_BINFMT_ELF=y
212# CONFIG_BINFMT_AOUT is not set
213# CONFIG_BINFMT_MISC is not set
214# CONFIG_ARTHUR is not set
215
216#
217# Power management options
218#
219# CONFIG_PM is not set
220# CONFIG_APM is not set
221
222#
223# Networking
224#
225# CONFIG_NET is not set
226
227#
228# Device Drivers
229#
230
231#
232# Generic Driver Options
233#
234CONFIG_STANDALONE=y
235CONFIG_PREVENT_FIRMWARE_BUILD=y
236# CONFIG_FW_LOADER is not set
237# CONFIG_DEBUG_DRIVER is not set
238# CONFIG_SYS_HYPERVISOR is not set
239
240#
241# Connector - unified userspace <-> kernelspace linker
242#
243
244#
245# Memory Technology Devices (MTD)
246#
247# CONFIG_MTD is not set
248
249#
250# Parallel port support
251#
252# CONFIG_PARPORT is not set
253
254#
255# Plug and Play support
256#
257
258#
259# Block devices
260#
261# CONFIG_BLK_DEV_COW_COMMON is not set
262# CONFIG_BLK_DEV_LOOP is not set
263CONFIG_BLK_DEV_RAM=y
264CONFIG_BLK_DEV_RAM_COUNT=16
265CONFIG_BLK_DEV_RAM_SIZE=4096
266CONFIG_BLK_DEV_RAM_BLOCKSIZE=1024
267CONFIG_BLK_DEV_INITRD=y
268# CONFIG_CDROM_PKTCDVD is not set
269
270#
271# SCSI device support
272#
273# CONFIG_RAID_ATTRS is not set
274# CONFIG_SCSI is not set
275# CONFIG_SCSI_NETLINK is not set
276
277#
278# Serial ATA (prod) and Parallel ATA (experimental) drivers
279#
280# CONFIG_ATA is not set
281
282#
283# Multi-device support (RAID and LVM)
284#
285# CONFIG_MD is not set
286
287#
288# Fusion MPT device support
289#
290# CONFIG_FUSION is not set
291
292#
293# IEEE 1394 (FireWire) support
294#
295
296#
297# I2O device support
298#
299
300#
301# ISDN subsystem
302#
303
304#
305# Input device support
306#
307CONFIG_INPUT=y
308# CONFIG_INPUT_FF_MEMLESS is not set
309
310#
311# Userland interfaces
312#
313# CONFIG_INPUT_MOUSEDEV is not set
314# CONFIG_INPUT_JOYDEV is not set
315# CONFIG_INPUT_TSDEV is not set
316# CONFIG_INPUT_EVDEV is not set
317# CONFIG_INPUT_EVBUG is not set
318
319#
320# Input Device Drivers
321#
322# CONFIG_INPUT_KEYBOARD is not set
323# CONFIG_INPUT_MOUSE is not set
324# CONFIG_INPUT_JOYSTICK is not set
325# CONFIG_INPUT_TOUCHSCREEN is not set
326# CONFIG_INPUT_MISC is not set
327
328#
329# Hardware I/O ports
330#
331CONFIG_SERIO=y
332# CONFIG_SERIO_SERPORT is not set
333CONFIG_SERIO_LIBPS2=y
334# CONFIG_SERIO_RAW is not set
335# CONFIG_GAMEPORT is not set
336
337#
338# Character devices
339#
340CONFIG_VT=y
341CONFIG_VT_CONSOLE=y
342CONFIG_HW_CONSOLE=y
343# CONFIG_VT_HW_CONSOLE_BINDING is not set
344# CONFIG_SERIAL_NONSTANDARD is not set
345
346#
347# Serial drivers
348#
349CONFIG_SERIAL_8250=y
350CONFIG_SERIAL_8250_CONSOLE=y
351CONFIG_SERIAL_8250_NR_UARTS=4
352CONFIG_SERIAL_8250_RUNTIME_UARTS=4
353CONFIG_SERIAL_8250_EXTENDED=y
354# CONFIG_SERIAL_8250_MANY_PORTS is not set
355# CONFIG_SERIAL_8250_SHARE_IRQ is not set
356# CONFIG_SERIAL_8250_DETECT_IRQ is not set
357# CONFIG_SERIAL_8250_RSA is not set
358
359#
360# Non-8250 serial port support
361#
362CONFIG_SERIAL_CORE=y
363CONFIG_SERIAL_CORE_CONSOLE=y
364CONFIG_UNIX98_PTYS=y
365# CONFIG_LEGACY_PTYS is not set
366
367#
368# IPMI
369#
370# CONFIG_IPMI_HANDLER is not set
371
372#
373# Watchdog Cards
374#
375# CONFIG_WATCHDOG is not set
376# CONFIG_HW_RANDOM is not set
377# CONFIG_NVRAM is not set
378# CONFIG_DTLK is not set
379# CONFIG_R3964 is not set
380# CONFIG_RAW_DRIVER is not set
381
382#
383# TPM devices
384#
385# CONFIG_TCG_TPM is not set
386
387#
388# I2C support
389#
390# CONFIG_I2C is not set
391
392#
393# SPI support
394#
395# CONFIG_SPI is not set
396# CONFIG_SPI_MASTER is not set
397
398#
399# Dallas's 1-wire bus
400#
401# CONFIG_W1 is not set
402
403#
404# Hardware Monitoring support
405#
406# CONFIG_HWMON is not set
407# CONFIG_HWMON_VID is not set
408
409#
410# Misc devices
411#
412# CONFIG_TIFM_CORE is not set
413
414#
415# LED devices
416#
417# CONFIG_NEW_LEDS is not set
418
419#
420# LED drivers
421#
422
423#
424# LED Triggers
425#
426
427#
428# Multimedia devices
429#
430# CONFIG_VIDEO_DEV is not set
431
432#
433# Digital Video Broadcasting Devices
434#
435
436#
437# Graphics support
438#
439# CONFIG_FIRMWARE_EDID is not set
440# CONFIG_FB is not set
441
442#
443# Console display driver support
444#
445# CONFIG_VGA_CONSOLE is not set
446CONFIG_DUMMY_CONSOLE=y
447# CONFIG_BACKLIGHT_LCD_SUPPORT is not set
448
449#
450# Sound
451#
452# CONFIG_SOUND is not set
453
454#
455# HID Devices
456#
457CONFIG_HID=y
458
459#
460# USB support
461#
462CONFIG_USB_ARCH_HAS_HCD=y
463# CONFIG_USB_ARCH_HAS_OHCI is not set
464# CONFIG_USB_ARCH_HAS_EHCI is not set
465# CONFIG_USB is not set
466
467#
468# NOTE: USB_STORAGE enables SCSI, and 'SCSI disk support'
469#
470
471#
472# USB Gadget Support
473#
474# CONFIG_USB_GADGET is not set
475
476#
477# MMC/SD Card support
478#
479# CONFIG_MMC is not set
480
481#
482# Real Time Clock
483#
484CONFIG_RTC_LIB=y
485# CONFIG_RTC_CLASS is not set
486
487#
488# File systems
489#
490CONFIG_EXT2_FS=y
491# CONFIG_EXT2_FS_XATTR is not set
492# CONFIG_EXT2_FS_XIP is not set
493# CONFIG_EXT3_FS is not set
494# CONFIG_EXT4DEV_FS is not set
495# CONFIG_REISERFS_FS is not set
496# CONFIG_JFS_FS is not set
497# CONFIG_FS_POSIX_ACL is not set
498# CONFIG_XFS_FS is not set
499# CONFIG_GFS2_FS is not set
500# CONFIG_MINIX_FS is not set
501# CONFIG_ROMFS_FS is not set
502CONFIG_INOTIFY=y
503CONFIG_INOTIFY_USER=y
504# CONFIG_QUOTA is not set
505# CONFIG_DNOTIFY is not set
506# CONFIG_AUTOFS_FS is not set
507# CONFIG_AUTOFS4_FS is not set
508# CONFIG_FUSE_FS is not set
509
510#
511# CD-ROM/DVD Filesystems
512#
513# CONFIG_ISO9660_FS is not set
514# CONFIG_UDF_FS is not set
515
516#
517# DOS/FAT/NT Filesystems
518#
519# CONFIG_MSDOS_FS is not set
520# CONFIG_VFAT_FS is not set
521# CONFIG_NTFS_FS is not set
522
523#
524# Pseudo filesystems
525#
526CONFIG_PROC_FS=y
527CONFIG_PROC_SYSCTL=y
528CONFIG_SYSFS=y
529CONFIG_TMPFS=y
530# CONFIG_TMPFS_POSIX_ACL is not set
531# CONFIG_HUGETLB_PAGE is not set
532CONFIG_RAMFS=y
533# CONFIG_CONFIGFS_FS is not set
534
535#
536# Miscellaneous filesystems
537#
538# CONFIG_ADFS_FS is not set
539# CONFIG_AFFS_FS is not set
540# CONFIG_HFS_FS is not set
541# CONFIG_HFSPLUS_FS is not set
542# CONFIG_BEFS_FS is not set
543# CONFIG_BFS_FS is not set
544# CONFIG_EFS_FS is not set
545# CONFIG_CRAMFS is not set
546# CONFIG_VXFS_FS is not set
547# CONFIG_HPFS_FS is not set
548# CONFIG_QNX4FS_FS is not set
549# CONFIG_SYSV_FS is not set
550# CONFIG_UFS_FS is not set
551
552#
553# Partition Types
554#
555# CONFIG_PARTITION_ADVANCED is not set
556CONFIG_MSDOS_PARTITION=y
557
558#
559# Native Language Support
560#
561# CONFIG_NLS is not set
562
563#
564# Profiling support
565#
566# CONFIG_PROFILING is not set
567
568#
569# Kernel hacking
570#
571# CONFIG_PRINTK_TIME is not set
572# CONFIG_ENABLE_MUST_CHECK is not set
573# CONFIG_MAGIC_SYSRQ is not set
574# CONFIG_UNUSED_SYMBOLS is not set
575# CONFIG_DEBUG_FS is not set
576# CONFIG_HEADERS_CHECK is not set
577CONFIG_DEBUG_KERNEL=y
578CONFIG_LOG_BUF_SHIFT=14
579# CONFIG_DETECT_SOFTLOCKUP is not set
580# CONFIG_SCHEDSTATS is not set
581# CONFIG_DEBUG_SLAB is not set
582# CONFIG_DEBUG_RT_MUTEXES is not set
583# CONFIG_RT_MUTEX_TESTER is not set
584# CONFIG_DEBUG_SPINLOCK is not set
585# CONFIG_DEBUG_MUTEXES is not set
586# CONFIG_DEBUG_RWSEMS is not set
587# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
588# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
589# CONFIG_DEBUG_KOBJECT is not set
590CONFIG_DEBUG_BUGVERBOSE=y
591CONFIG_DEBUG_INFO=y
592# CONFIG_DEBUG_VM is not set
593# CONFIG_DEBUG_LIST is not set
594CONFIG_FRAME_POINTER=y
595CONFIG_FORCED_INLINING=y
596# CONFIG_RCU_TORTURE_TEST is not set
597CONFIG_DEBUG_USER=y
598CONFIG_DEBUG_ERRORS=y
599CONFIG_DEBUG_LL=y
600CONFIG_DEBUG_ICEDCC=y
601
602#
603# Security options
604#
605# CONFIG_KEYS is not set
606# CONFIG_SECURITY is not set
607
608#
609# Cryptographic options
610#
611# CONFIG_CRYPTO is not set
612
613#
614# Library routines
615#
616# CONFIG_CRC_CCITT is not set
617# CONFIG_CRC16 is not set
618# CONFIG_CRC32 is not set
619# CONFIG_LIBCRC32C is not set
620CONFIG_PLIST=y
621CONFIG_IOMAP_COPY=y
diff --git a/arch/arm/configs/s3c2410_defconfig b/arch/arm/configs/s3c2410_defconfig
index 3b31a33d0080..df19e3632038 100644
--- a/arch/arm/configs/s3c2410_defconfig
+++ b/arch/arm/configs/s3c2410_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.19-rc4 3# Linux kernel version: 2.6.20
4# Fri Nov 3 17:41:31 2006 4# Thu Feb 15 11:26:24 2007
5# 5#
6CONFIG_ARM=y 6CONFIG_ARM=y
7# CONFIG_GENERIC_TIME is not set 7# CONFIG_GENERIC_TIME is not set
@@ -11,6 +11,8 @@ CONFIG_TRACE_IRQFLAGS_SUPPORT=y
11CONFIG_HARDIRQS_SW_RESEND=y 11CONFIG_HARDIRQS_SW_RESEND=y
12CONFIG_GENERIC_IRQ_PROBE=y 12CONFIG_GENERIC_IRQ_PROBE=y
13CONFIG_RWSEM_GENERIC_SPINLOCK=y 13CONFIG_RWSEM_GENERIC_SPINLOCK=y
14# CONFIG_ARCH_HAS_ILOG2_U32 is not set
15# CONFIG_ARCH_HAS_ILOG2_U64 is not set
14CONFIG_GENERIC_HWEIGHT=y 16CONFIG_GENERIC_HWEIGHT=y
15CONFIG_GENERIC_CALIBRATE_DELAY=y 17CONFIG_GENERIC_CALIBRATE_DELAY=y
16CONFIG_VECTORS_BASE=0xffff0000 18CONFIG_VECTORS_BASE=0xffff0000
@@ -37,13 +39,14 @@ CONFIG_SYSVIPC=y
37# CONFIG_UTS_NS is not set 39# CONFIG_UTS_NS is not set
38# CONFIG_AUDIT is not set 40# CONFIG_AUDIT is not set
39# CONFIG_IKCONFIG is not set 41# CONFIG_IKCONFIG is not set
42CONFIG_SYSFS_DEPRECATED=y
40# CONFIG_RELAY is not set 43# CONFIG_RELAY is not set
41CONFIG_INITRAMFS_SOURCE="" 44CONFIG_INITRAMFS_SOURCE=""
42CONFIG_CC_OPTIMIZE_FOR_SIZE=y 45CONFIG_CC_OPTIMIZE_FOR_SIZE=y
43CONFIG_SYSCTL=y 46CONFIG_SYSCTL=y
44# CONFIG_EMBEDDED is not set 47# CONFIG_EMBEDDED is not set
45CONFIG_UID16=y 48CONFIG_UID16=y
46# CONFIG_SYSCTL_SYSCALL is not set 49CONFIG_SYSCTL_SYSCALL=y
47CONFIG_KALLSYMS=y 50CONFIG_KALLSYMS=y
48# CONFIG_KALLSYMS_ALL is not set 51# CONFIG_KALLSYMS_ALL is not set
49# CONFIG_KALLSYMS_EXTRA_PASS is not set 52# CONFIG_KALLSYMS_EXTRA_PASS is not set
@@ -76,7 +79,9 @@ CONFIG_KMOD=y
76# Block layer 79# Block layer
77# 80#
78CONFIG_BLOCK=y 81CONFIG_BLOCK=y
82# CONFIG_LBD is not set
79# CONFIG_BLK_DEV_IO_TRACE is not set 83# CONFIG_BLK_DEV_IO_TRACE is not set
84# CONFIG_LSF is not set
80 85
81# 86#
82# IO Schedulers 87# IO Schedulers
@@ -110,6 +115,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
110# CONFIG_ARCH_IMX is not set 115# CONFIG_ARCH_IMX is not set
111# CONFIG_ARCH_IOP32X is not set 116# CONFIG_ARCH_IOP32X is not set
112# CONFIG_ARCH_IOP33X is not set 117# CONFIG_ARCH_IOP33X is not set
118# CONFIG_ARCH_IOP13XX is not set
113# CONFIG_ARCH_IXP4XX is not set 119# CONFIG_ARCH_IXP4XX is not set
114# CONFIG_ARCH_IXP2000 is not set 120# CONFIG_ARCH_IXP2000 is not set
115# CONFIG_ARCH_IXP23XX is not set 121# CONFIG_ARCH_IXP23XX is not set
@@ -122,54 +128,73 @@ CONFIG_ARCH_S3C2410=y
122# CONFIG_ARCH_SHARK is not set 128# CONFIG_ARCH_SHARK is not set
123# CONFIG_ARCH_LH7A40X is not set 129# CONFIG_ARCH_LH7A40X is not set
124# CONFIG_ARCH_OMAP is not set 130# CONFIG_ARCH_OMAP is not set
131CONFIG_PLAT_S3C24XX=y
132CONFIG_CPU_S3C244X=y
133CONFIG_PM_SIMTEC=y
134# CONFIG_S3C2410_BOOT_WATCHDOG is not set
135# CONFIG_S3C2410_BOOT_ERROR_RESET is not set
136# CONFIG_S3C2410_PM_DEBUG is not set
137# CONFIG_S3C2410_PM_CHECK is not set
138CONFIG_S3C2410_LOWLEVEL_UART_PORT=0
139CONFIG_S3C2410_DMA=y
140# CONFIG_S3C2410_DMA_DEBUG is not set
141CONFIG_MACH_SMDK=y
125 142
126# 143#
127# S3C24XX Implementations 144# S3C2400 Machines
128# 145#
129# CONFIG_MACH_AML_M5900 is not set 146CONFIG_CPU_S3C2410=y
130CONFIG_MACH_ANUBIS=y 147CONFIG_CPU_S3C2410_DMA=y
131CONFIG_MACH_OSIRIS=y 148CONFIG_S3C2410_PM=y
132CONFIG_ARCH_BAST=y 149CONFIG_S3C2410_GPIO=y
133CONFIG_BAST_PC104_IRQ=y 150CONFIG_S3C2410_CLOCK=y
151
152#
153# S3C2410 Machines
154#
155CONFIG_ARCH_SMDK2410=y
134CONFIG_ARCH_H1940=y 156CONFIG_ARCH_H1940=y
157CONFIG_PM_H1940=y
135CONFIG_MACH_N30=y 158CONFIG_MACH_N30=y
136CONFIG_MACH_SMDK=y 159CONFIG_ARCH_BAST=y
137CONFIG_ARCH_SMDK2410=y
138CONFIG_ARCH_S3C2440=y
139CONFIG_SMDK2440_CPU2440=y
140CONFIG_SMDK2440_CPU2442=y
141CONFIG_MACH_S3C2413=y
142CONFIG_MACH_SMDK2413=y
143CONFIG_MACH_VR1000=y
144CONFIG_MACH_RX3715=y
145CONFIG_MACH_OTOM=y 160CONFIG_MACH_OTOM=y
146CONFIG_MACH_NEXCODER_2440=y 161CONFIG_MACH_AML_M5900=y
147CONFIG_MACH_VSTMS=y 162CONFIG_BAST_PC104_IRQ=y
148CONFIG_S3C2410_CLOCK=y 163CONFIG_MACH_VR1000=y
149CONFIG_S3C2410_PM=y
150CONFIG_CPU_S3C2410_DMA=y
151CONFIG_CPU_S3C2410=y
152CONFIG_S3C2412_PM=y
153CONFIG_CPU_S3C2412=y 164CONFIG_CPU_S3C2412=y
154CONFIG_CPU_S3C244X=y 165CONFIG_S3C2412_DMA=y
166CONFIG_S3C2412_PM=y
167
168#
169# S3C2412 Machines
170#
171CONFIG_MACH_SMDK2413=y
172CONFIG_MACH_S3C2413=y
173CONFIG_MACH_VSTMS=y
155CONFIG_CPU_S3C2440=y 174CONFIG_CPU_S3C2440=y
175CONFIG_S3C2440_DMA=y
176
177#
178# S3C2440 Machines
179#
180CONFIG_MACH_ANUBIS=y
181CONFIG_MACH_OSIRIS=y
182CONFIG_MACH_RX3715=y
183CONFIG_ARCH_S3C2440=y
184CONFIG_MACH_NEXCODER_2440=y
185CONFIG_SMDK2440_CPU2440=y
156CONFIG_CPU_S3C2442=y 186CONFIG_CPU_S3C2442=y
157 187
158# 188#
159# S3C2410 Boot 189# S3C2442 Machines
160# 190#
161# CONFIG_S3C2410_BOOT_WATCHDOG is not set 191CONFIG_SMDK2440_CPU2442=y
162# CONFIG_S3C2410_BOOT_ERROR_RESET is not set 192CONFIG_CPU_S3C2443=y
163 193
164# 194#
165# S3C2410 Setup 195# S3C2443 Machines
166# 196#
167CONFIG_S3C2410_DMA=y 197CONFIG_MACH_SMDK2443=y
168# CONFIG_S3C2410_DMA_DEBUG is not set
169# CONFIG_S3C2410_PM_DEBUG is not set
170# CONFIG_S3C2410_PM_CHECK is not set
171CONFIG_PM_SIMTEC=y
172CONFIG_S3C2410_LOWLEVEL_UART_PORT=0
173 198
174# 199#
175# Processor Type 200# Processor Type
@@ -196,6 +221,7 @@ CONFIG_CPU_CP15_MMU=y
196# CONFIG_CPU_DCACHE_DISABLE is not set 221# CONFIG_CPU_DCACHE_DISABLE is not set
197# CONFIG_CPU_DCACHE_WRITETHROUGH is not set 222# CONFIG_CPU_DCACHE_WRITETHROUGH is not set
198# CONFIG_CPU_CACHE_ROUND_ROBIN is not set 223# CONFIG_CPU_CACHE_ROUND_ROBIN is not set
224# CONFIG_OUTER_CACHE is not set
199 225
200# 226#
201# Bus support 227# Bus support
@@ -303,6 +329,7 @@ CONFIG_INET_TCP_DIAG=y
303# CONFIG_TCP_CONG_ADVANCED is not set 329# CONFIG_TCP_CONG_ADVANCED is not set
304CONFIG_TCP_CONG_CUBIC=y 330CONFIG_TCP_CONG_CUBIC=y
305CONFIG_DEFAULT_TCP_CONG="cubic" 331CONFIG_DEFAULT_TCP_CONG="cubic"
332# CONFIG_TCP_MD5SIG is not set
306# CONFIG_IPV6 is not set 333# CONFIG_IPV6 is not set
307# CONFIG_INET6_XFRM_TUNNEL is not set 334# CONFIG_INET6_XFRM_TUNNEL is not set
308# CONFIG_INET6_TUNNEL is not set 335# CONFIG_INET6_TUNNEL is not set
@@ -385,6 +412,7 @@ CONFIG_MTD_CMDLINE_PARTS=y
385# User Modules And Translation Layers 412# User Modules And Translation Layers
386# 413#
387CONFIG_MTD_CHAR=y 414CONFIG_MTD_CHAR=y
415CONFIG_MTD_BLKDEVS=y
388CONFIG_MTD_BLOCK=y 416CONFIG_MTD_BLOCK=y
389# CONFIG_FTL is not set 417# CONFIG_FTL is not set
390# CONFIG_NFTL is not set 418# CONFIG_NFTL is not set
@@ -531,6 +559,11 @@ CONFIG_BLK_DEV_IDE_BAST=y
531# CONFIG_SCSI_NETLINK is not set 559# CONFIG_SCSI_NETLINK is not set
532 560
533# 561#
562# Serial ATA (prod) and Parallel ATA (experimental) drivers
563#
564# CONFIG_ATA is not set
565
566#
534# Multi-device support (RAID and LVM) 567# Multi-device support (RAID and LVM)
535# 568#
536# CONFIG_MD is not set 569# CONFIG_MD is not set
@@ -682,7 +715,7 @@ CONFIG_SERIAL_NONSTANDARD=y
682# CONFIG_DIGIEPCA is not set 715# CONFIG_DIGIEPCA is not set
683# CONFIG_MOXA_INTELLIO is not set 716# CONFIG_MOXA_INTELLIO is not set
684# CONFIG_MOXA_SMARTIO is not set 717# CONFIG_MOXA_SMARTIO is not set
685# CONFIG_ISI is not set 718# CONFIG_MOXA_SMARTIO_NEW is not set
686# CONFIG_SYNCLINKMP is not set 719# CONFIG_SYNCLINKMP is not set
687# CONFIG_N_HDLC is not set 720# CONFIG_N_HDLC is not set
688# CONFIG_RISCOM8 is not set 721# CONFIG_RISCOM8 is not set
@@ -700,13 +733,14 @@ CONFIG_SERIAL_8250_NR_UARTS=8
700CONFIG_SERIAL_8250_RUNTIME_UARTS=4 733CONFIG_SERIAL_8250_RUNTIME_UARTS=4
701CONFIG_SERIAL_8250_EXTENDED=y 734CONFIG_SERIAL_8250_EXTENDED=y
702CONFIG_SERIAL_8250_MANY_PORTS=y 735CONFIG_SERIAL_8250_MANY_PORTS=y
703CONFIG_SERIAL_8250_SHARE_IRQ=y
704# CONFIG_SERIAL_8250_DETECT_IRQ is not set
705# CONFIG_SERIAL_8250_RSA is not set
706# CONFIG_SERIAL_8250_FOURPORT is not set 736# CONFIG_SERIAL_8250_FOURPORT is not set
707# CONFIG_SERIAL_8250_ACCENT is not set 737# CONFIG_SERIAL_8250_ACCENT is not set
708# CONFIG_SERIAL_8250_BOCA is not set 738# CONFIG_SERIAL_8250_BOCA is not set
739# CONFIG_SERIAL_8250_EXAR_ST16C554 is not set
709# CONFIG_SERIAL_8250_HUB6 is not set 740# CONFIG_SERIAL_8250_HUB6 is not set
741CONFIG_SERIAL_8250_SHARE_IRQ=y
742# CONFIG_SERIAL_8250_DETECT_IRQ is not set
743# CONFIG_SERIAL_8250_RSA is not set
710 744
711# 745#
712# Non-8250 serial port support 746# Non-8250 serial port support
@@ -755,10 +789,6 @@ CONFIG_HW_RANDOM=y
755# CONFIG_NVRAM is not set 789# CONFIG_NVRAM is not set
756# CONFIG_DTLK is not set 790# CONFIG_DTLK is not set
757# CONFIG_R3964 is not set 791# CONFIG_R3964 is not set
758
759#
760# Ftape, the floppy tape device driver
761#
762# CONFIG_RAW_DRIVER is not set 792# CONFIG_RAW_DRIVER is not set
763 793
764# 794#
@@ -863,6 +893,7 @@ CONFIG_SENSORS_LM85=m
863# CONFIG_SENSORS_LM92 is not set 893# CONFIG_SENSORS_LM92 is not set
864# CONFIG_SENSORS_MAX1619 is not set 894# CONFIG_SENSORS_MAX1619 is not set
865# CONFIG_SENSORS_PC87360 is not set 895# CONFIG_SENSORS_PC87360 is not set
896# CONFIG_SENSORS_PC87427 is not set
866# CONFIG_SENSORS_SMSC47M1 is not set 897# CONFIG_SENSORS_SMSC47M1 is not set
867# CONFIG_SENSORS_SMSC47M192 is not set 898# CONFIG_SENSORS_SMSC47M192 is not set
868# CONFIG_SENSORS_SMSC47B397 is not set 899# CONFIG_SENSORS_SMSC47B397 is not set
@@ -870,6 +901,7 @@ CONFIG_SENSORS_LM85=m
870# CONFIG_SENSORS_W83781D is not set 901# CONFIG_SENSORS_W83781D is not set
871# CONFIG_SENSORS_W83791D is not set 902# CONFIG_SENSORS_W83791D is not set
872# CONFIG_SENSORS_W83792D is not set 903# CONFIG_SENSORS_W83792D is not set
904# CONFIG_SENSORS_W83793 is not set
873# CONFIG_SENSORS_W83L785TS is not set 905# CONFIG_SENSORS_W83L785TS is not set
874# CONFIG_SENSORS_W83627HF is not set 906# CONFIG_SENSORS_W83627HF is not set
875# CONFIG_SENSORS_W83627EHF is not set 907# CONFIG_SENSORS_W83627EHF is not set
@@ -952,6 +984,11 @@ CONFIG_FONT_8x16=y
952# CONFIG_SOUND is not set 984# CONFIG_SOUND is not set
953 985
954# 986#
987# HID Devices
988#
989CONFIG_HID=y
990
991#
955# USB support 992# USB support
956# 993#
957CONFIG_USB_ARCH_HAS_HCD=y 994CONFIG_USB_ARCH_HAS_HCD=y
@@ -1028,6 +1065,7 @@ CONFIG_USB_OHCI_LITTLE_ENDIAN=y
1028# CONFIG_USB_KAWETH is not set 1065# CONFIG_USB_KAWETH is not set
1029# CONFIG_USB_PEGASUS is not set 1066# CONFIG_USB_PEGASUS is not set
1030# CONFIG_USB_RTL8150 is not set 1067# CONFIG_USB_RTL8150 is not set
1068# CONFIG_USB_USBNET_MII is not set
1031# CONFIG_USB_USBNET is not set 1069# CONFIG_USB_USBNET is not set
1032CONFIG_USB_MON=y 1070CONFIG_USB_MON=y
1033 1071
@@ -1179,9 +1217,6 @@ CONFIG_RAMFS=y
1179# CONFIG_BEFS_FS is not set 1217# CONFIG_BEFS_FS is not set
1180# CONFIG_BFS_FS is not set 1218# CONFIG_BFS_FS is not set
1181# CONFIG_EFS_FS is not set 1219# CONFIG_EFS_FS is not set
1182CONFIG_JFFS_FS=y
1183CONFIG_JFFS_FS_VERBOSE=0
1184# CONFIG_JFFS_PROC_FS is not set
1185CONFIG_JFFS2_FS=y 1220CONFIG_JFFS2_FS=y
1186CONFIG_JFFS2_FS_DEBUG=0 1221CONFIG_JFFS2_FS_DEBUG=0
1187CONFIG_JFFS2_FS_WRITEBUFFER=y 1222CONFIG_JFFS2_FS_WRITEBUFFER=y
@@ -1191,7 +1226,7 @@ CONFIG_JFFS2_FS_WRITEBUFFER=y
1191CONFIG_JFFS2_ZLIB=y 1226CONFIG_JFFS2_ZLIB=y
1192CONFIG_JFFS2_RTIME=y 1227CONFIG_JFFS2_RTIME=y
1193# CONFIG_JFFS2_RUBIN is not set 1228# CONFIG_JFFS2_RUBIN is not set
1194# CONFIG_CRAMFS is not set 1229CONFIG_CRAMFS=y
1195# CONFIG_VXFS_FS is not set 1230# CONFIG_VXFS_FS is not set
1196# CONFIG_HPFS_FS is not set 1231# CONFIG_HPFS_FS is not set
1197# CONFIG_QNX4FS_FS is not set 1232# CONFIG_QNX4FS_FS is not set
@@ -1285,6 +1320,11 @@ CONFIG_NLS_DEFAULT="iso8859-1"
1285# CONFIG_NLS_UTF8 is not set 1320# CONFIG_NLS_UTF8 is not set
1286 1321
1287# 1322#
1323# Distributed Lock Manager
1324#
1325# CONFIG_DLM is not set
1326
1327#
1288# Profiling support 1328# Profiling support
1289# 1329#
1290# CONFIG_PROFILING is not set 1330# CONFIG_PROFILING is not set
@@ -1296,6 +1336,8 @@ CONFIG_NLS_DEFAULT="iso8859-1"
1296CONFIG_ENABLE_MUST_CHECK=y 1336CONFIG_ENABLE_MUST_CHECK=y
1297CONFIG_MAGIC_SYSRQ=y 1337CONFIG_MAGIC_SYSRQ=y
1298# CONFIG_UNUSED_SYMBOLS is not set 1338# CONFIG_UNUSED_SYMBOLS is not set
1339# CONFIG_DEBUG_FS is not set
1340# CONFIG_HEADERS_CHECK is not set
1299CONFIG_DEBUG_KERNEL=y 1341CONFIG_DEBUG_KERNEL=y
1300CONFIG_LOG_BUF_SHIFT=16 1342CONFIG_LOG_BUF_SHIFT=16
1301CONFIG_DETECT_SOFTLOCKUP=y 1343CONFIG_DETECT_SOFTLOCKUP=y
@@ -1311,12 +1353,10 @@ CONFIG_DEBUG_MUTEXES=y
1311# CONFIG_DEBUG_KOBJECT is not set 1353# CONFIG_DEBUG_KOBJECT is not set
1312CONFIG_DEBUG_BUGVERBOSE=y 1354CONFIG_DEBUG_BUGVERBOSE=y
1313CONFIG_DEBUG_INFO=y 1355CONFIG_DEBUG_INFO=y
1314# CONFIG_DEBUG_FS is not set
1315# CONFIG_DEBUG_VM is not set 1356# CONFIG_DEBUG_VM is not set
1316# CONFIG_DEBUG_LIST is not set 1357# CONFIG_DEBUG_LIST is not set
1317CONFIG_FRAME_POINTER=y 1358CONFIG_FRAME_POINTER=y
1318CONFIG_FORCED_INLINING=y 1359CONFIG_FORCED_INLINING=y
1319# CONFIG_HEADERS_CHECK is not set
1320# CONFIG_RCU_TORTURE_TEST is not set 1360# CONFIG_RCU_TORTURE_TEST is not set
1321CONFIG_DEBUG_USER=y 1361CONFIG_DEBUG_USER=y
1322# CONFIG_DEBUG_ERRORS is not set 1362# CONFIG_DEBUG_ERRORS is not set
@@ -1339,6 +1379,7 @@ CONFIG_DEBUG_S3C2410_UART=0
1339# 1379#
1340# Library routines 1380# Library routines
1341# 1381#
1382CONFIG_BITREVERSE=y
1342# CONFIG_CRC_CCITT is not set 1383# CONFIG_CRC_CCITT is not set
1343# CONFIG_CRC16 is not set 1384# CONFIG_CRC16 is not set
1344CONFIG_CRC32=y 1385CONFIG_CRC32=y
@@ -1346,3 +1387,4 @@ CONFIG_CRC32=y
1346CONFIG_ZLIB_INFLATE=y 1387CONFIG_ZLIB_INFLATE=y
1347CONFIG_ZLIB_DEFLATE=y 1388CONFIG_ZLIB_DEFLATE=y
1348CONFIG_PLIST=y 1389CONFIG_PLIST=y
1390CONFIG_IOMAP_COPY=y
diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile
index 1b935fb94b83..bb28087bf818 100644
--- a/arch/arm/kernel/Makefile
+++ b/arch/arm/kernel/Makefile
@@ -18,6 +18,7 @@ obj-$(CONFIG_ARTHUR) += arthur.o
18obj-$(CONFIG_ISA_DMA) += dma-isa.o 18obj-$(CONFIG_ISA_DMA) += dma-isa.o
19obj-$(CONFIG_PCI) += bios32.o isa.o 19obj-$(CONFIG_PCI) += bios32.o isa.o
20obj-$(CONFIG_SMP) += smp.o 20obj-$(CONFIG_SMP) += smp.o
21obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o
21obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o 22obj-$(CONFIG_OABI_COMPAT) += sys_oabi-compat.o
22 23
23obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o 24obj-$(CONFIG_CRUNCH) += crunch.o crunch-bits.o
diff --git a/arch/arm/kernel/calls.S b/arch/arm/kernel/calls.S
index f7598cbc7ec5..ae89cdd82b16 100644
--- a/arch/arm/kernel/calls.S
+++ b/arch/arm/kernel/calls.S
@@ -356,6 +356,7 @@
356 CALL(sys_move_pages) 356 CALL(sys_move_pages)
357/* 345 */ CALL(sys_getcpu) 357/* 345 */ CALL(sys_getcpu)
358 CALL(sys_ni_syscall) /* eventually epoll_pwait */ 358 CALL(sys_ni_syscall) /* eventually epoll_pwait */
359 CALL(sys_kexec_load)
359#ifndef syscalls_counted 360#ifndef syscalls_counted
360.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls 361.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls
361#define syscalls_counted 362#define syscalls_counted
diff --git a/arch/arm/kernel/crunch.c b/arch/arm/kernel/crunch.c
index cec83783206e..627d79414c9d 100644
--- a/arch/arm/kernel/crunch.c
+++ b/arch/arm/kernel/crunch.c
@@ -75,6 +75,7 @@ static struct notifier_block crunch_notifier_block = {
75static int __init crunch_init(void) 75static int __init crunch_init(void)
76{ 76{
77 thread_register_notifier(&crunch_notifier_block); 77 thread_register_notifier(&crunch_notifier_block);
78 elf_hwcap |= HWCAP_CRUNCH;
78 79
79 return 0; 80 return 0;
80} 81}
diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c
index 71257e3d513f..f1c0fb974177 100644
--- a/arch/arm/kernel/ecard.c
+++ b/arch/arm/kernel/ecard.c
@@ -1009,7 +1009,7 @@ ecard_probe(int slot, card_type_t type)
1009 ec->fiqmask = 4; 1009 ec->fiqmask = 4;
1010 } 1010 }
1011 1011
1012 for (i = 0; i < sizeof(blacklist) / sizeof(*blacklist); i++) 1012 for (i = 0; i < ARRAY_SIZE(blacklist); i++)
1013 if (blacklist[i].manufacturer == ec->cid.manufacturer && 1013 if (blacklist[i].manufacturer == ec->cid.manufacturer &&
1014 blacklist[i].product == ec->cid.product) { 1014 blacklist[i].product == ec->cid.product) {
1015 ec->card_desc = blacklist[i].type; 1015 ec->card_desc = blacklist[i].type;
diff --git a/arch/arm/kernel/entry-armv.S b/arch/arm/kernel/entry-armv.S
index 8517c3c3eb33..cc10a093a545 100644
--- a/arch/arm/kernel/entry-armv.S
+++ b/arch/arm/kernel/entry-armv.S
@@ -99,7 +99,6 @@ common_invalid:
99 @ cpsr_<exception>, "old_r0" 99 @ cpsr_<exception>, "old_r0"
100 100
101 mov r0, sp 101 mov r0, sp
102 and r2, r6, #0x1f
103 b bad_mode 102 b bad_mode
104 103
105/* 104/*
diff --git a/arch/arm/kernel/machine_kexec.c b/arch/arm/kernel/machine_kexec.c
new file mode 100644
index 000000000000..863c66454f2b
--- /dev/null
+++ b/arch/arm/kernel/machine_kexec.c
@@ -0,0 +1,78 @@
1/*
2 * machine_kexec.c - handle transition of Linux booting another kernel
3 */
4
5#include <linux/mm.h>
6#include <linux/kexec.h>
7#include <linux/delay.h>
8#include <linux/reboot.h>
9#include <asm/pgtable.h>
10#include <asm/pgalloc.h>
11#include <asm/mmu_context.h>
12#include <asm/io.h>
13#include <asm/cacheflush.h>
14#include <asm/mach-types.h>
15
16const extern unsigned char relocate_new_kernel[];
17const extern unsigned int relocate_new_kernel_size;
18
19extern void setup_mm_for_reboot(char mode);
20
21extern unsigned long kexec_start_address;
22extern unsigned long kexec_indirection_page;
23extern unsigned long kexec_mach_type;
24
25/*
26 * Provide a dummy crash_notes definition while crash dump arrives to arm.
27 * This prevents breakage of crash_notes attribute in kernel/ksysfs.c.
28 */
29
30int machine_kexec_prepare(struct kimage *image)
31{
32 return 0;
33}
34
35void machine_kexec_cleanup(struct kimage *image)
36{
37}
38
39void machine_shutdown(void)
40{
41}
42
43void machine_crash_shutdown(struct pt_regs *regs)
44{
45}
46
47void machine_kexec(struct kimage *image)
48{
49 unsigned long page_list;
50 unsigned long reboot_code_buffer_phys;
51 void *reboot_code_buffer;
52
53
54 page_list = image->head & PAGE_MASK;
55
56 /* we need both effective and real address here */
57 reboot_code_buffer_phys =
58 page_to_pfn(image->control_code_page) << PAGE_SHIFT;
59 reboot_code_buffer = page_address(image->control_code_page);
60
61 /* Prepare parameters for reboot_code_buffer*/
62 kexec_start_address = image->start;
63 kexec_indirection_page = page_list;
64 kexec_mach_type = machine_arch_type;
65
66 /* copy our kernel relocation code to the control code page */
67 memcpy(reboot_code_buffer,
68 relocate_new_kernel, relocate_new_kernel_size);
69
70
71 flush_icache_range((unsigned long) reboot_code_buffer,
72 (unsigned long) reboot_code_buffer + KEXEC_CONTROL_CODE_SIZE);
73 printk(KERN_INFO "Bye!\n");
74
75 cpu_proc_fin();
76 setup_mm_for_reboot(0); /* mode is not used, so just pass 0*/
77 cpu_reset(reboot_code_buffer_phys);
78}
diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c
index a9e8f7e55fd6..782af3cb213f 100644
--- a/arch/arm/kernel/process.c
+++ b/arch/arm/kernel/process.c
@@ -36,7 +36,13 @@
36#include <asm/uaccess.h> 36#include <asm/uaccess.h>
37#include <asm/mach/time.h> 37#include <asm/mach/time.h>
38 38
39extern const char *processor_modes[]; 39static const char *processor_modes[] = {
40 "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
41 "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26",
42 "USER_32", "FIQ_32" , "IRQ_32" , "SVC_32" , "UK4_32" , "UK5_32" , "UK6_32" , "ABT_32" ,
43 "UK8_32" , "UK9_32" , "UK10_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32"
44};
45
40extern void setup_mm_for_reboot(char mode); 46extern void setup_mm_for_reboot(char mode);
41 47
42static volatile int hlt_counter; 48static volatile int hlt_counter;
diff --git a/arch/arm/kernel/relocate_kernel.S b/arch/arm/kernel/relocate_kernel.S
new file mode 100644
index 000000000000..7baadae7cb27
--- /dev/null
+++ b/arch/arm/kernel/relocate_kernel.S
@@ -0,0 +1,74 @@
1/*
2 * relocate_kernel.S - put the kernel image in place to boot
3 */
4
5#include <asm/kexec.h>
6
7 .globl relocate_new_kernel
8relocate_new_kernel:
9
10 ldr r0,kexec_indirection_page
11 ldr r1,kexec_start_address
12
13
140: /* top, read another word for the indirection page */
15 ldr r3, [r0],#4
16
17 /* Is it a destination page. Put destination address to r4 */
18 tst r3,#1,0
19 beq 1f
20 bic r4,r3,#1
21 b 0b
221:
23 /* Is it an indirection page */
24 tst r3,#2,0
25 beq 1f
26 bic r0,r3,#2
27 b 0b
281:
29
30 /* are we done ? */
31 tst r3,#4,0
32 beq 1f
33 b 2f
34
351:
36 /* is it source ? */
37 tst r3,#8,0
38 beq 0b
39 bic r3,r3,#8
40 mov r6,#1024
419:
42 ldr r5,[r3],#4
43 str r5,[r4],#4
44 subs r6,r6,#1
45 bne 9b
46 b 0b
47
482:
49 /* Jump to relocated kernel */
50 mov lr,r1
51 mov r0,#0
52 ldr r1,kexec_mach_type
53 mov r2,#0
54 mov pc,lr
55
56 .globl kexec_start_address
57kexec_start_address:
58 .long 0x0
59
60 .globl kexec_indirection_page
61kexec_indirection_page:
62 .long 0x0
63
64 .globl kexec_mach_type
65kexec_mach_type:
66 .long 0x0
67
68relocate_new_kernel_end:
69
70 .globl relocate_new_kernel_size
71relocate_new_kernel_size:
72 .long relocate_new_kernel_end - relocate_new_kernel
73
74
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c
index ed522151878b..03e37af315d7 100644
--- a/arch/arm/kernel/setup.c
+++ b/arch/arm/kernel/setup.c
@@ -88,6 +88,9 @@ struct cpu_user_fns cpu_user;
88#ifdef MULTI_CACHE 88#ifdef MULTI_CACHE
89struct cpu_cache_fns cpu_cache; 89struct cpu_cache_fns cpu_cache;
90#endif 90#endif
91#ifdef CONFIG_OUTER_CACHE
92struct outer_cache_fns outer_cache;
93#endif
91 94
92struct stack { 95struct stack {
93 u32 irq[3]; 96 u32 irq[3];
diff --git a/arch/arm/kernel/time.c b/arch/arm/kernel/time.c
index ee47c532e210..f61decb89ba2 100644
--- a/arch/arm/kernel/time.c
+++ b/arch/arm/kernel/time.c
@@ -40,12 +40,14 @@
40 */ 40 */
41struct sys_timer *system_timer; 41struct sys_timer *system_timer;
42 42
43#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
43/* this needs a better home */ 44/* this needs a better home */
44DEFINE_SPINLOCK(rtc_lock); 45DEFINE_SPINLOCK(rtc_lock);
45 46
46#ifdef CONFIG_SA1100_RTC_MODULE 47#ifdef CONFIG_RTC_DRV_CMOS_MODULE
47EXPORT_SYMBOL(rtc_lock); 48EXPORT_SYMBOL(rtc_lock);
48#endif 49#endif
50#endif /* pc-style 'CMOS' RTC support */
49 51
50/* change this if you have some constant time drift */ 52/* change this if you have some constant time drift */
51#define USECS_PER_JIFFY (1000000/HZ) 53#define USECS_PER_JIFFY (1000000/HZ)
diff --git a/arch/arm/kernel/traps.c b/arch/arm/kernel/traps.c
index 908915675edc..24095601359b 100644
--- a/arch/arm/kernel/traps.c
+++ b/arch/arm/kernel/traps.c
@@ -32,13 +32,6 @@
32#include "ptrace.h" 32#include "ptrace.h"
33#include "signal.h" 33#include "signal.h"
34 34
35const char *processor_modes[]=
36{ "USER_26", "FIQ_26" , "IRQ_26" , "SVC_26" , "UK4_26" , "UK5_26" , "UK6_26" , "UK7_26" ,
37 "UK8_26" , "UK9_26" , "UK10_26", "UK11_26", "UK12_26", "UK13_26", "UK14_26", "UK15_26",
38 "USER_32", "FIQ_32" , "IRQ_32" , "SVC_32" , "UK4_32" , "UK5_32" , "UK6_32" , "ABT_32" ,
39 "UK8_32" , "UK9_32" , "UK10_32", "UND_32" , "UK12_32", "UK13_32", "UK14_32", "SYS_32"
40};
41
42static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" }; 35static const char *handler[]= { "prefetch abort", "data abort", "address exception", "interrupt" };
43 36
44#ifdef CONFIG_DEBUG_USER 37#ifdef CONFIG_DEBUG_USER
@@ -289,7 +282,10 @@ asmlinkage void do_undefinstr(struct pt_regs *regs)
289 regs->ARM_pc -= correction; 282 regs->ARM_pc -= correction;
290 283
291 pc = (void __user *)instruction_pointer(regs); 284 pc = (void __user *)instruction_pointer(regs);
292 if (thumb_mode(regs)) { 285
286 if (processor_mode(regs) == SVC_MODE) {
287 instr = *(u32 *) pc;
288 } else if (thumb_mode(regs)) {
293 get_user(instr, (u16 __user *)pc); 289 get_user(instr, (u16 __user *)pc);
294 } else { 290 } else {
295 get_user(instr, (u32 __user *)pc); 291 get_user(instr, (u32 __user *)pc);
@@ -337,12 +333,11 @@ asmlinkage void do_unexp_fiq (struct pt_regs *regs)
337 * It never returns, and never tries to sync. We hope that we can at least 333 * It never returns, and never tries to sync. We hope that we can at least
338 * dump out some state information... 334 * dump out some state information...
339 */ 335 */
340asmlinkage void bad_mode(struct pt_regs *regs, int reason, int proc_mode) 336asmlinkage void bad_mode(struct pt_regs *regs, int reason)
341{ 337{
342 console_verbose(); 338 console_verbose();
343 339
344 printk(KERN_CRIT "Bad mode in %s handler detected: mode %s\n", 340 printk(KERN_CRIT "Bad mode in %s handler detected\n", handler[reason]);
345 handler[reason], processor_modes[proc_mode]);
346 341
347 die("Oops - bad mode", regs, 0); 342 die("Oops - bad mode", regs, 0);
348 local_irq_disable(); 343 local_irq_disable();
diff --git a/arch/arm/mach-at91rm9200/Kconfig b/arch/arm/mach-at91/Kconfig
index 9f11db8af233..bf0d96272e3a 100644
--- a/arch/arm/mach-at91rm9200/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -9,11 +9,14 @@ config ARCH_AT91RM9200
9 bool "AT91RM9200" 9 bool "AT91RM9200"
10 10
11config ARCH_AT91SAM9260 11config ARCH_AT91SAM9260
12 bool "AT91SAM9260" 12 bool "AT91SAM9260 or AT91SAM9XE"
13 13
14config ARCH_AT91SAM9261 14config ARCH_AT91SAM9261
15 bool "AT91SAM9261" 15 bool "AT91SAM9261"
16 16
17config ARCH_AT91SAM9263
18 bool "AT91SAM9263"
19
17endchoice 20endchoice
18 21
19# ---------------------------------------------------------- 22# ----------------------------------------------------------
@@ -90,13 +93,22 @@ endif
90 93
91if ARCH_AT91SAM9260 94if ARCH_AT91SAM9260
92 95
93comment "AT91SAM9260 Board Type" 96comment "AT91SAM9260 Variants"
97
98config ARCH_AT91SAM9260_SAM9XE
99 bool "AT91SAM9XE"
100 depends on ARCH_AT91SAM9260
101 help
102 Select this if you are using Atmel's AT91SAM9XE System-on-Chip.
103 They are basicaly AT91SAM9260s with various sizes of embedded Flash.
104
105comment "AT91SAM9260 / AT91SAM9XE Board Type"
94 106
95config MACH_AT91SAM9260EK 107config MACH_AT91SAM9260EK
96 bool "Atmel AT91SAM9260-EK Evaluation Kit" 108 bool "Atmel AT91SAM9260-EK / AT91SAM9XE Evaluation Kit"
97 depends on ARCH_AT91SAM9260 109 depends on ARCH_AT91SAM9260
98 help 110 help
99 Select this if you are using Atmel's AT91SAM9260-EK Evaluation Kit. 111 Select this if you are using Atmel's AT91SAM9260-EK or AT91SAM9XE Evaluation Kit
100 <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3933> 112 <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=3933>
101 113
102endif 114endif
@@ -118,17 +130,32 @@ endif
118 130
119# ---------------------------------------------------------- 131# ----------------------------------------------------------
120 132
133if ARCH_AT91SAM9263
134
135comment "AT91SAM9263 Board Type"
136
137config MACH_AT91SAM9263EK
138 bool "Atmel AT91SAM9263-EK Evaluation Kit"
139 depends on ARCH_AT91SAM9263
140 help
141 Select this if you are using Atmel's AT91SAM9263-EK Evaluation Kit.
142 <http://www.atmel.com/dyn/products/tools_card.asp?tool_id=4057>
143
144endif
145
146# ----------------------------------------------------------
147
121comment "AT91 Board Options" 148comment "AT91 Board Options"
122 149
123config MTD_AT91_DATAFLASH_CARD 150config MTD_AT91_DATAFLASH_CARD
124 bool "Enable DataFlash Card support" 151 bool "Enable DataFlash Card support"
125 depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK) 152 depends on (ARCH_AT91RM9200DK || MACH_AT91RM9200EK || MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK)
126 help 153 help
127 Enable support for the DataFlash card. 154 Enable support for the DataFlash card.
128 155
129config MTD_NAND_AT91_BUSWIDTH_16 156config MTD_NAND_AT91_BUSWIDTH_16
130 bool "Enable 16-bit data bus interface to NAND flash" 157 bool "Enable 16-bit data bus interface to NAND flash"
131 depends on (MACH_AT91SAM9261EK || MACH_AT91SAM9260EK) 158 depends on (MACH_AT91SAM9260EK || MACH_AT91SAM9261EK || MACH_AT91SAM9263EK)
132 help 159 help
133 On AT91SAM926x boards both types of NAND flash can be present 160 On AT91SAM926x boards both types of NAND flash can be present
134 (8 and 16 bit data bus width). 161 (8 and 16 bit data bus width).
diff --git a/arch/arm/mach-at91rm9200/Makefile b/arch/arm/mach-at91/Makefile
index cf777007847a..05de6cdc88f1 100644
--- a/arch/arm/mach-at91rm9200/Makefile
+++ b/arch/arm/mach-at91/Makefile
@@ -13,6 +13,7 @@ obj-$(CONFIG_PM) += pm.o
13obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.o 13obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.o
14obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o 14obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam926x_time.o at91sam9260_devices.o
15obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o 15obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam926x_time.o at91sam9261_devices.o
16obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam926x_time.o at91sam9263_devices.o
16 17
17# AT91RM9200 board-specific support 18# AT91RM9200 board-specific support
18obj-$(CONFIG_MACH_ONEARM) += board-1arm.o 19obj-$(CONFIG_MACH_ONEARM) += board-1arm.o
@@ -31,6 +32,9 @@ obj-$(CONFIG_MACH_AT91SAM9260EK) += board-sam9260ek.o
31# AT91SAM9261 board-specific support 32# AT91SAM9261 board-specific support
32obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o 33obj-$(CONFIG_MACH_AT91SAM9261EK) += board-sam9261ek.o
33 34
35# AT91SAM9263 board-specific support
36obj-$(CONFIG_MACH_AT91SAM9263EK) += board-sam9263ek.o
37
34# LEDs support 38# LEDs support
35led-$(CONFIG_ARCH_AT91RM9200DK) += leds.o 39led-$(CONFIG_ARCH_AT91RM9200DK) += leds.o
36led-$(CONFIG_MACH_AT91RM9200EK) += leds.o 40led-$(CONFIG_MACH_AT91RM9200EK) += leds.o
diff --git a/arch/arm/mach-at91rm9200/Makefile.boot b/arch/arm/mach-at91/Makefile.boot
index e667dcc7cd34..e667dcc7cd34 100644
--- a/arch/arm/mach-at91rm9200/Makefile.boot
+++ b/arch/arm/mach-at91/Makefile.boot
diff --git a/arch/arm/mach-at91rm9200/at91rm9200.c b/arch/arm/mach-at91/at91rm9200.c
index a92e9a495b07..2ddcdd69df7d 100644
--- a/arch/arm/mach-at91rm9200/at91rm9200.c
+++ b/arch/arm/mach-at91/at91rm9200.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/mach-at91rm9200/at91rm9200.c 2 * arch/arm/mach-at91/at91rm9200.c
3 * 3 *
4 * Copyright (C) 2005 SAN People 4 * Copyright (C) 2005 SAN People
5 * 5 *
@@ -117,6 +117,36 @@ static struct clk pioD_clk = {
117 .pmc_mask = 1 << AT91RM9200_ID_PIOD, 117 .pmc_mask = 1 << AT91RM9200_ID_PIOD,
118 .type = CLK_TYPE_PERIPHERAL, 118 .type = CLK_TYPE_PERIPHERAL,
119}; 119};
120static struct clk tc0_clk = {
121 .name = "tc0_clk",
122 .pmc_mask = 1 << AT91RM9200_ID_TC0,
123 .type = CLK_TYPE_PERIPHERAL,
124};
125static struct clk tc1_clk = {
126 .name = "tc1_clk",
127 .pmc_mask = 1 << AT91RM9200_ID_TC1,
128 .type = CLK_TYPE_PERIPHERAL,
129};
130static struct clk tc2_clk = {
131 .name = "tc2_clk",
132 .pmc_mask = 1 << AT91RM9200_ID_TC2,
133 .type = CLK_TYPE_PERIPHERAL,
134};
135static struct clk tc3_clk = {
136 .name = "tc3_clk",
137 .pmc_mask = 1 << AT91RM9200_ID_TC3,
138 .type = CLK_TYPE_PERIPHERAL,
139};
140static struct clk tc4_clk = {
141 .name = "tc4_clk",
142 .pmc_mask = 1 << AT91RM9200_ID_TC4,
143 .type = CLK_TYPE_PERIPHERAL,
144};
145static struct clk tc5_clk = {
146 .name = "tc5_clk",
147 .pmc_mask = 1 << AT91RM9200_ID_TC5,
148 .type = CLK_TYPE_PERIPHERAL,
149};
120 150
121static struct clk *periph_clocks[] __initdata = { 151static struct clk *periph_clocks[] __initdata = {
122 &pioA_clk, 152 &pioA_clk,
@@ -132,7 +162,12 @@ static struct clk *periph_clocks[] __initdata = {
132 &twi_clk, 162 &twi_clk,
133 &spi_clk, 163 &spi_clk,
134 // ssc 0 .. ssc2 164 // ssc 0 .. ssc2
135 // tc0 .. tc5 165 &tc0_clk,
166 &tc1_clk,
167 &tc2_clk,
168 &tc3_clk,
169 &tc4_clk,
170 &tc5_clk,
136 &ohci_clk, 171 &ohci_clk,
137 &ether_clk, 172 &ether_clk,
138 // irq0 .. irq6 173 // irq0 .. irq6
diff --git a/arch/arm/mach-at91rm9200/at91rm9200_devices.c b/arch/arm/mach-at91/at91rm9200_devices.c
index 57fac7203fe4..2624a4f22d61 100644
--- a/arch/arm/mach-at91rm9200/at91rm9200_devices.c
+++ b/arch/arm/mach-at91/at91rm9200_devices.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/mach-at91rm9200/at91rm9200_devices.c 2 * arch/arm/mach-at91/at91rm9200_devices.c
3 * 3 *
4 * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org> 4 * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
5 * Copyright (C) 2005 David Brownell 5 * Copyright (C) 2005 David Brownell
@@ -315,7 +315,7 @@ static struct platform_device at91rm9200_mmc_device = {
315 .num_resources = ARRAY_SIZE(mmc_resources), 315 .num_resources = ARRAY_SIZE(mmc_resources),
316}; 316};
317 317
318void __init at91_add_device_mmc(struct at91_mmc_data *data) 318void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
319{ 319{
320 if (!data) 320 if (!data)
321 return; 321 return;
@@ -361,7 +361,7 @@ void __init at91_add_device_mmc(struct at91_mmc_data *data)
361 platform_device_register(&at91rm9200_mmc_device); 361 platform_device_register(&at91rm9200_mmc_device);
362} 362}
363#else 363#else
364void __init at91_add_device_mmc(struct at91_mmc_data *data) {} 364void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
365#endif 365#endif
366 366
367 367
@@ -594,6 +594,10 @@ u8 at91_leds_timer;
594 594
595void __init at91_init_leds(u8 cpu_led, u8 timer_led) 595void __init at91_init_leds(u8 cpu_led, u8 timer_led)
596{ 596{
597 /* Enable GPIO to access the LEDs */
598 at91_set_gpio_output(cpu_led, 1);
599 at91_set_gpio_output(timer_led, 1);
600
597 at91_leds_cpu = cpu_led; 601 at91_leds_cpu = cpu_led;
598 at91_leds_timer = timer_led; 602 at91_leds_timer = timer_led;
599} 603}
diff --git a/arch/arm/mach-at91rm9200/at91rm9200_time.c b/arch/arm/mach-at91/at91rm9200_time.c
index b999e192a7e9..949199a244c7 100644
--- a/arch/arm/mach-at91rm9200/at91rm9200_time.c
+++ b/arch/arm/mach-at91/at91rm9200_time.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-at91rm9200/at91rm9200_time.c 2 * linux/arch/arm/mach-at91/at91rm9200_time.c
3 * 3 *
4 * Copyright (C) 2003 SAN People 4 * Copyright (C) 2003 SAN People
5 * Copyright (C) 2003 ATMEL 5 * Copyright (C) 2003 ATMEL
diff --git a/arch/arm/mach-at91rm9200/at91sam9260.c b/arch/arm/mach-at91/at91sam9260.c
index b14871adc300..6ea41d8266cb 100644
--- a/arch/arm/mach-at91rm9200/at91sam9260.c
+++ b/arch/arm/mach-at91/at91sam9260.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/mach-at91rm9200/at91sam9260.c 2 * arch/arm/mach-at91/at91sam9260.c
3 * 3 *
4 * Copyright (C) 2006 SAN People 4 * Copyright (C) 2006 SAN People
5 * 5 *
@@ -14,6 +14,7 @@
14 14
15#include <asm/mach/arch.h> 15#include <asm/mach/arch.h>
16#include <asm/mach/map.h> 16#include <asm/mach/map.h>
17#include <asm/arch/cpu.h>
17#include <asm/arch/at91sam9260.h> 18#include <asm/arch/at91sam9260.h>
18#include <asm/arch/at91_pmc.h> 19#include <asm/arch/at91_pmc.h>
19#include <asm/arch/at91_rstc.h> 20#include <asm/arch/at91_rstc.h>
@@ -27,7 +28,11 @@ static struct map_desc at91sam9260_io_desc[] __initdata = {
27 .pfn = __phys_to_pfn(AT91_BASE_SYS), 28 .pfn = __phys_to_pfn(AT91_BASE_SYS),
28 .length = SZ_16K, 29 .length = SZ_16K,
29 .type = MT_DEVICE, 30 .type = MT_DEVICE,
30 }, { 31 }
32};
33
34static struct map_desc at91sam9260_sram_desc[] __initdata = {
35 {
31 .virtual = AT91_IO_VIRT_BASE - AT91SAM9260_SRAM0_SIZE, 36 .virtual = AT91_IO_VIRT_BASE - AT91SAM9260_SRAM0_SIZE,
32 .pfn = __phys_to_pfn(AT91SAM9260_SRAM0_BASE), 37 .pfn = __phys_to_pfn(AT91SAM9260_SRAM0_BASE),
33 .length = AT91SAM9260_SRAM0_SIZE, 38 .length = AT91SAM9260_SRAM0_SIZE,
@@ -37,7 +42,14 @@ static struct map_desc at91sam9260_io_desc[] __initdata = {
37 .pfn = __phys_to_pfn(AT91SAM9260_SRAM1_BASE), 42 .pfn = __phys_to_pfn(AT91SAM9260_SRAM1_BASE),
38 .length = AT91SAM9260_SRAM1_SIZE, 43 .length = AT91SAM9260_SRAM1_SIZE,
39 .type = MT_DEVICE, 44 .type = MT_DEVICE,
40 }, 45 }
46};
47
48static struct map_desc at91sam9xe_sram_desc[] __initdata = {
49 {
50 .pfn = __phys_to_pfn(AT91SAM9XE_SRAM_BASE),
51 .type = MT_DEVICE,
52 }
41}; 53};
42 54
43/* -------------------------------------------------------------------- 55/* --------------------------------------------------------------------
@@ -107,13 +119,28 @@ static struct clk spi1_clk = {
107 .pmc_mask = 1 << AT91SAM9260_ID_SPI1, 119 .pmc_mask = 1 << AT91SAM9260_ID_SPI1,
108 .type = CLK_TYPE_PERIPHERAL, 120 .type = CLK_TYPE_PERIPHERAL,
109}; 121};
122static struct clk tc0_clk = {
123 .name = "tc0_clk",
124 .pmc_mask = 1 << AT91SAM9260_ID_TC0,
125 .type = CLK_TYPE_PERIPHERAL,
126};
127static struct clk tc1_clk = {
128 .name = "tc1_clk",
129 .pmc_mask = 1 << AT91SAM9260_ID_TC1,
130 .type = CLK_TYPE_PERIPHERAL,
131};
132static struct clk tc2_clk = {
133 .name = "tc2_clk",
134 .pmc_mask = 1 << AT91SAM9260_ID_TC2,
135 .type = CLK_TYPE_PERIPHERAL,
136};
110static struct clk ohci_clk = { 137static struct clk ohci_clk = {
111 .name = "ohci_clk", 138 .name = "ohci_clk",
112 .pmc_mask = 1 << AT91SAM9260_ID_UHP, 139 .pmc_mask = 1 << AT91SAM9260_ID_UHP,
113 .type = CLK_TYPE_PERIPHERAL, 140 .type = CLK_TYPE_PERIPHERAL,
114}; 141};
115static struct clk ether_clk = { 142static struct clk macb_clk = {
116 .name = "ether_clk", 143 .name = "macb_clk",
117 .pmc_mask = 1 << AT91SAM9260_ID_EMAC, 144 .pmc_mask = 1 << AT91SAM9260_ID_EMAC,
118 .type = CLK_TYPE_PERIPHERAL, 145 .type = CLK_TYPE_PERIPHERAL,
119}; 146};
@@ -137,6 +164,21 @@ static struct clk usart5_clk = {
137 .pmc_mask = 1 << AT91SAM9260_ID_US5, 164 .pmc_mask = 1 << AT91SAM9260_ID_US5,
138 .type = CLK_TYPE_PERIPHERAL, 165 .type = CLK_TYPE_PERIPHERAL,
139}; 166};
167static struct clk tc3_clk = {
168 .name = "tc3_clk",
169 .pmc_mask = 1 << AT91SAM9260_ID_TC3,
170 .type = CLK_TYPE_PERIPHERAL,
171};
172static struct clk tc4_clk = {
173 .name = "tc4_clk",
174 .pmc_mask = 1 << AT91SAM9260_ID_TC4,
175 .type = CLK_TYPE_PERIPHERAL,
176};
177static struct clk tc5_clk = {
178 .name = "tc5_clk",
179 .pmc_mask = 1 << AT91SAM9260_ID_TC5,
180 .type = CLK_TYPE_PERIPHERAL,
181};
140 182
141static struct clk *periph_clocks[] __initdata = { 183static struct clk *periph_clocks[] __initdata = {
142 &pioA_clk, 184 &pioA_clk,
@@ -152,14 +194,18 @@ static struct clk *periph_clocks[] __initdata = {
152 &spi0_clk, 194 &spi0_clk,
153 &spi1_clk, 195 &spi1_clk,
154 // ssc 196 // ssc
155 // tc0 .. tc2 197 &tc0_clk,
198 &tc1_clk,
199 &tc2_clk,
156 &ohci_clk, 200 &ohci_clk,
157 &ether_clk, 201 &macb_clk,
158 &isi_clk, 202 &isi_clk,
159 &usart3_clk, 203 &usart3_clk,
160 &usart4_clk, 204 &usart4_clk,
161 &usart5_clk, 205 &usart5_clk,
162 // tc3 .. tc5 206 &tc3_clk,
207 &tc4_clk,
208 &tc5_clk,
163 // irq0 .. irq2 209 // irq0 .. irq2
164}; 210};
165 211
@@ -213,7 +259,7 @@ static struct at91_gpio_bank at91sam9260_gpio[] = {
213 259
214static void at91sam9260_reset(void) 260static void at91sam9260_reset(void)
215{ 261{
216 at91_sys_write(AT91_RSTC_CR, (0xA5 << 24) | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); 262 at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
217} 263}
218 264
219 265
@@ -221,11 +267,37 @@ static void at91sam9260_reset(void)
221 * AT91SAM9260 processor initialization 267 * AT91SAM9260 processor initialization
222 * -------------------------------------------------------------------- */ 268 * -------------------------------------------------------------------- */
223 269
270static void __init at91sam9xe_initialize(void)
271{
272 unsigned long cidr, sram_size;
273
274 cidr = at91_sys_read(AT91_DBGU_CIDR);
275
276 switch (cidr & AT91_CIDR_SRAMSIZ) {
277 case AT91_CIDR_SRAMSIZ_32K:
278 sram_size = 2 * SZ_16K;
279 break;
280 case AT91_CIDR_SRAMSIZ_16K:
281 default:
282 sram_size = SZ_16K;
283 }
284
285 at91sam9xe_sram_desc->virtual = AT91_IO_VIRT_BASE - sram_size;
286 at91sam9xe_sram_desc->length = sram_size;
287
288 iotable_init(at91sam9xe_sram_desc, ARRAY_SIZE(at91sam9xe_sram_desc));
289}
290
224void __init at91sam9260_initialize(unsigned long main_clock) 291void __init at91sam9260_initialize(unsigned long main_clock)
225{ 292{
226 /* Map peripherals */ 293 /* Map peripherals */
227 iotable_init(at91sam9260_io_desc, ARRAY_SIZE(at91sam9260_io_desc)); 294 iotable_init(at91sam9260_io_desc, ARRAY_SIZE(at91sam9260_io_desc));
228 295
296 if (cpu_is_at91sam9xe())
297 at91sam9xe_initialize();
298 else
299 iotable_init(at91sam9260_sram_desc, ARRAY_SIZE(at91sam9260_sram_desc));
300
229 at91_arch_reset = at91sam9260_reset; 301 at91_arch_reset = at91sam9260_reset;
230 at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1) 302 at91_extern_irq = (1 << AT91SAM9260_ID_IRQ0) | (1 << AT91SAM9260_ID_IRQ1)
231 | (1 << AT91SAM9260_ID_IRQ2); 303 | (1 << AT91SAM9260_ID_IRQ2);
diff --git a/arch/arm/mach-at91rm9200/at91sam9260_devices.c b/arch/arm/mach-at91/at91sam9260_devices.c
index f42d3a40ec3c..f7d342ccbebf 100644
--- a/arch/arm/mach-at91rm9200/at91sam9260_devices.c
+++ b/arch/arm/mach-at91/at91sam9260_devices.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/mach-at91rm9200/at91sam9260_devices.c 2 * arch/arm/mach-at91/at91sam9260_devices.c
3 * 3 *
4 * Copyright (C) 2006 Atmel 4 * Copyright (C) 2006 Atmel
5 * 5 *
@@ -128,7 +128,7 @@ void __init at91_add_device_udc(struct at91_udc_data *data) {}
128 128
129#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE) 129#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
130static u64 eth_dmamask = 0xffffffffUL; 130static u64 eth_dmamask = 0xffffffffUL;
131static struct eth_platform_data eth_data; 131static struct at91_eth_data eth_data;
132 132
133static struct resource eth_resources[] = { 133static struct resource eth_resources[] = {
134 [0] = { 134 [0] = {
@@ -155,7 +155,7 @@ static struct platform_device at91sam9260_eth_device = {
155 .num_resources = ARRAY_SIZE(eth_resources), 155 .num_resources = ARRAY_SIZE(eth_resources),
156}; 156};
157 157
158void __init at91_add_device_eth(struct eth_platform_data *data) 158void __init at91_add_device_eth(struct at91_eth_data *data)
159{ 159{
160 if (!data) 160 if (!data)
161 return; 161 return;
@@ -192,7 +192,7 @@ void __init at91_add_device_eth(struct eth_platform_data *data)
192 platform_device_register(&at91sam9260_eth_device); 192 platform_device_register(&at91sam9260_eth_device);
193} 193}
194#else 194#else
195void __init at91_add_device_eth(struct eth_platform_data *data) {} 195void __init at91_add_device_eth(struct at91_eth_data *data) {}
196#endif 196#endif
197 197
198 198
@@ -229,7 +229,7 @@ static struct platform_device at91sam9260_mmc_device = {
229 .num_resources = ARRAY_SIZE(mmc_resources), 229 .num_resources = ARRAY_SIZE(mmc_resources),
230}; 230};
231 231
232void __init at91_add_device_mmc(struct at91_mmc_data *data) 232void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
233{ 233{
234 if (!data) 234 if (!data)
235 return; 235 return;
@@ -275,7 +275,7 @@ void __init at91_add_device_mmc(struct at91_mmc_data *data)
275 platform_device_register(&at91sam9260_mmc_device); 275 platform_device_register(&at91sam9260_mmc_device);
276} 276}
277#else 277#else
278void __init at91_add_device_mmc(struct at91_mmc_data *data) {} 278void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
279#endif 279#endif
280 280
281 281
@@ -515,6 +515,10 @@ u8 at91_leds_timer;
515 515
516void __init at91_init_leds(u8 cpu_led, u8 timer_led) 516void __init at91_init_leds(u8 cpu_led, u8 timer_led)
517{ 517{
518 /* Enable GPIO to access the LEDs */
519 at91_set_gpio_output(cpu_led, 1);
520 at91_set_gpio_output(timer_led, 1);
521
518 at91_leds_cpu = cpu_led; 522 at91_leds_cpu = cpu_led;
519 at91_leds_timer = timer_led; 523 at91_leds_timer = timer_led;
520} 524}
diff --git a/arch/arm/mach-at91rm9200/at91sam9261.c b/arch/arm/mach-at91/at91sam9261.c
index d242bb885c6d..784d1e682d6d 100644
--- a/arch/arm/mach-at91rm9200/at91sam9261.c
+++ b/arch/arm/mach-at91/at91sam9261.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/mach-at91rm9200/at91sam9261.c 2 * arch/arm/mach-at91/at91sam9261.c
3 * 3 *
4 * Copyright (C) 2005 SAN People 4 * Copyright (C) 2005 SAN People
5 * 5 *
@@ -97,6 +97,21 @@ static struct clk spi1_clk = {
97 .pmc_mask = 1 << AT91SAM9261_ID_SPI1, 97 .pmc_mask = 1 << AT91SAM9261_ID_SPI1,
98 .type = CLK_TYPE_PERIPHERAL, 98 .type = CLK_TYPE_PERIPHERAL,
99}; 99};
100static struct clk tc0_clk = {
101 .name = "tc0_clk",
102 .pmc_mask = 1 << AT91SAM9261_ID_TC0,
103 .type = CLK_TYPE_PERIPHERAL,
104};
105static struct clk tc1_clk = {
106 .name = "tc1_clk",
107 .pmc_mask = 1 << AT91SAM9261_ID_TC1,
108 .type = CLK_TYPE_PERIPHERAL,
109};
110static struct clk tc2_clk = {
111 .name = "tc2_clk",
112 .pmc_mask = 1 << AT91SAM9261_ID_TC2,
113 .type = CLK_TYPE_PERIPHERAL,
114};
100static struct clk ohci_clk = { 115static struct clk ohci_clk = {
101 .name = "ohci_clk", 116 .name = "ohci_clk",
102 .pmc_mask = 1 << AT91SAM9261_ID_UHP, 117 .pmc_mask = 1 << AT91SAM9261_ID_UHP,
@@ -121,7 +136,9 @@ static struct clk *periph_clocks[] __initdata = {
121 &spi0_clk, 136 &spi0_clk,
122 &spi1_clk, 137 &spi1_clk,
123 // ssc 0 .. ssc2 138 // ssc 0 .. ssc2
124 // tc0 .. tc2 139 &tc0_clk,
140 &tc1_clk,
141 &tc2_clk,
125 &ohci_clk, 142 &ohci_clk,
126 &lcdc_clk, 143 &lcdc_clk,
127 // irq0 .. irq2 144 // irq0 .. irq2
@@ -208,7 +225,7 @@ static struct at91_gpio_bank at91sam9261_gpio[] = {
208 225
209static void at91sam9261_reset(void) 226static void at91sam9261_reset(void)
210{ 227{
211 at91_sys_write(AT91_RSTC_CR, (0xA5 << 24) | AT91_RSTC_PROCRST | AT91_RSTC_PERRST); 228 at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
212} 229}
213 230
214 231
diff --git a/arch/arm/mach-at91rm9200/at91sam9261_devices.c b/arch/arm/mach-at91/at91sam9261_devices.c
index ed1d79081b35..e1504766fd64 100644
--- a/arch/arm/mach-at91rm9200/at91sam9261_devices.c
+++ b/arch/arm/mach-at91/at91sam9261_devices.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/mach-at91rm9200/at91sam9261_devices.c 2 * arch/arm/mach-at91/at91sam9261_devices.c
3 * 3 *
4 * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org> 4 * Copyright (C) 2005 Thibaut VARENE <varenet@parisc-linux.org>
5 * Copyright (C) 2005 David Brownell 5 * Copyright (C) 2005 David Brownell
@@ -159,7 +159,7 @@ static struct platform_device at91sam9261_mmc_device = {
159 .num_resources = ARRAY_SIZE(mmc_resources), 159 .num_resources = ARRAY_SIZE(mmc_resources),
160}; 160};
161 161
162void __init at91_add_device_mmc(struct at91_mmc_data *data) 162void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
163{ 163{
164 if (!data) 164 if (!data)
165 return; 165 return;
@@ -192,7 +192,7 @@ void __init at91_add_device_mmc(struct at91_mmc_data *data)
192 platform_device_register(&at91sam9261_mmc_device); 192 platform_device_register(&at91sam9261_mmc_device);
193} 193}
194#else 194#else
195void __init at91_add_device_mmc(struct at91_mmc_data *data) {} 195void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
196#endif 196#endif
197 197
198 198
@@ -513,6 +513,10 @@ u8 at91_leds_timer;
513 513
514void __init at91_init_leds(u8 cpu_led, u8 timer_led) 514void __init at91_init_leds(u8 cpu_led, u8 timer_led)
515{ 515{
516 /* Enable GPIO to access the LEDs */
517 at91_set_gpio_output(cpu_led, 1);
518 at91_set_gpio_output(timer_led, 1);
519
516 at91_leds_cpu = cpu_led; 520 at91_leds_cpu = cpu_led;
517 at91_leds_timer = timer_led; 521 at91_leds_timer = timer_led;
518} 522}
diff --git a/arch/arm/mach-at91/at91sam9263.c b/arch/arm/mach-at91/at91sam9263.c
new file mode 100644
index 000000000000..6aa342e8f1b1
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9263.c
@@ -0,0 +1,313 @@
1/*
2 * arch/arm/mach-at91/at91sam9263.c
3 *
4 * Copyright (C) 2007 Atmel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 */
12
13#include <linux/module.h>
14
15#include <asm/mach/arch.h>
16#include <asm/mach/map.h>
17#include <asm/arch/at91sam9263.h>
18#include <asm/arch/at91_pmc.h>
19#include <asm/arch/at91_rstc.h>
20
21#include "generic.h"
22#include "clock.h"
23
24static struct map_desc at91sam9263_io_desc[] __initdata = {
25 {
26 .virtual = AT91_VA_BASE_SYS,
27 .pfn = __phys_to_pfn(AT91_BASE_SYS),
28 .length = SZ_16K,
29 .type = MT_DEVICE,
30 }, {
31 .virtual = AT91_IO_VIRT_BASE - AT91SAM9263_SRAM0_SIZE,
32 .pfn = __phys_to_pfn(AT91SAM9263_SRAM0_BASE),
33 .length = AT91SAM9263_SRAM0_SIZE,
34 .type = MT_DEVICE,
35 }, {
36 .virtual = AT91_IO_VIRT_BASE - AT91SAM9263_SRAM0_SIZE - AT91SAM9263_SRAM1_SIZE,
37 .pfn = __phys_to_pfn(AT91SAM9263_SRAM1_BASE),
38 .length = AT91SAM9263_SRAM1_SIZE,
39 .type = MT_DEVICE,
40 },
41};
42
43/* --------------------------------------------------------------------
44 * Clocks
45 * -------------------------------------------------------------------- */
46
47/*
48 * The peripheral clocks.
49 */
50static struct clk pioA_clk = {
51 .name = "pioA_clk",
52 .pmc_mask = 1 << AT91SAM9263_ID_PIOA,
53 .type = CLK_TYPE_PERIPHERAL,
54};
55static struct clk pioB_clk = {
56 .name = "pioB_clk",
57 .pmc_mask = 1 << AT91SAM9263_ID_PIOB,
58 .type = CLK_TYPE_PERIPHERAL,
59};
60static struct clk pioCDE_clk = {
61 .name = "pioCDE_clk",
62 .pmc_mask = 1 << AT91SAM9263_ID_PIOCDE,
63 .type = CLK_TYPE_PERIPHERAL,
64};
65static struct clk usart0_clk = {
66 .name = "usart0_clk",
67 .pmc_mask = 1 << AT91SAM9263_ID_US0,
68 .type = CLK_TYPE_PERIPHERAL,
69};
70static struct clk usart1_clk = {
71 .name = "usart1_clk",
72 .pmc_mask = 1 << AT91SAM9263_ID_US1,
73 .type = CLK_TYPE_PERIPHERAL,
74};
75static struct clk usart2_clk = {
76 .name = "usart2_clk",
77 .pmc_mask = 1 << AT91SAM9263_ID_US2,
78 .type = CLK_TYPE_PERIPHERAL,
79};
80static struct clk mmc0_clk = {
81 .name = "mci0_clk",
82 .pmc_mask = 1 << AT91SAM9263_ID_MCI0,
83 .type = CLK_TYPE_PERIPHERAL,
84};
85static struct clk mmc1_clk = {
86 .name = "mci1_clk",
87 .pmc_mask = 1 << AT91SAM9263_ID_MCI1,
88 .type = CLK_TYPE_PERIPHERAL,
89};
90static struct clk twi_clk = {
91 .name = "twi_clk",
92 .pmc_mask = 1 << AT91SAM9263_ID_TWI,
93 .type = CLK_TYPE_PERIPHERAL,
94};
95static struct clk spi0_clk = {
96 .name = "spi0_clk",
97 .pmc_mask = 1 << AT91SAM9263_ID_SPI0,
98 .type = CLK_TYPE_PERIPHERAL,
99};
100static struct clk spi1_clk = {
101 .name = "spi1_clk",
102 .pmc_mask = 1 << AT91SAM9263_ID_SPI1,
103 .type = CLK_TYPE_PERIPHERAL,
104};
105static struct clk tcb_clk = {
106 .name = "tcb_clk",
107 .pmc_mask = 1 << AT91SAM9263_ID_TCB,
108 .type = CLK_TYPE_PERIPHERAL,
109};
110static struct clk macb_clk = {
111 .name = "macb_clk",
112 .pmc_mask = 1 << AT91SAM9263_ID_EMAC,
113 .type = CLK_TYPE_PERIPHERAL,
114};
115static struct clk udc_clk = {
116 .name = "udc_clk",
117 .pmc_mask = 1 << AT91SAM9263_ID_UDP,
118 .type = CLK_TYPE_PERIPHERAL,
119};
120static struct clk isi_clk = {
121 .name = "isi_clk",
122 .pmc_mask = 1 << AT91SAM9263_ID_ISI,
123 .type = CLK_TYPE_PERIPHERAL,
124};
125static struct clk lcdc_clk = {
126 .name = "lcdc_clk",
127 .pmc_mask = 1 << AT91SAM9263_ID_ISI,
128 .type = CLK_TYPE_PERIPHERAL,
129};
130static struct clk ohci_clk = {
131 .name = "ohci_clk",
132 .pmc_mask = 1 << AT91SAM9263_ID_UHP,
133 .type = CLK_TYPE_PERIPHERAL,
134};
135
136static struct clk *periph_clocks[] __initdata = {
137 &pioA_clk,
138 &pioB_clk,
139 &pioCDE_clk,
140 &usart0_clk,
141 &usart1_clk,
142 &usart2_clk,
143 &mmc0_clk,
144 &mmc1_clk,
145 // can
146 &twi_clk,
147 &spi0_clk,
148 &spi1_clk,
149 // ssc0 .. ssc1
150 // ac97
151 &tcb_clk,
152 // pwmc
153 &macb_clk,
154 // 2dge
155 &udc_clk,
156 &isi_clk,
157 &lcdc_clk,
158 // dma
159 &ohci_clk,
160 // irq0 .. irq1
161};
162
163/*
164 * The four programmable clocks.
165 * You must configure pin multiplexing to bring these signals out.
166 */
167static struct clk pck0 = {
168 .name = "pck0",
169 .pmc_mask = AT91_PMC_PCK0,
170 .type = CLK_TYPE_PROGRAMMABLE,
171 .id = 0,
172};
173static struct clk pck1 = {
174 .name = "pck1",
175 .pmc_mask = AT91_PMC_PCK1,
176 .type = CLK_TYPE_PROGRAMMABLE,
177 .id = 1,
178};
179static struct clk pck2 = {
180 .name = "pck2",
181 .pmc_mask = AT91_PMC_PCK2,
182 .type = CLK_TYPE_PROGRAMMABLE,
183 .id = 2,
184};
185static struct clk pck3 = {
186 .name = "pck3",
187 .pmc_mask = AT91_PMC_PCK3,
188 .type = CLK_TYPE_PROGRAMMABLE,
189 .id = 3,
190};
191
192static void __init at91sam9263_register_clocks(void)
193{
194 int i;
195
196 for (i = 0; i < ARRAY_SIZE(periph_clocks); i++)
197 clk_register(periph_clocks[i]);
198
199 clk_register(&pck0);
200 clk_register(&pck1);
201 clk_register(&pck2);
202 clk_register(&pck3);
203}
204
205/* --------------------------------------------------------------------
206 * GPIO
207 * -------------------------------------------------------------------- */
208
209static struct at91_gpio_bank at91sam9263_gpio[] = {
210 {
211 .id = AT91SAM9263_ID_PIOA,
212 .offset = AT91_PIOA,
213 .clock = &pioA_clk,
214 }, {
215 .id = AT91SAM9263_ID_PIOB,
216 .offset = AT91_PIOB,
217 .clock = &pioB_clk,
218 }, {
219 .id = AT91SAM9263_ID_PIOCDE,
220 .offset = AT91_PIOC,
221 .clock = &pioCDE_clk,
222 }, {
223 .id = AT91SAM9263_ID_PIOCDE,
224 .offset = AT91_PIOD,
225 .clock = &pioCDE_clk,
226 }, {
227 .id = AT91SAM9263_ID_PIOCDE,
228 .offset = AT91_PIOE,
229 .clock = &pioCDE_clk,
230 }
231};
232
233static void at91sam9263_reset(void)
234{
235 at91_sys_write(AT91_RSTC_CR, AT91_RSTC_KEY | AT91_RSTC_PROCRST | AT91_RSTC_PERRST);
236}
237
238
239/* --------------------------------------------------------------------
240 * AT91SAM9263 processor initialization
241 * -------------------------------------------------------------------- */
242
243void __init at91sam9263_initialize(unsigned long main_clock)
244{
245 /* Map peripherals */
246 iotable_init(at91sam9263_io_desc, ARRAY_SIZE(at91sam9263_io_desc));
247
248 at91_arch_reset = at91sam9263_reset;
249 at91_extern_irq = (1 << AT91SAM9263_ID_IRQ0) | (1 << AT91SAM9263_ID_IRQ1);
250
251 /* Init clock subsystem */
252 at91_clock_init(main_clock);
253
254 /* Register the processor-specific clocks */
255 at91sam9263_register_clocks();
256
257 /* Register GPIO subsystem */
258 at91_gpio_init(at91sam9263_gpio, 5);
259}
260
261/* --------------------------------------------------------------------
262 * Interrupt initialization
263 * -------------------------------------------------------------------- */
264
265/*
266 * The default interrupt priority levels (0 = lowest, 7 = highest).
267 */
268static unsigned int at91sam9263_default_irq_priority[NR_AIC_IRQS] __initdata = {
269 7, /* Advanced Interrupt Controller (FIQ) */
270 7, /* System Peripherals */
271 0, /* Parallel IO Controller A */
272 0, /* Parallel IO Controller B */
273 0, /* Parallel IO Controller C, D and E */
274 0,
275 0,
276 6, /* USART 0 */
277 6, /* USART 1 */
278 6, /* USART 2 */
279 0, /* Multimedia Card Interface 0 */
280 0, /* Multimedia Card Interface 1 */
281 4, /* CAN */
282 0, /* Two-Wire Interface */
283 6, /* Serial Peripheral Interface 0 */
284 6, /* Serial Peripheral Interface 1 */
285 5, /* Serial Synchronous Controller 0 */
286 5, /* Serial Synchronous Controller 1 */
287 6, /* AC97 Controller */
288 0, /* Timer Counter 0, 1 and 2 */
289 0, /* Pulse Width Modulation Controller */
290 3, /* Ethernet */
291 0,
292 0, /* 2D Graphic Engine */
293 3, /* USB Device Port */
294 0, /* Image Sensor Interface */
295 3, /* LDC Controller */
296 0, /* DMA Controller */
297 0,
298 3, /* USB Host port */
299 0, /* Advanced Interrupt Controller (IRQ0) */
300 0, /* Advanced Interrupt Controller (IRQ1) */
301};
302
303void __init at91sam9263_init_interrupts(unsigned int priority[NR_AIC_IRQS])
304{
305 if (!priority)
306 priority = at91sam9263_default_irq_priority;
307
308 /* Initialize the AIC interrupt controller */
309 at91_aic_init(priority);
310
311 /* Enable GPIO interrupts */
312 at91_gpio_irq_setup();
313}
diff --git a/arch/arm/mach-at91/at91sam9263_devices.c b/arch/arm/mach-at91/at91sam9263_devices.c
new file mode 100644
index 000000000000..d9af7ca58bce
--- /dev/null
+++ b/arch/arm/mach-at91/at91sam9263_devices.c
@@ -0,0 +1,818 @@
1/*
2 * arch/arm/mach-at91/at91sam9263_devices.c
3 *
4 * Copyright (C) 2007 Atmel Corporation.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 */
12#include <asm/mach/arch.h>
13#include <asm/mach/map.h>
14
15#include <linux/platform_device.h>
16
17#include <asm/arch/board.h>
18#include <asm/arch/gpio.h>
19#include <asm/arch/at91sam9263.h>
20#include <asm/arch/at91sam926x_mc.h>
21#include <asm/arch/at91sam9263_matrix.h>
22
23#include "generic.h"
24
25#define SZ_512 0x00000200
26#define SZ_256 0x00000100
27#define SZ_16 0x00000010
28
29/* --------------------------------------------------------------------
30 * USB Host
31 * -------------------------------------------------------------------- */
32
33#if defined(CONFIG_USB_OHCI_HCD) || defined(CONFIG_USB_OHCI_HCD_MODULE)
34static u64 ohci_dmamask = 0xffffffffUL;
35static struct at91_usbh_data usbh_data;
36
37static struct resource usbh_resources[] = {
38 [0] = {
39 .start = AT91SAM9263_UHP_BASE,
40 .end = AT91SAM9263_UHP_BASE + SZ_1M - 1,
41 .flags = IORESOURCE_MEM,
42 },
43 [1] = {
44 .start = AT91SAM9263_ID_UHP,
45 .end = AT91SAM9263_ID_UHP,
46 .flags = IORESOURCE_IRQ,
47 },
48};
49
50static struct platform_device at91_usbh_device = {
51 .name = "at91_ohci",
52 .id = -1,
53 .dev = {
54 .dma_mask = &ohci_dmamask,
55 .coherent_dma_mask = 0xffffffff,
56 .platform_data = &usbh_data,
57 },
58 .resource = usbh_resources,
59 .num_resources = ARRAY_SIZE(usbh_resources),
60};
61
62void __init at91_add_device_usbh(struct at91_usbh_data *data)
63{
64 int i;
65
66 if (!data)
67 return;
68
69 /* Enable VBus control for UHP ports */
70 for (i = 0; i < data->ports; i++) {
71 if (data->vbus_pin[i])
72 at91_set_gpio_output(data->vbus_pin[i], 0);
73 }
74
75 usbh_data = *data;
76 platform_device_register(&at91_usbh_device);
77}
78#else
79void __init at91_add_device_usbh(struct at91_usbh_data *data) {}
80#endif
81
82
83/* --------------------------------------------------------------------
84 * USB Device (Gadget)
85 * -------------------------------------------------------------------- */
86
87#ifdef CONFIG_USB_GADGET_AT91
88static struct at91_udc_data udc_data;
89
90static struct resource udc_resources[] = {
91 [0] = {
92 .start = AT91SAM9263_BASE_UDP,
93 .end = AT91SAM9263_BASE_UDP + SZ_16K - 1,
94 .flags = IORESOURCE_MEM,
95 },
96 [1] = {
97 .start = AT91SAM9263_ID_UDP,
98 .end = AT91SAM9263_ID_UDP,
99 .flags = IORESOURCE_IRQ,
100 },
101};
102
103static struct platform_device at91_udc_device = {
104 .name = "at91_udc",
105 .id = -1,
106 .dev = {
107 .platform_data = &udc_data,
108 },
109 .resource = udc_resources,
110 .num_resources = ARRAY_SIZE(udc_resources),
111};
112
113void __init at91_add_device_udc(struct at91_udc_data *data)
114{
115 if (!data)
116 return;
117
118 if (data->vbus_pin) {
119 at91_set_gpio_input(data->vbus_pin, 0);
120 at91_set_deglitch(data->vbus_pin, 1);
121 }
122
123 /* Pullup pin is handled internally by USB device peripheral */
124
125 udc_data = *data;
126 platform_device_register(&at91_udc_device);
127}
128#else
129void __init at91_add_device_udc(struct at91_udc_data *data) {}
130#endif
131
132
133/* --------------------------------------------------------------------
134 * Ethernet
135 * -------------------------------------------------------------------- */
136
137#if defined(CONFIG_MACB) || defined(CONFIG_MACB_MODULE)
138static u64 eth_dmamask = 0xffffffffUL;
139static struct at91_eth_data eth_data;
140
141static struct resource eth_resources[] = {
142 [0] = {
143 .start = AT91SAM9263_BASE_EMAC,
144 .end = AT91SAM9263_BASE_EMAC + SZ_16K - 1,
145 .flags = IORESOURCE_MEM,
146 },
147 [1] = {
148 .start = AT91SAM9263_ID_EMAC,
149 .end = AT91SAM9263_ID_EMAC,
150 .flags = IORESOURCE_IRQ,
151 },
152};
153
154static struct platform_device at91sam9263_eth_device = {
155 .name = "macb",
156 .id = -1,
157 .dev = {
158 .dma_mask = &eth_dmamask,
159 .coherent_dma_mask = 0xffffffff,
160 .platform_data = &eth_data,
161 },
162 .resource = eth_resources,
163 .num_resources = ARRAY_SIZE(eth_resources),
164};
165
166void __init at91_add_device_eth(struct at91_eth_data *data)
167{
168 if (!data)
169 return;
170
171 if (data->phy_irq_pin) {
172 at91_set_gpio_input(data->phy_irq_pin, 0);
173 at91_set_deglitch(data->phy_irq_pin, 1);
174 }
175
176 /* Pins used for MII and RMII */
177 at91_set_A_periph(AT91_PIN_PE21, 0); /* ETXCK_EREFCK */
178 at91_set_B_periph(AT91_PIN_PC25, 0); /* ERXDV */
179 at91_set_A_periph(AT91_PIN_PE25, 0); /* ERX0 */
180 at91_set_A_periph(AT91_PIN_PE26, 0); /* ERX1 */
181 at91_set_A_periph(AT91_PIN_PE27, 0); /* ERXER */
182 at91_set_A_periph(AT91_PIN_PE28, 0); /* ETXEN */
183 at91_set_A_periph(AT91_PIN_PE23, 0); /* ETX0 */
184 at91_set_A_periph(AT91_PIN_PE24, 0); /* ETX1 */
185 at91_set_A_periph(AT91_PIN_PE30, 0); /* EMDIO */
186 at91_set_A_periph(AT91_PIN_PE29, 0); /* EMDC */
187
188 if (!data->is_rmii) {
189 at91_set_A_periph(AT91_PIN_PE22, 0); /* ECRS */
190 at91_set_B_periph(AT91_PIN_PC26, 0); /* ECOL */
191 at91_set_B_periph(AT91_PIN_PC22, 0); /* ERX2 */
192 at91_set_B_periph(AT91_PIN_PC23, 0); /* ERX3 */
193 at91_set_B_periph(AT91_PIN_PC27, 0); /* ERXCK */
194 at91_set_B_periph(AT91_PIN_PC20, 0); /* ETX2 */
195 at91_set_B_periph(AT91_PIN_PC21, 0); /* ETX3 */
196 at91_set_B_periph(AT91_PIN_PC24, 0); /* ETXER */
197 }
198
199 eth_data = *data;
200 platform_device_register(&at91sam9263_eth_device);
201}
202#else
203void __init at91_add_device_eth(struct at91_eth_data *data) {}
204#endif
205
206
207/* --------------------------------------------------------------------
208 * MMC / SD
209 * -------------------------------------------------------------------- */
210
211#if defined(CONFIG_MMC_AT91) || defined(CONFIG_MMC_AT91_MODULE)
212static u64 mmc_dmamask = 0xffffffffUL;
213static struct at91_mmc_data mmc0_data, mmc1_data;
214
215static struct resource mmc0_resources[] = {
216 [0] = {
217 .start = AT91SAM9263_BASE_MCI0,
218 .end = AT91SAM9263_BASE_MCI0 + SZ_16K - 1,
219 .flags = IORESOURCE_MEM,
220 },
221 [1] = {
222 .start = AT91SAM9263_ID_MCI0,
223 .end = AT91SAM9263_ID_MCI0,
224 .flags = IORESOURCE_IRQ,
225 },
226};
227
228static struct platform_device at91sam9263_mmc0_device = {
229 .name = "at91_mci",
230 .id = 0,
231 .dev = {
232 .dma_mask = &mmc_dmamask,
233 .coherent_dma_mask = 0xffffffff,
234 .platform_data = &mmc0_data,
235 },
236 .resource = mmc0_resources,
237 .num_resources = ARRAY_SIZE(mmc0_resources),
238};
239
240static struct resource mmc1_resources[] = {
241 [0] = {
242 .start = AT91SAM9263_BASE_MCI1,
243 .end = AT91SAM9263_BASE_MCI1 + SZ_16K - 1,
244 .flags = IORESOURCE_MEM,
245 },
246 [1] = {
247 .start = AT91SAM9263_ID_MCI1,
248 .end = AT91SAM9263_ID_MCI1,
249 .flags = IORESOURCE_IRQ,
250 },
251};
252
253static struct platform_device at91sam9263_mmc1_device = {
254 .name = "at91_mci",
255 .id = 1,
256 .dev = {
257 .dma_mask = &mmc_dmamask,
258 .coherent_dma_mask = 0xffffffff,
259 .platform_data = &mmc1_data,
260 },
261 .resource = mmc1_resources,
262 .num_resources = ARRAY_SIZE(mmc1_resources),
263};
264
265void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data)
266{
267 if (!data)
268 return;
269
270 /* input/irq */
271 if (data->det_pin) {
272 at91_set_gpio_input(data->det_pin, 1);
273 at91_set_deglitch(data->det_pin, 1);
274 }
275 if (data->wp_pin)
276 at91_set_gpio_input(data->wp_pin, 1);
277 if (data->vcc_pin)
278 at91_set_gpio_output(data->vcc_pin, 0);
279
280 if (mmc_id == 0) { /* MCI0 */
281 /* CLK */
282 at91_set_A_periph(AT91_PIN_PA12, 0);
283
284 if (data->slot_b) {
285 /* CMD */
286 at91_set_A_periph(AT91_PIN_PA16, 1);
287
288 /* DAT0, maybe DAT1..DAT3 */
289 at91_set_A_periph(AT91_PIN_PA17, 1);
290 if (data->wire4) {
291 at91_set_A_periph(AT91_PIN_PA18, 1);
292 at91_set_A_periph(AT91_PIN_PA19, 1);
293 at91_set_A_periph(AT91_PIN_PA20, 1);
294 }
295 } else {
296 /* CMD */
297 at91_set_A_periph(AT91_PIN_PA1, 1);
298
299 /* DAT0, maybe DAT1..DAT3 */
300 at91_set_A_periph(AT91_PIN_PA0, 1);
301 if (data->wire4) {
302 at91_set_A_periph(AT91_PIN_PA3, 1);
303 at91_set_A_periph(AT91_PIN_PA4, 1);
304 at91_set_A_periph(AT91_PIN_PA5, 1);
305 }
306 }
307
308 mmc0_data = *data;
309 at91_clock_associate("mci0_clk", &at91sam9263_mmc1_device.dev, "mci_clk");
310 platform_device_register(&at91sam9263_mmc0_device);
311 } else { /* MCI1 */
312 /* CLK */
313 at91_set_A_periph(AT91_PIN_PA6, 0);
314
315 if (data->slot_b) {
316 /* CMD */
317 at91_set_A_periph(AT91_PIN_PA21, 1);
318
319 /* DAT0, maybe DAT1..DAT3 */
320 at91_set_A_periph(AT91_PIN_PA22, 1);
321 if (data->wire4) {
322 at91_set_A_periph(AT91_PIN_PA23, 1);
323 at91_set_A_periph(AT91_PIN_PA24, 1);
324 at91_set_A_periph(AT91_PIN_PA25, 1);
325 }
326 } else {
327 /* CMD */
328 at91_set_A_periph(AT91_PIN_PA7, 1);
329
330 /* DAT0, maybe DAT1..DAT3 */
331 at91_set_A_periph(AT91_PIN_PA8, 1);
332 if (data->wire4) {
333 at91_set_A_periph(AT91_PIN_PA9, 1);
334 at91_set_A_periph(AT91_PIN_PA10, 1);
335 at91_set_A_periph(AT91_PIN_PA11, 1);
336 }
337 }
338
339 mmc1_data = *data;
340 at91_clock_associate("mci1_clk", &at91sam9263_mmc1_device.dev, "mci_clk");
341 platform_device_register(&at91sam9263_mmc1_device);
342 }
343}
344#else
345void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data) {}
346#endif
347
348
349/* --------------------------------------------------------------------
350 * NAND / SmartMedia
351 * -------------------------------------------------------------------- */
352
353#if defined(CONFIG_MTD_NAND_AT91) || defined(CONFIG_MTD_NAND_AT91_MODULE)
354static struct at91_nand_data nand_data;
355
356#define NAND_BASE AT91_CHIPSELECT_3
357
358static struct resource nand_resources[] = {
359 {
360 .start = NAND_BASE,
361 .end = NAND_BASE + SZ_256M - 1,
362 .flags = IORESOURCE_MEM,
363 }
364};
365
366static struct platform_device at91sam9263_nand_device = {
367 .name = "at91_nand",
368 .id = -1,
369 .dev = {
370 .platform_data = &nand_data,
371 },
372 .resource = nand_resources,
373 .num_resources = ARRAY_SIZE(nand_resources),
374};
375
376void __init at91_add_device_nand(struct at91_nand_data *data)
377{
378 unsigned long csa, mode;
379
380 if (!data)
381 return;
382
383 csa = at91_sys_read(AT91_MATRIX_EBI0CSA);
384 at91_sys_write(AT91_MATRIX_EBI0CSA, csa | AT91_MATRIX_EBI0_CS3A_SMC);
385
386 /* set the bus interface characteristics */
387 at91_sys_write(AT91_SMC_SETUP(3), AT91_SMC_NWESETUP_(0) | AT91_SMC_NCS_WRSETUP_(0)
388 | AT91_SMC_NRDSETUP_(0) | AT91_SMC_NCS_RDSETUP_(0));
389
390 at91_sys_write(AT91_SMC_PULSE(3), AT91_SMC_NWEPULSE_(3) | AT91_SMC_NCS_WRPULSE_(3)
391 | AT91_SMC_NRDPULSE_(3) | AT91_SMC_NCS_RDPULSE_(3));
392
393 at91_sys_write(AT91_SMC_CYCLE(3), AT91_SMC_NWECYCLE_(5) | AT91_SMC_NRDCYCLE_(5));
394
395 if (data->bus_width_16)
396 mode = AT91_SMC_DBW_16;
397 else
398 mode = AT91_SMC_DBW_8;
399 at91_sys_write(AT91_SMC_MODE(3), mode | AT91_SMC_READMODE | AT91_SMC_WRITEMODE | AT91_SMC_EXNWMODE_DISABLE | AT91_SMC_TDF_(2));
400
401 /* enable pin */
402 if (data->enable_pin)
403 at91_set_gpio_output(data->enable_pin, 1);
404
405 /* ready/busy pin */
406 if (data->rdy_pin)
407 at91_set_gpio_input(data->rdy_pin, 1);
408
409 /* card detect pin */
410 if (data->det_pin)
411 at91_set_gpio_input(data->det_pin, 1);
412
413 nand_data = *data;
414 platform_device_register(&at91sam9263_nand_device);
415}
416#else
417void __init at91_add_device_nand(struct at91_nand_data *data) {}
418#endif
419
420
421/* --------------------------------------------------------------------
422 * TWI (i2c)
423 * -------------------------------------------------------------------- */
424
425#if defined(CONFIG_I2C_AT91) || defined(CONFIG_I2C_AT91_MODULE)
426
427static struct resource twi_resources[] = {
428 [0] = {
429 .start = AT91SAM9263_BASE_TWI,
430 .end = AT91SAM9263_BASE_TWI + SZ_16K - 1,
431 .flags = IORESOURCE_MEM,
432 },
433 [1] = {
434 .start = AT91SAM9263_ID_TWI,
435 .end = AT91SAM9263_ID_TWI,
436 .flags = IORESOURCE_IRQ,
437 },
438};
439
440static struct platform_device at91sam9263_twi_device = {
441 .name = "at91_i2c",
442 .id = -1,
443 .resource = twi_resources,
444 .num_resources = ARRAY_SIZE(twi_resources),
445};
446
447void __init at91_add_device_i2c(void)
448{
449 /* pins used for TWI interface */
450 at91_set_A_periph(AT91_PIN_PB4, 0); /* TWD */
451 at91_set_multi_drive(AT91_PIN_PB4, 1);
452
453 at91_set_A_periph(AT91_PIN_PB5, 0); /* TWCK */
454 at91_set_multi_drive(AT91_PIN_PB5, 1);
455
456 platform_device_register(&at91sam9263_twi_device);
457}
458#else
459void __init at91_add_device_i2c(void) {}
460#endif
461
462
463/* --------------------------------------------------------------------
464 * SPI
465 * -------------------------------------------------------------------- */
466
467#if defined(CONFIG_SPI_ATMEL) || defined(CONFIG_SPI_ATMEL_MODULE)
468static u64 spi_dmamask = 0xffffffffUL;
469
470static struct resource spi0_resources[] = {
471 [0] = {
472 .start = AT91SAM9263_BASE_SPI0,
473 .end = AT91SAM9263_BASE_SPI0 + SZ_16K - 1,
474 .flags = IORESOURCE_MEM,
475 },
476 [1] = {
477 .start = AT91SAM9263_ID_SPI0,
478 .end = AT91SAM9263_ID_SPI0,
479 .flags = IORESOURCE_IRQ,
480 },
481};
482
483static struct platform_device at91sam9263_spi0_device = {
484 .name = "atmel_spi",
485 .id = 0,
486 .dev = {
487 .dma_mask = &spi_dmamask,
488 .coherent_dma_mask = 0xffffffff,
489 },
490 .resource = spi0_resources,
491 .num_resources = ARRAY_SIZE(spi0_resources),
492};
493
494static const unsigned spi0_standard_cs[4] = { AT91_PIN_PA5, AT91_PIN_PA3, AT91_PIN_PA4, AT91_PIN_PB11 };
495
496static struct resource spi1_resources[] = {
497 [0] = {
498 .start = AT91SAM9263_BASE_SPI1,
499 .end = AT91SAM9263_BASE_SPI1 + SZ_16K - 1,
500 .flags = IORESOURCE_MEM,
501 },
502 [1] = {
503 .start = AT91SAM9263_ID_SPI1,
504 .end = AT91SAM9263_ID_SPI1,
505 .flags = IORESOURCE_IRQ,
506 },
507};
508
509static struct platform_device at91sam9263_spi1_device = {
510 .name = "atmel_spi",
511 .id = 1,
512 .dev = {
513 .dma_mask = &spi_dmamask,
514 .coherent_dma_mask = 0xffffffff,
515 },
516 .resource = spi1_resources,
517 .num_resources = ARRAY_SIZE(spi1_resources),
518};
519
520static const unsigned spi1_standard_cs[4] = { AT91_PIN_PB15, AT91_PIN_PB16, AT91_PIN_PB17, AT91_PIN_PB18 };
521
522void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices)
523{
524 int i;
525 unsigned long cs_pin;
526 short enable_spi0 = 0;
527 short enable_spi1 = 0;
528
529 /* Choose SPI chip-selects */
530 for (i = 0; i < nr_devices; i++) {
531 if (devices[i].controller_data)
532 cs_pin = (unsigned long) devices[i].controller_data;
533 else if (devices[i].bus_num == 0)
534 cs_pin = spi0_standard_cs[devices[i].chip_select];
535 else
536 cs_pin = spi1_standard_cs[devices[i].chip_select];
537
538 if (devices[i].bus_num == 0)
539 enable_spi0 = 1;
540 else
541 enable_spi1 = 1;
542
543 /* enable chip-select pin */
544 at91_set_gpio_output(cs_pin, 1);
545
546 /* pass chip-select pin to driver */
547 devices[i].controller_data = (void *) cs_pin;
548 }
549
550 spi_register_board_info(devices, nr_devices);
551
552 /* Configure SPI bus(es) */
553 if (enable_spi0) {
554 at91_set_B_periph(AT91_PIN_PA0, 0); /* SPI0_MISO */
555 at91_set_B_periph(AT91_PIN_PA1, 0); /* SPI0_MOSI */
556 at91_set_B_periph(AT91_PIN_PA2, 0); /* SPI1_SPCK */
557
558 at91_clock_associate("spi0_clk", &at91sam9263_spi0_device.dev, "spi_clk");
559 platform_device_register(&at91sam9263_spi0_device);
560 }
561 if (enable_spi1) {
562 at91_set_A_periph(AT91_PIN_PB12, 0); /* SPI1_MISO */
563 at91_set_A_periph(AT91_PIN_PB13, 0); /* SPI1_MOSI */
564 at91_set_A_periph(AT91_PIN_PB14, 0); /* SPI1_SPCK */
565
566 at91_clock_associate("spi1_clk", &at91sam9263_spi1_device.dev, "spi_clk");
567 platform_device_register(&at91sam9263_spi1_device);
568 }
569}
570#else
571void __init at91_add_device_spi(struct spi_board_info *devices, int nr_devices) {}
572#endif
573
574
575/* --------------------------------------------------------------------
576 * LEDs
577 * -------------------------------------------------------------------- */
578
579#if defined(CONFIG_LEDS)
580u8 at91_leds_cpu;
581u8 at91_leds_timer;
582
583void __init at91_init_leds(u8 cpu_led, u8 timer_led)
584{
585 /* Enable GPIO to access the LEDs */
586 at91_set_gpio_output(cpu_led, 1);
587 at91_set_gpio_output(timer_led, 1);
588
589 at91_leds_cpu = cpu_led;
590 at91_leds_timer = timer_led;
591}
592#else
593void __init at91_init_leds(u8 cpu_led, u8 timer_led) {}
594#endif
595
596
597/* --------------------------------------------------------------------
598 * UART
599 * -------------------------------------------------------------------- */
600
601#if defined(CONFIG_SERIAL_ATMEL)
602
603static struct resource dbgu_resources[] = {
604 [0] = {
605 .start = AT91_VA_BASE_SYS + AT91_DBGU,
606 .end = AT91_VA_BASE_SYS + AT91_DBGU + SZ_512 - 1,
607 .flags = IORESOURCE_MEM,
608 },
609 [1] = {
610 .start = AT91_ID_SYS,
611 .end = AT91_ID_SYS,
612 .flags = IORESOURCE_IRQ,
613 },
614};
615
616static struct atmel_uart_data dbgu_data = {
617 .use_dma_tx = 0,
618 .use_dma_rx = 0, /* DBGU not capable of receive DMA */
619 .regs = (void __iomem *)(AT91_VA_BASE_SYS + AT91_DBGU),
620};
621
622static struct platform_device at91sam9263_dbgu_device = {
623 .name = "atmel_usart",
624 .id = 0,
625 .dev = {
626 .platform_data = &dbgu_data,
627 .coherent_dma_mask = 0xffffffff,
628 },
629 .resource = dbgu_resources,
630 .num_resources = ARRAY_SIZE(dbgu_resources),
631};
632
633static inline void configure_dbgu_pins(void)
634{
635 at91_set_A_periph(AT91_PIN_PC30, 0); /* DRXD */
636 at91_set_A_periph(AT91_PIN_PC31, 1); /* DTXD */
637}
638
639static struct resource uart0_resources[] = {
640 [0] = {
641 .start = AT91SAM9263_BASE_US0,
642 .end = AT91SAM9263_BASE_US0 + SZ_16K - 1,
643 .flags = IORESOURCE_MEM,
644 },
645 [1] = {
646 .start = AT91SAM9263_ID_US0,
647 .end = AT91SAM9263_ID_US0,
648 .flags = IORESOURCE_IRQ,
649 },
650};
651
652static struct atmel_uart_data uart0_data = {
653 .use_dma_tx = 1,
654 .use_dma_rx = 1,
655};
656
657static struct platform_device at91sam9263_uart0_device = {
658 .name = "atmel_usart",
659 .id = 1,
660 .dev = {
661 .platform_data = &uart0_data,
662 .coherent_dma_mask = 0xffffffff,
663 },
664 .resource = uart0_resources,
665 .num_resources = ARRAY_SIZE(uart0_resources),
666};
667
668static inline void configure_usart0_pins(void)
669{
670 at91_set_A_periph(AT91_PIN_PA26, 1); /* TXD0 */
671 at91_set_A_periph(AT91_PIN_PA27, 0); /* RXD0 */
672 at91_set_A_periph(AT91_PIN_PA28, 0); /* RTS0 */
673 at91_set_A_periph(AT91_PIN_PA29, 0); /* CTS0 */
674}
675
676static struct resource uart1_resources[] = {
677 [0] = {
678 .start = AT91SAM9263_BASE_US1,
679 .end = AT91SAM9263_BASE_US1 + SZ_16K - 1,
680 .flags = IORESOURCE_MEM,
681 },
682 [1] = {
683 .start = AT91SAM9263_ID_US1,
684 .end = AT91SAM9263_ID_US1,
685 .flags = IORESOURCE_IRQ,
686 },
687};
688
689static struct atmel_uart_data uart1_data = {
690 .use_dma_tx = 1,
691 .use_dma_rx = 1,
692};
693
694static struct platform_device at91sam9263_uart1_device = {
695 .name = "atmel_usart",
696 .id = 2,
697 .dev = {
698 .platform_data = &uart1_data,
699 .coherent_dma_mask = 0xffffffff,
700 },
701 .resource = uart1_resources,
702 .num_resources = ARRAY_SIZE(uart1_resources),
703};
704
705static inline void configure_usart1_pins(void)
706{
707 at91_set_A_periph(AT91_PIN_PD0, 1); /* TXD1 */
708 at91_set_A_periph(AT91_PIN_PD1, 0); /* RXD1 */
709 at91_set_B_periph(AT91_PIN_PD7, 0); /* RTS1 */
710 at91_set_B_periph(AT91_PIN_PD8, 0); /* CTS1 */
711}
712
713static struct resource uart2_resources[] = {
714 [0] = {
715 .start = AT91SAM9263_BASE_US2,
716 .end = AT91SAM9263_BASE_US2 + SZ_16K - 1,
717 .flags = IORESOURCE_MEM,
718 },
719 [1] = {
720 .start = AT91SAM9263_ID_US2,
721 .end = AT91SAM9263_ID_US2,
722 .flags = IORESOURCE_IRQ,
723 },
724};
725
726static struct atmel_uart_data uart2_data = {
727 .use_dma_tx = 1,
728 .use_dma_rx = 1,
729};
730
731static struct platform_device at91sam9263_uart2_device = {
732 .name = "atmel_usart",
733 .id = 3,
734 .dev = {
735 .platform_data = &uart2_data,
736 .coherent_dma_mask = 0xffffffff,
737 },
738 .resource = uart2_resources,
739 .num_resources = ARRAY_SIZE(uart2_resources),
740};
741
742static inline void configure_usart2_pins(void)
743{
744 at91_set_A_periph(AT91_PIN_PD2, 1); /* TXD2 */
745 at91_set_A_periph(AT91_PIN_PD3, 0); /* RXD2 */
746 at91_set_B_periph(AT91_PIN_PD5, 0); /* RTS2 */
747 at91_set_B_periph(AT91_PIN_PD6, 0); /* CTS2 */
748}
749
750struct platform_device *at91_uarts[ATMEL_MAX_UART]; /* the UARTs to use */
751struct platform_device *atmel_default_console_device; /* the serial console device */
752
753void __init at91_init_serial(struct at91_uart_config *config)
754{
755 int i;
756
757 /* Fill in list of supported UARTs */
758 for (i = 0; i < config->nr_tty; i++) {
759 switch (config->tty_map[i]) {
760 case 0:
761 configure_usart0_pins();
762 at91_uarts[i] = &at91sam9263_uart0_device;
763 at91_clock_associate("usart0_clk", &at91sam9263_uart0_device.dev, "usart");
764 break;
765 case 1:
766 configure_usart1_pins();
767 at91_uarts[i] = &at91sam9263_uart1_device;
768 at91_clock_associate("usart1_clk", &at91sam9263_uart1_device.dev, "usart");
769 break;
770 case 2:
771 configure_usart2_pins();
772 at91_uarts[i] = &at91sam9263_uart2_device;
773 at91_clock_associate("usart2_clk", &at91sam9263_uart2_device.dev, "usart");
774 break;
775 case 3:
776 configure_dbgu_pins();
777 at91_uarts[i] = &at91sam9263_dbgu_device;
778 at91_clock_associate("mck", &at91sam9263_dbgu_device.dev, "usart");
779 break;
780 default:
781 continue;
782 }
783 at91_uarts[i]->id = i; /* update ID number to mapped ID */
784 }
785
786 /* Set serial console device */
787 if (config->console_tty < ATMEL_MAX_UART)
788 atmel_default_console_device = at91_uarts[config->console_tty];
789 if (!atmel_default_console_device)
790 printk(KERN_INFO "AT91: No default serial console defined.\n");
791}
792
793void __init at91_add_device_serial(void)
794{
795 int i;
796
797 for (i = 0; i < ATMEL_MAX_UART; i++) {
798 if (at91_uarts[i])
799 platform_device_register(at91_uarts[i]);
800 }
801}
802#else
803void __init at91_init_serial(struct at91_uart_config *config) {}
804void __init at91_add_device_serial(void) {}
805#endif
806
807
808/* -------------------------------------------------------------------- */
809/*
810 * These devices are always present and don't need any board-specific
811 * setup.
812 */
813static int __init at91_add_standard_devices(void)
814{
815 return 0;
816}
817
818arch_initcall(at91_add_standard_devices);
diff --git a/arch/arm/mach-at91rm9200/at91sam926x_time.c b/arch/arm/mach-at91/at91sam926x_time.c
index 99df5f6ee42e..a4dded27fa16 100644
--- a/arch/arm/mach-at91rm9200/at91sam926x_time.c
+++ b/arch/arm/mach-at91/at91sam926x_time.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-at91rm9200/at91sam926x_time.c 2 * linux/arch/arm/mach-at91/at91sam926x_time.c
3 * 3 *
4 * Copyright (C) 2005-2006 M. Amine SAYA, ATMEL Rousset, France 4 * Copyright (C) 2005-2006 M. Amine SAYA, ATMEL Rousset, France
5 * Revision 2005 M. Nicolas Diremdjian, ATMEL Rousset, France 5 * Revision 2005 M. Nicolas Diremdjian, ATMEL Rousset, France
@@ -30,7 +30,6 @@
30 * Returns number of microseconds since last timer interrupt. Note that interrupts 30 * Returns number of microseconds since last timer interrupt. Note that interrupts
31 * will have been disabled by do_gettimeofday() 31 * will have been disabled by do_gettimeofday()
32 * 'LATCH' is hwclock ticks (see CLOCK_TICK_RATE in timex.h) per jiffy. 32 * 'LATCH' is hwclock ticks (see CLOCK_TICK_RATE in timex.h) per jiffy.
33 * 'tick' is usecs per jiffy (linux/timex.h).
34 */ 33 */
35static unsigned long at91sam926x_gettimeoffset(void) 34static unsigned long at91sam926x_gettimeoffset(void)
36{ 35{
@@ -39,7 +38,7 @@ static unsigned long at91sam926x_gettimeoffset(void)
39 38
40 elapsed = (PIT_PICNT(t) * LATCH) + PIT_CPIV(t); /* hardware clock cycles */ 39 elapsed = (PIT_PICNT(t) * LATCH) + PIT_CPIV(t); /* hardware clock cycles */
41 40
42 return (unsigned long)(elapsed * 1000000) / LATCH; 41 return (unsigned long)(elapsed * jiffies_to_usecs(1)) / LATCH;
43} 42}
44 43
45/* 44/*
diff --git a/arch/arm/mach-at91rm9200/board-1arm.c b/arch/arm/mach-at91/board-1arm.c
index 971c3e2d8e36..2d3d4b6f7b02 100644
--- a/arch/arm/mach-at91rm9200/board-1arm.c
+++ b/arch/arm/mach-at91/board-1arm.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-at91rm9200/board-1arm.c 2 * linux/arch/arm/mach-at91/board-1arm.c
3 * 3 *
4 * Copyright (C) 2005 SAN People 4 * Copyright (C) 2005 SAN People
5 * 5 *
diff --git a/arch/arm/mach-at91rm9200/board-carmeva.c b/arch/arm/mach-at91/board-carmeva.c
index 654f0379550a..b4518619063a 100644
--- a/arch/arm/mach-at91rm9200/board-carmeva.c
+++ b/arch/arm/mach-at91/board-carmeva.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-at91rm9200/board-carmeva.c 2 * linux/arch/arm/mach-at91/board-carmeva.c
3 * 3 *
4 * Copyright (c) 2005 Peer Georgi 4 * Copyright (c) 2005 Peer Georgi
5 * Conitec Datasystems 5 * Conitec Datasystems
@@ -134,7 +134,7 @@ static void __init carmeva_board_init(void)
134 /* Compact Flash */ 134 /* Compact Flash */
135// at91_add_device_cf(&carmeva_cf_data); 135// at91_add_device_cf(&carmeva_cf_data);
136 /* MMC */ 136 /* MMC */
137 at91_add_device_mmc(&carmeva_mmc_data); 137 at91_add_device_mmc(0, &carmeva_mmc_data);
138} 138}
139 139
140MACHINE_START(CARMEVA, "Carmeva") 140MACHINE_START(CARMEVA, "Carmeva")
diff --git a/arch/arm/mach-at91rm9200/board-csb337.c b/arch/arm/mach-at91/board-csb337.c
index b8bb8052607a..e18a41e61f0c 100644
--- a/arch/arm/mach-at91rm9200/board-csb337.c
+++ b/arch/arm/mach-at91/board-csb337.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-at91rm9200/board-csb337.c 2 * linux/arch/arm/mach-at91/board-csb337.c
3 * 3 *
4 * Copyright (C) 2005 SAN People 4 * Copyright (C) 2005 SAN People
5 * 5 *
@@ -24,6 +24,7 @@
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26#include <linux/spi/spi.h> 26#include <linux/spi/spi.h>
27#include <linux/mtd/physmap.h>
27 28
28#include <asm/hardware.h> 29#include <asm/hardware.h>
29#include <asm/setup.h> 30#include <asm/setup.h>
@@ -112,6 +113,42 @@ static struct spi_board_info csb337_spi_devices[] = {
112 }, 113 },
113}; 114};
114 115
116#define CSB_FLASH_BASE AT91_CHIPSELECT_0
117#define CSB_FLASH_SIZE 0x800000
118
119static struct mtd_partition csb_flash_partitions[] = {
120 {
121 .name = "uMON flash",
122 .offset = 0,
123 .size = MTDPART_SIZ_FULL,
124 .mask_flags = MTD_WRITEABLE, /* read only */
125 }
126};
127
128static struct physmap_flash_data csb_flash_data = {
129 .width = 2,
130 .parts = csb_flash_partitions,
131 .nr_parts = ARRAY_SIZE(csb_flash_partitions),
132};
133
134static struct resource csb_flash_resources[] = {
135 {
136 .start = CSB_FLASH_BASE,
137 .end = CSB_FLASH_BASE + CSB_FLASH_SIZE - 1,
138 .flags = IORESOURCE_MEM,
139 }
140};
141
142static struct platform_device csb_flash = {
143 .name = "physmap-flash",
144 .id = 0,
145 .dev = {
146 .platform_data = &csb_flash_data,
147 },
148 .resource = csb_flash_resources,
149 .num_resources = ARRAY_SIZE(csb_flash_resources),
150};
151
115static void __init csb337_board_init(void) 152static void __init csb337_board_init(void)
116{ 153{
117 /* Serial */ 154 /* Serial */
@@ -130,7 +167,9 @@ static void __init csb337_board_init(void)
130 /* SPI */ 167 /* SPI */
131 at91_add_device_spi(csb337_spi_devices, ARRAY_SIZE(csb337_spi_devices)); 168 at91_add_device_spi(csb337_spi_devices, ARRAY_SIZE(csb337_spi_devices));
132 /* MMC */ 169 /* MMC */
133 at91_add_device_mmc(&csb337_mmc_data); 170 at91_add_device_mmc(0, &csb337_mmc_data);
171 /* NOR flash */
172 platform_device_register(&csb_flash);
134} 173}
135 174
136MACHINE_START(CSB337, "Cogent CSB337") 175MACHINE_START(CSB337, "Cogent CSB337")
diff --git a/arch/arm/mach-at91rm9200/board-csb637.c b/arch/arm/mach-at91/board-csb637.c
index a29fa0e822ce..77f04b935b3a 100644
--- a/arch/arm/mach-at91rm9200/board-csb637.c
+++ b/arch/arm/mach-at91/board-csb637.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-at91rm9200/board-csb637.c 2 * linux/arch/arm/mach-at91/board-csb637.c
3 * 3 *
4 * Copyright (C) 2005 SAN People 4 * Copyright (C) 2005 SAN People
5 * 5 *
@@ -23,6 +23,7 @@
23#include <linux/mm.h> 23#include <linux/mm.h>
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/platform_device.h> 25#include <linux/platform_device.h>
26#include <linux/mtd/physmap.h>
26 27
27#include <asm/hardware.h> 28#include <asm/hardware.h>
28#include <asm/setup.h> 29#include <asm/setup.h>
@@ -81,6 +82,42 @@ static struct at91_udc_data __initdata csb637_udc_data = {
81 .pullup_pin = AT91_PIN_PB1, 82 .pullup_pin = AT91_PIN_PB1,
82}; 83};
83 84
85#define CSB_FLASH_BASE AT91_CHIPSELECT_0
86#define CSB_FLASH_SIZE 0x1000000
87
88static struct mtd_partition csb_flash_partitions[] = {
89 {
90 .name = "uMON flash",
91 .offset = 0,
92 .size = MTDPART_SIZ_FULL,
93 .mask_flags = MTD_WRITEABLE, /* read only */
94 }
95};
96
97static struct physmap_flash_data csb_flash_data = {
98 .width = 2,
99 .parts = csb_flash_partitions,
100 .nr_parts = ARRAY_SIZE(csb_flash_partitions),
101};
102
103static struct resource csb_flash_resources[] = {
104 {
105 .start = CSB_FLASH_BASE,
106 .end = CSB_FLASH_BASE + CSB_FLASH_SIZE - 1,
107 .flags = IORESOURCE_MEM,
108 }
109};
110
111static struct platform_device csb_flash = {
112 .name = "physmap-flash",
113 .id = 0,
114 .dev = {
115 .platform_data = &csb_flash_data,
116 },
117 .resource = csb_flash_resources,
118 .num_resources = ARRAY_SIZE(csb_flash_resources),
119};
120
84static void __init csb637_board_init(void) 121static void __init csb637_board_init(void)
85{ 122{
86 /* Serial */ 123 /* Serial */
@@ -95,6 +132,8 @@ static void __init csb637_board_init(void)
95 at91_add_device_i2c(); 132 at91_add_device_i2c();
96 /* SPI */ 133 /* SPI */
97 at91_add_device_spi(NULL, 0); 134 at91_add_device_spi(NULL, 0);
135 /* NOR flash */
136 platform_device_register(&csb_flash);
98} 137}
99 138
100MACHINE_START(CSB637, "Cogent CSB637") 139MACHINE_START(CSB637, "Cogent CSB637")
diff --git a/arch/arm/mach-at91rm9200/board-dk.c b/arch/arm/mach-at91/board-dk.c
index 7522bf91bce8..6043c38c0a9e 100644
--- a/arch/arm/mach-at91rm9200/board-dk.c
+++ b/arch/arm/mach-at91/board-dk.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-at91rm9200/board-dk.c 2 * linux/arch/arm/mach-at91/board-dk.c
3 * 3 *
4 * Copyright (C) 2005 SAN People 4 * Copyright (C) 2005 SAN People
5 * 5 *
@@ -194,7 +194,7 @@ static void __init dk_board_init(void)
194#else 194#else
195 /* MMC */ 195 /* MMC */
196 at91_set_gpio_output(AT91_PIN_PB7, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */ 196 at91_set_gpio_output(AT91_PIN_PB7, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */
197 at91_add_device_mmc(&dk_mmc_data); 197 at91_add_device_mmc(0, &dk_mmc_data);
198#endif 198#endif
199 /* NAND */ 199 /* NAND */
200 at91_add_device_nand(&dk_nand_data); 200 at91_add_device_nand(&dk_nand_data);
diff --git a/arch/arm/mach-at91rm9200/board-eb9200.c b/arch/arm/mach-at91/board-eb9200.c
index 80b72cf7264c..20458b5548f0 100644
--- a/arch/arm/mach-at91rm9200/board-eb9200.c
+++ b/arch/arm/mach-at91/board-eb9200.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-at91rm9200/board-eb9200.c 2 * linux/arch/arm/mach-at91/board-eb9200.c
3 * 3 *
4 * Copyright (C) 2005 SAN People, adapted for ATEB9200 from Embest 4 * Copyright (C) 2005 SAN People, adapted for ATEB9200 from Embest
5 * by Andrew Patrikalakis 5 * by Andrew Patrikalakis
@@ -109,7 +109,7 @@ static void __init eb9200_board_init(void)
109 at91_add_device_spi(NULL, 0); 109 at91_add_device_spi(NULL, 0);
110 /* MMC */ 110 /* MMC */
111 /* only supports 1 or 4 bit interface, not wired through to SPI */ 111 /* only supports 1 or 4 bit interface, not wired through to SPI */
112 at91_add_device_mmc(&eb9200_mmc_data); 112 at91_add_device_mmc(0, &eb9200_mmc_data);
113} 113}
114 114
115MACHINE_START(ATEB9200, "Embest ATEB9200") 115MACHINE_START(ATEB9200, "Embest ATEB9200")
diff --git a/arch/arm/mach-at91rm9200/board-ek.c b/arch/arm/mach-at91/board-ek.c
index c4fdb415f20e..322fdd75a1e4 100644
--- a/arch/arm/mach-at91rm9200/board-ek.c
+++ b/arch/arm/mach-at91/board-ek.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-at91rm9200/board-ek.c 2 * linux/arch/arm/mach-at91/board-ek.c
3 * 3 *
4 * Copyright (C) 2005 SAN People 4 * Copyright (C) 2005 SAN People
5 * 5 *
@@ -154,7 +154,7 @@ static void __init ek_board_init(void)
154#else 154#else
155 /* MMC */ 155 /* MMC */
156 at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */ 156 at91_set_gpio_output(AT91_PIN_PB22, 1); /* this MMC card slot can optionally use SPI signaling (CS3). */
157 at91_add_device_mmc(&ek_mmc_data); 157 at91_add_device_mmc(0, &ek_mmc_data);
158#endif 158#endif
159 /* NOR Flash */ 159 /* NOR Flash */
160 platform_device_register(&ek_flash); 160 platform_device_register(&ek_flash);
diff --git a/arch/arm/mach-at91rm9200/board-kafa.c b/arch/arm/mach-at91/board-kafa.c
index 6ef3c4879829..c77d84ce9cae 100644
--- a/arch/arm/mach-at91rm9200/board-kafa.c
+++ b/arch/arm/mach-at91/board-kafa.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-at91rm9200/board-kafa.c 2 * linux/arch/arm/mach-at91/board-kafa.c
3 * 3 *
4 * Copyright (C) 2006 Sperry-Sun 4 * Copyright (C) 2006 Sperry-Sun
5 * 5 *
diff --git a/arch/arm/mach-at91rm9200/board-kb9202.c b/arch/arm/mach-at91/board-kb9202.c
index 759d8191854f..76f6e1e553ea 100644
--- a/arch/arm/mach-at91rm9200/board-kb9202.c
+++ b/arch/arm/mach-at91/board-kb9202.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-at91rm9200/board-kb9202.c 2 * linux/arch/arm/mach-at91/board-kb9202.c
3 * 3 *
4 * Copyright (c) 2005 kb_admin 4 * Copyright (c) 2005 kb_admin
5 * KwikByte, Inc. 5 * KwikByte, Inc.
@@ -122,7 +122,7 @@ static void __init kb9202_board_init(void)
122 /* USB Device */ 122 /* USB Device */
123 at91_add_device_udc(&kb9202_udc_data); 123 at91_add_device_udc(&kb9202_udc_data);
124 /* MMC */ 124 /* MMC */
125 at91_add_device_mmc(&kb9202_mmc_data); 125 at91_add_device_mmc(0, &kb9202_mmc_data);
126 /* I2C */ 126 /* I2C */
127 at91_add_device_i2c(); 127 at91_add_device_i2c();
128 /* SPI */ 128 /* SPI */
diff --git a/arch/arm/mach-at91rm9200/board-sam9260ek.c b/arch/arm/mach-at91/board-sam9260ek.c
index da5d58ac870b..57fb4499d969 100644
--- a/arch/arm/mach-at91rm9200/board-sam9260ek.c
+++ b/arch/arm/mach-at91/board-sam9260ek.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-at91rm9200/board-ek.c 2 * linux/arch/arm/mach-at91/board-sam9260ek.c
3 * 3 *
4 * Copyright (C) 2005 SAN People 4 * Copyright (C) 2005 SAN People
5 * Copyright (C) 2006 Atmel 5 * Copyright (C) 2006 Atmel
@@ -118,7 +118,7 @@ static struct spi_board_info ek_spi_devices[] = {
118/* 118/*
119 * MACB Ethernet device 119 * MACB Ethernet device
120 */ 120 */
121static struct __initdata eth_platform_data ek_macb_data = { 121static struct __initdata at91_eth_data ek_macb_data = {
122 .phy_irq_pin = AT91_PIN_PA7, 122 .phy_irq_pin = AT91_PIN_PA7,
123 .is_rmii = 1, 123 .is_rmii = 1,
124}; 124};
@@ -187,7 +187,7 @@ static void __init ek_board_init(void)
187 /* Ethernet */ 187 /* Ethernet */
188 at91_add_device_eth(&ek_macb_data); 188 at91_add_device_eth(&ek_macb_data);
189 /* MMC */ 189 /* MMC */
190 at91_add_device_mmc(&ek_mmc_data); 190 at91_add_device_mmc(0, &ek_mmc_data);
191} 191}
192 192
193MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK") 193MACHINE_START(AT91SAM9260EK, "Atmel AT91SAM9260-EK")
diff --git a/arch/arm/mach-at91rm9200/board-sam9261ek.c b/arch/arm/mach-at91/board-sam9261ek.c
index 30b490d8886b..b7e772467cf6 100644
--- a/arch/arm/mach-at91rm9200/board-sam9261ek.c
+++ b/arch/arm/mach-at91/board-sam9261ek.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-at91rm9200/board-ek.c 2 * linux/arch/arm/mach-at91/board-sam9261ek.c
3 * 3 *
4 * Copyright (C) 2005 SAN People 4 * Copyright (C) 2005 SAN People
5 * Copyright (C) 2006 Atmel 5 * Copyright (C) 2006 Atmel
@@ -243,7 +243,7 @@ static void __init ek_board_init(void)
243 at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices)); 243 at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
244#else 244#else
245 /* MMC */ 245 /* MMC */
246 at91_add_device_mmc(&ek_mmc_data); 246 at91_add_device_mmc(0, &ek_mmc_data);
247#endif 247#endif
248} 248}
249 249
diff --git a/arch/arm/mach-at91/board-sam9263ek.c b/arch/arm/mach-at91/board-sam9263ek.c
new file mode 100644
index 000000000000..8fdce11a880c
--- /dev/null
+++ b/arch/arm/mach-at91/board-sam9263ek.c
@@ -0,0 +1,176 @@
1/*
2 * linux/arch/arm/mach-at91/board-sam9263ek.c
3 *
4 * Copyright (C) 2005 SAN People
5 * Copyright (C) 2007 Atmel Corporation.
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
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20 */
21
22#include <linux/types.h>
23#include <linux/init.h>
24#include <linux/mm.h>
25#include <linux/module.h>
26#include <linux/platform_device.h>
27#include <linux/spi/spi.h>
28
29#include <asm/hardware.h>
30#include <asm/setup.h>
31#include <asm/mach-types.h>
32#include <asm/irq.h>
33
34#include <asm/mach/arch.h>
35#include <asm/mach/map.h>
36#include <asm/mach/irq.h>
37
38#include <asm/arch/board.h>
39#include <asm/arch/gpio.h>
40#include <asm/arch/at91sam926x_mc.h>
41
42#include "generic.h"
43
44
45/*
46 * Serial port configuration.
47 * 0 .. 2 = USART0 .. USART2
48 * 3 = DBGU
49 */
50static struct at91_uart_config __initdata ek_uart_config = {
51 .console_tty = 0, /* ttyS0 */
52 .nr_tty = 2,
53 .tty_map = { 3, 0, -1, -1, } /* ttyS0, ..., ttyS3 */
54};
55
56static void __init ek_map_io(void)
57{
58 /* Initialize processor: 16.367 MHz crystal */
59 at91sam9263_initialize(16367660);
60
61 /* Setup the serial ports and console */
62 at91_init_serial(&ek_uart_config);
63}
64
65static void __init ek_init_irq(void)
66{
67 at91sam9263_init_interrupts(NULL);
68}
69
70
71/*
72 * USB Host port
73 */
74static struct at91_usbh_data __initdata ek_usbh_data = {
75 .ports = 2,
76 .vbus_pin = { AT91_PIN_PA24, AT91_PIN_PA21 },
77};
78
79/*
80 * USB Device port
81 */
82static struct at91_udc_data __initdata ek_udc_data = {
83 .vbus_pin = AT91_PIN_PA25,
84 .pullup_pin = 0, /* pull-up driven by UDC */
85};
86
87
88/*
89 * SPI devices.
90 */
91static struct spi_board_info ek_spi_devices[] = {
92#if defined(CONFIG_MTD_AT91_DATAFLASH_CARD)
93 { /* DataFlash card */
94 .modalias = "mtd_dataflash",
95 .chip_select = 0,
96 .max_speed_hz = 15 * 1000 * 1000,
97 .bus_num = 0,
98 },
99#endif
100};
101
102
103/*
104 * MCI (SD/MMC)
105 */
106static struct at91_mmc_data __initdata ek_mmc_data = {
107 .wire4 = 1,
108 .det_pin = AT91_PIN_PE18,
109 .wp_pin = AT91_PIN_PE19,
110// .vcc_pin = ... not connected
111};
112
113
114/*
115 * NAND flash
116 */
117static struct mtd_partition __initdata ek_nand_partition[] = {
118 {
119 .name = "Partition 1",
120 .offset = 0,
121 .size = 64 * 1024 * 1024,
122 },
123 {
124 .name = "Partition 2",
125 .offset = 64 * 1024 * 1024,
126 .size = MTDPART_SIZ_FULL,
127 },
128};
129
130static struct mtd_partition *nand_partitions(int size, int *num_partitions)
131{
132 *num_partitions = ARRAY_SIZE(ek_nand_partition);
133 return ek_nand_partition;
134}
135
136static struct at91_nand_data __initdata ek_nand_data = {
137 .ale = 21,
138 .cle = 22,
139// .det_pin = ... not connected
140 .rdy_pin = AT91_PIN_PA22,
141 .enable_pin = AT91_PIN_PD15,
142 .partition_info = nand_partitions,
143#if defined(CONFIG_MTD_NAND_AT91_BUSWIDTH_16)
144 .bus_width_16 = 1,
145#else
146 .bus_width_16 = 0,
147#endif
148};
149
150
151static void __init ek_board_init(void)
152{
153 /* Serial */
154 at91_add_device_serial();
155 /* USB Host */
156 at91_add_device_usbh(&ek_usbh_data);
157 /* USB Device */
158 at91_add_device_udc(&ek_udc_data);
159 /* SPI */
160 at91_add_device_spi(ek_spi_devices, ARRAY_SIZE(ek_spi_devices));
161 /* MMC */
162 at91_add_device_mmc(1, &ek_mmc_data);
163 /* NAND */
164 at91_add_device_nand(&ek_nand_data);
165}
166
167MACHINE_START(AT91SAM9263EK, "Atmel AT91SAM9263-EK")
168 /* Maintainer: Atmel */
169 .phys_io = AT91_BASE_SYS,
170 .io_pg_offst = (AT91_VA_BASE_SYS >> 18) & 0xfffc,
171 .boot_params = AT91_SDRAM_BASE + 0x100,
172 .timer = &at91sam926x_timer,
173 .map_io = ek_map_io,
174 .init_irq = ek_init_irq,
175 .init_machine = ek_board_init,
176MACHINE_END
diff --git a/arch/arm/mach-at91rm9200/clock.c b/arch/arm/mach-at91/clock.c
index 36a8e4d1cc6d..06c9a0507d0d 100644
--- a/arch/arm/mach-at91rm9200/clock.c
+++ b/arch/arm/mach-at91/clock.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-at91rm9200/clock.c 2 * linux/arch/arm/mach-at91/clock.c
3 * 3 *
4 * Copyright (C) 2005 David Brownell 4 * Copyright (C) 2005 David Brownell
5 * Copyright (C) 2005 Ivan Kokshaysky 5 * Copyright (C) 2005 Ivan Kokshaysky
@@ -525,27 +525,6 @@ fail:
525 return 0; 525 return 0;
526} 526}
527 527
528/*
529 * Several unused clocks may be active. Turn them off.
530 */
531static void __init at91_periphclk_reset(void)
532{
533 unsigned long reg;
534 struct clk *clk;
535
536 reg = at91_sys_read(AT91_PMC_PCSR);
537
538 list_for_each_entry(clk, &clocks, node) {
539 if (clk->mode != pmc_periph_mode)
540 continue;
541
542 if (clk->users > 0)
543 reg &= ~clk->pmc_mask;
544 }
545
546 at91_sys_write(AT91_PMC_PCDR, reg);
547}
548
549static struct clk *const standard_pmc_clocks[] __initdata = { 528static struct clk *const standard_pmc_clocks[] __initdata = {
550 /* four primary clocks */ 529 /* four primary clocks */
551 &clk32k, 530 &clk32k,
@@ -586,7 +565,7 @@ int __init at91_clock_init(unsigned long main_clock)
586 pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000); 565 pr_info("Clocks: PLLA overclocked, %ld MHz\n", plla.rate_hz / 1000000);
587 566
588 /* 567 /*
589 * USB clock init: choose 48 MHz PLLB value, turn all clocks off, 568 * USB clock init: choose 48 MHz PLLB value,
590 * disable 48MHz clock during usb peripheral suspend. 569 * disable 48MHz clock during usb peripheral suspend.
591 * 570 *
592 * REVISIT: assumes MCK doesn't derive from PLLB! 571 * REVISIT: assumes MCK doesn't derive from PLLB!
@@ -596,16 +575,10 @@ int __init at91_clock_init(unsigned long main_clock)
596 if (cpu_is_at91rm9200()) { 575 if (cpu_is_at91rm9200()) {
597 uhpck.pmc_mask = AT91RM9200_PMC_UHP; 576 uhpck.pmc_mask = AT91RM9200_PMC_UHP;
598 udpck.pmc_mask = AT91RM9200_PMC_UDP; 577 udpck.pmc_mask = AT91RM9200_PMC_UDP;
599 at91_sys_write(AT91_PMC_SCDR, AT91RM9200_PMC_UHP | AT91RM9200_PMC_UDP);
600 at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP); 578 at91_sys_write(AT91_PMC_SCER, AT91RM9200_PMC_MCKUDP);
601 } else if (cpu_is_at91sam9260()) { 579 } else if (cpu_is_at91sam9260() || cpu_is_at91sam9261() || cpu_is_at91sam9263()) {
602 uhpck.pmc_mask = AT91SAM926x_PMC_UHP; 580 uhpck.pmc_mask = AT91SAM926x_PMC_UHP;
603 udpck.pmc_mask = AT91SAM926x_PMC_UDP; 581 udpck.pmc_mask = AT91SAM926x_PMC_UDP;
604 at91_sys_write(AT91_PMC_SCDR, AT91SAM926x_PMC_UHP | AT91SAM926x_PMC_UDP);
605 } else if (cpu_is_at91sam9261()) {
606 uhpck.pmc_mask = (AT91SAM926x_PMC_UHP | AT91_PMC_HCK0);
607 udpck.pmc_mask = AT91SAM926x_PMC_UDP;
608 at91_sys_write(AT91_PMC_SCDR, AT91SAM926x_PMC_UHP | AT91_PMC_HCK0 | AT91SAM926x_PMC_UDP);
609 } 582 }
610 at91_sys_write(AT91_CKGR_PLLBR, 0); 583 at91_sys_write(AT91_CKGR_PLLBR, 0);
611 584
@@ -634,11 +607,34 @@ int __init at91_clock_init(unsigned long main_clock)
634 (unsigned) main_clock / 1000000, 607 (unsigned) main_clock / 1000000,
635 ((unsigned) main_clock % 1000000) / 1000); 608 ((unsigned) main_clock % 1000000) / 1000);
636 609
637 /* disable all programmable clocks */ 610 return 0;
638 at91_sys_write(AT91_PMC_SCDR, AT91_PMC_PCK0 | AT91_PMC_PCK1 | AT91_PMC_PCK2 | AT91_PMC_PCK3); 611}
612
613/*
614 * Several unused clocks may be active. Turn them off.
615 */
616static int __init at91_clock_reset(void)
617{
618 unsigned long pcdr = 0;
619 unsigned long scdr = 0;
620 struct clk *clk;
621
622 list_for_each_entry(clk, &clocks, node) {
623 if (clk->users > 0)
624 continue;
625
626 if (clk->mode == pmc_periph_mode)
627 pcdr |= clk->pmc_mask;
628
629 if (clk->mode == pmc_sys_mode)
630 scdr |= clk->pmc_mask;
631
632 pr_debug("Clocks: disable unused %s\n", clk->name);
633 }
639 634
640 /* disable all other unused peripheral clocks */ 635 at91_sys_write(AT91_PMC_PCDR, pcdr);
641 at91_periphclk_reset(); 636 at91_sys_write(AT91_PMC_SCDR, scdr);
642 637
643 return 0; 638 return 0;
644} 639}
640late_initcall(at91_clock_reset);
diff --git a/arch/arm/mach-at91rm9200/clock.h b/arch/arm/mach-at91/clock.h
index b5c7a2eb2d1d..1ba3b95ff359 100644
--- a/arch/arm/mach-at91rm9200/clock.h
+++ b/arch/arm/mach-at91/clock.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-at91rm9200/clock.h 2 * linux/arch/arm/mach-at91/clock.h
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify 4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as 5 * it under the terms of the GNU General Public License version 2 as
diff --git a/arch/arm/mach-at91rm9200/generic.h b/arch/arm/mach-at91/generic.h
index 8c4d5a77d485..bda26221c522 100644
--- a/arch/arm/mach-at91rm9200/generic.h
+++ b/arch/arm/mach-at91/generic.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-at91rm9200/generic.h 2 * linux/arch/arm/mach-at91/generic.h
3 * 3 *
4 * Copyright (C) 2005 David Brownell 4 * Copyright (C) 2005 David Brownell
5 * 5 *
@@ -12,11 +12,13 @@
12extern void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks); 12extern void __init at91rm9200_initialize(unsigned long main_clock, unsigned short banks);
13extern void __init at91sam9260_initialize(unsigned long main_clock); 13extern void __init at91sam9260_initialize(unsigned long main_clock);
14extern void __init at91sam9261_initialize(unsigned long main_clock); 14extern void __init at91sam9261_initialize(unsigned long main_clock);
15extern void __init at91sam9263_initialize(unsigned long main_clock);
15 16
16 /* Interrupts */ 17 /* Interrupts */
17extern void __init at91rm9200_init_interrupts(unsigned int priority[]); 18extern void __init at91rm9200_init_interrupts(unsigned int priority[]);
18extern void __init at91sam9260_init_interrupts(unsigned int priority[]); 19extern void __init at91sam9260_init_interrupts(unsigned int priority[]);
19extern void __init at91sam9261_init_interrupts(unsigned int priority[]); 20extern void __init at91sam9261_init_interrupts(unsigned int priority[]);
21extern void __init at91sam9263_init_interrupts(unsigned int priority[]);
20extern void __init at91_aic_init(unsigned int priority[]); 22extern void __init at91_aic_init(unsigned int priority[]);
21 23
22 /* Timer */ 24 /* Timer */
diff --git a/arch/arm/mach-at91rm9200/gpio.c b/arch/arm/mach-at91/gpio.c
index 15eb5b6b29f2..7b87f3f101b7 100644
--- a/arch/arm/mach-at91rm9200/gpio.c
+++ b/arch/arm/mach-at91/gpio.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-at91rm9200/gpio.c 2 * linux/arch/arm/mach-at91/gpio.c
3 * 3 *
4 * Copyright (C) 2005 HP Labs 4 * Copyright (C) 2005 HP Labs
5 * 5 *
diff --git a/arch/arm/mach-at91rm9200/irq.c b/arch/arm/mach-at91/irq.c
index 2148daafd29c..78a5cdb746dc 100644
--- a/arch/arm/mach-at91rm9200/irq.c
+++ b/arch/arm/mach-at91/irq.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * linux/arch/arm/mach-at91rm9200/irq.c 2 * linux/arch/arm/mach-at91/irq.c
3 * 3 *
4 * Copyright (C) 2004 SAN People 4 * Copyright (C) 2004 SAN People
5 * Copyright (C) 2004 ATMEL 5 * Copyright (C) 2004 ATMEL
diff --git a/arch/arm/mach-at91rm9200/leds.c b/arch/arm/mach-at91/leds.c
index 1a333730466e..0d5144973988 100644
--- a/arch/arm/mach-at91rm9200/leds.c
+++ b/arch/arm/mach-at91/leds.c
@@ -86,10 +86,6 @@ static int __init leds_init(void)
86 if (!at91_leds_timer || !at91_leds_cpu) 86 if (!at91_leds_timer || !at91_leds_cpu)
87 return -ENODEV; 87 return -ENODEV;
88 88
89 /* Enable PIO to access the LEDs */
90 at91_set_gpio_output(at91_leds_timer, 1);
91 at91_set_gpio_output(at91_leds_cpu, 1);
92
93 leds_event = at91_leds_event; 89 leds_event = at91_leds_event;
94 90
95 leds_event(led_start); 91 leds_event(led_start);
diff --git a/arch/arm/mach-at91rm9200/pm.c b/arch/arm/mach-at91/pm.c
index 67aa5572a3ea..b49bfda53d7f 100644
--- a/arch/arm/mach-at91rm9200/pm.c
+++ b/arch/arm/mach-at91/pm.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * arch/arm/mach-at91rm9200/pm.c 2 * arch/arm/mach-at91/pm.c
3 * AT91 Power Management 3 * AT91 Power Management
4 * 4 *
5 * Copyright (C) 2005 David Brownell 5 * Copyright (C) 2005 David Brownell
@@ -80,6 +80,8 @@ static int at91_pm_verify_clocks(void)
80#warning "Check SAM9260 USB clocks" 80#warning "Check SAM9260 USB clocks"
81 } else if (cpu_is_at91sam9261()) { 81 } else if (cpu_is_at91sam9261()) {
82#warning "Check SAM9261 USB clocks" 82#warning "Check SAM9261 USB clocks"
83 } else if (cpu_is_at91sam9263()) {
84#warning "Check SAM9263 USB clocks"
83 } 85 }
84 86
85#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS 87#ifdef CONFIG_AT91_PROGRAMMABLE_CLOCKS
diff --git a/arch/arm/mach-ep93xx/Kconfig b/arch/arm/mach-ep93xx/Kconfig
index af7904b3d0a8..575a21dabd2f 100644
--- a/arch/arm/mach-ep93xx/Kconfig
+++ b/arch/arm/mach-ep93xx/Kconfig
@@ -51,6 +51,31 @@ config MACH_GESBC9312
51 Say 'Y' here if you want your kernel to support the Glomation 51 Say 'Y' here if you want your kernel to support the Glomation
52 GESBC-9312-sx board. 52 GESBC-9312-sx board.
53 53
54config MACH_MICRO9
55 bool
56 default n
57
58config MACH_MICRO9H
59 bool "Support Contec Hypercontrol Micro9-H"
60 select MACH_MICRO9
61 help
62 Say 'Y' here if you want your kernel to support the
63 Contec Hypercontrol Micro9-H board.
64
65config MACH_MICRO9M
66 bool "Support Contec Hypercontrol Micro9-M"
67 select MACH_MICRO9
68 help
69 Say 'Y' here if you want your kernel to support the
70 Contec Hypercontrol Micro9-M board.
71
72config MACH_MICRO9L
73 bool "Support Contec Hypercontrol Micro9-L"
74 select MACH_MICRO9
75 help
76 Say 'Y' here if you want your kernel to support the
77 Contec Hypercontrol Micro9-L board.
78
54config MACH_TS72XX 79config MACH_TS72XX
55 bool "Support Technologic Systems TS-72xx SBC" 80 bool "Support Technologic Systems TS-72xx SBC"
56 help 81 help
diff --git a/arch/arm/mach-ep93xx/Makefile b/arch/arm/mach-ep93xx/Makefile
index b06641dd450d..0d3bf932654e 100644
--- a/arch/arm/mach-ep93xx/Makefile
+++ b/arch/arm/mach-ep93xx/Makefile
@@ -13,4 +13,5 @@ obj-$(CONFIG_MACH_EDB9312) += edb9312.o
13obj-$(CONFIG_MACH_EDB9315) += edb9315.o 13obj-$(CONFIG_MACH_EDB9315) += edb9315.o
14obj-$(CONFIG_MACH_EDB9315A) += edb9315a.o 14obj-$(CONFIG_MACH_EDB9315A) += edb9315a.o
15obj-$(CONFIG_MACH_GESBC9312) += gesbc9312.o 15obj-$(CONFIG_MACH_GESBC9312) += gesbc9312.o
16obj-$(CONFIG_MACH_MICRO9) += micro9.o
16obj-$(CONFIG_MACH_TS72XX) += ts72xx.o 17obj-$(CONFIG_MACH_TS72XX) += ts72xx.o
diff --git a/arch/arm/mach-ep93xx/clock.c b/arch/arm/mach-ep93xx/clock.c
index 08ad782c1649..f174d1a3b11c 100644
--- a/arch/arm/mach-ep93xx/clock.c
+++ b/arch/arm/mach-ep93xx/clock.c
@@ -13,6 +13,7 @@
13#include <linux/kernel.h> 13#include <linux/kernel.h>
14#include <linux/clk.h> 14#include <linux/clk.h>
15#include <linux/err.h> 15#include <linux/err.h>
16#include <linux/module.h>
16#include <linux/string.h> 17#include <linux/string.h>
17#include <asm/div64.h> 18#include <asm/div64.h>
18#include <asm/hardware.h> 19#include <asm/hardware.h>
@@ -124,7 +125,7 @@ static unsigned long calc_pll_rate(u32 config_word)
124 return (unsigned long)rate; 125 return (unsigned long)rate;
125} 126}
126 127
127void ep93xx_clock_init(void) 128static int __init ep93xx_clock_init(void)
128{ 129{
129 u32 value; 130 u32 value;
130 131
@@ -153,4 +154,7 @@ void ep93xx_clock_init(void)
153 printk(KERN_INFO "ep93xx: FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n", 154 printk(KERN_INFO "ep93xx: FCLK %ld MHz, HCLK %ld MHz, PCLK %ld MHz\n",
154 clk_f.rate / 1000000, clk_h.rate / 1000000, 155 clk_f.rate / 1000000, clk_h.rate / 1000000,
155 clk_p.rate / 1000000); 156 clk_p.rate / 1000000);
157
158 return 0;
156} 159}
160arch_initcall(ep93xx_clock_init);
diff --git a/arch/arm/mach-ep93xx/core.c b/arch/arm/mach-ep93xx/core.c
index 6b26346191c0..829aed696d98 100644
--- a/arch/arm/mach-ep93xx/core.c
+++ b/arch/arm/mach-ep93xx/core.c
@@ -152,22 +152,30 @@ struct sys_timer ep93xx_timer = {
152/************************************************************************* 152/*************************************************************************
153 * GPIO handling for EP93xx 153 * GPIO handling for EP93xx
154 *************************************************************************/ 154 *************************************************************************/
155static unsigned char gpio_int_enable[2]; 155static unsigned char gpio_int_unmasked[3];
156static unsigned char gpio_int_type1[2]; 156static unsigned char gpio_int_enabled[3];
157static unsigned char gpio_int_type2[2]; 157static unsigned char gpio_int_type1[3];
158static unsigned char gpio_int_type2[3];
158 159
159static void update_gpio_ab_int_params(int port) 160static void update_gpio_int_params(int abf)
160{ 161{
161 if (port == 0) { 162 if (abf == 0) {
162 __raw_writeb(0, EP93XX_GPIO_A_INT_ENABLE); 163 __raw_writeb(0, EP93XX_GPIO_A_INT_ENABLE);
163 __raw_writeb(gpio_int_type2[0], EP93XX_GPIO_A_INT_TYPE2); 164 __raw_writeb(gpio_int_type2[0], EP93XX_GPIO_A_INT_TYPE2);
164 __raw_writeb(gpio_int_type1[0], EP93XX_GPIO_A_INT_TYPE1); 165 __raw_writeb(gpio_int_type1[0], EP93XX_GPIO_A_INT_TYPE1);
165 __raw_writeb(gpio_int_enable[0], EP93XX_GPIO_A_INT_ENABLE); 166 __raw_writeb(gpio_int_unmasked[0] & gpio_int_enabled[0], EP93XX_GPIO_A_INT_ENABLE);
166 } else if (port == 1) { 167 } else if (abf == 1) {
167 __raw_writeb(0, EP93XX_GPIO_B_INT_ENABLE); 168 __raw_writeb(0, EP93XX_GPIO_B_INT_ENABLE);
168 __raw_writeb(gpio_int_type2[1], EP93XX_GPIO_B_INT_TYPE2); 169 __raw_writeb(gpio_int_type2[1], EP93XX_GPIO_B_INT_TYPE2);
169 __raw_writeb(gpio_int_type1[1], EP93XX_GPIO_B_INT_TYPE1); 170 __raw_writeb(gpio_int_type1[1], EP93XX_GPIO_B_INT_TYPE1);
170 __raw_writeb(gpio_int_enable[1], EP93XX_GPIO_B_INT_ENABLE); 171 __raw_writeb(gpio_int_unmasked[1] & gpio_int_enabled[1], EP93XX_GPIO_B_INT_ENABLE);
172 } else if (abf == 2) {
173 __raw_writeb(0, EP93XX_GPIO_F_INT_ENABLE);
174 __raw_writeb(gpio_int_type2[2], EP93XX_GPIO_F_INT_TYPE2);
175 __raw_writeb(gpio_int_type1[2], EP93XX_GPIO_F_INT_TYPE1);
176 __raw_writeb(gpio_int_unmasked[2] & gpio_int_enabled[2], EP93XX_GPIO_F_INT_ENABLE);
177 } else {
178 BUG();
171 } 179 }
172} 180}
173 181
@@ -192,8 +200,13 @@ void gpio_line_config(int line, int direction)
192 local_irq_save(flags); 200 local_irq_save(flags);
193 if (direction == GPIO_OUT) { 201 if (direction == GPIO_OUT) {
194 if (line >= 0 && line < 16) { 202 if (line >= 0 && line < 16) {
195 gpio_int_enable[line >> 3] &= ~(1 << (line & 7)); 203 /* Port A/B. */
196 update_gpio_ab_int_params(line >> 3); 204 gpio_int_unmasked[line >> 3] &= ~(1 << (line & 7));
205 update_gpio_int_params(line >> 3);
206 } else if (line >= 40 && line < 48) {
207 /* Port F. */
208 gpio_int_unmasked[2] &= ~(1 << (line & 7));
209 update_gpio_int_params(2);
197 } 210 }
198 211
199 v = __raw_readb(data_direction_register); 212 v = __raw_readb(data_direction_register);
@@ -244,8 +257,7 @@ EXPORT_SYMBOL(gpio_line_set);
244/************************************************************************* 257/*************************************************************************
245 * EP93xx IRQ handling 258 * EP93xx IRQ handling
246 *************************************************************************/ 259 *************************************************************************/
247static void ep93xx_gpio_ab_irq_handler(unsigned int irq, 260static void ep93xx_gpio_ab_irq_handler(unsigned int irq, struct irq_desc *desc)
248 struct irq_desc *desc)
249{ 261{
250 unsigned char status; 262 unsigned char status;
251 int i; 263 int i;
@@ -267,37 +279,46 @@ static void ep93xx_gpio_ab_irq_handler(unsigned int irq,
267 } 279 }
268} 280}
269 281
270static void ep93xx_gpio_ab_irq_mask_ack(unsigned int irq) 282static void ep93xx_gpio_f_irq_handler(unsigned int irq, struct irq_desc *desc)
283{
284 int gpio_irq = IRQ_EP93XX_GPIO(16) + (((irq + 1) & 7) ^ 4);
285
286 desc_handle_irq(gpio_irq, irq_desc + gpio_irq);
287}
288
289static void ep93xx_gpio_irq_mask_ack(unsigned int irq)
271{ 290{
272 int line = irq - IRQ_EP93XX_GPIO(0); 291 int line = irq - IRQ_EP93XX_GPIO(0);
273 int port = line >> 3; 292 int port = line >> 3;
274 293
275 gpio_int_enable[port] &= ~(1 << (line & 7)); 294 gpio_int_unmasked[port] &= ~(1 << (line & 7));
276 update_gpio_ab_int_params(port); 295 update_gpio_int_params(port);
277 296
278 if (line >> 3) { 297 if (port == 0) {
279 __raw_writel(1 << (line & 7), EP93XX_GPIO_B_INT_ACK);
280 } else {
281 __raw_writel(1 << (line & 7), EP93XX_GPIO_A_INT_ACK); 298 __raw_writel(1 << (line & 7), EP93XX_GPIO_A_INT_ACK);
299 } else if (port == 1) {
300 __raw_writel(1 << (line & 7), EP93XX_GPIO_B_INT_ACK);
301 } else if (port == 2) {
302 __raw_writel(1 << (line & 7), EP93XX_GPIO_F_INT_ACK);
282 } 303 }
283} 304}
284 305
285static void ep93xx_gpio_ab_irq_mask(unsigned int irq) 306static void ep93xx_gpio_irq_mask(unsigned int irq)
286{ 307{
287 int line = irq - IRQ_EP93XX_GPIO(0); 308 int line = irq - IRQ_EP93XX_GPIO(0);
288 int port = line >> 3; 309 int port = line >> 3;
289 310
290 gpio_int_enable[port] &= ~(1 << (line & 7)); 311 gpio_int_unmasked[port] &= ~(1 << (line & 7));
291 update_gpio_ab_int_params(port); 312 update_gpio_int_params(port);
292} 313}
293 314
294static void ep93xx_gpio_ab_irq_unmask(unsigned int irq) 315static void ep93xx_gpio_irq_unmask(unsigned int irq)
295{ 316{
296 int line = irq - IRQ_EP93XX_GPIO(0); 317 int line = irq - IRQ_EP93XX_GPIO(0);
297 int port = line >> 3; 318 int port = line >> 3;
298 319
299 gpio_int_enable[port] |= 1 << (line & 7); 320 gpio_int_unmasked[port] |= 1 << (line & 7);
300 update_gpio_ab_int_params(port); 321 update_gpio_int_params(port);
301} 322}
302 323
303 324
@@ -306,40 +327,51 @@ static void ep93xx_gpio_ab_irq_unmask(unsigned int irq)
306 * edge (1) triggered, while gpio_int_type2 controls whether it 327 * edge (1) triggered, while gpio_int_type2 controls whether it
307 * triggers on low/falling (0) or high/rising (1). 328 * triggers on low/falling (0) or high/rising (1).
308 */ 329 */
309static int ep93xx_gpio_ab_irq_type(unsigned int irq, unsigned int type) 330static int ep93xx_gpio_irq_type(unsigned int irq, unsigned int type)
310{ 331{
311 int port; 332 int port;
312 int line; 333 int line;
313 334
314 line = irq - IRQ_EP93XX_GPIO(0); 335 line = irq - IRQ_EP93XX_GPIO(0);
315 gpio_line_config(line, GPIO_IN); 336 if (line >= 0 && line < 16) {
337 gpio_line_config(line, GPIO_IN);
338 } else {
339 gpio_line_config(EP93XX_GPIO_LINE_F(line), GPIO_IN);
340 }
316 341
317 port = line >> 3; 342 port = line >> 3;
318 line &= 7; 343 line &= 7;
319 344
320 if (type & IRQT_RISING) { 345 if (type & IRQT_RISING) {
346 gpio_int_enabled[port] |= 1 << line;
321 gpio_int_type1[port] |= 1 << line; 347 gpio_int_type1[port] |= 1 << line;
322 gpio_int_type2[port] |= 1 << line; 348 gpio_int_type2[port] |= 1 << line;
323 } else if (type & IRQT_FALLING) { 349 } else if (type & IRQT_FALLING) {
350 gpio_int_enabled[port] |= 1 << line;
324 gpio_int_type1[port] |= 1 << line; 351 gpio_int_type1[port] |= 1 << line;
325 gpio_int_type2[port] &= ~(1 << line); 352 gpio_int_type2[port] &= ~(1 << line);
326 } else if (type & IRQT_HIGH) { 353 } else if (type & IRQT_HIGH) {
354 gpio_int_enabled[port] |= 1 << line;
327 gpio_int_type1[port] &= ~(1 << line); 355 gpio_int_type1[port] &= ~(1 << line);
328 gpio_int_type2[port] |= 1 << line; 356 gpio_int_type2[port] |= 1 << line;
329 } else if (type & IRQT_LOW) { 357 } else if (type & IRQT_LOW) {
358 gpio_int_enabled[port] |= 1 << line;
330 gpio_int_type1[port] &= ~(1 << line); 359 gpio_int_type1[port] &= ~(1 << line);
331 gpio_int_type2[port] &= ~(1 << line); 360 gpio_int_type2[port] &= ~(1 << line);
361 } else {
362 gpio_int_enabled[port] &= ~(1 << line);
332 } 363 }
333 update_gpio_ab_int_params(port); 364 update_gpio_int_params(port);
334 365
335 return 0; 366 return 0;
336} 367}
337 368
338static struct irq_chip ep93xx_gpio_ab_irq_chip = { 369static struct irq_chip ep93xx_gpio_irq_chip = {
339 .ack = ep93xx_gpio_ab_irq_mask_ack, 370 .name = "GPIO",
340 .mask = ep93xx_gpio_ab_irq_mask, 371 .ack = ep93xx_gpio_irq_mask_ack,
341 .unmask = ep93xx_gpio_ab_irq_unmask, 372 .mask = ep93xx_gpio_irq_mask,
342 .set_type = ep93xx_gpio_ab_irq_type, 373 .unmask = ep93xx_gpio_irq_unmask,
374 .set_type = ep93xx_gpio_irq_type,
343}; 375};
344 376
345 377
@@ -350,12 +382,21 @@ void __init ep93xx_init_irq(void)
350 vic_init((void *)EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK); 382 vic_init((void *)EP93XX_VIC1_BASE, 0, EP93XX_VIC1_VALID_IRQ_MASK);
351 vic_init((void *)EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK); 383 vic_init((void *)EP93XX_VIC2_BASE, 32, EP93XX_VIC2_VALID_IRQ_MASK);
352 384
353 for (irq = IRQ_EP93XX_GPIO(0) ; irq <= IRQ_EP93XX_GPIO(15); irq++) { 385 for (irq = IRQ_EP93XX_GPIO(0); irq <= IRQ_EP93XX_GPIO(23); irq++) {
354 set_irq_chip(irq, &ep93xx_gpio_ab_irq_chip); 386 set_irq_chip(irq, &ep93xx_gpio_irq_chip);
355 set_irq_handler(irq, handle_level_irq); 387 set_irq_handler(irq, handle_level_irq);
356 set_irq_flags(irq, IRQF_VALID); 388 set_irq_flags(irq, IRQF_VALID);
357 } 389 }
390
358 set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler); 391 set_irq_chained_handler(IRQ_EP93XX_GPIO_AB, ep93xx_gpio_ab_irq_handler);
392 set_irq_chained_handler(IRQ_EP93XX_GPIO0MUX, ep93xx_gpio_f_irq_handler);
393 set_irq_chained_handler(IRQ_EP93XX_GPIO1MUX, ep93xx_gpio_f_irq_handler);
394 set_irq_chained_handler(IRQ_EP93XX_GPIO2MUX, ep93xx_gpio_f_irq_handler);
395 set_irq_chained_handler(IRQ_EP93XX_GPIO3MUX, ep93xx_gpio_f_irq_handler);
396 set_irq_chained_handler(IRQ_EP93XX_GPIO4MUX, ep93xx_gpio_f_irq_handler);
397 set_irq_chained_handler(IRQ_EP93XX_GPIO5MUX, ep93xx_gpio_f_irq_handler);
398 set_irq_chained_handler(IRQ_EP93XX_GPIO6MUX, ep93xx_gpio_f_irq_handler);
399 set_irq_chained_handler(IRQ_EP93XX_GPIO7MUX, ep93xx_gpio_f_irq_handler);
359} 400}
360 401
361 402
@@ -461,8 +502,6 @@ void __init ep93xx_init_devices(void)
461{ 502{
462 unsigned int v; 503 unsigned int v;
463 504
464 ep93xx_clock_init();
465
466 /* 505 /*
467 * Disallow access to MaverickCrunch initially. 506 * Disallow access to MaverickCrunch initially.
468 */ 507 */
@@ -477,8 +516,4 @@ void __init ep93xx_init_devices(void)
477 516
478 platform_device_register(&ep93xx_rtc_device); 517 platform_device_register(&ep93xx_rtc_device);
479 platform_device_register(&ep93xx_ohci_device); 518 platform_device_register(&ep93xx_ohci_device);
480
481#ifdef CONFIG_CRUNCH
482 elf_hwcap |= HWCAP_CRUNCH;
483#endif
484} 519}
diff --git a/arch/arm/mach-ep93xx/micro9.c b/arch/arm/mach-ep93xx/micro9.c
new file mode 100644
index 000000000000..f28c1294cae1
--- /dev/null
+++ b/arch/arm/mach-ep93xx/micro9.c
@@ -0,0 +1,157 @@
1/*
2 * linux/arch/arm/mach-ep93xx/micro9.c
3 *
4 * Copyright (C) 2006 Contec Steuerungstechnik & Automation GmbH
5 * Manfred Gruber <manfred.gruber@contec.at>
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 version 2 as
9 * published by the Free Software Foundation.
10 */
11
12#include <linux/init.h>
13#include <linux/interrupt.h>
14#include <linux/ioport.h>
15#include <linux/kernel.h>
16#include <linux/mm.h>
17#include <linux/platform_device.h>
18#include <linux/sched.h>
19
20#include <linux/mtd/physmap.h>
21
22#include <asm/io.h>
23#include <asm/hardware.h>
24
25#include <asm/mach/arch.h>
26#include <asm/mach-types.h>
27
28static struct ep93xx_eth_data micro9_eth_data = {
29 .phy_id = 0x1f,
30};
31
32static struct resource micro9_eth_resource[] = {
33 {
34 .start = EP93XX_ETHERNET_PHYS_BASE,
35 .end = EP93XX_ETHERNET_PHYS_BASE + 0xffff,
36 .flags = IORESOURCE_MEM,
37 }, {
38 .start = IRQ_EP93XX_ETHERNET,
39 .end = IRQ_EP93XX_ETHERNET,
40 .flags = IORESOURCE_IRQ,
41 }
42};
43
44static struct platform_device micro9_eth_device = {
45 .name = "ep93xx-eth",
46 .id = -1,
47 .dev = {
48 .platform_data = &micro9_eth_data,
49 },
50 .num_resources = ARRAY_SIZE(micro9_eth_resource),
51 .resource = micro9_eth_resource,
52};
53
54static void __init micro9_eth_init(void)
55{
56 memcpy(micro9_eth_data.dev_addr,
57 (void *)(EP93XX_ETHERNET_BASE + 0x50), 6);
58 platform_device_register(&micro9_eth_device);
59}
60
61static void __init micro9_init(void)
62{
63 micro9_eth_init();
64}
65
66/*
67 * Micro9-H
68 */
69#ifdef CONFIG_MACH_MICRO9H
70static struct physmap_flash_data micro9h_flash_data = {
71 .width = 4,
72};
73
74static struct resource micro9h_flash_resource = {
75 .start = 0x10000000,
76 .end = 0x13ffffff,
77 .flags = IORESOURCE_MEM,
78};
79
80static struct platform_device micro9h_flash = {
81 .name = "physmap-flash",
82 .id = 0,
83 .dev = {
84 .platform_data = &micro9h_flash_data,
85 },
86 .num_resources = 1,
87 .resource = &micro9h_flash_resource,
88};
89
90static void __init micro9h_init(void)
91{
92 platform_device_register(&micro9h_flash);
93}
94
95static void __init micro9h_init_machine(void)
96{
97 ep93xx_init_devices();
98 micro9_init();
99 micro9h_init();
100}
101
102MACHINE_START(MICRO9, "Contec Hypercontrol Micro9-H")
103 /* Maintainer: Manfred Gruber <manfred.gruber@contec.at> */
104 .phys_io = EP93XX_APB_PHYS_BASE,
105 .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
106 .boot_params = 0x00000100,
107 .map_io = ep93xx_map_io,
108 .init_irq = ep93xx_init_irq,
109 .timer = &ep93xx_timer,
110 .init_machine = micro9h_init_machine,
111MACHINE_END
112#endif
113
114/*
115 * Micro9-M
116 */
117#ifdef CONFIG_MACH_MICRO9M
118static void __init micro9m_init_machine(void)
119{
120 ep93xx_init_devices();
121 micro9_init();
122}
123
124MACHINE_START(MICRO9M, "Contec Hypercontrol Micro9-M")
125 /* Maintainer: Manfred Gruber <manfred.gruber@contec.at> */
126 .phys_io = EP93XX_APB_PHYS_BASE,
127 .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
128 .boot_params = 0x00000100,
129 .map_io = ep93xx_map_io,
130 .init_irq = ep93xx_init_irq,
131 .timer = &ep93xx_timer,
132 .init_machine = micro9m_init_machine,
133MACHINE_END
134#endif
135
136/*
137 * Micro9-L
138 */
139#ifdef CONFIG_MACH_MICRO9L
140static void __init micro9l_init_machine(void)
141{
142 ep93xx_init_devices();
143 micro9_init();
144}
145
146MACHINE_START(MICRO9L, "Contec Hypercontrol Micro9-L")
147 /* Maintainer: Manfred Gruber <manfred.gruber@contec.at> */
148 .phys_io = EP93XX_APB_PHYS_BASE,
149 .io_pg_offst = ((EP93XX_APB_VIRT_BASE) >> 18) & 0xfffc,
150 .boot_params = 0x00000100,
151 .map_io = ep93xx_map_io,
152 .init_irq = ep93xx_init_irq,
153 .timer = &ep93xx_timer,
154 .init_machine = micro9l_init_machine,
155MACHINE_END
156#endif
157
diff --git a/arch/arm/mach-iop13xx/irq.c b/arch/arm/mach-iop13xx/irq.c
index dbbc07c38b14..162b93214965 100644
--- a/arch/arm/mach-iop13xx/irq.c
+++ b/arch/arm/mach-iop13xx/irq.c
@@ -250,11 +250,14 @@ static struct irq_chip iop13xx_irqchip4 = {
250 .unmask = iop13xx_irq_unmask3, 250 .unmask = iop13xx_irq_unmask3,
251}; 251};
252 252
253extern void iop_init_cp6_handler(void);
254
253void __init iop13xx_init_irq(void) 255void __init iop13xx_init_irq(void)
254{ 256{
255 unsigned int i; 257 unsigned int i;
256 258
257 u32 cp_flags = iop13xx_cp6_save(); 259 u32 cp_flags = iop13xx_cp6_save();
260 iop_init_cp6_handler();
258 261
259 /* disable all interrupts */ 262 /* disable all interrupts */
260 write_intctl_0(0); 263 write_intctl_0(0);
diff --git a/arch/arm/mach-iop32x/irq.c b/arch/arm/mach-iop32x/irq.c
index 3ec1cd5c4f99..8b0ac5590ae4 100644
--- a/arch/arm/mach-iop32x/irq.c
+++ b/arch/arm/mach-iop32x/irq.c
@@ -60,6 +60,8 @@ void __init iop32x_init_irq(void)
60{ 60{
61 int i; 61 int i;
62 62
63 iop_init_cp6_handler();
64
63 intctl_write(0); 65 intctl_write(0);
64 intstr_write(0); 66 intstr_write(0);
65 if (machine_is_glantank() || 67 if (machine_is_glantank() ||
diff --git a/arch/arm/mach-iop32x/n2100.c b/arch/arm/mach-iop32x/n2100.c
index 2499a7707e3c..966aa51aee09 100644
--- a/arch/arm/mach-iop32x/n2100.c
+++ b/arch/arm/mach-iop32x/n2100.c
@@ -120,6 +120,20 @@ static struct hw_pci n2100_pci __initdata = {
120 .map_irq = n2100_pci_map_irq, 120 .map_irq = n2100_pci_map_irq,
121}; 121};
122 122
123/*
124 * Both r8169 chips on the n2100 exhibit PCI parity problems. Set
125 * the ->broken_parity_status flag for both ports so that the r8169
126 * driver knows it should ignore error interrupts.
127 */
128static void n2100_fixup_r8169(struct pci_dev *dev)
129{
130 if (dev->bus->number == 0 &&
131 (dev->devfn == PCI_DEVFN(1, 0) ||
132 dev->devfn == PCI_DEVFN(2, 0)))
133 dev->broken_parity_status = 1;
134}
135DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_REALTEK, PCI_ANY_ID, n2100_fixup_r8169);
136
123static int __init n2100_pci_init(void) 137static int __init n2100_pci_init(void)
124{ 138{
125 if (machine_is_n2100()) 139 if (machine_is_n2100())
diff --git a/arch/arm/mach-iop33x/irq.c b/arch/arm/mach-iop33x/irq.c
index 00b37f32d72e..effbe6b782d0 100644
--- a/arch/arm/mach-iop33x/irq.c
+++ b/arch/arm/mach-iop33x/irq.c
@@ -110,6 +110,8 @@ void __init iop33x_init_irq(void)
110{ 110{
111 int i; 111 int i;
112 112
113 iop_init_cp6_handler();
114
113 intctl0_write(0); 115 intctl0_write(0);
114 intctl1_write(0); 116 intctl1_write(0);
115 intstr0_write(0); 117 intstr0_write(0);
diff --git a/arch/arm/mach-ixp4xx/Kconfig b/arch/arm/mach-ixp4xx/Kconfig
index e316bd93313f..8a339cdfe222 100644
--- a/arch/arm/mach-ixp4xx/Kconfig
+++ b/arch/arm/mach-ixp4xx/Kconfig
@@ -17,7 +17,7 @@ config MACH_NSLU2
17 NSLU2 NAS device. For more information on this platform, 17 NSLU2 NAS device. For more information on this platform,
18 see http://www.nslu2-linux.org 18 see http://www.nslu2-linux.org
19 19
20config ARCH_AVILA 20config MACH_AVILA
21 bool "Avila" 21 bool "Avila"
22 select PCI 22 select PCI
23 help 23 help
@@ -25,6 +25,14 @@ config ARCH_AVILA
25 Avila Network Platform. For more information on this platform, 25 Avila Network Platform. For more information on this platform,
26 see <file:Documentation/arm/IXP4xx>. 26 see <file:Documentation/arm/IXP4xx>.
27 27
28config MACH_LOFT
29 bool "Loft"
30 depends on MACH_AVILA
31 help
32 Say 'Y' here if you want your kernel to support the Giant
33 Shoulder Inc Loft board (a minor variation on the standard
34 Gateworks Avila Network Platform).
35
28config ARCH_ADI_COYOTE 36config ARCH_ADI_COYOTE
29 bool "Coyote" 37 bool "Coyote"
30 select PCI 38 select PCI
@@ -86,7 +94,7 @@ config MACH_NAS100D
86# 94#
87config ARCH_IXDP4XX 95config ARCH_IXDP4XX
88 bool 96 bool
89 depends on ARCH_IXDP425 || ARCH_AVILA || MACH_IXDP465 97 depends on ARCH_IXDP425 || MACH_IXDP465
90 default y 98 default y
91 99
92# 100#
diff --git a/arch/arm/mach-ixp4xx/Makefile b/arch/arm/mach-ixp4xx/Makefile
index 640315d8b96a..746e297284ed 100644
--- a/arch/arm/mach-ixp4xx/Makefile
+++ b/arch/arm/mach-ixp4xx/Makefile
@@ -6,6 +6,7 @@ obj-pci-y :=
6obj-pci-n := 6obj-pci-n :=
7 7
8obj-pci-$(CONFIG_ARCH_IXDP4XX) += ixdp425-pci.o 8obj-pci-$(CONFIG_ARCH_IXDP4XX) += ixdp425-pci.o
9obj-pci-$(CONFIG_MACH_AVILA) += avila-pci.o
9obj-pci-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o 10obj-pci-$(CONFIG_MACH_IXDPG425) += ixdpg425-pci.o
10obj-pci-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o 11obj-pci-$(CONFIG_ARCH_ADI_COYOTE) += coyote-pci.o
11obj-pci-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o 12obj-pci-$(CONFIG_MACH_GTWX5715) += gtwx5715-pci.o
@@ -15,6 +16,7 @@ obj-pci-$(CONFIG_MACH_NAS100D) += nas100d-pci.o
15obj-y += common.o 16obj-y += common.o
16 17
17obj-$(CONFIG_ARCH_IXDP4XX) += ixdp425-setup.o 18obj-$(CONFIG_ARCH_IXDP4XX) += ixdp425-setup.o
19obj-$(CONFIG_MACH_AVILA) += avila-setup.o
18obj-$(CONFIG_MACH_IXDPG425) += coyote-setup.o 20obj-$(CONFIG_MACH_IXDPG425) += coyote-setup.o
19obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-setup.o 21obj-$(CONFIG_ARCH_ADI_COYOTE) += coyote-setup.o
20obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-setup.o 22obj-$(CONFIG_MACH_GTWX5715) += gtwx5715-setup.o
diff --git a/arch/arm/mach-ixp4xx/avila-pci.c b/arch/arm/mach-ixp4xx/avila-pci.c
new file mode 100644
index 000000000000..3f867691d9f2
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/avila-pci.c
@@ -0,0 +1,78 @@
1/*
2 * arch/arm/mach-ixp4xx/avila-pci.c
3 *
4 * Gateworks Avila board-level PCI initialization
5 *
6 * Author: Michael-Luke Jones <mlj28@cam.ac.uk>
7 *
8 * Based on ixdp-pci.c
9 * Copyright (C) 2002 Intel Corporation.
10 * Copyright (C) 2003-2004 MontaVista Software, Inc.
11 *
12 * Maintainer: Deepak Saxena <dsaxena@plexity.net>
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License version 2 as
16 * published by the Free Software Foundation.
17 *
18 */
19
20#include <linux/kernel.h>
21#include <linux/pci.h>
22#include <linux/init.h>
23#include <linux/irq.h>
24#include <linux/delay.h>
25
26#include <asm/mach/pci.h>
27#include <asm/irq.h>
28#include <asm/hardware.h>
29#include <asm/mach-types.h>
30
31void __init avila_pci_preinit(void)
32{
33 set_irq_type(IRQ_AVILA_PCI_INTA, IRQT_LOW);
34 set_irq_type(IRQ_AVILA_PCI_INTB, IRQT_LOW);
35 set_irq_type(IRQ_AVILA_PCI_INTC, IRQT_LOW);
36 set_irq_type(IRQ_AVILA_PCI_INTD, IRQT_LOW);
37
38 ixp4xx_pci_preinit();
39}
40
41static int __init avila_map_irq(struct pci_dev *dev, u8 slot, u8 pin)
42{
43 static int pci_irq_table[AVILA_PCI_IRQ_LINES] = {
44 IRQ_AVILA_PCI_INTA,
45 IRQ_AVILA_PCI_INTB,
46 IRQ_AVILA_PCI_INTC,
47 IRQ_AVILA_PCI_INTD
48 };
49
50 int irq = -1;
51
52 if (slot >= 1 &&
53 slot <= (machine_is_loft() ? LOFT_PCI_MAX_DEV : AVILA_PCI_MAX_DEV) &&
54 pin >= 1 && pin <= AVILA_PCI_IRQ_LINES) {
55 irq = pci_irq_table[(slot + pin - 2) % 4];
56 }
57
58 return irq;
59}
60
61struct hw_pci avila_pci __initdata = {
62 .nr_controllers = 1,
63 .preinit = avila_pci_preinit,
64 .swizzle = pci_std_swizzle,
65 .setup = ixp4xx_setup,
66 .scan = ixp4xx_scan_bus,
67 .map_irq = avila_map_irq,
68};
69
70int __init avila_pci_init(void)
71{
72 if (machine_is_avila() || machine_is_loft())
73 pci_common_init(&avila_pci);
74 return 0;
75}
76
77subsys_initcall(avila_pci_init);
78
diff --git a/arch/arm/mach-ixp4xx/avila-setup.c b/arch/arm/mach-ixp4xx/avila-setup.c
new file mode 100644
index 000000000000..d59b8dc7dc7a
--- /dev/null
+++ b/arch/arm/mach-ixp4xx/avila-setup.c
@@ -0,0 +1,192 @@
1/*
2 * arch/arm/mach-ixp4xx/avila-setup.c
3 *
4 * Gateworks Avila board-setup
5 *
6 * Author: Michael-Luke Jones <mlj28@cam.ac.uk>
7 *
8 * Based on ixdp-setup.c
9 * Copyright (C) 2003-2005 MontaVista Software, Inc.
10 *
11 * Author: Deepak Saxena <dsaxena@plexity.net>
12 */
13
14#include <linux/kernel.h>
15#include <linux/init.h>
16#include <linux/device.h>
17#include <linux/serial.h>
18#include <linux/tty.h>
19#include <linux/serial_8250.h>
20#include <linux/slab.h>
21
22#include <asm/types.h>
23#include <asm/setup.h>
24#include <asm/memory.h>
25#include <asm/hardware.h>
26#include <asm/mach-types.h>
27#include <asm/irq.h>
28#include <asm/mach/arch.h>
29#include <asm/mach/flash.h>
30
31static struct flash_platform_data avila_flash_data = {
32 .map_name = "cfi_probe",
33 .width = 2,
34};
35
36static struct resource avila_flash_resource = {
37 .flags = IORESOURCE_MEM,
38};
39
40static struct platform_device avila_flash = {
41 .name = "IXP4XX-Flash",
42 .id = 0,
43 .dev = {
44 .platform_data = &avila_flash_data,
45 },
46 .num_resources = 1,
47 .resource = &avila_flash_resource,
48};
49
50static struct ixp4xx_i2c_pins avila_i2c_gpio_pins = {
51 .sda_pin = AVILA_SDA_PIN,
52 .scl_pin = AVILA_SCL_PIN,
53};
54
55static struct platform_device avila_i2c_controller = {
56 .name = "IXP4XX-I2C",
57 .id = 0,
58 .dev = {
59 .platform_data = &avila_i2c_gpio_pins,
60 },
61 .num_resources = 0
62};
63
64static struct resource avila_uart_resources[] = {
65 {
66 .start = IXP4XX_UART1_BASE_PHYS,
67 .end = IXP4XX_UART1_BASE_PHYS + 0x0fff,
68 .flags = IORESOURCE_MEM
69 },
70 {
71 .start = IXP4XX_UART2_BASE_PHYS,
72 .end = IXP4XX_UART2_BASE_PHYS + 0x0fff,
73 .flags = IORESOURCE_MEM
74 }
75};
76
77static struct plat_serial8250_port avila_uart_data[] = {
78 {
79 .mapbase = IXP4XX_UART1_BASE_PHYS,
80 .membase = (char *)IXP4XX_UART1_BASE_VIRT + REG_OFFSET,
81 .irq = IRQ_IXP4XX_UART1,
82 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
83 .iotype = UPIO_MEM,
84 .regshift = 2,
85 .uartclk = IXP4XX_UART_XTAL,
86 },
87 {
88 .mapbase = IXP4XX_UART2_BASE_PHYS,
89 .membase = (char *)IXP4XX_UART2_BASE_VIRT + REG_OFFSET,
90 .irq = IRQ_IXP4XX_UART2,
91 .flags = UPF_BOOT_AUTOCONF | UPF_SKIP_TEST,
92 .iotype = UPIO_MEM,
93 .regshift = 2,
94 .uartclk = IXP4XX_UART_XTAL,
95 },
96 { },
97};
98
99static struct platform_device avila_uart = {
100 .name = "serial8250",
101 .id = PLAT8250_DEV_PLATFORM,
102 .dev.platform_data = avila_uart_data,
103 .num_resources = 2,
104 .resource = avila_uart_resources
105};
106
107static struct resource avila_pata_resources[] = {
108 {
109 .flags = IORESOURCE_MEM
110 },
111 {
112 .flags = IORESOURCE_MEM,
113 },
114 {
115 .name = "intrq",
116 .start = IRQ_IXP4XX_GPIO12,
117 .end = IRQ_IXP4XX_GPIO12,
118 .flags = IORESOURCE_IRQ,
119 },
120};
121
122static struct ixp4xx_pata_data avila_pata_data = {
123 .cs0_bits = 0xbfff0043,
124 .cs1_bits = 0xbfff0043,
125};
126
127static struct platform_device avila_pata = {
128 .name = "pata_ixp4xx_cf",
129 .id = 0,
130 .dev.platform_data = &avila_pata_data,
131 .num_resources = ARRAY_SIZE(avila_pata_resources),
132 .resource = avila_pata_resources,
133};
134
135static struct platform_device *avila_devices[] __initdata = {
136 &avila_i2c_controller,
137 &avila_flash,
138 &avila_uart
139};
140
141static void __init avila_init(void)
142{
143 ixp4xx_sys_init();
144
145 avila_flash_resource.start = IXP4XX_EXP_BUS_BASE(0);
146 avila_flash_resource.end =
147 IXP4XX_EXP_BUS_BASE(0) + ixp4xx_exp_bus_size - 1;
148
149 platform_add_devices(avila_devices, ARRAY_SIZE(avila_devices));
150
151 avila_pata_resources[0].start = IXP4XX_EXP_BUS_BASE(1);
152 avila_pata_resources[0].end = IXP4XX_EXP_BUS_END(1);
153
154 avila_pata_resources[1].start = IXP4XX_EXP_BUS_BASE(2);
155 avila_pata_resources[1].end = IXP4XX_EXP_BUS_END(2);
156
157 avila_pata_data.cs0_cfg = IXP4XX_EXP_CS1;
158 avila_pata_data.cs1_cfg = IXP4XX_EXP_CS2;
159
160 platform_device_register(&avila_pata);
161
162}
163
164MACHINE_START(AVILA, "Gateworks Avila Network Platform")
165 /* Maintainer: Deepak Saxena <dsaxena@plexity.net> */
166 .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
167 .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
168 .map_io = ixp4xx_map_io,
169 .init_irq = ixp4xx_init_irq,
170 .timer = &ixp4xx_timer,
171 .boot_params = 0x0100,
172 .init_machine = avila_init,
173MACHINE_END
174
175 /*
176 * Loft is functionally equivalent to Avila except that it has a
177 * different number for the maximum PCI devices. The MACHINE
178 * structure below is identical to Avila except for the comment.
179 */
180#ifdef CONFIG_MACH_LOFT
181MACHINE_START(LOFT, "Giant Shoulder Inc Loft board")
182 /* Maintainer: Tom Billman <kernel@giantshoulderinc.com> */
183 .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
184 .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
185 .map_io = ixp4xx_map_io,
186 .init_irq = ixp4xx_init_irq,
187 .timer = &ixp4xx_timer,
188 .boot_params = 0x0100,
189 .init_machine = avila_init,
190MACHINE_END
191#endif
192
diff --git a/arch/arm/mach-ixp4xx/ixdp425-pci.c b/arch/arm/mach-ixp4xx/ixdp425-pci.c
index d5156c043f0b..99c1dc8033c8 100644
--- a/arch/arm/mach-ixp4xx/ixdp425-pci.c
+++ b/arch/arm/mach-ixp4xx/ixdp425-pci.c
@@ -66,7 +66,7 @@ struct hw_pci ixdp425_pci __initdata = {
66int __init ixdp425_pci_init(void) 66int __init ixdp425_pci_init(void)
67{ 67{
68 if (machine_is_ixdp425() || machine_is_ixcdp1100() || 68 if (machine_is_ixdp425() || machine_is_ixcdp1100() ||
69 machine_is_avila() || machine_is_ixdp465()) 69 machine_is_ixdp465())
70 pci_common_init(&ixdp425_pci); 70 pci_common_init(&ixdp425_pci);
71 return 0; 71 return 0;
72} 72}
diff --git a/arch/arm/mach-ixp4xx/ixdp425-setup.c b/arch/arm/mach-ixp4xx/ixdp425-setup.c
index da72383ee301..04b1d56396a0 100644
--- a/arch/arm/mach-ixp4xx/ixdp425-setup.c
+++ b/arch/arm/mach-ixp4xx/ixdp425-setup.c
@@ -156,23 +156,3 @@ MACHINE_START(IXCDP1100, "Intel IXCDP1100 Development Platform")
156 .init_machine = ixdp425_init, 156 .init_machine = ixdp425_init,
157MACHINE_END 157MACHINE_END
158#endif 158#endif
159
160/*
161 * Avila is functionally equivalent to IXDP425 except that it adds
162 * a CF IDE slot hanging off the expansion bus. When we have a
163 * driver for IXP4xx CF IDE with driver model support we'll move
164 * Avila to it's own setup file.
165 */
166#ifdef CONFIG_ARCH_AVILA
167MACHINE_START(AVILA, "Gateworks Avila Network Platform")
168 /* Maintainer: Deepak Saxena <dsaxena@plexity.net> */
169 .phys_io = IXP4XX_PERIPHERAL_BASE_PHYS,
170 .io_pg_offst = ((IXP4XX_PERIPHERAL_BASE_VIRT) >> 18) & 0xfffc,
171 .map_io = ixp4xx_map_io,
172 .init_irq = ixp4xx_init_irq,
173 .timer = &ixp4xx_timer,
174 .boot_params = 0x0100,
175 .init_machine = ixdp425_init,
176MACHINE_END
177#endif
178
diff --git a/arch/arm/mach-ns9xxx/Kconfig b/arch/arm/mach-ns9xxx/Kconfig
new file mode 100644
index 000000000000..8175ba92a2fa
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/Kconfig
@@ -0,0 +1,21 @@
1if ARCH_NS9XXX
2
3menu "NS9xxx Implementations"
4
5config MACH_CC9P9360DEV
6 bool "Connect Core 9P 9360 on an A9M9750 Devboard"
7 select PROCESSOR_NS9360
8 select BOARD_A9M9750DEV
9 help
10 Say Y here if you are using the Digi Connect Core 9P 9360
11 on an A9M9750 Development Board.
12
13config PROCESSOR_NS9360
14 bool
15
16config BOARD_A9M9750DEV
17 bool
18
19endmenu
20
21endif
diff --git a/arch/arm/mach-ns9xxx/Makefile b/arch/arm/mach-ns9xxx/Makefile
new file mode 100644
index 000000000000..91e945f5e16d
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/Makefile
@@ -0,0 +1,5 @@
1obj-y := irq.o time.o generic.o
2
3obj-$(CONFIG_MACH_CC9P9360DEV) += mach-cc9p9360dev.o
4
5obj-$(CONFIG_BOARD_A9M9750DEV) += board-a9m9750dev.o
diff --git a/arch/arm/mach-ns9xxx/Makefile.boot b/arch/arm/mach-ns9xxx/Makefile.boot
new file mode 100644
index 000000000000..75ed64e90fa4
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/Makefile.boot
@@ -0,0 +1,2 @@
1zreladdr-y := 0x108000
2params_phys-y := 0x100
diff --git a/arch/arm/mach-ns9xxx/board-a9m9750dev.c b/arch/arm/mach-ns9xxx/board-a9m9750dev.c
new file mode 100644
index 000000000000..25289884a607
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/board-a9m9750dev.c
@@ -0,0 +1,199 @@
1/*
2 * arch/arm/mach-ns9xxx/board-a9m9750dev.c
3 *
4 * Copyright (C) 2006,2007 by Digi International Inc.
5 * All rights reserved.
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 version 2 as published by
9 * the Free Software Foundation.
10 */
11#include <linux/platform_device.h>
12#include <linux/serial_8250.h>
13#include <linux/irq.h>
14
15#include <asm/mach/map.h>
16
17#include <asm/arch-ns9xxx/board.h>
18#include <asm/arch-ns9xxx/regs-sys.h>
19#include <asm/arch-ns9xxx/regs-mem.h>
20#include <asm/arch-ns9xxx/regs-bbu.h>
21#include <asm/arch-ns9xxx/regs-board-a9m9750dev.h>
22
23#include "board-a9m9750dev.h"
24
25static struct map_desc board_a9m9750dev_io_desc[] __initdata = {
26 { /* FPGA on CS0 */
27 .virtual = io_p2v(NS9XXX_CSxSTAT_PHYS(0)),
28 .pfn = __phys_to_pfn(NS9XXX_CSxSTAT_PHYS(0)),
29 .length = NS9XXX_CS0STAT_LENGTH,
30 .type = MT_DEVICE,
31 },
32};
33
34void __init board_a9m9750dev_map_io(void)
35{
36 iotable_init(board_a9m9750dev_io_desc,
37 ARRAY_SIZE(board_a9m9750dev_io_desc));
38}
39
40static void a9m9750dev_fpga_ack_irq(unsigned int irq)
41{
42 /* nothing */
43}
44
45static void a9m9750dev_fpga_mask_irq(unsigned int irq)
46{
47 FPGA_IER &= ~(1 << (irq - FPGA_IRQ(0)));
48}
49
50static void a9m9750dev_fpga_maskack_irq(unsigned int irq)
51{
52 a9m9750dev_fpga_mask_irq(irq);
53 a9m9750dev_fpga_ack_irq(irq);
54}
55
56static void a9m9750dev_fpga_unmask_irq(unsigned int irq)
57{
58 FPGA_IER |= 1 << (irq - FPGA_IRQ(0));
59}
60
61static struct irq_chip a9m9750dev_fpga_chip = {
62 .ack = a9m9750dev_fpga_ack_irq,
63 .mask = a9m9750dev_fpga_mask_irq,
64 .mask_ack = a9m9750dev_fpga_maskack_irq,
65 .unmask = a9m9750dev_fpga_unmask_irq,
66};
67
68static void a9m9750dev_fpga_demux_handler(unsigned int irq,
69 struct irq_desc *desc)
70{
71 int stat = FPGA_ISR;
72
73 while (stat != 0) {
74 int irqno = fls(stat) - 1;
75
76 stat &= ~(1 << irqno);
77
78 desc = irq_desc + FPGA_IRQ(irqno);
79
80 desc_handle_irq(irqno, desc);
81 }
82}
83
84void __init board_a9m9750dev_init_irq(void)
85{
86 u32 reg;
87 int i;
88
89 /*
90 * configure gpio for IRQ_EXT2
91 * use GPIO 11, because GPIO 32 is used for the LCD
92 */
93 /* XXX: proper GPIO handling */
94 BBU_GC(2) &= ~0x2000;
95
96 for (i = FPGA_IRQ(0); i <= FPGA_IRQ(7); ++i) {
97 set_irq_chip(i, &a9m9750dev_fpga_chip);
98 set_irq_handler(i, handle_level_irq);
99 set_irq_flags(i, IRQF_VALID);
100 }
101
102 /* IRQ_EXT2: level sensitive + active low */
103 reg = SYS_EIC(2);
104 REGSET(reg, SYS_EIC, PLTY, AL);
105 REGSET(reg, SYS_EIC, LVEDG, LEVEL);
106 SYS_EIC(2) = reg;
107
108 set_irq_chained_handler(IRQ_EXT2,
109 a9m9750dev_fpga_demux_handler);
110}
111
112static struct plat_serial8250_port board_a9m9750dev_serial8250_port[] = {
113 {
114 .iobase = FPGA_UARTA_BASE,
115 .membase = (unsigned char*)FPGA_UARTA_BASE,
116 .mapbase = FPGA_UARTA_BASE,
117 .irq = IRQ_FPGA_UARTA,
118 .iotype = UPIO_MEM,
119 .uartclk = 18432000,
120 .regshift = 0,
121 .flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ,
122 }, {
123 .iobase = FPGA_UARTB_BASE,
124 .membase = (unsigned char*)FPGA_UARTB_BASE,
125 .mapbase = FPGA_UARTB_BASE,
126 .irq = IRQ_FPGA_UARTB,
127 .iotype = UPIO_MEM,
128 .uartclk = 18432000,
129 .regshift = 0,
130 .flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ,
131 }, {
132 .iobase = FPGA_UARTC_BASE,
133 .membase = (unsigned char*)FPGA_UARTC_BASE,
134 .mapbase = FPGA_UARTC_BASE,
135 .irq = IRQ_FPGA_UARTC,
136 .iotype = UPIO_MEM,
137 .uartclk = 18432000,
138 .regshift = 0,
139 .flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ,
140 }, {
141 .iobase = FPGA_UARTD_BASE,
142 .membase = (unsigned char*)FPGA_UARTD_BASE,
143 .mapbase = FPGA_UARTD_BASE,
144 .irq = IRQ_FPGA_UARTD,
145 .iotype = UPIO_MEM,
146 .uartclk = 18432000,
147 .regshift = 0,
148 .flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ,
149 }, {
150 /* end marker */
151 },
152};
153
154static struct platform_device board_a9m9750dev_serial_device = {
155 .name = "serial8250",
156 .dev = {
157 .platform_data = board_a9m9750dev_serial8250_port,
158 },
159};
160
161static struct platform_device *board_a9m9750dev_devices[] __initdata = {
162 &board_a9m9750dev_serial_device,
163};
164
165void __init board_a9m9750dev_init_machine(void)
166{
167 u32 reg;
168
169 /* setup static CS0: memory base ... */
170 REGSETIM(SYS_SMCSSMB(0), SYS_SMCSSMB, CSxB,
171 NS9XXX_CSxSTAT_PHYS(0) >> 12);
172
173 /* ... and mask */
174 reg = SYS_SMCSSMM(0);
175 REGSETIM(reg, SYS_SMCSSMM, CSxM, 0xfffff);
176 REGSET(reg, SYS_SMCSSMM, CSEx, EN);
177 SYS_SMCSSMM(0) = reg;
178
179 /* setup static CS0: memory configuration */
180 reg = MEM_SMC(0);
181 REGSET(reg, MEM_SMC, WSMC, OFF);
182 REGSET(reg, MEM_SMC, BSMC, OFF);
183 REGSET(reg, MEM_SMC, EW, OFF);
184 REGSET(reg, MEM_SMC, PB, 1);
185 REGSET(reg, MEM_SMC, PC, AL);
186 REGSET(reg, MEM_SMC, PM, DIS);
187 REGSET(reg, MEM_SMC, MW, 8);
188 MEM_SMC(0) = reg;
189
190 /* setup static CS0: timing */
191 MEM_SMWED(0) = 0x2;
192 MEM_SMOED(0) = 0x2;
193 MEM_SMRD(0) = 0x6;
194 MEM_SMWD(0) = 0x6;
195
196 platform_add_devices(board_a9m9750dev_devices,
197 ARRAY_SIZE(board_a9m9750dev_devices));
198}
199
diff --git a/arch/arm/mach-ns9xxx/board-a9m9750dev.h b/arch/arm/mach-ns9xxx/board-a9m9750dev.h
new file mode 100644
index 000000000000..edc75abbc5dd
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/board-a9m9750dev.h
@@ -0,0 +1,15 @@
1/*
2 * arch/arm/mach-ns9xxx/board-a9m9750dev.h
3 *
4 * Copyright (C) 2006 by Digi International Inc.
5 * All rights reserved.
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 version 2 as published by
9 * the Free Software Foundation.
10 */
11#include <linux/init.h>
12
13void __init board_a9m9750dev_map_io(void);
14void __init board_a9m9750dev_init_machine(void);
15void __init board_a9m9750dev_init_irq(void);
diff --git a/arch/arm/mach-ns9xxx/generic.c b/arch/arm/mach-ns9xxx/generic.c
new file mode 100644
index 000000000000..83e2b6532b22
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/generic.c
@@ -0,0 +1,42 @@
1/*
2 * arch/arm/mach-ns9xxx/generic.c
3 *
4 * Copyright (C) 2006 by Digi International Inc.
5 * All rights reserved.
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 version 2 as published by
9 * the Free Software Foundation.
10 */
11#include <linux/kernel.h>
12#include <linux/init.h>
13#include <asm/memory.h>
14#include <asm/page.h>
15#include <asm/mach-types.h>
16#include <asm/mach/map.h>
17#include <asm/arch-ns9xxx/regs-sys.h>
18#include <asm/arch-ns9xxx/regs-mem.h>
19#include <asm/arch-ns9xxx/board.h>
20
21static struct map_desc standard_io_desc[] __initdata = {
22 { /* BBus */
23 .virtual = io_p2v(0x90000000),
24 .pfn = __phys_to_pfn(0x90000000),
25 .length = 0x00700000,
26 .type = MT_DEVICE,
27 }, { /* AHB */
28 .virtual = io_p2v(0xa0100000),
29 .pfn = __phys_to_pfn(0xa0100000),
30 .length = 0x00900000,
31 .type = MT_DEVICE,
32 },
33};
34
35void __init ns9xxx_map_io(void)
36{
37 iotable_init(standard_io_desc, ARRAY_SIZE(standard_io_desc));
38}
39
40void __init ns9xxx_init_machine(void)
41{
42}
diff --git a/arch/arm/mach-ns9xxx/generic.h b/arch/arm/mach-ns9xxx/generic.h
new file mode 100644
index 000000000000..687e291773f4
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/generic.h
@@ -0,0 +1,19 @@
1/*
2 * arch/arm/mach-ns9xxx/generic.h
3 *
4 * Copyright (C) 2006 by Digi International Inc.
5 * All rights reserved.
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 version 2 as published by
9 * the Free Software Foundation.
10 */
11#include <linux/time.h>
12#include <asm/mach/time.h>
13#include <linux/init.h>
14
15void __init ns9xxx_init_irq(void);
16void __init ns9xxx_map_io(void);
17void __init ns9xxx_init_machine(void);
18
19extern struct sys_timer ns9xxx_timer;
diff --git a/arch/arm/mach-ns9xxx/irq.c b/arch/arm/mach-ns9xxx/irq.c
new file mode 100644
index 000000000000..83d92724a971
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/irq.c
@@ -0,0 +1,94 @@
1/*
2 * arch/arm/mach-ns9xxx/irq.c
3 *
4 * Copyright (C) 2006,2007 by Digi International Inc.
5 * All rights reserved.
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 version 2 as published by
9 * the Free Software Foundation.
10 */
11#include <linux/interrupt.h>
12#include <asm/mach/irq.h>
13#include <asm/mach-types.h>
14#include <asm/arch-ns9xxx/regs-sys.h>
15#include <asm/arch-ns9xxx/irqs.h>
16#include <asm/arch-ns9xxx/board.h>
17
18#include "generic.h"
19
20static void ns9xxx_ack_irq_timer(unsigned int irq)
21{
22 u32 tc = SYS_TC(irq - IRQ_TIMER0);
23
24 REGSET(tc, SYS_TCx, INTC, SET);
25 SYS_TC(irq - IRQ_TIMER0) = tc;
26
27 REGSET(tc, SYS_TCx, INTC, UNSET);
28 SYS_TC(irq - IRQ_TIMER0) = tc;
29}
30
31void (*ns9xxx_ack_irq_functions[NR_IRQS])(unsigned int) = {
32 [IRQ_TIMER0] = ns9xxx_ack_irq_timer,
33 [IRQ_TIMER1] = ns9xxx_ack_irq_timer,
34 [IRQ_TIMER2] = ns9xxx_ack_irq_timer,
35 [IRQ_TIMER3] = ns9xxx_ack_irq_timer,
36};
37
38static void ns9xxx_mask_irq(unsigned int irq)
39{
40 /* XXX: better use cpp symbols */
41 SYS_IC(irq / 4) &= ~(1 << (7 + 8 * (3 - (irq & 3))));
42}
43
44static void ns9xxx_ack_irq(unsigned int irq)
45{
46 if (!ns9xxx_ack_irq_functions[irq]) {
47 printk(KERN_ERR "no ack function for irq %u\n", irq);
48 BUG();
49 }
50
51 ns9xxx_ack_irq_functions[irq](irq);
52 SYS_ISRADDR = 0;
53}
54
55static void ns9xxx_maskack_irq(unsigned int irq)
56{
57 ns9xxx_mask_irq(irq);
58 ns9xxx_ack_irq(irq);
59}
60
61static void ns9xxx_unmask_irq(unsigned int irq)
62{
63 /* XXX: better use cpp symbols */
64 SYS_IC(irq / 4) |= 1 << (7 + 8 * (3 - (irq & 3)));
65}
66
67static struct irq_chip ns9xxx_chip = {
68 .ack = ns9xxx_ack_irq,
69 .mask = ns9xxx_mask_irq,
70 .mask_ack = ns9xxx_maskack_irq,
71 .unmask = ns9xxx_unmask_irq,
72};
73
74void __init ns9xxx_init_irq(void)
75{
76 int i;
77
78 /* disable all IRQs */
79 for (i = 0; i < 8; ++i)
80 SYS_IC(i) = (4 * i) << 24 | (4 * i + 1) << 16 |
81 (4 * i + 2) << 8 | (4 * i + 3);
82
83 /* simple interrupt prio table:
84 * prio(x) < prio(y) <=> x < y
85 */
86 for (i = 0; i < 32; ++i)
87 SYS_IVA(i) = i;
88
89 for (i = IRQ_WATCHDOG; i <= IRQ_EXT3; ++i) {
90 set_irq_chip(i, &ns9xxx_chip);
91 set_irq_handler(i, handle_level_irq);
92 set_irq_flags(i, IRQF_VALID);
93 }
94}
diff --git a/arch/arm/mach-ns9xxx/mach-cc9p9360dev.c b/arch/arm/mach-ns9xxx/mach-cc9p9360dev.c
new file mode 100644
index 000000000000..a193dd931512
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/mach-cc9p9360dev.c
@@ -0,0 +1,41 @@
1/*
2 * arch/arm/mach-ns9xxx/mach-cc9p9360dev.c
3 *
4 * Copyright (C) 2006 by Digi International Inc.
5 * All rights reserved.
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 version 2 as published by
9 * the Free Software Foundation.
10 */
11#include <asm/mach/arch.h>
12#include <asm/mach-types.h>
13
14#include "board-a9m9750dev.h"
15#include "generic.h"
16
17static void __init mach_cc9p9360dev_map_io(void)
18{
19 ns9xxx_map_io();
20 board_a9m9750dev_map_io();
21}
22
23static void __init mach_cc9p9360dev_init_irq(void)
24{
25 ns9xxx_init_irq();
26 board_a9m9750dev_init_irq();
27}
28
29static void __init mach_cc9p9360dev_init_machine(void)
30{
31 ns9xxx_init_machine();
32 board_a9m9750dev_init_machine();
33}
34
35MACHINE_START(CC9P9360DEV, "Connect Core 9P 9360 on an A9M9750 Devboard")
36 .map_io = mach_cc9p9360dev_map_io,
37 .init_irq = mach_cc9p9360dev_init_irq,
38 .init_machine = mach_cc9p9360dev_init_machine,
39 .timer = &ns9xxx_timer,
40 .boot_params = 0x100,
41MACHINE_END
diff --git a/arch/arm/mach-ns9xxx/time.c b/arch/arm/mach-ns9xxx/time.c
new file mode 100644
index 000000000000..eec05f18714a
--- /dev/null
+++ b/arch/arm/mach-ns9xxx/time.c
@@ -0,0 +1,88 @@
1/*
2 * arch/arm/mach-ns9xxx/time.c
3 *
4 * Copyright (C) 2006 by Digi International Inc.
5 * All rights reserved.
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 version 2 as published by
9 * the Free Software Foundation.
10 */
11#include <linux/jiffies.h>
12#include <linux/interrupt.h>
13#include <linux/irq.h>
14#include <asm/arch-ns9xxx/regs-sys.h>
15#include <asm/arch-ns9xxx/clock.h>
16#include <asm/arch-ns9xxx/irqs.h>
17#include <asm/arch/system.h>
18#include "generic.h"
19
20#define TIMERCLOCKSELECT 64
21
22static u32 usecs_per_tick;
23
24static irqreturn_t
25ns9xxx_timer_interrupt(int irq, void *dev_id)
26{
27 write_seqlock(&xtime_lock);
28 timer_tick();
29 write_sequnlock(&xtime_lock);
30
31 return IRQ_HANDLED;
32}
33
34static unsigned long ns9xxx_timer_gettimeoffset(void)
35{
36 /* return the microseconds which have passed since the last interrupt
37 * was _serviced_. That is, if an interrupt is pending or the counter
38 * reloads, return one periode more. */
39
40 u32 counter1 = SYS_TR(0);
41 int pending = SYS_ISR & (1 << IRQ_TIMER0);
42 u32 counter2 = SYS_TR(0);
43 u32 elapsed;
44
45 if (pending || counter2 > counter1)
46 elapsed = 2 * SYS_TRC(0) - counter2;
47 else
48 elapsed = SYS_TRC(0) - counter1;
49
50 return (elapsed * usecs_per_tick) >> 16;
51
52}
53
54static struct irqaction ns9xxx_timer_irq = {
55 .name = "NS9xxx Timer Tick",
56 .flags = IRQF_DISABLED | IRQF_TIMER,
57 .handler = ns9xxx_timer_interrupt,
58};
59
60static void __init ns9xxx_timer_init(void)
61{
62 int tc;
63
64 usecs_per_tick =
65 SH_DIV(1000000 * TIMERCLOCKSELECT, ns9xxx_cpuclock(), 16);
66
67 /* disable timer */
68 if ((tc = SYS_TC(0)) & SYS_TCx_TEN)
69 SYS_TC(0) = tc & ~SYS_TCx_TEN;
70
71 SYS_TRC(0) = SH_DIV(ns9xxx_cpuclock(), (TIMERCLOCKSELECT * HZ), 0);
72
73 REGSET(tc, SYS_TCx, TEN, EN);
74 REGSET(tc, SYS_TCx, TLCS, DIV64); /* This must match TIMERCLOCKSELECT */
75 REGSET(tc, SYS_TCx, INTS, EN);
76 REGSET(tc, SYS_TCx, UDS, DOWN);
77 REGSET(tc, SYS_TCx, TDBG, STOP);
78 REGSET(tc, SYS_TCx, TSZ, 32);
79 REGSET(tc, SYS_TCx, REN, EN);
80 SYS_TC(0) = tc;
81
82 setup_irq(IRQ_TIMER0, &ns9xxx_timer_irq);
83}
84
85struct sys_timer ns9xxx_timer = {
86 .init = ns9xxx_timer_init,
87 .offset = ns9xxx_timer_gettimeoffset,
88};
diff --git a/arch/arm/mach-pxa/generic.c b/arch/arm/mach-pxa/generic.c
index 9de1278d234f..390524c4710f 100644
--- a/arch/arm/mach-pxa/generic.c
+++ b/arch/arm/mach-pxa/generic.c
@@ -338,6 +338,27 @@ static struct platform_device i2c_device = {
338 .num_resources = ARRAY_SIZE(i2c_resources), 338 .num_resources = ARRAY_SIZE(i2c_resources),
339}; 339};
340 340
341#ifdef CONFIG_PXA27x
342static struct resource i2c_power_resources[] = {
343 {
344 .start = 0x40f00180,
345 .end = 0x40f001a3,
346 .flags = IORESOURCE_MEM,
347 }, {
348 .start = IRQ_PWRI2C,
349 .end = IRQ_PWRI2C,
350 .flags = IORESOURCE_IRQ,
351 },
352};
353
354static struct platform_device i2c_power_device = {
355 .name = "pxa2xx-i2c",
356 .id = 1,
357 .resource = i2c_power_resources,
358 .num_resources = ARRAY_SIZE(i2c_resources),
359};
360#endif
361
341void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info) 362void __init pxa_set_i2c_info(struct i2c_pxa_platform_data *info)
342{ 363{
343 i2c_device.dev.platform_data = info; 364 i2c_device.dev.platform_data = info;
@@ -392,6 +413,9 @@ static struct platform_device *devices[] __initdata = {
392 &stuart_device, 413 &stuart_device,
393 &pxaficp_device, 414 &pxaficp_device,
394 &i2c_device, 415 &i2c_device,
416#ifdef CONFIG_PXA27x
417 &i2c_power_device,
418#endif
395 &i2s_device, 419 &i2s_device,
396 &pxartc_device, 420 &pxartc_device,
397}; 421};
diff --git a/arch/arm/mach-realview/Kconfig b/arch/arm/mach-realview/Kconfig
index 17f5f4439fe7..35156ca39df7 100644
--- a/arch/arm/mach-realview/Kconfig
+++ b/arch/arm/mach-realview/Kconfig
@@ -10,10 +10,21 @@ config MACH_REALVIEW_EB
10config REALVIEW_MPCORE 10config REALVIEW_MPCORE
11 bool "Support MPcore tile" 11 bool "Support MPcore tile"
12 depends on MACH_REALVIEW_EB 12 depends on MACH_REALVIEW_EB
13 select CACHE_L2X0
13 help 14 help
14 Enable support for the MPCore tile on the Realview platform. 15 Enable support for the MPCore tile on the Realview platform.
15 Since there are device address and interrupt differences, a 16 Since there are device address and interrupt differences, a
16 kernel built with this option enabled is not compatible with 17 kernel built with this option enabled is not compatible with
17 other tiles. 18 other tiles.
18 19
20config REALVIEW_MPCORE_REVB
21 bool "Support MPcore RevB tile"
22 depends on REALVIEW_MPCORE
23 default n
24 help
25 Enable support for the MPCore RevB tile on the Realview platform.
26 Since there are device address differences, a
27 kernel built with this option enabled is not compatible with
28 other tiles.
29
19endmenu 30endmenu
diff --git a/arch/arm/mach-realview/platsmp.c b/arch/arm/mach-realview/platsmp.c
index b8484e15dacb..fce3596f9950 100644
--- a/arch/arm/mach-realview/platsmp.c
+++ b/arch/arm/mach-realview/platsmp.c
@@ -52,13 +52,14 @@ void __cpuinit platform_secondary_init(unsigned int cpu)
52 * core (e.g. timer irq), then they will not have been enabled 52 * core (e.g. timer irq), then they will not have been enabled
53 * for us: do so 53 * for us: do so
54 */ 54 */
55 gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE)); 55 gic_cpu_init(0, __io_address(REALVIEW_GIC_CPU_BASE));
56 56
57 /* 57 /*
58 * let the primary processor know we're out of the 58 * let the primary processor know we're out of the
59 * pen, then head off into the C entry point 59 * pen, then head off into the C entry point
60 */ 60 */
61 pen_release = -1; 61 pen_release = -1;
62 smp_wmb();
62 63
63 /* 64 /*
64 * Synchronise with the boot thread. 65 * Synchronise with the boot thread.
@@ -102,6 +103,7 @@ int __cpuinit boot_secondary(unsigned int cpu, struct task_struct *idle)
102 103
103 timeout = jiffies + (1 * HZ); 104 timeout = jiffies + (1 * HZ);
104 while (time_before(jiffies, timeout)) { 105 while (time_before(jiffies, timeout)) {
106 smp_rmb();
105 if (pen_release == -1) 107 if (pen_release == -1)
106 break; 108 break;
107 109
diff --git a/arch/arm/mach-realview/realview_eb.c b/arch/arm/mach-realview/realview_eb.c
index 9741b4d3c9cf..3dba666151db 100644
--- a/arch/arm/mach-realview/realview_eb.c
+++ b/arch/arm/mach-realview/realview_eb.c
@@ -31,6 +31,7 @@
31#include <asm/mach-types.h> 31#include <asm/mach-types.h>
32#include <asm/hardware/gic.h> 32#include <asm/hardware/gic.h>
33#include <asm/hardware/icst307.h> 33#include <asm/hardware/icst307.h>
34#include <asm/hardware/cache-l2x0.h>
34 35
35#include <asm/mach/arch.h> 36#include <asm/mach/arch.h>
36#include <asm/mach/map.h> 37#include <asm/mach/map.h>
@@ -57,7 +58,26 @@ static struct map_desc realview_eb_io_desc[] __initdata = {
57 .pfn = __phys_to_pfn(REALVIEW_GIC_DIST_BASE), 58 .pfn = __phys_to_pfn(REALVIEW_GIC_DIST_BASE),
58 .length = SZ_4K, 59 .length = SZ_4K,
59 .type = MT_DEVICE, 60 .type = MT_DEVICE,
61 },
62#ifdef CONFIG_REALVIEW_MPCORE
63 {
64 .virtual = IO_ADDRESS(REALVIEW_GIC1_CPU_BASE),
65 .pfn = __phys_to_pfn(REALVIEW_GIC1_CPU_BASE),
66 .length = SZ_4K,
67 .type = MT_DEVICE,
68 }, {
69 .virtual = IO_ADDRESS(REALVIEW_GIC1_DIST_BASE),
70 .pfn = __phys_to_pfn(REALVIEW_GIC1_DIST_BASE),
71 .length = SZ_4K,
72 .type = MT_DEVICE,
60 }, { 73 }, {
74 .virtual = IO_ADDRESS(REALVIEW_MPCORE_L220_BASE),
75 .pfn = __phys_to_pfn(REALVIEW_MPCORE_L220_BASE),
76 .length = SZ_8K,
77 .type = MT_DEVICE,
78 },
79#endif
80 {
61 .virtual = IO_ADDRESS(REALVIEW_SCTL_BASE), 81 .virtual = IO_ADDRESS(REALVIEW_SCTL_BASE),
62 .pfn = __phys_to_pfn(REALVIEW_SCTL_BASE), 82 .pfn = __phys_to_pfn(REALVIEW_SCTL_BASE),
63 .length = SZ_4K, 83 .length = SZ_4K,
@@ -138,19 +158,29 @@ static void __init gic_init_irq(void)
138#ifdef CONFIG_REALVIEW_MPCORE 158#ifdef CONFIG_REALVIEW_MPCORE
139 unsigned int pldctrl; 159 unsigned int pldctrl;
140 writel(0x0000a05f, __io_address(REALVIEW_SYS_LOCK)); 160 writel(0x0000a05f, __io_address(REALVIEW_SYS_LOCK));
141 pldctrl = readl(__io_address(REALVIEW_SYS_BASE) + 0xd8); 161 pldctrl = readl(__io_address(REALVIEW_SYS_BASE) + REALVIEW_MPCORE_SYS_PLD_CTRL1);
142 pldctrl |= 0x00800000; /* New irq mode */ 162 pldctrl |= 0x00800000; /* New irq mode */
143 writel(pldctrl, __io_address(REALVIEW_SYS_BASE) + 0xd8); 163 writel(pldctrl, __io_address(REALVIEW_SYS_BASE) + REALVIEW_MPCORE_SYS_PLD_CTRL1);
144 writel(0x00000000, __io_address(REALVIEW_SYS_LOCK)); 164 writel(0x00000000, __io_address(REALVIEW_SYS_LOCK));
145#endif 165#endif
146 gic_dist_init(__io_address(REALVIEW_GIC_DIST_BASE)); 166 gic_dist_init(0, __io_address(REALVIEW_GIC_DIST_BASE), 29);
147 gic_cpu_init(__io_address(REALVIEW_GIC_CPU_BASE)); 167 gic_cpu_init(0, __io_address(REALVIEW_GIC_CPU_BASE));
168#ifdef CONFIG_REALVIEW_MPCORE
169 gic_dist_init(1, __io_address(REALVIEW_GIC1_DIST_BASE), 64);
170 gic_cpu_init(1, __io_address(REALVIEW_GIC1_CPU_BASE));
171 gic_cascade_irq(1, IRQ_EB_IRQ1);
172#endif
148} 173}
149 174
150static void __init realview_eb_init(void) 175static void __init realview_eb_init(void)
151{ 176{
152 int i; 177 int i;
153 178
179#ifdef CONFIG_REALVIEW_MPCORE
180 /* 1MB (128KB/way), 8-way associativity, evmon/parity/share enabled
181 * Bits: .... ...0 0111 1001 0000 .... .... .... */
182 l2x0_init(__io_address(REALVIEW_MPCORE_L220_BASE), 0x00790000, 0xfe000fff);
183#endif
154 clk_register(&realview_clcd_clk); 184 clk_register(&realview_clcd_clk);
155 185
156 platform_device_register(&realview_flash_device); 186 platform_device_register(&realview_flash_device);
diff --git a/arch/arm/mach-s3c2400/Kconfig b/arch/arm/mach-s3c2400/Kconfig
new file mode 100644
index 000000000000..deab0722836e
--- /dev/null
+++ b/arch/arm/mach-s3c2400/Kconfig
@@ -0,0 +1,13 @@
1# arch/arm/mach-s3c2400/Kconfig
2#
3# Copyright 2007 Simtec Electronics
4#
5# Licensed under GPLv2
6
7
8
9menu "S3C2400 Machines"
10
11
12endmenu
13
diff --git a/arch/arm/mach-s3c2400/Makefile b/arch/arm/mach-s3c2400/Makefile
new file mode 100644
index 000000000000..7e23f4e13766
--- /dev/null
+++ b/arch/arm/mach-s3c2400/Makefile
@@ -0,0 +1,15 @@
1# arch/arm/mach-s3c2400/Makefile
2#
3# Copyright 2007 Simtec Electronics
4#
5# Licensed under GPLv2
6
7obj-y :=
8obj-m :=
9obj-n :=
10obj- :=
11
12obj-$(CONFIG_CPU_S3C2400) += gpio.o
13
14# Machine support
15
diff --git a/arch/arm/mach-s3c2410/s3c2400-gpio.c b/arch/arm/mach-s3c2400/gpio.c
index 1576d01d5f82..758e160410e9 100644
--- a/arch/arm/mach-s3c2410/s3c2400-gpio.c
+++ b/arch/arm/mach-s3c2400/gpio.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/s3c2400-gpio.c 1/* linux/arch/arm/mach-s3c2400/gpio.c
2 * 2 *
3 * Copyright (c) 2006 Lucas Correia Villa Real <lucasvr@gobolinux.org> 3 * Copyright (c) 2006 Lucas Correia Villa Real <lucasvr@gobolinux.org>
4 * 4 *
diff --git a/arch/arm/mach-s3c2410/Kconfig b/arch/arm/mach-s3c2410/Kconfig
index eb4ec411312b..d4b013b283c3 100644
--- a/arch/arm/mach-s3c2410/Kconfig
+++ b/arch/arm/mach-s3c2410/Kconfig
@@ -1,54 +1,51 @@
1if ARCH_S3C2410 1# arch/arm/mach-s3c2410/Kconfig
2#
3# Copyright 2007 Simtec Electronics
4#
5# Licensed under GPLv2
2 6
3menu "S3C24XX Implementations" 7config CPU_S3C2410
8 bool
9 depends on ARCH_S3C2410
10 select S3C2410_CLOCK
11 select S3C2410_GPIO
12 select S3C2410_PM if PM
13 help
14 Support for S3C2410 and S3C2410A family from the S3C24XX line
15 of Samsung Mobile CPUs.
4 16
5config MACH_AML_M5900 17config CPU_S3C2410_DMA
6 bool "AML M5900 Series" 18 bool
7 select CPU_S3C2410 19 depends on S3C2410_DMA && (CPU_S3C2410 || CPU_S3C2442)
8 select PM_SIMTEC if PM 20 default y if CPU_S3C2410 || CPU_S3C2442
9 help 21 help
10 Say Y here if you are using the American Microsystems M5900 Series 22 DMA device selection for S3C2410 and compatible CPUs
11 <http://www.amltd.com>
12 23
13config MACH_ANUBIS 24config S3C2410_PM
14 bool "Simtec Electronics ANUBIS" 25 bool
15 select CPU_S3C2440
16 select PM_SIMTEC if PM
17 help 26 help
18 Say Y here if you are using the Simtec Electronics ANUBIS 27 Power Management code common to S3C2410 and better
19 development system
20 28
21config MACH_OSIRIS 29config S3C2410_GPIO
22 bool "Simtec IM2440D20 (OSIRIS) module" 30 bool
23 select CPU_S3C2440
24 select PM_SIMTEC if PM
25 help 31 help
26 Say Y here if you are using the Simtec IM2440D20 module, also 32 GPIO code for S3C2410 and similar processors
27 known as the Osiris.
28 33
29config ARCH_BAST 34config S3C2410_CLOCK
30 bool "Simtec Electronics BAST (EB2410ITX)" 35 bool
31 select CPU_S3C2410
32 select PM_SIMTEC if PM
33 select ISA
34 help 36 help
35 Say Y here if you are using the Simtec Electronics EB2410ITX 37 Clock code for the S3C2410, and similar processors
36 development board (also known as BAST)
37 38
38 Product page: <http://www.simtec.co.uk/products/EB2410ITX/>.
39 39
40config BAST_PC104_IRQ 40menu "S3C2410 Machines"
41 bool "BAST PC104 IRQ support"
42 depends on ARCH_BAST
43 default y
44 help
45 Say Y here to enable the PC104 IRQ routing on the
46 Simtec BAST (EB2410ITX)
47 41
48config PM_H1940 42config ARCH_SMDK2410
49 bool 43 bool "SMDK2410/A9M2410"
44 select CPU_S3C2410
45 select MACH_SMDK
50 help 46 help
51 Internal node for H1940 and related PM 47 Say Y here if you are using the SMDK2410 or the derived module A9M2410
48 <http://www.fsforth.de>
52 49
53config ARCH_H1940 50config ARCH_H1940
54 bool "IPAQ H1940" 51 bool "IPAQ H1940"
@@ -57,7 +54,10 @@ config ARCH_H1940
57 help 54 help
58 Say Y here if you are using the HP IPAQ H1940 55 Say Y here if you are using the HP IPAQ H1940
59 56
60 <http://www.handhelds.org/projects/h1940.html>. 57config PM_H1940
58 bool
59 help
60 Internal node for H1940 and related PM
61 61
62config MACH_N30 62config MACH_N30
63 bool "Acer N30" 63 bool "Acer N30"
@@ -65,53 +65,36 @@ config MACH_N30
65 help 65 help
66 Say Y here if you are using the Acer N30 66 Say Y here if you are using the Acer N30
67 67
68 <http://zoo.weinigel.se/n30>. 68config ARCH_BAST
69 69 bool "Simtec Electronics BAST (EB2410ITX)"
70config MACH_SMDK
71 bool
72 help
73 Common machine code for SMDK2410 and SMDK2440
74
75config ARCH_SMDK2410
76 bool "SMDK2410/A9M2410"
77 select CPU_S3C2410 70 select CPU_S3C2410
78 select MACH_SMDK 71 select PM_SIMTEC if PM
72 select ISA
79 help 73 help
80 Say Y here if you are using the SMDK2410 or the derived module A9M2410 74 Say Y here if you are using the Simtec Electronics EB2410ITX
81 <http://www.fsforth.de> 75 development board (also known as BAST)
82 76
83config ARCH_S3C2440 77config MACH_OTOM
84 bool "SMDK2440" 78 bool "NexVision OTOM Board"
85 select CPU_S3C2440 79 select CPU_S3C2410
86 select MACH_SMDK
87 help 80 help
88 Say Y here if you are using the SMDK2440. 81 Say Y here if you are using the Nex Vision OTOM board
89
90config SMDK2440_CPU2440
91 bool "SMDK2440 with S3C2440 CPU module"
92 depends on ARCH_S3C2440
93 default y if ARCH_S3C2440
94 select CPU_S3C2440
95
96config SMDK2440_CPU2442
97 bool "SMDM2440 with S3C2442 CPU module"
98 depends on ARCH_S3C2440
99 select CPU_S3C2442
100 82
101config MACH_S3C2413 83config MACH_AML_M5900
102 bool 84 bool "AML M5900 Series"
85 select CPU_S3C2410
86 select PM_SIMTEC if PM
103 help 87 help
104 Internal node for S3C2413 version of SMDK2413, so that 88 Say Y here if you are using the American Microsystems M5900 Series
105 machine_is_s3c2413() will work when MACH_SMDK2413 is 89 <http://www.amltd.com>
106 selected
107 90
108config MACH_SMDK2413 91config BAST_PC104_IRQ
109 bool "SMDK2413" 92 bool "BAST PC104 IRQ support"
110 select CPU_S3C2412 93 depends on ARCH_BAST
111 select MACH_S3C2413 94 default y
112 select MACH_SMDK
113 help 95 help
114 Say Y here if you are using an SMDK2413 96 Say Y here to enable the PC104 IRQ routing on the
97 Simtec BAST (EB2410ITX)
115 98
116config MACH_VR1000 99config MACH_VR1000
117 bool "Thorcom VR1000" 100 bool "Thorcom VR1000"
@@ -120,202 +103,11 @@ config MACH_VR1000
120 help 103 help
121 Say Y here if you are using the Thorcom VR1000 board. 104 Say Y here if you are using the Thorcom VR1000 board.
122 105
123 This linux port is currently being maintained by Simtec, on behalf 106config MACH_QT2410
124 of Thorcom. Any queries, please contact Thorcom first. 107 bool "QT2410"
125 108 select CPU_S3C2410
126config MACH_RX3715
127 bool "HP iPAQ rx3715"
128 select CPU_S3C2440
129 select PM_H1940 if PM
130 help
131 Say Y here if you are using the HP iPAQ rx3715.
132
133 See <http://www.handhelds.org/projects/rx3715.html> for more
134 information on this project
135
136config MACH_OTOM
137 bool "NexVision OTOM Board"
138 select CPU_S3C2410
139 help
140 Say Y here if you are using the Nex Vision OTOM board
141
142config MACH_NEXCODER_2440
143 bool "NexVision NEXCODER 2440 Light Board"
144 select CPU_S3C2440
145 help
146 Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board
147
148config MACH_VSTMS
149 bool "VMSTMS"
150 select CPU_S3C2412
151 help 109 help
152 Say Y here if you are using an VSTMS board 110 Say Y here if you are using the Armzone QT2410
153 111
154endmenu 112endmenu
155 113
156config S3C2410_CLOCK
157 bool
158 help
159 Clock code for the S3C2410, and similar processors
160
161config S3C2410_PM
162 bool
163 help
164 Power Management code common to S3C2410 and better
165
166config CPU_S3C2410_DMA
167 bool
168 depends on S3C2410_DMA && (CPU_S3C2410 || CPU_S3C2442)
169 default y if CPU_S3C2410 || CPU_S3C2442
170 help
171 DMA device selection for S3C2410 and compatible CPUs
172
173config CPU_S3C2410
174 bool
175 depends on ARCH_S3C2410
176 select S3C2410_CLOCK
177 select S3C2410_PM if PM
178 help
179 Support for S3C2410 and S3C2410A family from the S3C24XX line
180 of Samsung Mobile CPUs.
181
182# internal node to signify if we are only dealing with an S3C2412
183
184config CPU_S3C2412_ONLY
185 bool
186 depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \
187 !CPU_S3C2440 && !CPU_S3C2442 && CPU_S3C2412
188 default y if CPU_S3C2412
189
190config S3C2412_PM
191 bool
192 help
193 Internal config node to apply S3C2412 power management
194
195config CPU_S3C2412
196 bool
197 depends on ARCH_S3C2410
198 select S3C2412_PM if PM
199 help
200 Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
201
202config CPU_S3C244X
203 bool
204 depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442)
205 help
206 Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems.
207
208config CPU_S3C2440
209 bool
210 depends on ARCH_S3C2410
211 select S3C2410_CLOCK
212 select S3C2410_PM if PM
213 select CPU_S3C244X
214 help
215 Support for S3C2440 Samsung Mobile CPU based systems.
216
217config CPU_S3C2442
218 bool
219 depends on ARCH_S3C2420
220 select S3C2410_CLOCK
221 select S3C2410_PM if PM
222 select CPU_S3C244X
223 help
224 Support for S3C2442 Samsung Mobile CPU based systems.
225
226comment "S3C2410 Boot"
227
228config S3C2410_BOOT_WATCHDOG
229 bool "S3C2410 Initialisation watchdog"
230 depends on ARCH_S3C2410 && S3C2410_WATCHDOG
231 help
232 Say y to enable the watchdog during the kernel decompression
233 stage. If the kernel fails to uncompress, then the watchdog
234 will trigger a reset and the system should restart.
235
236 Although this uses the same hardware unit as the kernel watchdog
237 driver, it is not a replacement for it. If you use this option,
238 you will have to use the watchdg driver to either stop the timeout
239 or restart it. If you do not, then your kernel will reboot after
240 startup.
241
242 The driver uses a fixed timeout value, so the exact time till the
243 system resets depends on the value of PCLK. The timeout on an
244 200MHz s3c2410 should be about 30 seconds.
245
246config S3C2410_BOOT_ERROR_RESET
247 bool "S3C2410 Reboot on decompression error"
248 depends on ARCH_S3C2410
249 help
250 Say y here to use the watchdog to reset the system if the
251 kernel decompressor detects an error during decompression.
252
253
254comment "S3C2410 Setup"
255
256config S3C2410_DMA
257 bool "S3C2410 DMA support"
258 depends on ARCH_S3C2410
259 help
260 S3C2410 DMA support. This is needed for drivers like sound which
261 use the S3C2410's DMA system to move data to and from the
262 peripheral blocks.
263
264config S3C2410_DMA_DEBUG
265 bool "S3C2410 DMA support debug"
266 depends on ARCH_S3C2410 && S3C2410_DMA
267 help
268 Enable debugging output for the DMA code. This option sends info
269 to the kernel log, at priority KERN_DEBUG.
270
271 Note, it is easy to create and fill the log buffer in a small
272 amount of time, as well as using an significant percentage of
273 the CPU time doing so.
274
275
276config S3C2410_PM_DEBUG
277 bool "S3C2410 PM Suspend debug"
278 depends on ARCH_S3C2410 && PM
279 help
280 Say Y here if you want verbose debugging from the PM Suspend and
281 Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
282 for more information.
283
284config S3C2410_PM_CHECK
285 bool "S3C2410 PM Suspend Memory CRC"
286 depends on ARCH_S3C2410 && PM && CRC32
287 help
288 Enable the PM code's memory area checksum over sleep. This option
289 will generate CRCs of all blocks of memory, and store them before
290 going to sleep. The blocks are then checked on resume for any
291 errors.
292
293config S3C2410_PM_CHECK_CHUNKSIZE
294 int "S3C2410 PM Suspend CRC Chunksize (KiB)"
295 depends on ARCH_S3C2410 && PM && S3C2410_PM_CHECK
296 default 64
297 help
298 Set the chunksize in Kilobytes of the CRC for checking memory
299 corruption over suspend and resume. A smaller value will mean that
300 the CRC data block will take more memory, but wil identify any
301 faults with better precision.
302
303config PM_SIMTEC
304 bool
305 help
306 Common power management code for systems that are
307 compatible with the Simtec style of power management
308
309config S3C2410_LOWLEVEL_UART_PORT
310 int "S3C2410 UART to use for low-level messages"
311 default 0
312 help
313 Choice of which UART port to use for the low-level messages,
314 such as the `Uncompressing...` at start time. The value of
315 this configuration should be between zero and two. The port
316 must have been initialised by the boot-loader before use.
317
318 Note, this does not affect the port used by the debug messages,
319 which is a separate configuration.
320
321endif
diff --git a/arch/arm/mach-s3c2410/Makefile b/arch/arm/mach-s3c2410/Makefile
index 27663e28cc88..9a3d3d24c084 100644
--- a/arch/arm/mach-s3c2410/Makefile
+++ b/arch/arm/mach-s3c2410/Makefile
@@ -1,92 +1,31 @@
1 1# arch/arm/mach-s3c2410/Makefile
2# 2#
3# Makefile for the linux kernel. 3# Copyright 2007 Simtec Electronics
4# 4#
5# Licensed under GPLv2
5 6
6# Object file lists. 7obj-y :=
7 8obj-m :=
8obj-y := cpu.o irq.o time.o gpio.o clock.o devs.o 9obj-n :=
9obj-m := 10obj- :=
10obj-n :=
11obj- :=
12obj-dma-y :=
13obj-dma-n :=
14
15# DMA
16obj-$(CONFIG_S3C2410_DMA) += dma.o
17
18# S3C2400 support files
19obj-$(CONFIG_CPU_S3C2400) += s3c2400-gpio.o
20
21# S3C2410 support files
22 11
23obj-$(CONFIG_CPU_S3C2410) += s3c2410.o 12obj-$(CONFIG_CPU_S3C2410) += s3c2410.o
24obj-$(CONFIG_CPU_S3C2410) += s3c2410-gpio.o 13obj-$(CONFIG_CPU_S3C2410) += irq.o
25obj-$(CONFIG_CPU_S3C2410) += s3c2410-irq.o 14obj-$(CONFIG_CPU_S3C2410_DMA) += dma.o
26 15obj-$(CONFIG_CPU_S3C2410_DMA) += dma.o
27obj-$(CONFIG_S3C2410_PM) += s3c2410-pm.o s3c2410-sleep.o 16obj-$(CONFIG_S3C2410_PM) += pm.o sleep.o
28obj-$(CONFIG_CPU_S3C2410_DMA) += s3c2410-dma.o 17obj-$(CONFIG_S3C2410_GPIO) += gpio.o
29 18obj-$(CONFIG_S3C2410_CLOCK) += clock.o
30# Power Management support
31
32obj-$(CONFIG_PM) += pm.o sleep.o
33obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o
34obj-$(CONFIG_PM_H1940) += pm-h1940.o
35
36# S3C2412 support
37obj-$(CONFIG_CPU_S3C2412) += s3c2412.o
38obj-$(CONFIG_CPU_S3C2412) += s3c2412-irq.o
39obj-$(CONFIG_CPU_S3C2412) += s3c2412-clock.o
40obj-dma-$(CONFIG_CPU_S3C2412) += s3c2412-dma.o
41
42obj-$(CONFIG_S3C2412_PM) += s3c2412-pm.o
43
44#
45# S3C244X support
46
47obj-$(CONFIG_CPU_S3C244X) += s3c244x.o
48obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o
49
50# Clock control
51
52obj-$(CONFIG_S3C2410_CLOCK) += s3c2410-clock.o
53
54# S3C2440 support
55
56obj-$(CONFIG_CPU_S3C2440) += s3c2440.o s3c2440-dsc.o
57obj-$(CONFIG_CPU_S3C2440) += s3c2440-irq.o
58obj-$(CONFIG_CPU_S3C2440) += s3c2440-clock.o
59obj-$(CONFIG_CPU_S3C2440) += s3c2410-gpio.o
60obj-dma-$(CONFIG_CPU_S3C2440) += s3c2440-dma.o
61 19
62# S3C2442 support 20# Machine support
63 21
64obj-$(CONFIG_CPU_S3C2442) += s3c2442.o 22obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o
65obj-$(CONFIG_CPU_S3C2442) += s3c2442-clock.o
66
67# bast extras
68
69obj-$(CONFIG_BAST_PC104_IRQ) += bast-irq.o
70
71# merge in dma objects
72
73obj-y += $(obj-dma-y)
74
75# machine specific support
76
77obj-$(CONFIG_MACH_AML_M5900) += mach-amlm5900.o
78obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o
79obj-$(CONFIG_MACH_OSIRIS) += mach-osiris.o
80obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o
81obj-$(CONFIG_ARCH_H1940) += mach-h1940.o 23obj-$(CONFIG_ARCH_H1940) += mach-h1940.o
24obj-$(CONFIG_PM_H1940) += pm-h1940.o
82obj-$(CONFIG_MACH_N30) += mach-n30.o 25obj-$(CONFIG_MACH_N30) += mach-n30.o
83obj-$(CONFIG_ARCH_SMDK2410) += mach-smdk2410.o 26obj-$(CONFIG_ARCH_BAST) += mach-bast.o usb-simtec.o
84obj-$(CONFIG_MACH_SMDK2413) += mach-smdk2413.o
85obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o
86obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o usb-simtec.o
87obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o
88obj-$(CONFIG_MACH_OTOM) += mach-otom.o 27obj-$(CONFIG_MACH_OTOM) += mach-otom.o
89obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o 28obj-$(CONFIG_MACH_AML_M5900) += mach-amlm5900.o
90obj-$(CONFIG_MACH_VSTMS) += mach-vstms.o 29obj-$(CONFIG_BAST_PC104_IRQ) += bast-irq.o
91 30obj-$(CONFIG_MACH_VR1000) += mach-vr1000.o usb-simtec.o
92obj-$(CONFIG_MACH_SMDK) += common-smdk.o \ No newline at end of file 31obj-$(CONFIG_MACH_QT2410) += mach-qt2410.o
diff --git a/arch/arm/mach-s3c2410/bast-irq.c b/arch/arm/mach-s3c2410/bast-irq.c
index 379efe70778c..daeba427d781 100644
--- a/arch/arm/mach-s3c2410/bast-irq.c
+++ b/arch/arm/mach-s3c2410/bast-irq.c
@@ -39,7 +39,7 @@
39#include <asm/arch/bast-map.h> 39#include <asm/arch/bast-map.h>
40#include <asm/arch/bast-irq.h> 40#include <asm/arch/bast-irq.h>
41 41
42#include "irq.h" 42#include <asm/plat-s3c24xx/irq.h>
43 43
44#if 0 44#if 0
45#include <asm/debug-ll.h> 45#include <asm/debug-ll.h>
diff --git a/arch/arm/mach-s3c2410/bast.h b/arch/arm/mach-s3c2410/bast.h
index e5d03311752c..e98543742eb9 100644
--- a/arch/arm/mach-s3c2410/bast.h
+++ b/arch/arm/mach-s3c2410/bast.h
@@ -1,2 +1,2 @@
1 1/* linux/arch/arm/mach-s3c2410/bast.h
2extern void bast_init_irq(void); 2extern void bast_init_irq(void);
diff --git a/arch/arm/mach-s3c2410/clock.c b/arch/arm/mach-s3c2410/clock.c
index e13fb6778890..5b4831c4c1d8 100644
--- a/arch/arm/mach-s3c2410/clock.c
+++ b/arch/arm/mach-s3c2410/clock.c
@@ -1,15 +1,9 @@
1/* linux/arch/arm/mach-s3c2410/clock.c 1/* linux/arch/arm/mach-s3c2410/clock.c
2 * 2 *
3 * Copyright (c) 2004-2005 Simtec Electronics 3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
5 * 5 *
6 * S3C24XX Core clock control support 6 * S3C2410,S3C2440,S3C2442 Clock control support
7 *
8 * Based on, and code from linux/arch/arm/mach-versatile/clock.c
9 **
10 ** Copyright (C) 2004 ARM Limited.
11 ** Written by Deep Blue Solutions Limited.
12 *
13 * 7 *
14 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by 9 * it under the terms of the GNU General Public License as published by
@@ -32,418 +26,251 @@
32#include <linux/list.h> 26#include <linux/list.h>
33#include <linux/errno.h> 27#include <linux/errno.h>
34#include <linux/err.h> 28#include <linux/err.h>
35#include <linux/platform_device.h>
36#include <linux/sysdev.h> 29#include <linux/sysdev.h>
37#include <linux/interrupt.h>
38#include <linux/ioport.h>
39#include <linux/clk.h> 30#include <linux/clk.h>
40#include <linux/mutex.h> 31#include <linux/mutex.h>
41#include <linux/delay.h> 32#include <linux/delay.h>
33#include <linux/serial_core.h>
34
35#include <asm/mach/map.h>
42 36
43#include <asm/hardware.h> 37#include <asm/hardware.h>
44#include <asm/irq.h>
45#include <asm/io.h> 38#include <asm/io.h>
46 39
40#include <asm/arch/regs-serial.h>
47#include <asm/arch/regs-clock.h> 41#include <asm/arch/regs-clock.h>
48#include <asm/arch/regs-gpio.h> 42#include <asm/arch/regs-gpio.h>
49 43
50#include "clock.h" 44#include <asm/plat-s3c24xx/s3c2410.h>
51#include "cpu.h" 45#include <asm/plat-s3c24xx/clock.h>
52 46#include <asm/plat-s3c24xx/cpu.h>
53/* clock information */
54 47
55static LIST_HEAD(clocks); 48int s3c2410_clkcon_enable(struct clk *clk, int enable)
56
57DEFINE_MUTEX(clocks_mutex);
58
59/* enable and disable calls for use with the clk struct */
60
61static int clk_null_enable(struct clk *clk, int enable)
62{ 49{
63 return 0; 50 unsigned int clocks = clk->ctrlbit;
64} 51 unsigned long clkcon;
65
66/* Clock API calls */
67 52
68struct clk *clk_get(struct device *dev, const char *id) 53 clkcon = __raw_readl(S3C2410_CLKCON);
69{
70 struct clk *p;
71 struct clk *clk = ERR_PTR(-ENOENT);
72 int idno;
73 54
74 if (dev == NULL || dev->bus != &platform_bus_type) 55 if (enable)
75 idno = -1; 56 clkcon |= clocks;
76 else 57 else
77 idno = to_platform_device(dev)->id; 58 clkcon &= ~clocks;
78
79 mutex_lock(&clocks_mutex);
80
81 list_for_each_entry(p, &clocks, list) {
82 if (p->id == idno &&
83 strcmp(id, p->name) == 0 &&
84 try_module_get(p->owner)) {
85 clk = p;
86 break;
87 }
88 }
89
90 /* check for the case where a device was supplied, but the
91 * clock that was being searched for is not device specific */
92
93 if (IS_ERR(clk)) {
94 list_for_each_entry(p, &clocks, list) {
95 if (p->id == -1 && strcmp(id, p->name) == 0 &&
96 try_module_get(p->owner)) {
97 clk = p;
98 break;
99 }
100 }
101 }
102 59
103 mutex_unlock(&clocks_mutex); 60 /* ensure none of the special function bits set */
104 return clk; 61 clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER);
105}
106 62
107void clk_put(struct clk *clk) 63 __raw_writel(clkcon, S3C2410_CLKCON);
108{
109 module_put(clk->owner);
110}
111 64
112int clk_enable(struct clk *clk)
113{
114 if (IS_ERR(clk) || clk == NULL)
115 return -EINVAL;
116
117 clk_enable(clk->parent);
118
119 mutex_lock(&clocks_mutex);
120
121 if ((clk->usage++) == 0)
122 (clk->enable)(clk, 1);
123
124 mutex_unlock(&clocks_mutex);
125 return 0; 65 return 0;
126} 66}
127 67
128void clk_disable(struct clk *clk) 68static int s3c2410_upll_enable(struct clk *clk, int enable)
129{
130 if (IS_ERR(clk) || clk == NULL)
131 return;
132
133 mutex_lock(&clocks_mutex);
134
135 if ((--clk->usage) == 0)
136 (clk->enable)(clk, 0);
137
138 mutex_unlock(&clocks_mutex);
139 clk_disable(clk->parent);
140}
141
142
143unsigned long clk_get_rate(struct clk *clk)
144{
145 if (IS_ERR(clk))
146 return 0;
147
148 if (clk->rate != 0)
149 return clk->rate;
150
151 if (clk->get_rate != NULL)
152 return (clk->get_rate)(clk);
153
154 if (clk->parent != NULL)
155 return clk_get_rate(clk->parent);
156
157 return clk->rate;
158}
159
160long clk_round_rate(struct clk *clk, unsigned long rate)
161{
162 if (!IS_ERR(clk) && clk->round_rate)
163 return (clk->round_rate)(clk, rate);
164
165 return rate;
166}
167
168int clk_set_rate(struct clk *clk, unsigned long rate)
169{
170 int ret;
171
172 if (IS_ERR(clk))
173 return -EINVAL;
174
175 mutex_lock(&clocks_mutex);
176 ret = (clk->set_rate)(clk, rate);
177 mutex_unlock(&clocks_mutex);
178
179 return ret;
180}
181
182struct clk *clk_get_parent(struct clk *clk)
183{ 69{
184 return clk->parent; 70 unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
185} 71 unsigned long orig = clkslow;
186
187int clk_set_parent(struct clk *clk, struct clk *parent)
188{
189 int ret = 0;
190
191 if (IS_ERR(clk))
192 return -EINVAL;
193
194 mutex_lock(&clocks_mutex);
195
196 if (clk->set_parent)
197 ret = (clk->set_parent)(clk, parent);
198
199 mutex_unlock(&clocks_mutex);
200
201 return ret;
202}
203
204EXPORT_SYMBOL(clk_get);
205EXPORT_SYMBOL(clk_put);
206EXPORT_SYMBOL(clk_enable);
207EXPORT_SYMBOL(clk_disable);
208EXPORT_SYMBOL(clk_get_rate);
209EXPORT_SYMBOL(clk_round_rate);
210EXPORT_SYMBOL(clk_set_rate);
211EXPORT_SYMBOL(clk_get_parent);
212EXPORT_SYMBOL(clk_set_parent);
213
214/* base clocks */
215
216struct clk clk_xtal = {
217 .name = "xtal",
218 .id = -1,
219 .rate = 0,
220 .parent = NULL,
221 .ctrlbit = 0,
222};
223
224struct clk clk_mpll = {
225 .name = "mpll",
226 .id = -1,
227};
228
229struct clk clk_upll = {
230 .name = "upll",
231 .id = -1,
232 .parent = NULL,
233 .ctrlbit = 0,
234};
235
236struct clk clk_f = {
237 .name = "fclk",
238 .id = -1,
239 .rate = 0,
240 .parent = &clk_mpll,
241 .ctrlbit = 0,
242};
243
244struct clk clk_h = {
245 .name = "hclk",
246 .id = -1,
247 .rate = 0,
248 .parent = NULL,
249 .ctrlbit = 0,
250};
251
252struct clk clk_p = {
253 .name = "pclk",
254 .id = -1,
255 .rate = 0,
256 .parent = NULL,
257 .ctrlbit = 0,
258};
259
260struct clk clk_usb_bus = {
261 .name = "usb-bus",
262 .id = -1,
263 .rate = 0,
264 .parent = &clk_upll,
265};
266
267/* clocks that could be registered by external code */
268
269static int s3c24xx_dclk_enable(struct clk *clk, int enable)
270{
271 unsigned long dclkcon = __raw_readl(S3C24XX_DCLKCON);
272 72
273 if (enable) 73 if (enable)
274 dclkcon |= clk->ctrlbit; 74 clkslow &= ~S3C2410_CLKSLOW_UCLK_OFF;
275 else 75 else
276 dclkcon &= ~clk->ctrlbit; 76 clkslow |= S3C2410_CLKSLOW_UCLK_OFF;
277 77
278 __raw_writel(dclkcon, S3C24XX_DCLKCON); 78 __raw_writel(clkslow, S3C2410_CLKSLOW);
279 79
280 return 0; 80 /* if we started the UPLL, then allow to settle */
281}
282 81
283static int s3c24xx_dclk_setparent(struct clk *clk, struct clk *parent) 82 if (enable && (orig & S3C2410_CLKSLOW_UCLK_OFF))
284{ 83 udelay(200);
285 unsigned long dclkcon;
286 unsigned int uclk;
287
288 if (parent == &clk_upll)
289 uclk = 1;
290 else if (parent == &clk_p)
291 uclk = 0;
292 else
293 return -EINVAL;
294
295 clk->parent = parent;
296
297 dclkcon = __raw_readl(S3C24XX_DCLKCON);
298
299 if (clk->ctrlbit == S3C2410_DCLKCON_DCLK0EN) {
300 if (uclk)
301 dclkcon |= S3C2410_DCLKCON_DCLK0_UCLK;
302 else
303 dclkcon &= ~S3C2410_DCLKCON_DCLK0_UCLK;
304 } else {
305 if (uclk)
306 dclkcon |= S3C2410_DCLKCON_DCLK1_UCLK;
307 else
308 dclkcon &= ~S3C2410_DCLKCON_DCLK1_UCLK;
309 }
310
311 __raw_writel(dclkcon, S3C24XX_DCLKCON);
312 84
313 return 0; 85 return 0;
314} 86}
315 87
316 88/* standard clock definitions */
317static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent) 89
318{ 90static struct clk init_clocks_disable[] = {
319 unsigned long mask; 91 {
320 unsigned long source; 92 .name = "nand",
321 93 .id = -1,
322 /* calculate the MISCCR setting for the clock */ 94 .parent = &clk_h,
323 95 .enable = s3c2410_clkcon_enable,
324 if (parent == &clk_xtal) 96 .ctrlbit = S3C2410_CLKCON_NAND,
325 source = S3C2410_MISCCR_CLK0_MPLL; 97 }, {
326 else if (parent == &clk_upll) 98 .name = "sdi",
327 source = S3C2410_MISCCR_CLK0_UPLL; 99 .id = -1,
328 else if (parent == &clk_f) 100 .parent = &clk_p,
329 source = S3C2410_MISCCR_CLK0_FCLK; 101 .enable = s3c2410_clkcon_enable,
330 else if (parent == &clk_h) 102 .ctrlbit = S3C2410_CLKCON_SDI,
331 source = S3C2410_MISCCR_CLK0_HCLK; 103 }, {
332 else if (parent == &clk_p) 104 .name = "adc",
333 source = S3C2410_MISCCR_CLK0_PCLK; 105 .id = -1,
334 else if (clk == &s3c24xx_clkout0 && parent == &s3c24xx_dclk0) 106 .parent = &clk_p,
335 source = S3C2410_MISCCR_CLK0_DCLK0; 107 .enable = s3c2410_clkcon_enable,
336 else if (clk == &s3c24xx_clkout1 && parent == &s3c24xx_dclk1) 108 .ctrlbit = S3C2410_CLKCON_ADC,
337 source = S3C2410_MISCCR_CLK0_DCLK0; 109 }, {
338 else 110 .name = "i2c",
339 return -EINVAL; 111 .id = -1,
340 112 .parent = &clk_p,
341 clk->parent = parent; 113 .enable = s3c2410_clkcon_enable,
342 114 .ctrlbit = S3C2410_CLKCON_IIC,
343 if (clk == &s3c24xx_dclk0) 115 }, {
344 mask = S3C2410_MISCCR_CLK0_MASK; 116 .name = "iis",
345 else { 117 .id = -1,
346 source <<= 4; 118 .parent = &clk_p,
347 mask = S3C2410_MISCCR_CLK1_MASK; 119 .enable = s3c2410_clkcon_enable,
120 .ctrlbit = S3C2410_CLKCON_IIS,
121 }, {
122 .name = "spi",
123 .id = -1,
124 .parent = &clk_p,
125 .enable = s3c2410_clkcon_enable,
126 .ctrlbit = S3C2410_CLKCON_SPI,
348 } 127 }
349
350 s3c2410_modify_misccr(mask, source);
351 return 0;
352}
353
354/* external clock definitions */
355
356struct clk s3c24xx_dclk0 = {
357 .name = "dclk0",
358 .id = -1,
359 .ctrlbit = S3C2410_DCLKCON_DCLK0EN,
360 .enable = s3c24xx_dclk_enable,
361 .set_parent = s3c24xx_dclk_setparent,
362};
363
364struct clk s3c24xx_dclk1 = {
365 .name = "dclk1",
366 .id = -1,
367 .ctrlbit = S3C2410_DCLKCON_DCLK0EN,
368 .enable = s3c24xx_dclk_enable,
369 .set_parent = s3c24xx_dclk_setparent,
370}; 128};
371 129
372struct clk s3c24xx_clkout0 = { 130static struct clk init_clocks[] = {
373 .name = "clkout0", 131 {
374 .id = -1, 132 .name = "lcd",
375 .set_parent = s3c24xx_clkout_setparent, 133 .id = -1,
134 .parent = &clk_h,
135 .enable = s3c2410_clkcon_enable,
136 .ctrlbit = S3C2410_CLKCON_LCDC,
137 }, {
138 .name = "gpio",
139 .id = -1,
140 .parent = &clk_p,
141 .enable = s3c2410_clkcon_enable,
142 .ctrlbit = S3C2410_CLKCON_GPIO,
143 }, {
144 .name = "usb-host",
145 .id = -1,
146 .parent = &clk_h,
147 .enable = s3c2410_clkcon_enable,
148 .ctrlbit = S3C2410_CLKCON_USBH,
149 }, {
150 .name = "usb-device",
151 .id = -1,
152 .parent = &clk_h,
153 .enable = s3c2410_clkcon_enable,
154 .ctrlbit = S3C2410_CLKCON_USBD,
155 }, {
156 .name = "timers",
157 .id = -1,
158 .parent = &clk_p,
159 .enable = s3c2410_clkcon_enable,
160 .ctrlbit = S3C2410_CLKCON_PWMT,
161 }, {
162 .name = "uart",
163 .id = 0,
164 .parent = &clk_p,
165 .enable = s3c2410_clkcon_enable,
166 .ctrlbit = S3C2410_CLKCON_UART0,
167 }, {
168 .name = "uart",
169 .id = 1,
170 .parent = &clk_p,
171 .enable = s3c2410_clkcon_enable,
172 .ctrlbit = S3C2410_CLKCON_UART1,
173 }, {
174 .name = "uart",
175 .id = 2,
176 .parent = &clk_p,
177 .enable = s3c2410_clkcon_enable,
178 .ctrlbit = S3C2410_CLKCON_UART2,
179 }, {
180 .name = "rtc",
181 .id = -1,
182 .parent = &clk_p,
183 .enable = s3c2410_clkcon_enable,
184 .ctrlbit = S3C2410_CLKCON_RTC,
185 }, {
186 .name = "watchdog",
187 .id = -1,
188 .parent = &clk_p,
189 .ctrlbit = 0,
190 }, {
191 .name = "usb-bus-host",
192 .id = -1,
193 .parent = &clk_usb_bus,
194 }, {
195 .name = "usb-bus-gadget",
196 .id = -1,
197 .parent = &clk_usb_bus,
198 },
376}; 199};
377 200
378struct clk s3c24xx_clkout1 = { 201/* s3c2410_baseclk_add()
379 .name = "clkout1", 202 *
380 .id = -1, 203 * Add all the clocks used by the s3c2410 or compatible CPUs
381 .set_parent = s3c24xx_clkout_setparent, 204 * such as the S3C2440 and S3C2442.
382}; 205 *
383 206 * We cannot use a system device as we are needed before any
384struct clk s3c24xx_uclk = { 207 * of the init-calls that initialise the devices are actually
385 .name = "uclk", 208 * done.
386 .id = -1, 209*/
387};
388
389/* initialise the clock system */
390
391int s3c24xx_register_clock(struct clk *clk)
392{
393 clk->owner = THIS_MODULE;
394
395 if (clk->enable == NULL)
396 clk->enable = clk_null_enable;
397
398 /* add to the list of available clocks */
399
400 mutex_lock(&clocks_mutex);
401 list_add(&clk->list, &clocks);
402 mutex_unlock(&clocks_mutex);
403
404 return 0;
405}
406
407/* initalise all the clocks */
408 210
409int __init s3c24xx_setup_clocks(unsigned long xtal, 211int __init s3c2410_baseclk_add(void)
410 unsigned long fclk,
411 unsigned long hclk,
412 unsigned long pclk)
413{ 212{
414 printk(KERN_INFO "S3C24XX Clocks, (c) 2004 Simtec Electronics\n"); 213 unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
214 unsigned long clkcon = __raw_readl(S3C2410_CLKCON);
215 struct clk *clkp;
216 struct clk *xtal;
217 int ret;
218 int ptr;
415 219
416 /* initialise the main system clocks */ 220 clk_upll.enable = s3c2410_upll_enable;
417 221
418 clk_xtal.rate = xtal; 222 if (s3c24xx_register_clock(&clk_usb_bus) < 0)
419 clk_upll.rate = s3c2410_get_pll(__raw_readl(S3C2410_UPLLCON), xtal); 223 printk(KERN_ERR "failed to register usb bus clock\n");
420 224
421 clk_mpll.rate = fclk; 225 /* register clocks from clock array */
422 clk_h.rate = hclk;
423 clk_p.rate = pclk;
424 clk_f.rate = fclk;
425 226
426 /* assume uart clocks are correctly setup */ 227 clkp = init_clocks;
228 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
229 /* ensure that we note the clock state */
427 230
428 /* register our clocks */ 231 clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0;
429 232
430 if (s3c24xx_register_clock(&clk_xtal) < 0) 233 ret = s3c24xx_register_clock(clkp);
431 printk(KERN_ERR "failed to register master xtal\n"); 234 if (ret < 0) {
235 printk(KERN_ERR "Failed to register clock %s (%d)\n",
236 clkp->name, ret);
237 }
238 }
432 239
433 if (s3c24xx_register_clock(&clk_mpll) < 0) 240 /* We must be careful disabling the clocks we are not intending to
434 printk(KERN_ERR "failed to register mpll clock\n"); 241 * be using at boot time, as subsytems such as the LCD which do
242 * their own DMA requests to the bus can cause the system to lockup
243 * if they where in the middle of requesting bus access.
244 *
245 * Disabling the LCD clock if the LCD is active is very dangerous,
246 * and therefore the bootloader should be careful to not enable
247 * the LCD clock if it is not needed.
248 */
249
250 /* install (and disable) the clocks we do not need immediately */
251
252 clkp = init_clocks_disable;
253 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
254
255 ret = s3c24xx_register_clock(clkp);
256 if (ret < 0) {
257 printk(KERN_ERR "Failed to register clock %s (%d)\n",
258 clkp->name, ret);
259 }
435 260
436 if (s3c24xx_register_clock(&clk_upll) < 0) 261 s3c2410_clkcon_enable(clkp, 0);
437 printk(KERN_ERR "failed to register upll clock\n"); 262 }
438 263
439 if (s3c24xx_register_clock(&clk_f) < 0) 264 /* show the clock-slow value */
440 printk(KERN_ERR "failed to register cpu fclk\n");
441 265
442 if (s3c24xx_register_clock(&clk_h) < 0) 266 xtal = clk_get(NULL, "xtal");
443 printk(KERN_ERR "failed to register cpu hclk\n");
444 267
445 if (s3c24xx_register_clock(&clk_p) < 0) 268 printk("CLOCK: Slow mode (%ld.%ld MHz), %s, MPLL %s, UPLL %s\n",
446 printk(KERN_ERR "failed to register cpu pclk\n"); 269 print_mhz(clk_get_rate(xtal) /
270 ( 2 * S3C2410_CLKSLOW_GET_SLOWVAL(clkslow))),
271 (clkslow & S3C2410_CLKSLOW_SLOW) ? "slow" : "fast",
272 (clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on",
273 (clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on");
447 274
448 return 0; 275 return 0;
449} 276}
diff --git a/arch/arm/mach-s3c2410/dma.c b/arch/arm/mach-s3c2410/dma.c
index fa860e716b4f..67d1ad363973 100644
--- a/arch/arm/mach-s3c2410/dma.c
+++ b/arch/arm/mach-s3c2410/dma.c
@@ -1,9 +1,9 @@
1/* linux/arch/arm/mach-s3c2410/dma.c 1/* linux/arch/arm/mach-s3c2410/dma.c
2 * 2 *
3 * Copyright (c) 2003-2005,2006 Simtec Electronics 3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
5 * 5 *
6 * S3C2410 DMA core 6 * S3C2410 DMA selection
7 * 7 *
8 * http://armlinux.simtec.co.uk/ 8 * http://armlinux.simtec.co.uk/
9 * 9 *
@@ -12,1430 +12,170 @@
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13*/ 13*/
14 14
15 15#include <linux/kernel.h>
16#ifdef CONFIG_S3C2410_DMA_DEBUG
17#define DEBUG
18#endif
19
20#include <linux/module.h>
21#include <linux/init.h> 16#include <linux/init.h>
22#include <linux/sched.h>
23#include <linux/spinlock.h>
24#include <linux/interrupt.h>
25#include <linux/sysdev.h> 17#include <linux/sysdev.h>
26#include <linux/slab.h> 18#include <linux/serial_core.h>
27#include <linux/errno.h>
28#include <linux/delay.h>
29 19
30#include <asm/system.h>
31#include <asm/irq.h>
32#include <asm/hardware.h>
33#include <asm/io.h>
34#include <asm/dma.h> 20#include <asm/dma.h>
35 21#include <asm/arch/dma.h>
36#include <asm/mach/dma.h> 22
37#include <asm/arch/map.h> 23#include <asm/plat-s3c24xx/cpu.h>
38 24#include <asm/plat-s3c24xx/dma.h>
39#include "dma.h" 25
40 26#include <asm/arch/regs-serial.h>
41/* io map for dma */ 27#include <asm/arch/regs-gpio.h>
42static void __iomem *dma_base; 28#include <asm/arch/regs-ac97.h>
43static struct kmem_cache *dma_kmem; 29#include <asm/arch/regs-mem.h>
44 30#include <asm/arch/regs-lcd.h>
45struct s3c24xx_dma_selection dma_sel; 31#include <asm/arch/regs-sdi.h>
46 32#include <asm/arch/regs-iis.h>
47/* dma channel state information */ 33#include <asm/arch/regs-spi.h>
48struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS]; 34
49 35static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = {
50/* debugging functions */ 36 [DMACH_XD0] = {
51 37 .name = "xdreq0",
52#define BUF_MAGIC (0xcafebabe) 38 .channels[0] = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
53 39 },
54#define dmawarn(fmt...) printk(KERN_DEBUG fmt) 40 [DMACH_XD1] = {
55 41 .name = "xdreq1",
56#define dma_regaddr(chan, reg) ((chan)->regs + (reg)) 42 .channels[1] = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
57 43 },
58#if 1 44 [DMACH_SDI] = {
59#define dma_wrreg(chan, reg, val) writel((val), (chan)->regs + (reg)) 45 .name = "sdi",
60#else 46 .channels[0] = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
61static inline void 47 .channels[2] = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
62dma_wrreg(struct s3c2410_dma_chan *chan, int reg, unsigned long val) 48 .channels[3] = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
63{ 49 .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO,
64 pr_debug("writing %08x to register %08x\n",(unsigned int)val,reg); 50 .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO,
65 writel(val, dma_regaddr(chan, reg)); 51 },
66} 52 [DMACH_SPI0] = {
67#endif 53 .name = "spi0",
68 54 .channels[1] = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
69#define dma_rdreg(chan, reg) readl((chan)->regs + (reg)) 55 .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT,
70 56 .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT,
71/* captured register state for debug */ 57 },
72 58 [DMACH_SPI1] = {
73struct s3c2410_dma_regstate { 59 .name = "spi1",
74 unsigned long dcsrc; 60 .channels[3] = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
75 unsigned long disrc; 61 .hw_addr.to = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
76 unsigned long dstat; 62 .hw_addr.from = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
77 unsigned long dcon; 63 },
78 unsigned long dmsktrig; 64 [DMACH_UART0] = {
65 .name = "uart0",
66 .channels[0] = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
67 .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH,
68 .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH,
69 },
70 [DMACH_UART1] = {
71 .name = "uart1",
72 .channels[1] = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
73 .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH,
74 .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH,
75 },
76 [DMACH_UART2] = {
77 .name = "uart2",
78 .channels[3] = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
79 .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH,
80 .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH,
81 },
82 [DMACH_TIMER] = {
83 .name = "timer",
84 .channels[0] = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
85 .channels[2] = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
86 .channels[3] = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
87 },
88 [DMACH_I2S_IN] = {
89 .name = "i2s-sdi",
90 .channels[1] = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
91 .channels[2] = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
92 .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO,
93 },
94 [DMACH_I2S_OUT] = {
95 .name = "i2s-sdo",
96 .channels[2] = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
97 .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO,
98 },
99 [DMACH_USB_EP1] = {
100 .name = "usb-ep1",
101 .channels[0] = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
102 },
103 [DMACH_USB_EP2] = {
104 .name = "usb-ep2",
105 .channels[1] = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
106 },
107 [DMACH_USB_EP3] = {
108 .name = "usb-ep3",
109 .channels[2] = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
110 },
111 [DMACH_USB_EP4] = {
112 .name = "usb-ep4",
113 .channels[3] =S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
114 },
79}; 115};
80 116
81#ifdef CONFIG_S3C2410_DMA_DEBUG 117static void s3c2410_dma_select(struct s3c2410_dma_chan *chan,
82 118 struct s3c24xx_dma_map *map)
83/* dmadbg_showregs
84 *
85 * simple debug routine to print the current state of the dma registers
86*/
87
88static void
89dmadbg_capture(struct s3c2410_dma_chan *chan, struct s3c2410_dma_regstate *regs)
90{
91 regs->dcsrc = dma_rdreg(chan, S3C2410_DMA_DCSRC);
92 regs->disrc = dma_rdreg(chan, S3C2410_DMA_DISRC);
93 regs->dstat = dma_rdreg(chan, S3C2410_DMA_DSTAT);
94 regs->dcon = dma_rdreg(chan, S3C2410_DMA_DCON);
95 regs->dmsktrig = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
96}
97
98static void
99dmadbg_dumpregs(const char *fname, int line, struct s3c2410_dma_chan *chan,
100 struct s3c2410_dma_regstate *regs)
101{
102 printk(KERN_DEBUG "dma%d: %s:%d: DCSRC=%08lx, DISRC=%08lx, DSTAT=%08lx DMT=%02lx, DCON=%08lx\n",
103 chan->number, fname, line,
104 regs->dcsrc, regs->disrc, regs->dstat, regs->dmsktrig,
105 regs->dcon);
106}
107
108static void
109dmadbg_showchan(const char *fname, int line, struct s3c2410_dma_chan *chan)
110{
111 struct s3c2410_dma_regstate state;
112
113 dmadbg_capture(chan, &state);
114
115 printk(KERN_DEBUG "dma%d: %s:%d: ls=%d, cur=%p, %p %p\n",
116 chan->number, fname, line, chan->load_state,
117 chan->curr, chan->next, chan->end);
118
119 dmadbg_dumpregs(fname, line, chan, &state);
120}
121
122static void
123dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan)
124{
125 struct s3c2410_dma_regstate state;
126
127 dmadbg_capture(chan, &state);
128 dmadbg_dumpregs(fname, line, chan, &state);
129}
130
131#define dbg_showregs(chan) dmadbg_showregs(__FUNCTION__, __LINE__, (chan))
132#define dbg_showchan(chan) dmadbg_showchan(__FUNCTION__, __LINE__, (chan))
133#else
134#define dbg_showregs(chan) do { } while(0)
135#define dbg_showchan(chan) do { } while(0)
136#endif /* CONFIG_S3C2410_DMA_DEBUG */
137
138static struct s3c2410_dma_chan *dma_chan_map[DMACH_MAX];
139
140/* lookup_dma_channel
141 *
142 * change the dma channel number given into a real dma channel id
143*/
144
145static struct s3c2410_dma_chan *lookup_dma_channel(unsigned int channel)
146{
147 if (channel & DMACH_LOW_LEVEL)
148 return &s3c2410_chans[channel & ~DMACH_LOW_LEVEL];
149 else
150 return dma_chan_map[channel];
151}
152
153/* s3c2410_dma_stats_timeout
154 *
155 * Update DMA stats from timeout info
156*/
157
158static void
159s3c2410_dma_stats_timeout(struct s3c2410_dma_stats *stats, int val)
160{ 119{
161 if (stats == NULL) 120 chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
162 return;
163
164 if (val > stats->timeout_longest)
165 stats->timeout_longest = val;
166 if (val < stats->timeout_shortest)
167 stats->timeout_shortest = val;
168
169 stats->timeout_avg += val;
170} 121}
171 122
172/* s3c2410_dma_waitforload 123static struct s3c24xx_dma_selection __initdata s3c2410_dma_sel = {
173 * 124 .select = s3c2410_dma_select,
174 * wait for the DMA engine to load a buffer, and update the state accordingly 125 .dcon_mask = 7 << 24,
175*/ 126 .map = s3c2410_dma_mappings,
176 127 .map_size = ARRAY_SIZE(s3c2410_dma_mappings),
177static int 128};
178s3c2410_dma_waitforload(struct s3c2410_dma_chan *chan, int line)
179{
180 int timeout = chan->load_timeout;
181 int took;
182
183 if (chan->load_state != S3C2410_DMALOAD_1LOADED) {
184 printk(KERN_ERR "dma%d: s3c2410_dma_waitforload() called in loadstate %d from line %d\n", chan->number, chan->load_state, line);
185 return 0;
186 }
187
188 if (chan->stats != NULL)
189 chan->stats->loads++;
190
191 while (--timeout > 0) {
192 if ((dma_rdreg(chan, S3C2410_DMA_DSTAT) << (32-20)) != 0) {
193 took = chan->load_timeout - timeout;
194
195 s3c2410_dma_stats_timeout(chan->stats, took);
196
197 switch (chan->load_state) {
198 case S3C2410_DMALOAD_1LOADED:
199 chan->load_state = S3C2410_DMALOAD_1RUNNING;
200 break;
201
202 default:
203 printk(KERN_ERR "dma%d: unknown load_state in s3c2410_dma_waitforload() %d\n", chan->number, chan->load_state);
204 }
205
206 return 1;
207 }
208 }
209
210 if (chan->stats != NULL) {
211 chan->stats->timeout_failed++;
212 }
213
214 return 0;
215}
216
217
218
219/* s3c2410_dma_loadbuffer
220 *
221 * load a buffer, and update the channel state
222*/
223
224static inline int
225s3c2410_dma_loadbuffer(struct s3c2410_dma_chan *chan,
226 struct s3c2410_dma_buf *buf)
227{
228 unsigned long reload;
229
230 pr_debug("s3c2410_chan_loadbuffer: loading buff %p (0x%08lx,0x%06x)\n",
231 buf, (unsigned long)buf->data, buf->size);
232
233 if (buf == NULL) {
234 dmawarn("buffer is NULL\n");
235 return -EINVAL;
236 }
237
238 /* check the state of the channel before we do anything */
239
240 if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
241 dmawarn("load_state is S3C2410_DMALOAD_1LOADED\n");
242 }
243
244 if (chan->load_state == S3C2410_DMALOAD_1LOADED_1RUNNING) {
245 dmawarn("state is S3C2410_DMALOAD_1LOADED_1RUNNING\n");
246 }
247
248 /* it would seem sensible if we are the last buffer to not bother
249 * with the auto-reload bit, so that the DMA engine will not try
250 * and load another transfer after this one has finished...
251 */
252 if (chan->load_state == S3C2410_DMALOAD_NONE) {
253 pr_debug("load_state is none, checking for noreload (next=%p)\n",
254 buf->next);
255 reload = (buf->next == NULL) ? S3C2410_DCON_NORELOAD : 0;
256 } else {
257 //pr_debug("load_state is %d => autoreload\n", chan->load_state);
258 reload = S3C2410_DCON_AUTORELOAD;
259 }
260
261 if ((buf->data & 0xf0000000) != 0x30000000) {
262 dmawarn("dmaload: buffer is %p\n", (void *)buf->data);
263 }
264
265 writel(buf->data, chan->addr_reg);
266
267 dma_wrreg(chan, S3C2410_DMA_DCON,
268 chan->dcon | reload | (buf->size/chan->xfer_unit));
269
270 chan->next = buf->next;
271
272 /* update the state of the channel */
273
274 switch (chan->load_state) {
275 case S3C2410_DMALOAD_NONE:
276 chan->load_state = S3C2410_DMALOAD_1LOADED;
277 break;
278
279 case S3C2410_DMALOAD_1RUNNING:
280 chan->load_state = S3C2410_DMALOAD_1LOADED_1RUNNING;
281 break;
282
283 default:
284 dmawarn("dmaload: unknown state %d in loadbuffer\n",
285 chan->load_state);
286 break;
287 }
288
289 return 0;
290}
291
292/* s3c2410_dma_call_op
293 *
294 * small routine to call the op routine with the given op if it has been
295 * registered
296*/
297
298static void
299s3c2410_dma_call_op(struct s3c2410_dma_chan *chan, enum s3c2410_chan_op op)
300{
301 if (chan->op_fn != NULL) {
302 (chan->op_fn)(chan, op);
303 }
304}
305
306/* s3c2410_dma_buffdone
307 *
308 * small wrapper to check if callback routine needs to be called, and
309 * if so, call it
310*/
311
312static inline void
313s3c2410_dma_buffdone(struct s3c2410_dma_chan *chan, struct s3c2410_dma_buf *buf,
314 enum s3c2410_dma_buffresult result)
315{
316#if 0
317 pr_debug("callback_fn=%p, buf=%p, id=%p, size=%d, result=%d\n",
318 chan->callback_fn, buf, buf->id, buf->size, result);
319#endif
320
321 if (chan->callback_fn != NULL) {
322 (chan->callback_fn)(chan, buf->id, buf->size, result);
323 }
324}
325
326/* s3c2410_dma_start
327 *
328 * start a dma channel going
329*/
330
331static int s3c2410_dma_start(struct s3c2410_dma_chan *chan)
332{
333 unsigned long tmp;
334 unsigned long flags;
335
336 pr_debug("s3c2410_start_dma: channel=%d\n", chan->number);
337
338 local_irq_save(flags);
339
340 if (chan->state == S3C2410_DMA_RUNNING) {
341 pr_debug("s3c2410_start_dma: already running (%d)\n", chan->state);
342 local_irq_restore(flags);
343 return 0;
344 }
345
346 chan->state = S3C2410_DMA_RUNNING;
347
348 /* check wether there is anything to load, and if not, see
349 * if we can find anything to load
350 */
351
352 if (chan->load_state == S3C2410_DMALOAD_NONE) {
353 if (chan->next == NULL) {
354 printk(KERN_ERR "dma%d: channel has nothing loaded\n",
355 chan->number);
356 chan->state = S3C2410_DMA_IDLE;
357 local_irq_restore(flags);
358 return -EINVAL;
359 }
360
361 s3c2410_dma_loadbuffer(chan, chan->next);
362 }
363
364 dbg_showchan(chan);
365
366 /* enable the channel */
367
368 if (!chan->irq_enabled) {
369 enable_irq(chan->irq);
370 chan->irq_enabled = 1;
371 }
372
373 /* start the channel going */
374
375 tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
376 tmp &= ~S3C2410_DMASKTRIG_STOP;
377 tmp |= S3C2410_DMASKTRIG_ON;
378 dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
379
380 pr_debug("dma%d: %08lx to DMASKTRIG\n", chan->number, tmp);
381
382#if 0
383 /* the dma buffer loads should take care of clearing the AUTO
384 * reloading feature */
385 tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
386 tmp &= ~S3C2410_DCON_NORELOAD;
387 dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
388#endif
389
390 s3c2410_dma_call_op(chan, S3C2410_DMAOP_START);
391
392 dbg_showchan(chan);
393
394 /* if we've only loaded one buffer onto the channel, then chec
395 * to see if we have another, and if so, try and load it so when
396 * the first buffer is finished, the new one will be loaded onto
397 * the channel */
398
399 if (chan->next != NULL) {
400 if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
401
402 if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
403 pr_debug("%s: buff not yet loaded, no more todo\n",
404 __FUNCTION__);
405 } else {
406 chan->load_state = S3C2410_DMALOAD_1RUNNING;
407 s3c2410_dma_loadbuffer(chan, chan->next);
408 }
409
410 } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
411 s3c2410_dma_loadbuffer(chan, chan->next);
412 }
413 }
414
415
416 local_irq_restore(flags);
417
418 return 0;
419}
420
421/* s3c2410_dma_canload
422 *
423 * work out if we can queue another buffer into the DMA engine
424*/
425
426static int
427s3c2410_dma_canload(struct s3c2410_dma_chan *chan)
428{
429 if (chan->load_state == S3C2410_DMALOAD_NONE ||
430 chan->load_state == S3C2410_DMALOAD_1RUNNING)
431 return 1;
432
433 return 0;
434}
435
436/* s3c2410_dma_enqueue
437 *
438 * queue an given buffer for dma transfer.
439 *
440 * id the device driver's id information for this buffer
441 * data the physical address of the buffer data
442 * size the size of the buffer in bytes
443 *
444 * If the channel is not running, then the flag S3C2410_DMAF_AUTOSTART
445 * is checked, and if set, the channel is started. If this flag isn't set,
446 * then an error will be returned.
447 *
448 * It is possible to queue more than one DMA buffer onto a channel at
449 * once, and the code will deal with the re-loading of the next buffer
450 * when necessary.
451*/
452
453int s3c2410_dma_enqueue(unsigned int channel, void *id,
454 dma_addr_t data, int size)
455{
456 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
457 struct s3c2410_dma_buf *buf;
458 unsigned long flags;
459
460 if (chan == NULL)
461 return -EINVAL;
462
463 pr_debug("%s: id=%p, data=%08x, size=%d\n",
464 __FUNCTION__, id, (unsigned int)data, size);
465
466 buf = kmem_cache_alloc(dma_kmem, GFP_ATOMIC);
467 if (buf == NULL) {
468 pr_debug("%s: out of memory (%ld alloc)\n",
469 __FUNCTION__, (long)sizeof(*buf));
470 return -ENOMEM;
471 }
472
473 //pr_debug("%s: new buffer %p\n", __FUNCTION__, buf);
474 //dbg_showchan(chan);
475
476 buf->next = NULL;
477 buf->data = buf->ptr = data;
478 buf->size = size;
479 buf->id = id;
480 buf->magic = BUF_MAGIC;
481
482 local_irq_save(flags);
483
484 if (chan->curr == NULL) {
485 /* we've got nothing loaded... */
486 pr_debug("%s: buffer %p queued onto empty channel\n",
487 __FUNCTION__, buf);
488
489 chan->curr = buf;
490 chan->end = buf;
491 chan->next = NULL;
492 } else {
493 pr_debug("dma%d: %s: buffer %p queued onto non-empty channel\n",
494 chan->number, __FUNCTION__, buf);
495
496 if (chan->end == NULL)
497 pr_debug("dma%d: %s: %p not empty, and chan->end==NULL?\n",
498 chan->number, __FUNCTION__, chan);
499
500 chan->end->next = buf;
501 chan->end = buf;
502 }
503
504 /* if necessary, update the next buffer field */
505 if (chan->next == NULL)
506 chan->next = buf;
507
508 /* check to see if we can load a buffer */
509 if (chan->state == S3C2410_DMA_RUNNING) {
510 if (chan->load_state == S3C2410_DMALOAD_1LOADED && 1) {
511 if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
512 printk(KERN_ERR "dma%d: loadbuffer:"
513 "timeout loading buffer\n",
514 chan->number);
515 dbg_showchan(chan);
516 local_irq_restore(flags);
517 return -EINVAL;
518 }
519 }
520
521 while (s3c2410_dma_canload(chan) && chan->next != NULL) {
522 s3c2410_dma_loadbuffer(chan, chan->next);
523 }
524 } else if (chan->state == S3C2410_DMA_IDLE) {
525 if (chan->flags & S3C2410_DMAF_AUTOSTART) {
526 s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_START);
527 }
528 }
529
530 local_irq_restore(flags);
531 return 0;
532}
533
534EXPORT_SYMBOL(s3c2410_dma_enqueue);
535
536static inline void
537s3c2410_dma_freebuf(struct s3c2410_dma_buf *buf)
538{
539 int magicok = (buf->magic == BUF_MAGIC);
540
541 buf->magic = -1;
542
543 if (magicok) {
544 kmem_cache_free(dma_kmem, buf);
545 } else {
546 printk("s3c2410_dma_freebuf: buff %p with bad magic\n", buf);
547 }
548}
549
550/* s3c2410_dma_lastxfer
551 *
552 * called when the system is out of buffers, to ensure that the channel
553 * is prepared for shutdown.
554*/
555
556static inline void
557s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan)
558{
559#if 0
560 pr_debug("dma%d: s3c2410_dma_lastxfer: load_state %d\n",
561 chan->number, chan->load_state);
562#endif
563
564 switch (chan->load_state) {
565 case S3C2410_DMALOAD_NONE:
566 break;
567
568 case S3C2410_DMALOAD_1LOADED:
569 if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
570 /* flag error? */
571 printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
572 chan->number, __FUNCTION__);
573 return;
574 }
575 break;
576
577 case S3C2410_DMALOAD_1LOADED_1RUNNING:
578 /* I belive in this case we do not have anything to do
579 * until the next buffer comes along, and we turn off the
580 * reload */
581 return;
582
583 default:
584 pr_debug("dma%d: lastxfer: unhandled load_state %d with no next\n",
585 chan->number, chan->load_state);
586 return;
587
588 }
589
590 /* hopefully this'll shut the damned thing up after the transfer... */
591 dma_wrreg(chan, S3C2410_DMA_DCON, chan->dcon | S3C2410_DCON_NORELOAD);
592}
593
594
595#define dmadbg2(x...)
596
597static irqreturn_t
598s3c2410_dma_irq(int irq, void *devpw)
599{
600 struct s3c2410_dma_chan *chan = (struct s3c2410_dma_chan *)devpw;
601 struct s3c2410_dma_buf *buf;
602
603 buf = chan->curr;
604
605 dbg_showchan(chan);
606
607 /* modify the channel state */
608
609 switch (chan->load_state) {
610 case S3C2410_DMALOAD_1RUNNING:
611 /* TODO - if we are running only one buffer, we probably
612 * want to reload here, and then worry about the buffer
613 * callback */
614
615 chan->load_state = S3C2410_DMALOAD_NONE;
616 break;
617
618 case S3C2410_DMALOAD_1LOADED:
619 /* iirc, we should go back to NONE loaded here, we
620 * had a buffer, and it was never verified as being
621 * loaded.
622 */
623
624 chan->load_state = S3C2410_DMALOAD_NONE;
625 break;
626
627 case S3C2410_DMALOAD_1LOADED_1RUNNING:
628 /* we'll worry about checking to see if another buffer is
629 * ready after we've called back the owner. This should
630 * ensure we do not wait around too long for the DMA
631 * engine to start the next transfer
632 */
633
634 chan->load_state = S3C2410_DMALOAD_1LOADED;
635 break;
636
637 case S3C2410_DMALOAD_NONE:
638 printk(KERN_ERR "dma%d: IRQ with no loaded buffer?\n",
639 chan->number);
640 break;
641
642 default:
643 printk(KERN_ERR "dma%d: IRQ in invalid load_state %d\n",
644 chan->number, chan->load_state);
645 break;
646 }
647
648 if (buf != NULL) {
649 /* update the chain to make sure that if we load any more
650 * buffers when we call the callback function, things should
651 * work properly */
652
653 chan->curr = buf->next;
654 buf->next = NULL;
655
656 if (buf->magic != BUF_MAGIC) {
657 printk(KERN_ERR "dma%d: %s: buf %p incorrect magic\n",
658 chan->number, __FUNCTION__, buf);
659 return IRQ_HANDLED;
660 }
661
662 s3c2410_dma_buffdone(chan, buf, S3C2410_RES_OK);
663
664 /* free resouces */
665 s3c2410_dma_freebuf(buf);
666 } else {
667 }
668
669 /* only reload if the channel is still running... our buffer done
670 * routine may have altered the state by requesting the dma channel
671 * to stop or shutdown... */
672
673 /* todo: check that when the channel is shut-down from inside this
674 * function, we cope with unsetting reload, etc */
675
676 if (chan->next != NULL && chan->state != S3C2410_DMA_IDLE) {
677 unsigned long flags;
678
679 switch (chan->load_state) {
680 case S3C2410_DMALOAD_1RUNNING:
681 /* don't need to do anything for this state */
682 break;
683
684 case S3C2410_DMALOAD_NONE:
685 /* can load buffer immediately */
686 break;
687
688 case S3C2410_DMALOAD_1LOADED:
689 if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
690 /* flag error? */
691 printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
692 chan->number, __FUNCTION__);
693 return IRQ_HANDLED;
694 }
695
696 break;
697
698 case S3C2410_DMALOAD_1LOADED_1RUNNING:
699 goto no_load;
700
701 default:
702 printk(KERN_ERR "dma%d: unknown load_state in irq, %d\n",
703 chan->number, chan->load_state);
704 return IRQ_HANDLED;
705 }
706
707 local_irq_save(flags);
708 s3c2410_dma_loadbuffer(chan, chan->next);
709 local_irq_restore(flags);
710 } else {
711 s3c2410_dma_lastxfer(chan);
712
713 /* see if we can stop this channel.. */
714 if (chan->load_state == S3C2410_DMALOAD_NONE) {
715 pr_debug("dma%d: end of transfer, stopping channel (%ld)\n",
716 chan->number, jiffies);
717 s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL,
718 S3C2410_DMAOP_STOP);
719 }
720 }
721
722 no_load:
723 return IRQ_HANDLED;
724}
725
726static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel);
727
728/* s3c2410_request_dma
729 *
730 * get control of an dma channel
731*/
732
733int s3c2410_dma_request(unsigned int channel,
734 struct s3c2410_dma_client *client,
735 void *dev)
736{
737 struct s3c2410_dma_chan *chan;
738 unsigned long flags;
739 int err;
740
741 pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n",
742 channel, client->name, dev);
743
744 local_irq_save(flags);
745
746 chan = s3c2410_dma_map_channel(channel);
747 if (chan == NULL) {
748 local_irq_restore(flags);
749 return -EBUSY;
750 }
751
752 dbg_showchan(chan);
753
754 chan->client = client;
755 chan->in_use = 1;
756
757 if (!chan->irq_claimed) {
758 pr_debug("dma%d: %s : requesting irq %d\n",
759 channel, __FUNCTION__, chan->irq);
760
761 chan->irq_claimed = 1;
762 local_irq_restore(flags);
763
764 err = request_irq(chan->irq, s3c2410_dma_irq, IRQF_DISABLED,
765 client->name, (void *)chan);
766
767 local_irq_save(flags);
768
769 if (err) {
770 chan->in_use = 0;
771 chan->irq_claimed = 0;
772 local_irq_restore(flags);
773
774 printk(KERN_ERR "%s: cannot get IRQ %d for DMA %d\n",
775 client->name, chan->irq, chan->number);
776 return err;
777 }
778
779 chan->irq_enabled = 1;
780 }
781
782 local_irq_restore(flags);
783
784 /* need to setup */
785
786 pr_debug("%s: channel initialised, %p\n", __FUNCTION__, chan);
787
788 return 0;
789}
790
791EXPORT_SYMBOL(s3c2410_dma_request);
792 129
793/* s3c2410_dma_free 130static struct s3c24xx_dma_order __initdata s3c2410_dma_order = {
794 * 131 .channels = {
795 * release the given channel back to the system, will stop and flush 132 [DMACH_SDI] = {
796 * any outstanding transfers, and ensure the channel is ready for the 133 .list = {
797 * next claimant. 134 [0] = 3 | DMA_CH_VALID,
798 * 135 [1] = 2 | DMA_CH_VALID,
799 * Note, although a warning is currently printed if the freeing client 136 [2] = 0 | DMA_CH_VALID,
800 * info is not the same as the registrant's client info, the free is still 137 },
801 * allowed to go through. 138 },
802*/ 139 [DMACH_I2S_IN] = {
140 .list = {
141 [0] = 1 | DMA_CH_VALID,
142 [1] = 2 | DMA_CH_VALID,
143 },
144 },
145 },
146};
803 147
804int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *client) 148static int s3c2410_dma_add(struct sys_device *sysdev)
805{ 149{
806 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel); 150 s3c2410_dma_init();
807 unsigned long flags; 151 s3c24xx_dma_order_set(&s3c2410_dma_order);
808 152 return s3c24xx_dma_init_map(&s3c2410_dma_sel);
809 if (chan == NULL)
810 return -EINVAL;
811
812 local_irq_save(flags);
813
814 if (chan->client != client) {
815 printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n",
816 channel, chan->client, client);
817 }
818
819 /* sort out stopping and freeing the channel */
820
821 if (chan->state != S3C2410_DMA_IDLE) {
822 pr_debug("%s: need to stop dma channel %p\n",
823 __FUNCTION__, chan);
824
825 /* possibly flush the channel */
826 s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STOP);
827 }
828
829 chan->client = NULL;
830 chan->in_use = 0;
831
832 if (chan->irq_claimed)
833 free_irq(chan->irq, (void *)chan);
834
835 chan->irq_claimed = 0;
836
837 if (!(channel & DMACH_LOW_LEVEL))
838 dma_chan_map[channel] = NULL;
839
840 local_irq_restore(flags);
841
842 return 0;
843} 153}
844 154
845EXPORT_SYMBOL(s3c2410_dma_free); 155#if defined(CONFIG_CPU_S3C2410)
846 156static struct sysdev_driver s3c2410_dma_driver = {
847static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan) 157 .add = s3c2410_dma_add,
848{ 158};
849 unsigned long flags;
850 unsigned long tmp;
851
852 pr_debug("%s:\n", __FUNCTION__);
853
854 dbg_showchan(chan);
855
856 local_irq_save(flags);
857
858 s3c2410_dma_call_op(chan, S3C2410_DMAOP_STOP);
859
860 tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
861 tmp |= S3C2410_DMASKTRIG_STOP;
862 //tmp &= ~S3C2410_DMASKTRIG_ON;
863 dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
864
865#if 0
866 /* should also clear interrupts, according to WinCE BSP */
867 tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
868 tmp |= S3C2410_DCON_NORELOAD;
869 dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
870#endif
871
872 /* should stop do this, or should we wait for flush? */
873 chan->state = S3C2410_DMA_IDLE;
874 chan->load_state = S3C2410_DMALOAD_NONE;
875
876 local_irq_restore(flags);
877
878 return 0;
879}
880 159
881void s3c2410_dma_waitforstop(struct s3c2410_dma_chan *chan) 160static int __init s3c2410_dma_drvinit(void)
882{ 161{
883 unsigned long tmp; 162 return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_dma_driver);
884 unsigned int timeout = 0x10000;
885
886 while (timeout-- > 0) {
887 tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
888
889 if (!(tmp & S3C2410_DMASKTRIG_ON))
890 return;
891 }
892
893 pr_debug("dma%d: failed to stop?\n", chan->number);
894} 163}
895 164
896 165arch_initcall(s3c2410_dma_drvinit);
897/* s3c2410_dma_flush
898 *
899 * stop the channel, and remove all current and pending transfers
900*/
901
902static int s3c2410_dma_flush(struct s3c2410_dma_chan *chan)
903{
904 struct s3c2410_dma_buf *buf, *next;
905 unsigned long flags;
906
907 pr_debug("%s: chan %p (%d)\n", __FUNCTION__, chan, chan->number);
908
909 dbg_showchan(chan);
910
911 local_irq_save(flags);
912
913 if (chan->state != S3C2410_DMA_IDLE) {
914 pr_debug("%s: stopping channel...\n", __FUNCTION__ );
915 s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_STOP);
916 }
917
918 buf = chan->curr;
919 if (buf == NULL)
920 buf = chan->next;
921
922 chan->curr = chan->next = chan->end = NULL;
923
924 if (buf != NULL) {
925 for ( ; buf != NULL; buf = next) {
926 next = buf->next;
927
928 pr_debug("%s: free buffer %p, next %p\n",
929 __FUNCTION__, buf, buf->next);
930
931 s3c2410_dma_buffdone(chan, buf, S3C2410_RES_ABORT);
932 s3c2410_dma_freebuf(buf);
933 }
934 }
935
936 dbg_showregs(chan);
937
938 s3c2410_dma_waitforstop(chan);
939
940#if 0
941 /* should also clear interrupts, according to WinCE BSP */
942 {
943 unsigned long tmp;
944
945 tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
946 tmp |= S3C2410_DCON_NORELOAD;
947 dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
948 }
949#endif 166#endif
950 167
951 dbg_showregs(chan); 168#if defined(CONFIG_CPU_S3C2442)
952 169/* S3C2442 DMA contains the same selection table as the S3C2410 */
953 local_irq_restore(flags); 170static struct sysdev_driver s3c2442_dma_driver = {
954 171 .add = s3c2410_dma_add,
955 return 0;
956}
957
958int
959s3c2410_dma_started(struct s3c2410_dma_chan *chan)
960{
961 unsigned long flags;
962
963 local_irq_save(flags);
964
965 dbg_showchan(chan);
966
967 /* if we've only loaded one buffer onto the channel, then chec
968 * to see if we have another, and if so, try and load it so when
969 * the first buffer is finished, the new one will be loaded onto
970 * the channel */
971
972 if (chan->next != NULL) {
973 if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
974
975 if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
976 pr_debug("%s: buff not yet loaded, no more todo\n",
977 __FUNCTION__);
978 } else {
979 chan->load_state = S3C2410_DMALOAD_1RUNNING;
980 s3c2410_dma_loadbuffer(chan, chan->next);
981 }
982
983 } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
984 s3c2410_dma_loadbuffer(chan, chan->next);
985 }
986 }
987
988
989 local_irq_restore(flags);
990
991 return 0;
992
993}
994
995int
996s3c2410_dma_ctrl(dmach_t channel, enum s3c2410_chan_op op)
997{
998 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
999
1000 if (chan == NULL)
1001 return -EINVAL;
1002
1003 switch (op) {
1004 case S3C2410_DMAOP_START:
1005 return s3c2410_dma_start(chan);
1006
1007 case S3C2410_DMAOP_STOP:
1008 return s3c2410_dma_dostop(chan);
1009
1010 case S3C2410_DMAOP_PAUSE:
1011 case S3C2410_DMAOP_RESUME:
1012 return -ENOENT;
1013
1014 case S3C2410_DMAOP_FLUSH:
1015 return s3c2410_dma_flush(chan);
1016
1017 case S3C2410_DMAOP_STARTED:
1018 return s3c2410_dma_started(chan);
1019
1020 case S3C2410_DMAOP_TIMEOUT:
1021 return 0;
1022
1023 }
1024
1025 return -ENOENT; /* unknown, don't bother */
1026}
1027
1028EXPORT_SYMBOL(s3c2410_dma_ctrl);
1029
1030/* DMA configuration for each channel
1031 *
1032 * DISRCC -> source of the DMA (AHB,APB)
1033 * DISRC -> source address of the DMA
1034 * DIDSTC -> destination of the DMA (AHB,APD)
1035 * DIDST -> destination address of the DMA
1036*/
1037
1038/* s3c2410_dma_config
1039 *
1040 * xfersize: size of unit in bytes (1,2,4)
1041 * dcon: base value of the DCONx register
1042*/
1043
1044int s3c2410_dma_config(dmach_t channel,
1045 int xferunit,
1046 int dcon)
1047{
1048 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
1049
1050 pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n",
1051 __FUNCTION__, channel, xferunit, dcon);
1052
1053 if (chan == NULL)
1054 return -EINVAL;
1055
1056 pr_debug("%s: Initial dcon is %08x\n", __FUNCTION__, dcon);
1057
1058 dcon |= chan->dcon & dma_sel.dcon_mask;
1059
1060 pr_debug("%s: New dcon is %08x\n", __FUNCTION__, dcon);
1061
1062 switch (xferunit) {
1063 case 1:
1064 dcon |= S3C2410_DCON_BYTE;
1065 break;
1066
1067 case 2:
1068 dcon |= S3C2410_DCON_HALFWORD;
1069 break;
1070
1071 case 4:
1072 dcon |= S3C2410_DCON_WORD;
1073 break;
1074
1075 default:
1076 pr_debug("%s: bad transfer size %d\n", __FUNCTION__, xferunit);
1077 return -EINVAL;
1078 }
1079
1080 dcon |= S3C2410_DCON_HWTRIG;
1081 dcon |= S3C2410_DCON_INTREQ;
1082
1083 pr_debug("%s: dcon now %08x\n", __FUNCTION__, dcon);
1084
1085 chan->dcon = dcon;
1086 chan->xfer_unit = xferunit;
1087
1088 return 0;
1089}
1090
1091EXPORT_SYMBOL(s3c2410_dma_config);
1092
1093int s3c2410_dma_setflags(dmach_t channel, unsigned int flags)
1094{
1095 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
1096
1097 if (chan == NULL)
1098 return -EINVAL;
1099
1100 pr_debug("%s: chan=%p, flags=%08x\n", __FUNCTION__, chan, flags);
1101
1102 chan->flags = flags;
1103
1104 return 0;
1105}
1106
1107EXPORT_SYMBOL(s3c2410_dma_setflags);
1108
1109
1110/* do we need to protect the settings of the fields from
1111 * irq?
1112*/
1113
1114int s3c2410_dma_set_opfn(dmach_t channel, s3c2410_dma_opfn_t rtn)
1115{
1116 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
1117
1118 if (chan == NULL)
1119 return -EINVAL;
1120
1121 pr_debug("%s: chan=%p, op rtn=%p\n", __FUNCTION__, chan, rtn);
1122
1123 chan->op_fn = rtn;
1124
1125 return 0;
1126}
1127
1128EXPORT_SYMBOL(s3c2410_dma_set_opfn);
1129
1130int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn)
1131{
1132 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
1133
1134 if (chan == NULL)
1135 return -EINVAL;
1136
1137 pr_debug("%s: chan=%p, callback rtn=%p\n", __FUNCTION__, chan, rtn);
1138
1139 chan->callback_fn = rtn;
1140
1141 return 0;
1142}
1143
1144EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
1145
1146/* s3c2410_dma_devconfig
1147 *
1148 * configure the dma source/destination hardware type and address
1149 *
1150 * source: S3C2410_DMASRC_HW: source is hardware
1151 * S3C2410_DMASRC_MEM: source is memory
1152 *
1153 * hwcfg: the value for xxxSTCn register,
1154 * bit 0: 0=increment pointer, 1=leave pointer
1155 * bit 1: 0=soucre is AHB, 1=soucre is APB
1156 *
1157 * devaddr: physical address of the source
1158*/
1159
1160int s3c2410_dma_devconfig(int channel,
1161 enum s3c2410_dmasrc source,
1162 int hwcfg,
1163 unsigned long devaddr)
1164{
1165 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
1166
1167 if (chan == NULL)
1168 return -EINVAL;
1169
1170 pr_debug("%s: source=%d, hwcfg=%08x, devaddr=%08lx\n",
1171 __FUNCTION__, (int)source, hwcfg, devaddr);
1172
1173 chan->source = source;
1174 chan->dev_addr = devaddr;
1175
1176 switch (source) {
1177 case S3C2410_DMASRC_HW:
1178 /* source is hardware */
1179 pr_debug("%s: hw source, devaddr=%08lx, hwcfg=%d\n",
1180 __FUNCTION__, devaddr, hwcfg);
1181 dma_wrreg(chan, S3C2410_DMA_DISRCC, hwcfg & 3);
1182 dma_wrreg(chan, S3C2410_DMA_DISRC, devaddr);
1183 dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0));
1184
1185 chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST);
1186 return 0;
1187
1188 case S3C2410_DMASRC_MEM:
1189 /* source is memory */
1190 pr_debug( "%s: mem source, devaddr=%08lx, hwcfg=%d\n",
1191 __FUNCTION__, devaddr, hwcfg);
1192 dma_wrreg(chan, S3C2410_DMA_DISRCC, (0<<1) | (0<<0));
1193 dma_wrreg(chan, S3C2410_DMA_DIDST, devaddr);
1194 dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3);
1195
1196 chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DISRC);
1197 return 0;
1198 }
1199
1200 printk(KERN_ERR "dma%d: invalid source type (%d)\n", channel, source);
1201 return -EINVAL;
1202}
1203
1204EXPORT_SYMBOL(s3c2410_dma_devconfig);
1205
1206/* s3c2410_dma_getposition
1207 *
1208 * returns the current transfer points for the dma source and destination
1209*/
1210
1211int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst)
1212{
1213 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
1214
1215 if (chan == NULL)
1216 return -EINVAL;
1217
1218 if (src != NULL)
1219 *src = dma_rdreg(chan, S3C2410_DMA_DCSRC);
1220
1221 if (dst != NULL)
1222 *dst = dma_rdreg(chan, S3C2410_DMA_DCDST);
1223
1224 return 0;
1225}
1226
1227EXPORT_SYMBOL(s3c2410_dma_getposition);
1228
1229
1230/* system device class */
1231
1232#ifdef CONFIG_PM
1233
1234static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state)
1235{
1236 struct s3c2410_dma_chan *cp = container_of(dev, struct s3c2410_dma_chan, dev);
1237
1238 printk(KERN_DEBUG "suspending dma channel %d\n", cp->number);
1239
1240 if (dma_rdreg(cp, S3C2410_DMA_DMASKTRIG) & S3C2410_DMASKTRIG_ON) {
1241 /* the dma channel is still working, which is probably
1242 * a bad thing to do over suspend/resume. We stop the
1243 * channel and assume that the client is either going to
1244 * retry after resume, or that it is broken.
1245 */
1246
1247 printk(KERN_INFO "dma: stopping channel %d due to suspend\n",
1248 cp->number);
1249
1250 s3c2410_dma_dostop(cp);
1251 }
1252
1253 return 0;
1254}
1255
1256static int s3c2410_dma_resume(struct sys_device *dev)
1257{
1258 return 0;
1259}
1260
1261#else
1262#define s3c2410_dma_suspend NULL
1263#define s3c2410_dma_resume NULL
1264#endif /* CONFIG_PM */
1265
1266struct sysdev_class dma_sysclass = {
1267 set_kset_name("s3c24xx-dma"),
1268 .suspend = s3c2410_dma_suspend,
1269 .resume = s3c2410_dma_resume,
1270}; 172};
1271 173
1272/* kmem cache implementation */ 174static int __init s3c2442_dma_drvinit(void)
1273
1274static void s3c2410_dma_cache_ctor(void *p, struct kmem_cache *c, unsigned long f)
1275{
1276 memset(p, 0, sizeof(struct s3c2410_dma_buf));
1277}
1278
1279/* initialisation code */
1280
1281static int __init s3c2410_init_dma(void)
1282{
1283 struct s3c2410_dma_chan *cp;
1284 int channel;
1285 int ret;
1286
1287 printk("S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics\n");
1288
1289 dma_base = ioremap(S3C24XX_PA_DMA, 0x200);
1290 if (dma_base == NULL) {
1291 printk(KERN_ERR "dma failed to remap register block\n");
1292 return -ENOMEM;
1293 }
1294
1295 printk("Registering sysclass\n");
1296
1297 ret = sysdev_class_register(&dma_sysclass);
1298 if (ret != 0) {
1299 printk(KERN_ERR "dma sysclass registration failed\n");
1300 goto err;
1301 }
1302
1303 dma_kmem = kmem_cache_create("dma_desc", sizeof(struct s3c2410_dma_buf), 0,
1304 SLAB_HWCACHE_ALIGN,
1305 s3c2410_dma_cache_ctor, NULL);
1306
1307 if (dma_kmem == NULL) {
1308 printk(KERN_ERR "dma failed to make kmem cache\n");
1309 ret = -ENOMEM;
1310 goto err;
1311 }
1312
1313 for (channel = 0; channel < S3C2410_DMA_CHANNELS; channel++) {
1314 cp = &s3c2410_chans[channel];
1315
1316 memset(cp, 0, sizeof(struct s3c2410_dma_chan));
1317
1318 /* dma channel irqs are in order.. */
1319 cp->number = channel;
1320 cp->irq = channel + IRQ_DMA0;
1321 cp->regs = dma_base + (channel*0x40);
1322
1323 /* point current stats somewhere */
1324 cp->stats = &cp->stats_store;
1325 cp->stats_store.timeout_shortest = LONG_MAX;
1326
1327 /* basic channel configuration */
1328
1329 cp->load_timeout = 1<<18;
1330
1331 /* register system device */
1332
1333 cp->dev.cls = &dma_sysclass;
1334 cp->dev.id = channel;
1335 ret = sysdev_register(&cp->dev);
1336
1337 printk("DMA channel %d at %p, irq %d\n",
1338 cp->number, cp->regs, cp->irq);
1339 }
1340
1341 return 0;
1342
1343 err:
1344 kmem_cache_destroy(dma_kmem);
1345 iounmap(dma_base);
1346 dma_base = NULL;
1347 return ret;
1348}
1349
1350core_initcall(s3c2410_init_dma);
1351
1352static inline int is_channel_valid(unsigned int channel)
1353{ 175{
1354 return (channel & DMA_CH_VALID); 176 return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_dma_driver);
1355} 177}
1356 178
1357/* s3c2410_dma_map_channel() 179arch_initcall(s3c2442_dma_drvinit);
1358 * 180#endif
1359 * turn the virtual channel number into a real, and un-used hardware
1360 * channel.
1361 *
1362 * currently this code uses first-free channel from the specified harware
1363 * map, not taking into account anything that the board setup code may
1364 * have to say about the likely peripheral set to be in use.
1365*/
1366
1367struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)
1368{
1369 struct s3c24xx_dma_map *ch_map;
1370 struct s3c2410_dma_chan *dmach;
1371 int ch;
1372
1373 if (dma_sel.map == NULL || channel > dma_sel.map_size)
1374 return NULL;
1375
1376 ch_map = dma_sel.map + channel;
1377
1378 for (ch = 0; ch < S3C2410_DMA_CHANNELS; ch++) {
1379 if (!is_channel_valid(ch_map->channels[ch]))
1380 continue;
1381
1382 if (s3c2410_chans[ch].in_use == 0) {
1383 printk("mapped channel %d to %d\n", channel, ch);
1384 break;
1385 }
1386 }
1387
1388 if (ch >= S3C2410_DMA_CHANNELS)
1389 return NULL;
1390
1391 /* update our channel mapping */
1392
1393 dmach = &s3c2410_chans[ch];
1394 dma_chan_map[channel] = dmach;
1395
1396 /* select the channel */
1397
1398 (dma_sel.select)(dmach, ch_map);
1399
1400 return dmach;
1401}
1402
1403static void s3c24xx_dma_show_ch(struct s3c24xx_dma_map *map, int ch)
1404{
1405 /* show the channel configuration */
1406
1407 printk("%2d: %20s, channels %c%c%c%c\n", ch, map->name,
1408 (is_channel_valid(map->channels[0]) ? '0' : '-'),
1409 (is_channel_valid(map->channels[1]) ? '1' : '-'),
1410 (is_channel_valid(map->channels[2]) ? '2' : '-'),
1411 (is_channel_valid(map->channels[3]) ? '3' : '-'));
1412}
1413
1414static int s3c24xx_dma_check_entry(struct s3c24xx_dma_map *map, int ch)
1415{
1416 if (1)
1417 s3c24xx_dma_show_ch(map, ch);
1418
1419 return 0;
1420}
1421
1422int __init s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel)
1423{
1424 struct s3c24xx_dma_map *nmap;
1425 size_t map_sz = sizeof(*nmap) * sel->map_size;
1426 int ptr;
1427
1428 nmap = kmalloc(map_sz, GFP_KERNEL);
1429 if (nmap == NULL)
1430 return -ENOMEM;
1431
1432 memcpy(nmap, sel->map, map_sz);
1433 memcpy(&dma_sel, sel, sizeof(*sel));
1434
1435 dma_sel.map = nmap;
1436
1437 for (ptr = 0; ptr < sel->map_size; ptr++)
1438 s3c24xx_dma_check_entry(nmap+ptr, ptr);
1439 181
1440 return 0;
1441}
diff --git a/arch/arm/mach-s3c2410/gpio.c b/arch/arm/mach-s3c2410/gpio.c
index f6fb215bb48c..01e795d1146e 100644
--- a/arch/arm/mach-s3c2410/gpio.c
+++ b/arch/arm/mach-s3c2410/gpio.c
@@ -1,9 +1,9 @@
1/* linux/arch/arm/mach-s3c2410/gpio.c 1/* linux/arch/arm/mach-s3c2410/gpio.c
2 * 2 *
3 * Copyright (c) 2004-2005 Simtec Electronics 3 * Copyright (c) 2004-2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
5 * 5 *
6 * S3C24XX GPIO support 6 * S3C2410 GPIO support
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 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 9 * it under the terms of the GNU General Public License as published by
@@ -18,8 +18,7 @@
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 program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21*/ 21 */
22
23 22
24#include <linux/kernel.h> 23#include <linux/kernel.h>
25#include <linux/init.h> 24#include <linux/init.h>
@@ -33,156 +32,40 @@
33 32
34#include <asm/arch/regs-gpio.h> 33#include <asm/arch/regs-gpio.h>
35 34
36void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function) 35int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
37{ 36 unsigned int config)
38 void __iomem *base = S3C24XX_GPIO_BASE(pin);
39 unsigned long mask;
40 unsigned long con;
41 unsigned long flags;
42
43 if (pin < S3C2410_GPIO_BANKB) {
44 mask = 1 << S3C2410_GPIO_OFFSET(pin);
45 } else {
46 mask = 3 << S3C2410_GPIO_OFFSET(pin)*2;
47 }
48
49 switch (function) {
50 case S3C2410_GPIO_LEAVE:
51 mask = 0;
52 function = 0;
53 break;
54
55 case S3C2410_GPIO_INPUT:
56 case S3C2410_GPIO_OUTPUT:
57 case S3C2410_GPIO_SFN2:
58 case S3C2410_GPIO_SFN3:
59 if (pin < S3C2410_GPIO_BANKB) {
60 function -= 1;
61 function &= 1;
62 function <<= S3C2410_GPIO_OFFSET(pin);
63 } else {
64 function &= 3;
65 function <<= S3C2410_GPIO_OFFSET(pin)*2;
66 }
67 }
68
69 /* modify the specified register wwith IRQs off */
70
71 local_irq_save(flags);
72
73 con = __raw_readl(base + 0x00);
74 con &= ~mask;
75 con |= function;
76
77 __raw_writel(con, base + 0x00);
78
79 local_irq_restore(flags);
80}
81
82EXPORT_SYMBOL(s3c2410_gpio_cfgpin);
83
84unsigned int s3c2410_gpio_getcfg(unsigned int pin)
85{
86 void __iomem *base = S3C24XX_GPIO_BASE(pin);
87 unsigned long val = __raw_readl(base);
88
89 if (pin < S3C2410_GPIO_BANKB) {
90 val >>= S3C2410_GPIO_OFFSET(pin);
91 val &= 1;
92 val += 1;
93 } else {
94 val >>= S3C2410_GPIO_OFFSET(pin)*2;
95 val &= 3;
96 }
97
98 return val | S3C2410_GPIO_INPUT;
99}
100
101EXPORT_SYMBOL(s3c2410_gpio_getcfg);
102
103void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
104{ 37{
105 void __iomem *base = S3C24XX_GPIO_BASE(pin); 38 void __iomem *reg = S3C24XX_EINFLT0;
106 unsigned long offs = S3C2410_GPIO_OFFSET(pin);
107 unsigned long flags; 39 unsigned long flags;
108 unsigned long up; 40 unsigned long val;
109
110 if (pin < S3C2410_GPIO_BANKB)
111 return;
112
113 local_irq_save(flags);
114
115 up = __raw_readl(base + 0x08);
116 up &= ~(1L << offs);
117 up |= to << offs;
118 __raw_writel(up, base + 0x08);
119 41
120 local_irq_restore(flags); 42 if (pin < S3C2410_GPG8 || pin > S3C2410_GPG15)
121} 43 return -1;
122 44
123EXPORT_SYMBOL(s3c2410_gpio_pullup); 45 config &= 0xff;
124 46
125void s3c2410_gpio_setpin(unsigned int pin, unsigned int to) 47 pin -= S3C2410_GPG8;
126{ 48 reg += pin & ~3;
127 void __iomem *base = S3C24XX_GPIO_BASE(pin);
128 unsigned long offs = S3C2410_GPIO_OFFSET(pin);
129 unsigned long flags;
130 unsigned long dat;
131 49
132 local_irq_save(flags); 50 local_irq_save(flags);
133 51
134 dat = __raw_readl(base + 0x04); 52 /* update filter width and clock source */
135 dat &= ~(1 << offs);
136 dat |= to << offs;
137 __raw_writel(dat, base + 0x04);
138
139 local_irq_restore(flags);
140}
141
142EXPORT_SYMBOL(s3c2410_gpio_setpin);
143
144unsigned int s3c2410_gpio_getpin(unsigned int pin)
145{
146 void __iomem *base = S3C24XX_GPIO_BASE(pin);
147 unsigned long offs = S3C2410_GPIO_OFFSET(pin);
148 53
149 return __raw_readl(base + 0x04) & (1<< offs); 54 val = __raw_readl(reg);
150} 55 val &= ~(0xff << ((pin & 3) * 8));
56 val |= config << ((pin & 3) * 8);
57 __raw_writel(val, reg);
151 58
152EXPORT_SYMBOL(s3c2410_gpio_getpin); 59 /* update filter enable */
153 60
154unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change) 61 val = __raw_readl(S3C24XX_EXTINT2);
155{ 62 val &= ~(1 << ((pin * 4) + 3));
156 unsigned long flags; 63 val |= on << ((pin * 4) + 3);
157 unsigned long misccr; 64 __raw_writel(val, S3C24XX_EXTINT2);
158 65
159 local_irq_save(flags);
160 misccr = __raw_readl(S3C24XX_MISCCR);
161 misccr &= ~clear;
162 misccr ^= change;
163 __raw_writel(misccr, S3C24XX_MISCCR);
164 local_irq_restore(flags); 66 local_irq_restore(flags);
165 67
166 return misccr; 68 return 0;
167}
168
169EXPORT_SYMBOL(s3c2410_modify_misccr);
170
171int s3c2410_gpio_getirq(unsigned int pin)
172{
173 if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15)
174 return -1; /* not valid interrupts */
175
176 if (pin < S3C2410_GPG0 && pin > S3C2410_GPF7)
177 return -1; /* not valid pin */
178
179 if (pin < S3C2410_GPF4)
180 return (pin - S3C2410_GPF0) + IRQ_EINT0;
181
182 if (pin < S3C2410_GPG0)
183 return (pin - S3C2410_GPF4) + IRQ_EINT4;
184
185 return (pin - S3C2410_GPG0) + IRQ_EINT8;
186} 69}
187 70
188EXPORT_SYMBOL(s3c2410_gpio_getirq); 71EXPORT_SYMBOL(s3c2410_gpio_irqfilter);
diff --git a/arch/arm/mach-s3c2410/irq.c b/arch/arm/mach-s3c2410/irq.c
index 3c0ed7871c55..53cbdaa43ac6 100644
--- a/arch/arm/mach-s3c2410/irq.c
+++ b/arch/arm/mach-s3c2410/irq.c
@@ -1,6 +1,6 @@
1/* linux/arch/arm/mach-s3c2410/irq.c 1/* linux/arch/arm/mach-s3c2410/irq.c
2 * 2 *
3 * Copyright (c) 2003,2004 Simtec Electronics 3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
5 * 5 *
6 * This program is free software; you can redistribute it and/or modify 6 * This program is free software; you can redistribute it and/or modify
@@ -17,37 +17,6 @@
17 * along with this program; if not, write to the Free Software 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 18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 * 19 *
20 * Changelog:
21 *
22 * 22-Jul-2004 Ben Dooks <ben@simtec.co.uk>
23 * Fixed compile warnings
24 *
25 * 22-Jul-2004 Roc Wu <cooloney@yahoo.com.cn>
26 * Fixed s3c_extirq_type
27 *
28 * 21-Jul-2004 Arnaud Patard (Rtp) <arnaud.patard@rtp-net.org>
29 * Addition of ADC/TC demux
30 *
31 * 04-Oct-2004 Klaus Fetscher <k.fetscher@fetron.de>
32 * Fix for set_irq_type() on low EINT numbers
33 *
34 * 05-Oct-2004 Ben Dooks <ben@simtec.co.uk>
35 * Tidy up KF's patch and sort out new release
36 *
37 * 05-Oct-2004 Ben Dooks <ben@simtec.co.uk>
38 * Add support for power management controls
39 *
40 * 04-Nov-2004 Ben Dooks
41 * Fix standard IRQ wake for EINT0..4 and RTC
42 *
43 * 22-Feb-2005 Ben Dooks
44 * Fixed edge-triggering on ADC IRQ
45 *
46 * 28-Jun-2005 Ben Dooks
47 * Mark IRQ_LCD valid
48 *
49 * 25-Jul-2005 Ben Dooks
50 * Split the S3C2440 IRQ code to seperate file
51*/ 20*/
52 21
53#include <linux/init.h> 22#include <linux/init.h>
@@ -57,745 +26,23 @@
57#include <linux/ptrace.h> 26#include <linux/ptrace.h>
58#include <linux/sysdev.h> 27#include <linux/sysdev.h>
59 28
60#include <asm/hardware.h> 29#include <asm/plat-s3c24xx/cpu.h>
61#include <asm/irq.h> 30#include <asm/plat-s3c24xx/pm.h>
62#include <asm/io.h>
63
64#include <asm/mach/irq.h>
65
66#include <asm/arch/regs-irq.h>
67#include <asm/arch/regs-gpio.h>
68
69#include "cpu.h"
70#include "pm.h"
71#include "irq.h"
72
73/* wakeup irq control */
74
75#ifdef CONFIG_PM
76
77/* state for IRQs over sleep */
78
79/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
80 *
81 * set bit to 1 in allow bitfield to enable the wakeup settings on it
82*/
83
84unsigned long s3c_irqwake_intallow = 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
85unsigned long s3c_irqwake_intmask = 0xffffffffL;
86unsigned long s3c_irqwake_eintallow = 0x0000fff0L;
87unsigned long s3c_irqwake_eintmask = 0xffffffffL;
88
89int
90s3c_irq_wake(unsigned int irqno, unsigned int state)
91{
92 unsigned long irqbit = 1 << (irqno - IRQ_EINT0);
93
94 if (!(s3c_irqwake_intallow & irqbit))
95 return -ENOENT;
96
97 printk(KERN_INFO "wake %s for irq %d\n",
98 state ? "enabled" : "disabled", irqno);
99
100 if (!state)
101 s3c_irqwake_intmask |= irqbit;
102 else
103 s3c_irqwake_intmask &= ~irqbit;
104
105 return 0;
106}
107
108static int
109s3c_irqext_wake(unsigned int irqno, unsigned int state)
110{
111 unsigned long bit = 1L << (irqno - EXTINT_OFF);
112
113 if (!(s3c_irqwake_eintallow & bit))
114 return -ENOENT;
115
116 printk(KERN_INFO "wake %s for irq %d\n",
117 state ? "enabled" : "disabled", irqno);
118
119 if (!state)
120 s3c_irqwake_eintmask |= bit;
121 else
122 s3c_irqwake_eintmask &= ~bit;
123
124 return 0;
125}
126
127#else
128#define s3c_irqext_wake NULL
129#define s3c_irq_wake NULL
130#endif
131
132
133static void
134s3c_irq_mask(unsigned int irqno)
135{
136 unsigned long mask;
137
138 irqno -= IRQ_EINT0;
139
140 mask = __raw_readl(S3C2410_INTMSK);
141 mask |= 1UL << irqno;
142 __raw_writel(mask, S3C2410_INTMSK);
143}
144
145static inline void
146s3c_irq_ack(unsigned int irqno)
147{
148 unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
149
150 __raw_writel(bitval, S3C2410_SRCPND);
151 __raw_writel(bitval, S3C2410_INTPND);
152}
153
154static inline void
155s3c_irq_maskack(unsigned int irqno)
156{
157 unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
158 unsigned long mask;
159
160 mask = __raw_readl(S3C2410_INTMSK);
161 __raw_writel(mask|bitval, S3C2410_INTMSK);
162
163 __raw_writel(bitval, S3C2410_SRCPND);
164 __raw_writel(bitval, S3C2410_INTPND);
165}
166
167
168static void
169s3c_irq_unmask(unsigned int irqno)
170{
171 unsigned long mask;
172
173 if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23)
174 irqdbf2("s3c_irq_unmask %d\n", irqno);
175
176 irqno -= IRQ_EINT0;
177
178 mask = __raw_readl(S3C2410_INTMSK);
179 mask &= ~(1UL << irqno);
180 __raw_writel(mask, S3C2410_INTMSK);
181}
182
183struct irq_chip s3c_irq_level_chip = {
184 .name = "s3c-level",
185 .ack = s3c_irq_maskack,
186 .mask = s3c_irq_mask,
187 .unmask = s3c_irq_unmask,
188 .set_wake = s3c_irq_wake
189};
190
191static struct irq_chip s3c_irq_chip = {
192 .name = "s3c",
193 .ack = s3c_irq_ack,
194 .mask = s3c_irq_mask,
195 .unmask = s3c_irq_unmask,
196 .set_wake = s3c_irq_wake
197};
198
199static void
200s3c_irqext_mask(unsigned int irqno)
201{
202 unsigned long mask;
203
204 irqno -= EXTINT_OFF;
205
206 mask = __raw_readl(S3C24XX_EINTMASK);
207 mask |= ( 1UL << irqno);
208 __raw_writel(mask, S3C24XX_EINTMASK);
209}
210
211static void
212s3c_irqext_ack(unsigned int irqno)
213{
214 unsigned long req;
215 unsigned long bit;
216 unsigned long mask;
217 31
218 bit = 1UL << (irqno - EXTINT_OFF); 32static int s3c2410_irq_add(struct sys_device *sysdev)
219
220 mask = __raw_readl(S3C24XX_EINTMASK);
221
222 __raw_writel(bit, S3C24XX_EINTPEND);
223
224 req = __raw_readl(S3C24XX_EINTPEND);
225 req &= ~mask;
226
227 /* not sure if we should be acking the parent irq... */
228
229 if (irqno <= IRQ_EINT7 ) {
230 if ((req & 0xf0) == 0)
231 s3c_irq_ack(IRQ_EINT4t7);
232 } else {
233 if ((req >> 8) == 0)
234 s3c_irq_ack(IRQ_EINT8t23);
235 }
236}
237
238static void
239s3c_irqext_unmask(unsigned int irqno)
240{ 33{
241 unsigned long mask;
242
243 irqno -= EXTINT_OFF;
244
245 mask = __raw_readl(S3C24XX_EINTMASK);
246 mask &= ~( 1UL << irqno);
247 __raw_writel(mask, S3C24XX_EINTMASK);
248}
249
250int
251s3c_irqext_type(unsigned int irq, unsigned int type)
252{
253 void __iomem *extint_reg;
254 void __iomem *gpcon_reg;
255 unsigned long gpcon_offset, extint_offset;
256 unsigned long newvalue = 0, value;
257
258 if ((irq >= IRQ_EINT0) && (irq <= IRQ_EINT3))
259 {
260 gpcon_reg = S3C2410_GPFCON;
261 extint_reg = S3C24XX_EXTINT0;
262 gpcon_offset = (irq - IRQ_EINT0) * 2;
263 extint_offset = (irq - IRQ_EINT0) * 4;
264 }
265 else if ((irq >= IRQ_EINT4) && (irq <= IRQ_EINT7))
266 {
267 gpcon_reg = S3C2410_GPFCON;
268 extint_reg = S3C24XX_EXTINT0;
269 gpcon_offset = (irq - (EXTINT_OFF)) * 2;
270 extint_offset = (irq - (EXTINT_OFF)) * 4;
271 }
272 else if ((irq >= IRQ_EINT8) && (irq <= IRQ_EINT15))
273 {
274 gpcon_reg = S3C2410_GPGCON;
275 extint_reg = S3C24XX_EXTINT1;
276 gpcon_offset = (irq - IRQ_EINT8) * 2;
277 extint_offset = (irq - IRQ_EINT8) * 4;
278 }
279 else if ((irq >= IRQ_EINT16) && (irq <= IRQ_EINT23))
280 {
281 gpcon_reg = S3C2410_GPGCON;
282 extint_reg = S3C24XX_EXTINT2;
283 gpcon_offset = (irq - IRQ_EINT8) * 2;
284 extint_offset = (irq - IRQ_EINT16) * 4;
285 } else
286 return -1;
287
288 /* Set the GPIO to external interrupt mode */
289 value = __raw_readl(gpcon_reg);
290 value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset);
291 __raw_writel(value, gpcon_reg);
292
293 /* Set the external interrupt to pointed trigger type */
294 switch (type)
295 {
296 case IRQT_NOEDGE:
297 printk(KERN_WARNING "No edge setting!\n");
298 break;
299
300 case IRQT_RISING:
301 newvalue = S3C2410_EXTINT_RISEEDGE;
302 break;
303
304 case IRQT_FALLING:
305 newvalue = S3C2410_EXTINT_FALLEDGE;
306 break;
307
308 case IRQT_BOTHEDGE:
309 newvalue = S3C2410_EXTINT_BOTHEDGE;
310 break;
311
312 case IRQT_LOW:
313 newvalue = S3C2410_EXTINT_LOWLEV;
314 break;
315
316 case IRQT_HIGH:
317 newvalue = S3C2410_EXTINT_HILEV;
318 break;
319
320 default:
321 printk(KERN_ERR "No such irq type %d", type);
322 return -1;
323 }
324
325 value = __raw_readl(extint_reg);
326 value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset);
327 __raw_writel(value, extint_reg);
328
329 return 0; 34 return 0;
330} 35}
331 36
332static struct irq_chip s3c_irqext_chip = { 37static struct sysdev_driver s3c2410_irq_driver = {
333 .name = "s3c-ext", 38 .add = s3c2410_irq_add,
334 .mask = s3c_irqext_mask, 39 .suspend = s3c24xx_irq_suspend,
335 .unmask = s3c_irqext_unmask, 40 .resume = s3c24xx_irq_resume,
336 .ack = s3c_irqext_ack,
337 .set_type = s3c_irqext_type,
338 .set_wake = s3c_irqext_wake
339};
340
341static struct irq_chip s3c_irq_eint0t4 = {
342 .name = "s3c-ext0",
343 .ack = s3c_irq_ack,
344 .mask = s3c_irq_mask,
345 .unmask = s3c_irq_unmask,
346 .set_wake = s3c_irq_wake,
347 .set_type = s3c_irqext_type,
348};
349
350/* mask values for the parent registers for each of the interrupt types */
351
352#define INTMSK_UART0 (1UL << (IRQ_UART0 - IRQ_EINT0))
353#define INTMSK_UART1 (1UL << (IRQ_UART1 - IRQ_EINT0))
354#define INTMSK_UART2 (1UL << (IRQ_UART2 - IRQ_EINT0))
355#define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0))
356
357
358/* UART0 */
359
360static void
361s3c_irq_uart0_mask(unsigned int irqno)
362{
363 s3c_irqsub_mask(irqno, INTMSK_UART0, 7);
364}
365
366static void
367s3c_irq_uart0_unmask(unsigned int irqno)
368{
369 s3c_irqsub_unmask(irqno, INTMSK_UART0);
370}
371
372static void
373s3c_irq_uart0_ack(unsigned int irqno)
374{
375 s3c_irqsub_maskack(irqno, INTMSK_UART0, 7);
376}
377
378static struct irq_chip s3c_irq_uart0 = {
379 .name = "s3c-uart0",
380 .mask = s3c_irq_uart0_mask,
381 .unmask = s3c_irq_uart0_unmask,
382 .ack = s3c_irq_uart0_ack,
383};
384
385/* UART1 */
386
387static void
388s3c_irq_uart1_mask(unsigned int irqno)
389{
390 s3c_irqsub_mask(irqno, INTMSK_UART1, 7 << 3);
391}
392
393static void
394s3c_irq_uart1_unmask(unsigned int irqno)
395{
396 s3c_irqsub_unmask(irqno, INTMSK_UART1);
397}
398
399static void
400s3c_irq_uart1_ack(unsigned int irqno)
401{
402 s3c_irqsub_maskack(irqno, INTMSK_UART1, 7 << 3);
403}
404
405static struct irq_chip s3c_irq_uart1 = {
406 .name = "s3c-uart1",
407 .mask = s3c_irq_uart1_mask,
408 .unmask = s3c_irq_uart1_unmask,
409 .ack = s3c_irq_uart1_ack,
410};
411
412/* UART2 */
413
414static void
415s3c_irq_uart2_mask(unsigned int irqno)
416{
417 s3c_irqsub_mask(irqno, INTMSK_UART2, 7 << 6);
418}
419
420static void
421s3c_irq_uart2_unmask(unsigned int irqno)
422{
423 s3c_irqsub_unmask(irqno, INTMSK_UART2);
424}
425
426static void
427s3c_irq_uart2_ack(unsigned int irqno)
428{
429 s3c_irqsub_maskack(irqno, INTMSK_UART2, 7 << 6);
430}
431
432static struct irq_chip s3c_irq_uart2 = {
433 .name = "s3c-uart2",
434 .mask = s3c_irq_uart2_mask,
435 .unmask = s3c_irq_uart2_unmask,
436 .ack = s3c_irq_uart2_ack,
437};
438
439/* ADC and Touchscreen */
440
441static void
442s3c_irq_adc_mask(unsigned int irqno)
443{
444 s3c_irqsub_mask(irqno, INTMSK_ADCPARENT, 3 << 9);
445}
446
447static void
448s3c_irq_adc_unmask(unsigned int irqno)
449{
450 s3c_irqsub_unmask(irqno, INTMSK_ADCPARENT);
451}
452
453static void
454s3c_irq_adc_ack(unsigned int irqno)
455{
456 s3c_irqsub_ack(irqno, INTMSK_ADCPARENT, 3 << 9);
457}
458
459static struct irq_chip s3c_irq_adc = {
460 .name = "s3c-adc",
461 .mask = s3c_irq_adc_mask,
462 .unmask = s3c_irq_adc_unmask,
463 .ack = s3c_irq_adc_ack,
464};
465
466/* irq demux for adc */
467static void s3c_irq_demux_adc(unsigned int irq,
468 struct irq_desc *desc)
469{
470 unsigned int subsrc, submsk;
471 unsigned int offset = 9;
472 struct irq_desc *mydesc;
473
474 /* read the current pending interrupts, and the mask
475 * for what it is available */
476
477 subsrc = __raw_readl(S3C2410_SUBSRCPND);
478 submsk = __raw_readl(S3C2410_INTSUBMSK);
479
480 subsrc &= ~submsk;
481 subsrc >>= offset;
482 subsrc &= 3;
483
484 if (subsrc != 0) {
485 if (subsrc & 1) {
486 mydesc = irq_desc + IRQ_TC;
487 desc_handle_irq(IRQ_TC, mydesc);
488 }
489 if (subsrc & 2) {
490 mydesc = irq_desc + IRQ_ADC;
491 desc_handle_irq(IRQ_ADC, mydesc);
492 }
493 }
494}
495
496static void s3c_irq_demux_uart(unsigned int start)
497{
498 unsigned int subsrc, submsk;
499 unsigned int offset = start - IRQ_S3CUART_RX0;
500 struct irq_desc *desc;
501
502 /* read the current pending interrupts, and the mask
503 * for what it is available */
504
505 subsrc = __raw_readl(S3C2410_SUBSRCPND);
506 submsk = __raw_readl(S3C2410_INTSUBMSK);
507
508 irqdbf2("s3c_irq_demux_uart: start=%d (%d), subsrc=0x%08x,0x%08x\n",
509 start, offset, subsrc, submsk);
510
511 subsrc &= ~submsk;
512 subsrc >>= offset;
513 subsrc &= 7;
514
515 if (subsrc != 0) {
516 desc = irq_desc + start;
517
518 if (subsrc & 1)
519 desc_handle_irq(start, desc);
520
521 desc++;
522
523 if (subsrc & 2)
524 desc_handle_irq(start+1, desc);
525
526 desc++;
527
528 if (subsrc & 4)
529 desc_handle_irq(start+2, desc);
530 }
531}
532
533/* uart demux entry points */
534
535static void
536s3c_irq_demux_uart0(unsigned int irq,
537 struct irq_desc *desc)
538{
539 irq = irq;
540 s3c_irq_demux_uart(IRQ_S3CUART_RX0);
541}
542
543static void
544s3c_irq_demux_uart1(unsigned int irq,
545 struct irq_desc *desc)
546{
547 irq = irq;
548 s3c_irq_demux_uart(IRQ_S3CUART_RX1);
549}
550
551static void
552s3c_irq_demux_uart2(unsigned int irq,
553 struct irq_desc *desc)
554{
555 irq = irq;
556 s3c_irq_demux_uart(IRQ_S3CUART_RX2);
557}
558
559static void
560s3c_irq_demux_extint8(unsigned int irq,
561 struct irq_desc *desc)
562{
563 unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
564 unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
565
566 eintpnd &= ~eintmsk;
567 eintpnd &= ~0xff; /* ignore lower irqs */
568
569 /* we may as well handle all the pending IRQs here */
570
571 while (eintpnd) {
572 irq = __ffs(eintpnd);
573 eintpnd &= ~(1<<irq);
574
575 irq += (IRQ_EINT4 - 4);
576 desc_handle_irq(irq, irq_desc + irq);
577 }
578
579}
580
581static void
582s3c_irq_demux_extint4t7(unsigned int irq,
583 struct irq_desc *desc)
584{
585 unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
586 unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
587
588 eintpnd &= ~eintmsk;
589 eintpnd &= 0xff; /* only lower irqs */
590
591 /* we may as well handle all the pending IRQs here */
592
593 while (eintpnd) {
594 irq = __ffs(eintpnd);
595 eintpnd &= ~(1<<irq);
596
597 irq += (IRQ_EINT4 - 4);
598
599 desc_handle_irq(irq, irq_desc + irq);
600 }
601}
602
603#ifdef CONFIG_PM
604
605static struct sleep_save irq_save[] = {
606 SAVE_ITEM(S3C2410_INTMSK),
607 SAVE_ITEM(S3C2410_INTSUBMSK),
608}; 41};
609 42
610/* the extint values move between the s3c2410/s3c2440 and the s3c2412 43static int s3c2410_irq_init(void)
611 * so we use an array to hold them, and to calculate the address of
612 * the register at run-time
613*/
614
615static unsigned long save_extint[3];
616static unsigned long save_eintflt[4];
617static unsigned long save_eintmask;
618
619int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state)
620{ 44{
621 unsigned int i; 45 return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_irq_driver);
622
623 for (i = 0; i < ARRAY_SIZE(save_extint); i++)
624 save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4));
625
626 for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
627 save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4));
628
629 s3c2410_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
630 save_eintmask = __raw_readl(S3C24XX_EINTMASK);
631
632 return 0;
633} 46}
634 47
635int s3c24xx_irq_resume(struct sys_device *dev) 48arch_initcall(s3c2410_irq_init);
636{
637 unsigned int i;
638
639 for (i = 0; i < ARRAY_SIZE(save_extint); i++)
640 __raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4));
641
642 for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
643 __raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4));
644
645 s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
646 __raw_writel(save_eintmask, S3C24XX_EINTMASK);
647
648 return 0;
649}
650
651#else
652#define s3c24xx_irq_suspend NULL
653#define s3c24xx_irq_resume NULL
654#endif
655
656/* s3c24xx_init_irq
657 *
658 * Initialise S3C2410 IRQ system
659*/
660
661void __init s3c24xx_init_irq(void)
662{
663 unsigned long pend;
664 unsigned long last;
665 int irqno;
666 int i;
667
668 irqdbf("s3c2410_init_irq: clearing interrupt status flags\n");
669
670 /* first, clear all interrupts pending... */
671
672 last = 0;
673 for (i = 0; i < 4; i++) {
674 pend = __raw_readl(S3C24XX_EINTPEND);
675
676 if (pend == 0 || pend == last)
677 break;
678
679 __raw_writel(pend, S3C24XX_EINTPEND);
680 printk("irq: clearing pending ext status %08x\n", (int)pend);
681 last = pend;
682 }
683
684 last = 0;
685 for (i = 0; i < 4; i++) {
686 pend = __raw_readl(S3C2410_INTPND);
687
688 if (pend == 0 || pend == last)
689 break;
690
691 __raw_writel(pend, S3C2410_SRCPND);
692 __raw_writel(pend, S3C2410_INTPND);
693 printk("irq: clearing pending status %08x\n", (int)pend);
694 last = pend;
695 }
696
697 last = 0;
698 for (i = 0; i < 4; i++) {
699 pend = __raw_readl(S3C2410_SUBSRCPND);
700
701 if (pend == 0 || pend == last)
702 break;
703
704 printk("irq: clearing subpending status %08x\n", (int)pend);
705 __raw_writel(pend, S3C2410_SUBSRCPND);
706 last = pend;
707 }
708
709 /* register the main interrupts */
710
711 irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n");
712
713 for (irqno = IRQ_EINT4t7; irqno <= IRQ_ADCPARENT; irqno++) {
714 /* set all the s3c2410 internal irqs */
715
716 switch (irqno) {
717 /* deal with the special IRQs (cascaded) */
718
719 case IRQ_EINT4t7:
720 case IRQ_EINT8t23:
721 case IRQ_UART0:
722 case IRQ_UART1:
723 case IRQ_UART2:
724 case IRQ_ADCPARENT:
725 set_irq_chip(irqno, &s3c_irq_level_chip);
726 set_irq_handler(irqno, handle_level_irq);
727 break;
728
729 case IRQ_RESERVED6:
730 case IRQ_RESERVED24:
731 /* no IRQ here */
732 break;
733
734 default:
735 //irqdbf("registering irq %d (s3c irq)\n", irqno);
736 set_irq_chip(irqno, &s3c_irq_chip);
737 set_irq_handler(irqno, handle_edge_irq);
738 set_irq_flags(irqno, IRQF_VALID);
739 }
740 }
741
742 /* setup the cascade irq handlers */
743
744 set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint4t7);
745 set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint8);
746
747 set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
748 set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);
749 set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2);
750 set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc);
751
752 /* external interrupts */
753
754 for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
755 irqdbf("registering irq %d (ext int)\n", irqno);
756 set_irq_chip(irqno, &s3c_irq_eint0t4);
757 set_irq_handler(irqno, handle_edge_irq);
758 set_irq_flags(irqno, IRQF_VALID);
759 }
760
761 for (irqno = IRQ_EINT4; irqno <= IRQ_EINT23; irqno++) {
762 irqdbf("registering irq %d (extended s3c irq)\n", irqno);
763 set_irq_chip(irqno, &s3c_irqext_chip);
764 set_irq_handler(irqno, handle_edge_irq);
765 set_irq_flags(irqno, IRQF_VALID);
766 }
767
768 /* register the uart interrupts */
769
770 irqdbf("s3c2410: registering external interrupts\n");
771
772 for (irqno = IRQ_S3CUART_RX0; irqno <= IRQ_S3CUART_ERR0; irqno++) {
773 irqdbf("registering irq %d (s3c uart0 irq)\n", irqno);
774 set_irq_chip(irqno, &s3c_irq_uart0);
775 set_irq_handler(irqno, handle_level_irq);
776 set_irq_flags(irqno, IRQF_VALID);
777 }
778
779 for (irqno = IRQ_S3CUART_RX1; irqno <= IRQ_S3CUART_ERR1; irqno++) {
780 irqdbf("registering irq %d (s3c uart1 irq)\n", irqno);
781 set_irq_chip(irqno, &s3c_irq_uart1);
782 set_irq_handler(irqno, handle_level_irq);
783 set_irq_flags(irqno, IRQF_VALID);
784 }
785
786 for (irqno = IRQ_S3CUART_RX2; irqno <= IRQ_S3CUART_ERR2; irqno++) {
787 irqdbf("registering irq %d (s3c uart2 irq)\n", irqno);
788 set_irq_chip(irqno, &s3c_irq_uart2);
789 set_irq_handler(irqno, handle_level_irq);
790 set_irq_flags(irqno, IRQF_VALID);
791 }
792
793 for (irqno = IRQ_TC; irqno <= IRQ_ADC; irqno++) {
794 irqdbf("registering irq %d (s3c adc irq)\n", irqno);
795 set_irq_chip(irqno, &s3c_irq_adc);
796 set_irq_handler(irqno, handle_edge_irq);
797 set_irq_flags(irqno, IRQF_VALID);
798 }
799
800 irqdbf("s3c2410: registered interrupt handlers\n");
801}
diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c
index 817e2c684410..72f2cc4fcd03 100644
--- a/arch/arm/mach-s3c2410/mach-amlm5900.c
+++ b/arch/arm/mach-s3c2410/mach-amlm5900.c
@@ -1,4 +1,4 @@
1/*********************************************************************** 1/* linux/arch/arm/mach-s3c2410/mach-amlm5900.c
2 * 2 *
3 * linux/arch/arm/mach-s3c2410/mach-amlm5900.c 3 * linux/arch/arm/mach-s3c2410/mach-amlm5900.c
4 * 4 *
@@ -35,7 +35,7 @@
35#include <linux/device.h> 35#include <linux/device.h>
36#include <linux/platform_device.h> 36#include <linux/platform_device.h>
37#include <linux/proc_fs.h> 37#include <linux/proc_fs.h>
38 38#include <linux/serial_core.h>
39 39
40#include <asm/mach/arch.h> 40#include <asm/mach/arch.h>
41#include <asm/mach/map.h> 41#include <asm/mach/map.h>
@@ -52,8 +52,8 @@
52#include <asm/arch/regs-lcd.h> 52#include <asm/arch/regs-lcd.h>
53#include <asm/arch/regs-gpio.h> 53#include <asm/arch/regs-gpio.h>
54 54
55#include "devs.h" 55#include <asm/plat-s3c24xx/devs.h>
56#include "cpu.h" 56#include <asm/plat-s3c24xx/cpu.h>
57 57
58#ifdef CONFIG_MTD_PARTITIONS 58#ifdef CONFIG_MTD_PARTITIONS
59 59
@@ -113,12 +113,6 @@ static struct platform_device amlm5900_device_nor = {
113#endif 113#endif
114 114
115static struct map_desc amlm5900_iodesc[] __initdata = { 115static struct map_desc amlm5900_iodesc[] __initdata = {
116 {
117 .virtual = (u32)S3C24XX_VA_SPI,
118 .pfn = __phys_to_pfn(S3C2410_PA_SPI),
119 .length = SZ_1M,
120 .type = MT_DEVICE
121 }
122}; 116};
123 117
124#define UCON S3C2410_UCON_DEFAULT 118#define UCON S3C2410_UCON_DEFAULT
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index b8b76757ec54..7b81296427eb 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -50,9 +50,9 @@
50 50
51#include <linux/serial_8250.h> 51#include <linux/serial_8250.h>
52 52
53#include "clock.h" 53#include <asm/plat-s3c24xx/clock.h>
54#include "devs.h" 54#include <asm/plat-s3c24xx/devs.h>
55#include "cpu.h" 55#include <asm/plat-s3c24xx/cpu.h>
56#include "usb-simtec.h" 56#include "usb-simtec.h"
57 57
58#define COPYRIGHT ", (c) 2004-2005 Simtec Electronics" 58#define COPYRIGHT ", (c) 2004-2005 Simtec Electronics"
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index 15b625eae499..01c60d0923cd 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -25,23 +25,24 @@
25#include <asm/mach/irq.h> 25#include <asm/mach/irq.h>
26 26
27#include <asm/hardware.h> 27#include <asm/hardware.h>
28#include <asm/hardware/iomd.h>
29#include <asm/io.h> 28#include <asm/io.h>
30#include <asm/irq.h> 29#include <asm/irq.h>
31#include <asm/mach-types.h> 30#include <asm/mach-types.h>
32 31
33
34#include <asm/arch/regs-serial.h> 32#include <asm/arch/regs-serial.h>
35#include <asm/arch/regs-lcd.h> 33#include <asm/arch/regs-lcd.h>
34#include <asm/arch/regs-gpio.h>
35#include <asm/arch/regs-clock.h>
36 36
37#include <asm/arch/h1940.h> 37#include <asm/arch/h1940.h>
38#include <asm/arch/h1940-latch.h> 38#include <asm/arch/h1940-latch.h>
39#include <asm/arch/fb.h> 39#include <asm/arch/fb.h>
40#include <asm/arch/udc.h>
40 41
41#include "clock.h" 42#include <asm/plat-s3c24xx/clock.h>
42#include "devs.h" 43#include <asm/plat-s3c24xx/devs.h>
43#include "cpu.h" 44#include <asm/plat-s3c24xx/cpu.h>
44#include "pm.h" 45#include <asm/plat-s3c24xx/pm.h>
45 46
46static struct map_desc h1940_iodesc[] __initdata = { 47static struct map_desc h1940_iodesc[] __initdata = {
47 [0] = { 48 [0] = {
@@ -102,6 +103,32 @@ void h1940_latch_control(unsigned int clear, unsigned int set)
102 103
103EXPORT_SYMBOL_GPL(h1940_latch_control); 104EXPORT_SYMBOL_GPL(h1940_latch_control);
104 105
106static void h1940_udc_pullup(enum s3c2410_udc_cmd_e cmd)
107{
108 printk(KERN_DEBUG "udc: pullup(%d)\n",cmd);
109
110 switch (cmd)
111 {
112 case S3C2410_UDC_P_ENABLE :
113 h1940_latch_control(0, H1940_LATCH_USB_DP);
114 break;
115 case S3C2410_UDC_P_DISABLE :
116 h1940_latch_control(H1940_LATCH_USB_DP, 0);
117 break;
118 case S3C2410_UDC_P_RESET :
119 break;
120 default:
121 break;
122 }
123}
124
125static struct s3c2410_udc_mach_info h1940_udc_cfg __initdata = {
126 .udc_command = h1940_udc_pullup,
127 .vbus_pin = S3C2410_GPG5,
128 .vbus_pin_inverted = 1,
129};
130
131
105 132
106/** 133/**
107 * Set lcd on or off 134 * Set lcd on or off
@@ -146,12 +173,19 @@ static struct s3c2410fb_mach_info h1940_lcdcfg __initdata = {
146 .bpp= {16,16,16}, 173 .bpp= {16,16,16},
147}; 174};
148 175
176static struct platform_device s3c_device_leds = {
177 .name = "h1940-leds",
178 .id = -1,
179};
180
149static struct platform_device *h1940_devices[] __initdata = { 181static struct platform_device *h1940_devices[] __initdata = {
150 &s3c_device_usb, 182 &s3c_device_usb,
151 &s3c_device_lcd, 183 &s3c_device_lcd,
152 &s3c_device_wdt, 184 &s3c_device_wdt,
153 &s3c_device_i2c, 185 &s3c_device_i2c,
154 &s3c_device_iis, 186 &s3c_device_iis,
187 &s3c_device_usbgadget,
188 &s3c_device_leds,
155}; 189};
156 190
157static struct s3c24xx_board h1940_board __initdata = { 191static struct s3c24xx_board h1940_board __initdata = {
@@ -179,7 +213,23 @@ static void __init h1940_init_irq(void)
179 213
180static void __init h1940_init(void) 214static void __init h1940_init(void)
181{ 215{
216 u32 tmp;
217
182 s3c24xx_fb_set_platdata(&h1940_lcdcfg); 218 s3c24xx_fb_set_platdata(&h1940_lcdcfg);
219 s3c24xx_udc_set_platdata(&h1940_udc_cfg);
220
221 /* Turn off suspend on both USB ports, and switch the
222 * selectable USB port to USB device mode. */
223
224 s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
225 S3C2410_MISCCR_USBSUSPND0 |
226 S3C2410_MISCCR_USBSUSPND1, 0x0);
227
228 tmp = (
229 0x78 << S3C2410_PLLCON_MDIVSHIFT)
230 | (0x02 << S3C2410_PLLCON_PDIVSHIFT)
231 | (0x03 << S3C2410_PLLCON_SDIVSHIFT);
232 writel(tmp, S3C2410_UPLLCON);
183} 233}
184 234
185MACHINE_START(H1940, "IPAQ-H1940") 235MACHINE_START(H1940, "IPAQ-H1940")
@@ -189,6 +239,6 @@ MACHINE_START(H1940, "IPAQ-H1940")
189 .boot_params = S3C2410_SDRAM_PA + 0x100, 239 .boot_params = S3C2410_SDRAM_PA + 0x100,
190 .map_io = h1940_map_io, 240 .map_io = h1940_map_io,
191 .init_irq = h1940_init_irq, 241 .init_irq = h1940_init_irq,
192 .init_machine = h1940_init, 242 .init_machine = h1940_init,
193 .timer = &s3c24xx_timer, 243 .timer = &s3c24xx_timer,
194MACHINE_END 244MACHINE_END
diff --git a/arch/arm/mach-s3c2410/mach-n30.c b/arch/arm/mach-s3c2410/mach-n30.c
index 0411e9adb54d..261aa4cc0770 100644
--- a/arch/arm/mach-s3c2410/mach-n30.c
+++ b/arch/arm/mach-s3c2410/mach-n30.c
@@ -29,7 +29,6 @@
29#include <asm/mach/irq.h> 29#include <asm/mach/irq.h>
30 30
31#include <asm/hardware.h> 31#include <asm/hardware.h>
32#include <asm/hardware/iomd.h>
33#include <asm/io.h> 32#include <asm/io.h>
34#include <asm/irq.h> 33#include <asm/irq.h>
35#include <asm/mach-types.h> 34#include <asm/mach-types.h>
@@ -38,10 +37,10 @@
38#include <asm/arch/regs-gpio.h> 37#include <asm/arch/regs-gpio.h>
39#include <asm/arch/iic.h> 38#include <asm/arch/iic.h>
40 39
41#include "s3c2410.h" 40#include <asm/plat-s3c24xx/s3c2410.h>
42#include "clock.h" 41#include <asm/plat-s3c24xx/clock.h>
43#include "devs.h" 42#include <asm/plat-s3c24xx/devs.h>
44#include "cpu.h" 43#include <asm/plat-s3c24xx/cpu.h>
45 44
46static struct map_desc n30_iodesc[] __initdata = { 45static struct map_desc n30_iodesc[] __initdata = {
47 /* nothing here yet */ 46 /* nothing here yet */
diff --git a/arch/arm/mach-s3c2410/mach-otom.c b/arch/arm/mach-s3c2410/mach-otom.c
index 2c738b375e4d..c78ab75b44f3 100644
--- a/arch/arm/mach-s3c2410/mach-otom.c
+++ b/arch/arm/mach-s3c2410/mach-otom.c
@@ -32,10 +32,10 @@
32#include <asm/arch/regs-serial.h> 32#include <asm/arch/regs-serial.h>
33#include <asm/arch/regs-gpio.h> 33#include <asm/arch/regs-gpio.h>
34 34
35#include "s3c2410.h" 35#include <asm/plat-s3c24xx/s3c2410.h>
36#include "clock.h" 36#include <asm/plat-s3c24xx/clock.h>
37#include "devs.h" 37#include <asm/plat-s3c24xx/devs.h>
38#include "cpu.h" 38#include <asm/plat-s3c24xx/cpu.h>
39 39
40static struct map_desc otom11_iodesc[] __initdata = { 40static struct map_desc otom11_iodesc[] __initdata = {
41 /* Device area */ 41 /* Device area */
diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c
new file mode 100644
index 000000000000..c6a41593de21
--- /dev/null
+++ b/arch/arm/mach-s3c2410/mach-qt2410.c
@@ -0,0 +1,448 @@
1/* linux/arch/arm/mach-s3c2410/mach-qt2410.c
2 *
3 * Copyright (C) 2006 by OpenMoko, Inc.
4 * Author: Harald Welte <laforge@openmoko.org>
5 * All rights reserved.
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of
10 * the License, or (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
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
20 * MA 02111-1307 USA
21 *
22 */
23
24#include <linux/kernel.h>
25#include <linux/types.h>
26#include <linux/interrupt.h>
27#include <linux/list.h>
28#include <linux/timer.h>
29#include <linux/init.h>
30#include <linux/platform_device.h>
31#include <linux/serial_core.h>
32#include <linux/mmc/protocol.h>
33#include <linux/spi/spi.h>
34#include <linux/spi/spi_bitbang.h>
35
36#include <linux/mtd/mtd.h>
37#include <linux/mtd/nand.h>
38#include <linux/mtd/nand_ecc.h>
39#include <linux/mtd/partitions.h>
40
41#include <asm/mach/arch.h>
42#include <asm/mach/map.h>
43#include <asm/mach/irq.h>
44
45#include <asm/hardware.h>
46#include <asm/io.h>
47#include <asm/irq.h>
48#include <asm/mach-types.h>
49
50#include <asm/arch/regs-gpio.h>
51#include <asm/arch/leds-gpio.h>
52#include <asm/arch/regs-serial.h>
53#include <asm/arch/fb.h>
54#include <asm/arch/nand.h>
55#include <asm/arch/udc.h>
56#include <asm/arch/spi.h>
57#include <asm/arch/spi-gpio.h>
58
59#include <asm/plat-s3c24xx/common-smdk.h>
60#include <asm/plat-s3c24xx/devs.h>
61#include <asm/plat-s3c24xx/cpu.h>
62#include <asm/plat-s3c24xx/pm.h>
63
64static struct map_desc qt2410_iodesc[] __initdata = {
65 { 0xe0000000, __phys_to_pfn(S3C2410_CS3+0x01000000), SZ_1M, MT_DEVICE }
66};
67
68#define UCON S3C2410_UCON_DEFAULT
69#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
70#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
71
72static struct s3c2410_uartcfg smdk2410_uartcfgs[] = {
73 [0] = {
74 .hwport = 0,
75 .flags = 0,
76 .ucon = UCON,
77 .ulcon = ULCON,
78 .ufcon = UFCON,
79 },
80 [1] = {
81 .hwport = 1,
82 .flags = 0,
83 .ucon = UCON,
84 .ulcon = ULCON,
85 .ufcon = UFCON,
86 },
87 [2] = {
88 .hwport = 2,
89 .flags = 0,
90 .ucon = UCON,
91 .ulcon = ULCON,
92 .ufcon = UFCON,
93 }
94};
95
96/* LCD driver info */
97
98/* Configuration for 640x480 SHARP LQ080V3DG01 */
99static struct s3c2410fb_mach_info qt2410_biglcd_cfg __initdata = {
100 .regs = {
101
102 .lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
103 S3C2410_LCDCON1_TFT |
104 S3C2410_LCDCON1_CLKVAL(0x01), /* HCLK/4 */
105
106 .lcdcon2 = S3C2410_LCDCON2_VBPD(18) | /* 19 */
107 S3C2410_LCDCON2_LINEVAL(479) |
108 S3C2410_LCDCON2_VFPD(10) | /* 11 */
109 S3C2410_LCDCON2_VSPW(14), /* 15 */
110
111 .lcdcon3 = S3C2410_LCDCON3_HBPD(43) | /* 44 */
112 S3C2410_LCDCON3_HOZVAL(639) | /* 640 */
113 S3C2410_LCDCON3_HFPD(115), /* 116 */
114
115 .lcdcon4 = S3C2410_LCDCON4_MVAL(0) |
116 S3C2410_LCDCON4_HSPW(95), /* 96 */
117
118 .lcdcon5 = S3C2410_LCDCON5_FRM565 |
119 S3C2410_LCDCON5_INVVLINE |
120 S3C2410_LCDCON5_INVVFRAME |
121 S3C2410_LCDCON5_PWREN |
122 S3C2410_LCDCON5_HWSWP,
123 },
124
125 .lpcsel = ((0xCE6) & ~7) | 1<<4,
126
127 .width = 640,
128 .height = 480,
129
130 .xres = {
131 .min = 640,
132 .max = 640,
133 .defval = 640,
134 },
135
136 .yres = {
137 .min = 480,
138 .max = 480,
139 .defval = 480,
140 },
141
142 .bpp = {
143 .min = 16,
144 .max = 16,
145 .defval = 16,
146 },
147};
148
149/* Configuration for 480x640 toppoly TD028TTEC1 */
150static struct s3c2410fb_mach_info qt2410_prodlcd_cfg __initdata = {
151 .regs = {
152
153 .lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
154 S3C2410_LCDCON1_TFT |
155 S3C2410_LCDCON1_CLKVAL(0x01), /* HCLK/4 */
156
157 .lcdcon2 = S3C2410_LCDCON2_VBPD(1) | /* 2 */
158 S3C2410_LCDCON2_LINEVAL(639) |/* 640 */
159 S3C2410_LCDCON2_VFPD(3) | /* 4 */
160 S3C2410_LCDCON2_VSPW(1), /* 2 */
161
162 .lcdcon3 = S3C2410_LCDCON3_HBPD(7) | /* 8 */
163 S3C2410_LCDCON3_HOZVAL(479) | /* 479 */
164 S3C2410_LCDCON3_HFPD(23), /* 24 */
165
166 .lcdcon4 = S3C2410_LCDCON4_MVAL(0) |
167 S3C2410_LCDCON4_HSPW(7), /* 8 */
168
169 .lcdcon5 = S3C2410_LCDCON5_FRM565 |
170 S3C2410_LCDCON5_INVVLINE |
171 S3C2410_LCDCON5_INVVFRAME |
172 S3C2410_LCDCON5_PWREN |
173 S3C2410_LCDCON5_HWSWP,
174 },
175
176 .lpcsel = ((0xCE6) & ~7) | 1<<4,
177
178 .width = 480,
179 .height = 640,
180
181 .xres = {
182 .min = 480,
183 .max = 480,
184 .defval = 480,
185 },
186
187 .yres = {
188 .min = 640,
189 .max = 640,
190 .defval = 640,
191 },
192
193 .bpp = {
194 .min = 16,
195 .max = 16,
196 .defval = 16,
197 },
198};
199
200/* Config for 240x320 LCD */
201static struct s3c2410fb_mach_info qt2410_lcd_cfg __initdata = {
202 .regs = {
203
204 .lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
205 S3C2410_LCDCON1_TFT |
206 S3C2410_LCDCON1_CLKVAL(0x04),
207
208 .lcdcon2 = S3C2410_LCDCON2_VBPD(1) |
209 S3C2410_LCDCON2_LINEVAL(319) |
210 S3C2410_LCDCON2_VFPD(6) |
211 S3C2410_LCDCON2_VSPW(3),
212
213 .lcdcon3 = S3C2410_LCDCON3_HBPD(12) |
214 S3C2410_LCDCON3_HOZVAL(239) |
215 S3C2410_LCDCON3_HFPD(7),
216
217 .lcdcon4 = S3C2410_LCDCON4_MVAL(0) |
218 S3C2410_LCDCON4_HSPW(3),
219
220 .lcdcon5 = S3C2410_LCDCON5_FRM565 |
221 S3C2410_LCDCON5_INVVLINE |
222 S3C2410_LCDCON5_INVVFRAME |
223 S3C2410_LCDCON5_PWREN |
224 S3C2410_LCDCON5_HWSWP,
225 },
226
227 .lpcsel = ((0xCE6) & ~7) | 1<<4,
228
229 .width = 240,
230 .height = 320,
231
232 .xres = {
233 .min = 240,
234 .max = 240,
235 .defval = 240,
236 },
237
238 .yres = {
239 .min = 320,
240 .max = 320,
241 .defval = 320,
242 },
243
244 .bpp = {
245 .min = 16,
246 .max = 16,
247 .defval = 16,
248 },
249};
250
251/* CS8900 */
252
253static struct resource qt2410_cs89x0_resources[] = {
254 [0] = {
255 .start = 0x19000000,
256 .end = 0x19000000 + 16,
257 .flags = IORESOURCE_MEM,
258 },
259 [1] = {
260 .start = IRQ_EINT9,
261 .end = IRQ_EINT9,
262 .flags = IORESOURCE_IRQ,
263 },
264};
265
266static struct platform_device qt2410_cs89x0 = {
267 .name = "cirrus-cs89x0",
268 .num_resources = ARRAY_SIZE(qt2410_cs89x0_resources),
269 .resource = qt2410_cs89x0_resources,
270};
271
272/* LED */
273
274static struct s3c24xx_led_platdata qt2410_pdata_led = {
275 .gpio = S3C2410_GPB0,
276 .flags = S3C24XX_LEDF_ACTLOW | S3C24XX_LEDF_TRISTATE,
277 .name = "led",
278 .def_trigger = "timer",
279};
280
281static struct platform_device qt2410_led = {
282 .name = "s3c24xx_led",
283 .id = 0,
284 .dev = {
285 .platform_data = &qt2410_pdata_led,
286 },
287};
288
289/* SPI */
290
291static void spi_gpio_cs(struct s3c2410_spigpio_info *spi, int cs)
292{
293 switch (cs) {
294 case BITBANG_CS_ACTIVE:
295 s3c2410_gpio_setpin(S3C2410_GPB5, 0);
296 break;
297 case BITBANG_CS_INACTIVE:
298 s3c2410_gpio_setpin(S3C2410_GPB5, 1);
299 break;
300 }
301}
302
303static struct s3c2410_spigpio_info spi_gpio_cfg = {
304 .pin_clk = S3C2410_GPG7,
305 .pin_mosi = S3C2410_GPG6,
306 .pin_miso = S3C2410_GPG5,
307 .chip_select = &spi_gpio_cs,
308};
309
310
311static struct platform_device qt2410_spi = {
312 .name = "s3c24xx-spi-gpio",
313 .id = 1,
314 .dev = {
315 .platform_data = &spi_gpio_cfg,
316 },
317};
318
319/* Board devices */
320
321static struct platform_device *qt2410_devices[] __initdata = {
322 &s3c_device_usb,
323 &s3c_device_lcd,
324 &s3c_device_wdt,
325 &s3c_device_i2c,
326 &s3c_device_iis,
327 &s3c_device_sdi,
328 &s3c_device_usbgadget,
329 &qt2410_spi,
330 &qt2410_cs89x0,
331 &qt2410_led,
332};
333
334static struct s3c24xx_board qt2410_board __initdata = {
335 .devices = qt2410_devices,
336 .devices_count = ARRAY_SIZE(qt2410_devices)
337};
338
339static struct mtd_partition qt2410_nand_part[] = {
340 [0] = {
341 .name = "U-Boot",
342 .size = 0x30000,
343 .offset = 0,
344 },
345 [1] = {
346 .name = "U-Boot environment",
347 .offset = 0x30000,
348 .size = 0x4000,
349 },
350 [2] = {
351 .name = "kernel",
352 .offset = 0x34000,
353 .size = SZ_2M,
354 },
355 [3] = {
356 .name = "initrd",
357 .offset = 0x234000,
358 .size = SZ_4M,
359 },
360 [4] = {
361 .name = "jffs2",
362 .offset = 0x634000,
363 .size = 0x39cc000,
364 },
365};
366
367static struct s3c2410_nand_set qt2410_nand_sets[] = {
368 [0] = {
369 .name = "NAND",
370 .nr_chips = 1,
371 .nr_partitions = ARRAY_SIZE(qt2410_nand_part),
372 .partitions = qt2410_nand_part,
373 },
374};
375
376/* choose a set of timings which should suit most 512Mbit
377 * chips and beyond.
378 */
379
380static struct s3c2410_platform_nand qt2410_nand_info = {
381 .tacls = 20,
382 .twrph0 = 60,
383 .twrph1 = 20,
384 .nr_sets = ARRAY_SIZE(qt2410_nand_sets),
385 .sets = qt2410_nand_sets,
386};
387
388/* UDC */
389
390static struct s3c2410_udc_mach_info qt2410_udc_cfg = {
391};
392
393static char tft_type = 's';
394
395static int __init qt2410_tft_setup(char *str)
396{
397 tft_type = str[0];
398 return 1;
399}
400
401__setup("tft=", qt2410_tft_setup);
402
403static void __init qt2410_map_io(void)
404{
405 s3c24xx_init_io(qt2410_iodesc, ARRAY_SIZE(qt2410_iodesc));
406 s3c24xx_init_clocks(12*1000*1000);
407 s3c24xx_init_uarts(smdk2410_uartcfgs, ARRAY_SIZE(smdk2410_uartcfgs));
408 s3c24xx_set_board(&qt2410_board);
409}
410
411static void __init qt2410_machine_init(void)
412{
413 s3c_device_nand.dev.platform_data = &qt2410_nand_info;
414
415 switch (tft_type) {
416 case 'p': /* production */
417 s3c24xx_fb_set_platdata(&qt2410_prodlcd_cfg);
418 break;
419 case 'b': /* big */
420 s3c24xx_fb_set_platdata(&qt2410_biglcd_cfg);
421 break;
422 case 's': /* small */
423 default:
424 s3c24xx_fb_set_platdata(&qt2410_lcd_cfg);
425 break;
426 }
427
428 s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPIO_OUTPUT);
429 s3c2410_gpio_setpin(S3C2410_GPB0, 1);
430
431 s3c24xx_udc_set_platdata(&qt2410_udc_cfg);
432
433 s3c2410_gpio_cfgpin(S3C2410_GPB5, S3C2410_GPIO_OUTPUT);
434
435 s3c2410_pm_init();
436}
437
438MACHINE_START(QT2410, "QT2410")
439 .phys_io = S3C2410_PA_UART,
440 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
441 .boot_params = S3C2410_SDRAM_PA + 0x100,
442 .map_io = qt2410_map_io,
443 .init_irq = s3c24xx_init_irq,
444 .init_machine = qt2410_machine_init,
445 .timer = &s3c24xx_timer,
446MACHINE_END
447
448
diff --git a/arch/arm/mach-s3c2410/mach-smdk2410.c b/arch/arm/mach-s3c2410/mach-smdk2410.c
index 01c0c986d827..57b8a80f33d0 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2410.c
+++ b/arch/arm/mach-s3c2410/mach-smdk2410.c
@@ -1,4 +1,4 @@
1/*********************************************************************** 1/* linux/arch/arm/mach-s3c2410/mach-smdk2410.c
2 * 2 *
3 * linux/arch/arm/mach-s3c2410/mach-smdk2410.c 3 * linux/arch/arm/mach-s3c2410/mach-smdk2410.c
4 * 4 *
@@ -49,10 +49,10 @@
49 49
50#include <asm/arch/regs-serial.h> 50#include <asm/arch/regs-serial.h>
51 51
52#include "devs.h" 52#include <asm/plat-s3c24xx/devs.h>
53#include "cpu.h" 53#include <asm/plat-s3c24xx/cpu.h>
54 54
55#include "common-smdk.h" 55#include <asm/plat-s3c24xx/common-smdk.h>
56 56
57static struct map_desc smdk2410_iodesc[] __initdata = { 57static struct map_desc smdk2410_iodesc[] __initdata = {
58 /* nothing here yet */ 58 /* nothing here yet */
diff --git a/arch/arm/mach-s3c2410/mach-vr1000.c b/arch/arm/mach-s3c2410/mach-vr1000.c
index a382fc095110..c947c75bcbf0 100644
--- a/arch/arm/mach-s3c2410/mach-vr1000.c
+++ b/arch/arm/mach-s3c2410/mach-vr1000.c
@@ -43,9 +43,9 @@
43#include <asm/arch/regs-gpio.h> 43#include <asm/arch/regs-gpio.h>
44#include <asm/arch/leds-gpio.h> 44#include <asm/arch/leds-gpio.h>
45 45
46#include "clock.h" 46#include <asm/plat-s3c24xx/clock.h>
47#include "devs.h" 47#include <asm/plat-s3c24xx/devs.h>
48#include "cpu.h" 48#include <asm/plat-s3c24xx/cpu.h>
49#include "usb-simtec.h" 49#include "usb-simtec.h"
50 50
51/* macros for virtual address mods for the io space entries */ 51/* macros for virtual address mods for the io space entries */
diff --git a/arch/arm/mach-s3c2410/pm.c b/arch/arm/mach-s3c2410/pm.c
index ebf294dd31da..3b3a7db4e0dd 100644
--- a/arch/arm/mach-s3c2410/pm.c
+++ b/arch/arm/mach-s3c2410/pm.c
@@ -1,11 +1,9 @@
1/* linux/arch/arm/mach-s3c2410/pm.c 1/* linux/arch/arm/mach-s3c2410/pm.c
2 * 2 *
3 * Copyright (c) 2004,2006 Simtec Electronics 3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
5 * 5 *
6 * S3C24XX Power Manager (Suspend-To-RAM) support 6 * S3C2410 (and compatible) Power Manager (Suspend-To-RAM) support
7 *
8 * See Documentation/arm/Samsung-S3C24XX/Suspend.txt for more information
9 * 7 *
10 * This program is free software; you can redistribute it and/or modify 8 * 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 9 * it under the terms of the GNU General Public License as published by
@@ -20,640 +18,139 @@
20 * 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
21 * along with this program; if not, write to the Free Software 19 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 * Parts based on arch/arm/mach-pxa/pm.c
25 *
26 * Thanks to Dimitry Andric for debugging
27*/ 21*/
28 22
29#include <linux/init.h> 23#include <linux/init.h>
30#include <linux/suspend.h> 24#include <linux/suspend.h>
31#include <linux/errno.h> 25#include <linux/errno.h>
32#include <linux/time.h> 26#include <linux/time.h>
33#include <linux/interrupt.h> 27#include <linux/sysdev.h>
34#include <linux/crc32.h>
35#include <linux/ioport.h>
36#include <linux/delay.h>
37#include <linux/serial_core.h>
38 28
39#include <asm/cacheflush.h>
40#include <asm/hardware.h> 29#include <asm/hardware.h>
41#include <asm/io.h> 30#include <asm/io.h>
42 31
43#include <asm/arch/regs-serial.h> 32#include <asm/mach-types.h>
44#include <asm/arch/regs-clock.h>
45#include <asm/arch/regs-gpio.h>
46#include <asm/arch/regs-mem.h>
47#include <asm/arch/regs-irq.h>
48
49#include <asm/mach/time.h>
50
51#include "pm.h"
52
53/* for external use */
54
55unsigned long s3c_pm_flags;
56
57#define PFX "s3c24xx-pm: "
58
59static struct sleep_save core_save[] = {
60 SAVE_ITEM(S3C2410_LOCKTIME),
61 SAVE_ITEM(S3C2410_CLKCON),
62
63 /* we restore the timings here, with the proviso that the board
64 * brings the system up in an slower, or equal frequency setting
65 * to the original system.
66 *
67 * if we cannot guarantee this, then things are going to go very
68 * wrong here, as we modify the refresh and both pll settings.
69 */
70
71 SAVE_ITEM(S3C2410_BWSCON),
72 SAVE_ITEM(S3C2410_BANKCON0),
73 SAVE_ITEM(S3C2410_BANKCON1),
74 SAVE_ITEM(S3C2410_BANKCON2),
75 SAVE_ITEM(S3C2410_BANKCON3),
76 SAVE_ITEM(S3C2410_BANKCON4),
77 SAVE_ITEM(S3C2410_BANKCON5),
78
79 SAVE_ITEM(S3C2410_CLKDIVN),
80 SAVE_ITEM(S3C2410_MPLLCON),
81 SAVE_ITEM(S3C2410_UPLLCON),
82 SAVE_ITEM(S3C2410_CLKSLOW),
83 SAVE_ITEM(S3C2410_REFRESH),
84};
85
86static struct sleep_save gpio_save[] = {
87 SAVE_ITEM(S3C2410_GPACON),
88 SAVE_ITEM(S3C2410_GPADAT),
89
90 SAVE_ITEM(S3C2410_GPBCON),
91 SAVE_ITEM(S3C2410_GPBDAT),
92 SAVE_ITEM(S3C2410_GPBUP),
93
94 SAVE_ITEM(S3C2410_GPCCON),
95 SAVE_ITEM(S3C2410_GPCDAT),
96 SAVE_ITEM(S3C2410_GPCUP),
97
98 SAVE_ITEM(S3C2410_GPDCON),
99 SAVE_ITEM(S3C2410_GPDDAT),
100 SAVE_ITEM(S3C2410_GPDUP),
101
102 SAVE_ITEM(S3C2410_GPECON),
103 SAVE_ITEM(S3C2410_GPEDAT),
104 SAVE_ITEM(S3C2410_GPEUP),
105
106 SAVE_ITEM(S3C2410_GPFCON),
107 SAVE_ITEM(S3C2410_GPFDAT),
108 SAVE_ITEM(S3C2410_GPFUP),
109 33
110 SAVE_ITEM(S3C2410_GPGCON), 34#include <asm/arch/regs-gpio.h>
111 SAVE_ITEM(S3C2410_GPGDAT), 35#include <asm/arch/h1940.h>
112 SAVE_ITEM(S3C2410_GPGUP),
113
114 SAVE_ITEM(S3C2410_GPHCON),
115 SAVE_ITEM(S3C2410_GPHDAT),
116 SAVE_ITEM(S3C2410_GPHUP),
117 36
118 SAVE_ITEM(S3C2410_DCLKCON), 37#include <asm/plat-s3c24xx/cpu.h>
119}; 38#include <asm/plat-s3c24xx/pm.h>
120 39
121#ifdef CONFIG_S3C2410_PM_DEBUG 40#ifdef CONFIG_S3C2410_PM_DEBUG
122 41extern void pm_dbg(const char *fmt, ...);
123#define SAVE_UART(va) \
124 SAVE_ITEM((va) + S3C2410_ULCON), \
125 SAVE_ITEM((va) + S3C2410_UCON), \
126 SAVE_ITEM((va) + S3C2410_UFCON), \
127 SAVE_ITEM((va) + S3C2410_UMCON), \
128 SAVE_ITEM((va) + S3C2410_UBRDIV)
129
130static struct sleep_save uart_save[] = {
131 SAVE_UART(S3C24XX_VA_UART0),
132 SAVE_UART(S3C24XX_VA_UART1),
133#ifndef CONFIG_CPU_S3C2400
134 SAVE_UART(S3C24XX_VA_UART2),
135#endif
136};
137
138/* debug
139 *
140 * we send the debug to printascii() to allow it to be seen if the
141 * system never wakes up from the sleep
142*/
143
144extern void printascii(const char *);
145
146void pm_dbg(const char *fmt, ...)
147{
148 va_list va;
149 char buff[256];
150
151 va_start(va, fmt);
152 vsprintf(buff, fmt, va);
153 va_end(va);
154
155 printascii(buff);
156}
157
158static void s3c2410_pm_debug_init(void)
159{
160 unsigned long tmp = __raw_readl(S3C2410_CLKCON);
161
162 /* re-start uart clocks */
163 tmp |= S3C2410_CLKCON_UART0;
164 tmp |= S3C2410_CLKCON_UART1;
165 tmp |= S3C2410_CLKCON_UART2;
166
167 __raw_writel(tmp, S3C2410_CLKCON);
168 udelay(10);
169}
170
171#define DBG(fmt...) pm_dbg(fmt) 42#define DBG(fmt...) pm_dbg(fmt)
172#else 43#else
173#define DBG(fmt...) printk(KERN_DEBUG fmt) 44#define DBG(fmt...) printk(KERN_DEBUG fmt)
174
175#define s3c2410_pm_debug_init() do { } while(0)
176
177static struct sleep_save uart_save[] = {};
178#endif 45#endif
179 46
180#if defined(CONFIG_S3C2410_PM_CHECK) && CONFIG_S3C2410_PM_CHECK_CHUNKSIZE != 0 47static void s3c2410_pm_prepare(void)
181
182/* suspend checking code...
183 *
184 * this next area does a set of crc checks over all the installed
185 * memory, so the system can verify if the resume was ok.
186 *
187 * CONFIG_S3C2410_PM_CHECK_CHUNKSIZE defines the block-size for the CRC,
188 * increasing it will mean that the area corrupted will be less easy to spot,
189 * and reducing the size will cause the CRC save area to grow
190*/
191
192#define CHECK_CHUNKSIZE (CONFIG_S3C2410_PM_CHECK_CHUNKSIZE * 1024)
193
194static u32 crc_size; /* size needed for the crc block */
195static u32 *crcs; /* allocated over suspend/resume */
196
197typedef u32 *(run_fn_t)(struct resource *ptr, u32 *arg);
198
199/* s3c2410_pm_run_res
200 *
201 * go thorugh the given resource list, and look for system ram
202*/
203
204static void s3c2410_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg)
205{
206 while (ptr != NULL) {
207 if (ptr->child != NULL)
208 s3c2410_pm_run_res(ptr->child, fn, arg);
209
210 if ((ptr->flags & IORESOURCE_MEM) &&
211 strcmp(ptr->name, "System RAM") == 0) {
212 DBG("Found system RAM at %08lx..%08lx\n",
213 ptr->start, ptr->end);
214 arg = (fn)(ptr, arg);
215 }
216
217 ptr = ptr->sibling;
218 }
219}
220
221static void s3c2410_pm_run_sysram(run_fn_t fn, u32 *arg)
222{
223 s3c2410_pm_run_res(&iomem_resource, fn, arg);
224}
225
226static u32 *s3c2410_pm_countram(struct resource *res, u32 *val)
227{
228 u32 size = (u32)(res->end - res->start)+1;
229
230 size += CHECK_CHUNKSIZE-1;
231 size /= CHECK_CHUNKSIZE;
232
233 DBG("Area %08lx..%08lx, %d blocks\n", res->start, res->end, size);
234
235 *val += size * sizeof(u32);
236 return val;
237}
238
239/* s3c2410_pm_prepare_check
240 *
241 * prepare the necessary information for creating the CRCs. This
242 * must be done before the final save, as it will require memory
243 * allocating, and thus touching bits of the kernel we do not
244 * know about.
245*/
246
247static void s3c2410_pm_check_prepare(void)
248{ 48{
249 crc_size = 0; 49 /* ensure at least GSTATUS3 has the resume address */
250 50
251 s3c2410_pm_run_sysram(s3c2410_pm_countram, &crc_size); 51 __raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2410_GSTATUS3);
252 52
253 DBG("s3c2410_pm_prepare_check: %u checks needed\n", crc_size); 53 DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3));
54 DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4));
254 55
255 crcs = kmalloc(crc_size+4, GFP_KERNEL); 56 if (machine_is_h1940()) {
256 if (crcs == NULL) 57 void *base = phys_to_virt(H1940_SUSPEND_CHECK);
257 printk(KERN_ERR "Cannot allocated CRC save area\n"); 58 unsigned long ptr;
258} 59 unsigned long calc = 0;
259 60
260static u32 *s3c2410_pm_makecheck(struct resource *res, u32 *val) 61 /* generate check for the bootloader to check on resume */
261{
262 unsigned long addr, left;
263 62
264 for (addr = res->start; addr < res->end; 63 for (ptr = 0; ptr < 0x40000; ptr += 0x400)
265 addr += CHECK_CHUNKSIZE) { 64 calc += __raw_readl(base+ptr);
266 left = res->end - addr;
267 65
268 if (left > CHECK_CHUNKSIZE) 66 __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
269 left = CHECK_CHUNKSIZE;
270
271 *val = crc32_le(~0, phys_to_virt(addr), left);
272 val++;
273 } 67 }
274 68
275 return val; 69 /* the RX3715 uses similar code and the same H1940 and the
276} 70 * same offsets for resume and checksum pointers */
277
278/* s3c2410_pm_check_store
279 *
280 * compute the CRC values for the memory blocks before the final
281 * sleep.
282*/
283
284static void s3c2410_pm_check_store(void)
285{
286 if (crcs != NULL)
287 s3c2410_pm_run_sysram(s3c2410_pm_makecheck, crcs);
288}
289
290/* in_region
291 *
292 * return TRUE if the area defined by ptr..ptr+size contatins the
293 * what..what+whatsz
294*/
295
296static inline int in_region(void *ptr, int size, void *what, size_t whatsz)
297{
298 if ((what+whatsz) < ptr)
299 return 0;
300
301 if (what > (ptr+size))
302 return 0;
303
304 return 1;
305}
306
307static u32 *s3c2410_pm_runcheck(struct resource *res, u32 *val)
308{
309 void *save_at = phys_to_virt(s3c2410_sleep_save_phys);
310 unsigned long addr;
311 unsigned long left;
312 void *ptr;
313 u32 calc;
314
315 for (addr = res->start; addr < res->end;
316 addr += CHECK_CHUNKSIZE) {
317 left = res->end - addr;
318 71
319 if (left > CHECK_CHUNKSIZE) 72 if (machine_is_rx3715()) {
320 left = CHECK_CHUNKSIZE; 73 void *base = phys_to_virt(H1940_SUSPEND_CHECK);
74 unsigned long ptr;
75 unsigned long calc = 0;
321 76
322 ptr = phys_to_virt(addr); 77 /* generate check for the bootloader to check on resume */
323 78
324 if (in_region(ptr, left, crcs, crc_size)) { 79 for (ptr = 0; ptr < 0x40000; ptr += 0x4)
325 DBG("skipping %08lx, has crc block in\n", addr); 80 calc += __raw_readl(base+ptr);
326 goto skip_check;
327 }
328 81
329 if (in_region(ptr, left, save_at, 32*4 )) { 82 __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
330 DBG("skipping %08lx, has save block in\n", addr);
331 goto skip_check;
332 }
333
334 /* calculate and check the checksum */
335
336 calc = crc32_le(~0, ptr, left);
337 if (calc != *val) {
338 printk(KERN_ERR PFX "Restore CRC error at "
339 "%08lx (%08x vs %08x)\n", addr, calc, *val);
340
341 DBG("Restore CRC error at %08lx (%08x vs %08x)\n",
342 addr, calc, *val);
343 }
344
345 skip_check:
346 val++;
347 } 83 }
348 84
349 return val; 85 if ( machine_is_aml_m5900() )
350} 86 s3c2410_gpio_setpin(S3C2410_GPF2, 1);
351 87
352/* s3c2410_pm_check_restore
353 *
354 * check the CRCs after the restore event and free the memory used
355 * to hold them
356*/
357
358static void s3c2410_pm_check_restore(void)
359{
360 if (crcs != NULL) {
361 s3c2410_pm_run_sysram(s3c2410_pm_runcheck, crcs);
362 kfree(crcs);
363 crcs = NULL;
364 }
365} 88}
366 89
367#else 90static int s3c2410_pm_resume(struct sys_device *dev)
368
369#define s3c2410_pm_check_prepare() do { } while(0)
370#define s3c2410_pm_check_restore() do { } while(0)
371#define s3c2410_pm_check_store() do { } while(0)
372#endif
373
374/* helper functions to save and restore register state */
375
376void s3c2410_pm_do_save(struct sleep_save *ptr, int count)
377{ 91{
378 for (; count > 0; count--, ptr++) { 92 unsigned long tmp;
379 ptr->val = __raw_readl(ptr->reg);
380 DBG("saved %p value %08lx\n", ptr->reg, ptr->val);
381 }
382}
383 93
384/* s3c2410_pm_do_restore 94 /* unset the return-from-sleep flag, to ensure reset */
385 *
386 * restore the system from the given list of saved registers
387 *
388 * Note, we do not use DBG() in here, as the system may not have
389 * restore the UARTs state yet
390*/
391 95
392void s3c2410_pm_do_restore(struct sleep_save *ptr, int count) 96 tmp = __raw_readl(S3C2410_GSTATUS2);
393{ 97 tmp &= S3C2410_GSTATUS2_OFFRESET;
394 for (; count > 0; count--, ptr++) { 98 __raw_writel(tmp, S3C2410_GSTATUS2);
395 printk(KERN_DEBUG "restore %p (restore %08lx, was %08x)\n",
396 ptr->reg, ptr->val, __raw_readl(ptr->reg));
397
398 __raw_writel(ptr->val, ptr->reg);
399 }
400}
401 99
402/* s3c2410_pm_do_restore_core 100 if ( machine_is_aml_m5900() )
403 * 101 s3c2410_gpio_setpin(S3C2410_GPF2, 0);
404 * similar to s3c2410_pm_do_restore_core
405 *
406 * WARNING: Do not put any debug in here that may effect memory or use
407 * peripherals, as things may be changing!
408*/
409 102
410static void s3c2410_pm_do_restore_core(struct sleep_save *ptr, int count) 103 return 0;
411{
412 for (; count > 0; count--, ptr++) {
413 __raw_writel(ptr->val, ptr->reg);
414 }
415} 104}
416 105
417/* s3c2410_pm_show_resume_irqs 106static int s3c2410_pm_add(struct sys_device *dev)
418 *
419 * print any IRQs asserted at resume time (ie, we woke from)
420*/
421
422static void s3c2410_pm_show_resume_irqs(int start, unsigned long which,
423 unsigned long mask)
424{ 107{
425 int i; 108 pm_cpu_prep = s3c2410_pm_prepare;
109 pm_cpu_sleep = s3c2410_cpu_suspend;
426 110
427 which &= ~mask; 111 return 0;
428
429 for (i = 0; i <= 31; i++) {
430 if ((which) & (1L<<i)) {
431 DBG("IRQ %d asserted at resume\n", start+i);
432 }
433 }
434} 112}
435 113
436/* s3c2410_pm_check_resume_pin 114#if defined(CONFIG_CPU_S3C2410)
437 * 115static struct sysdev_driver s3c2410_pm_driver = {
438 * check to see if the pin is configured correctly for sleep mode, and 116 .add = s3c2410_pm_add,
439 * make any necessary adjustments if it is not 117 .resume = s3c2410_pm_resume,
440*/ 118};
441
442static void s3c2410_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
443{
444 unsigned long irqstate;
445 unsigned long pinstate;
446 int irq = s3c2410_gpio_getirq(pin);
447
448 if (irqoffs < 4)
449 irqstate = s3c_irqwake_intmask & (1L<<irqoffs);
450 else
451 irqstate = s3c_irqwake_eintmask & (1L<<irqoffs);
452
453 pinstate = s3c2410_gpio_getcfg(pin);
454
455 if (!irqstate) {
456 if (pinstate == S3C2410_GPIO_IRQ)
457 DBG("Leaving IRQ %d (pin %d) enabled\n", irq, pin);
458 } else {
459 if (pinstate == S3C2410_GPIO_IRQ) {
460 DBG("Disabling IRQ %d (pin %d)\n", irq, pin);
461 s3c2410_gpio_cfgpin(pin, S3C2410_GPIO_INPUT);
462 }
463 }
464}
465 119
466/* s3c2410_pm_configure_extint 120/* register ourselves */
467 *
468 * configure all external interrupt pins
469*/
470 121
471static void s3c2410_pm_configure_extint(void) 122static int __init s3c2410_pm_drvinit(void)
472{ 123{
473 int pin; 124 return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_pm_driver);
474
475 /* for each of the external interrupts (EINT0..EINT15) we
476 * need to check wether it is an external interrupt source,
477 * and then configure it as an input if it is not
478 */
479
480 for (pin = S3C2410_GPF0; pin <= S3C2410_GPF7; pin++) {
481 s3c2410_pm_check_resume_pin(pin, pin - S3C2410_GPF0);
482 }
483
484 for (pin = S3C2410_GPG0; pin <= S3C2410_GPG7; pin++) {
485 s3c2410_pm_check_resume_pin(pin, (pin - S3C2410_GPG0)+8);
486 }
487} 125}
488 126
489void (*pm_cpu_prep)(void); 127arch_initcall(s3c2410_pm_drvinit);
490void (*pm_cpu_sleep)(void); 128#endif
491
492#define any_allowed(mask, allow) (((mask) & (allow)) != (allow))
493
494/* s3c2410_pm_enter
495 *
496 * central control for sleep/resume process
497*/
498
499static int s3c2410_pm_enter(suspend_state_t state)
500{
501 unsigned long regs_save[16];
502
503 /* ensure the debug is initialised (if enabled) */
504
505 s3c2410_pm_debug_init();
506
507 DBG("s3c2410_pm_enter(%d)\n", state);
508
509 if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) {
510 printk(KERN_ERR PFX "error: no cpu sleep functions set\n");
511 return -EINVAL;
512 }
513
514 if (state != PM_SUSPEND_MEM) {
515 printk(KERN_ERR PFX "error: only PM_SUSPEND_MEM supported\n");
516 return -EINVAL;
517 }
518
519 /* check if we have anything to wake-up with... bad things seem
520 * to happen if you suspend with no wakeup (system will often
521 * require a full power-cycle)
522 */
523
524 if (!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) &&
525 !any_allowed(s3c_irqwake_eintmask, s3c_irqwake_eintallow)) {
526 printk(KERN_ERR PFX "No sources enabled for wake-up!\n");
527 printk(KERN_ERR PFX "Aborting sleep\n");
528 return -EINVAL;
529 }
530
531 /* prepare check area if configured */
532
533 s3c2410_pm_check_prepare();
534
535 /* store the physical address of the register recovery block */
536
537 s3c2410_sleep_save_phys = virt_to_phys(regs_save);
538
539 DBG("s3c2410_sleep_save_phys=0x%08lx\n", s3c2410_sleep_save_phys);
540
541 /* save all necessary core registers not covered by the drivers */
542
543 s3c2410_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save));
544 s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save));
545 s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save));
546
547 /* set the irq configuration for wake */
548
549 s3c2410_pm_configure_extint();
550
551 DBG("sleep: irq wakeup masks: %08lx,%08lx\n",
552 s3c_irqwake_intmask, s3c_irqwake_eintmask);
553
554 __raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK);
555 __raw_writel(s3c_irqwake_eintmask, S3C2410_EINTMASK);
556
557 /* ack any outstanding external interrupts before we go to sleep */
558
559 __raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND);
560 __raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND);
561 __raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND);
562
563 /* call cpu specific preperation */
564
565 pm_cpu_prep();
566
567 /* flush cache back to ram */
568
569 flush_cache_all();
570
571 s3c2410_pm_check_store();
572
573 /* send the cpu to sleep... */
574
575 __raw_writel(0x00, S3C2410_CLKCON); /* turn off clocks over sleep */
576
577 /* s3c2410_cpu_save will also act as our return point from when
578 * we resume as it saves its own register state, so use the return
579 * code to differentiate return from save and return from sleep */
580
581 if (s3c2410_cpu_save(regs_save) == 0) {
582 flush_cache_all();
583 pm_cpu_sleep();
584 }
585
586 /* restore the cpu state */
587
588 cpu_init();
589
590 /* restore the system state */
591
592 s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
593 s3c2410_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save));
594 s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save));
595
596 s3c2410_pm_debug_init();
597
598 /* check what irq (if any) restored the system */
599
600 DBG("post sleep: IRQs 0x%08x, 0x%08x\n",
601 __raw_readl(S3C2410_SRCPND),
602 __raw_readl(S3C2410_EINTPEND));
603
604 s3c2410_pm_show_resume_irqs(IRQ_EINT0, __raw_readl(S3C2410_SRCPND),
605 s3c_irqwake_intmask);
606
607 s3c2410_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND),
608 s3c_irqwake_eintmask);
609
610 DBG("post sleep, preparing to return\n");
611
612 s3c2410_pm_check_restore();
613
614 /* ok, let's return from sleep */
615 129
616 DBG("S3C2410 PM Resume (post-restore)\n"); 130#if defined(CONFIG_CPU_S3C2440)
617 return 0; 131static struct sysdev_driver s3c2440_pm_driver = {
618} 132 .add = s3c2410_pm_add,
133 .resume = s3c2410_pm_resume,
134};
619 135
620/* 136static int __init s3c2440_pm_drvinit(void)
621 * Called after processes are frozen, but before we shut down devices.
622 */
623static int s3c2410_pm_prepare(suspend_state_t state)
624{ 137{
625 return 0; 138 return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_pm_driver);
626} 139}
627 140
628/* 141arch_initcall(s3c2440_pm_drvinit);
629 * Called after devices are re-setup, but before processes are thawed. 142#endif
630 */
631static int s3c2410_pm_finish(suspend_state_t state)
632{
633 return 0;
634}
635 143
636/* 144#if defined(CONFIG_CPU_S3C2442)
637 * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk. 145static struct sysdev_driver s3c2442_pm_driver = {
638 */ 146 .add = s3c2410_pm_add,
639static struct pm_ops s3c2410_pm_ops = { 147 .resume = s3c2410_pm_resume,
640 .pm_disk_mode = PM_DISK_FIRMWARE,
641 .prepare = s3c2410_pm_prepare,
642 .enter = s3c2410_pm_enter,
643 .finish = s3c2410_pm_finish,
644}; 148};
645 149
646/* s3c2410_pm_init 150static int __init s3c2442_pm_drvinit(void)
647 *
648 * Attach the power management functions. This should be called
649 * from the board specific initialisation if the board supports
650 * it.
651*/
652
653int __init s3c2410_pm_init(void)
654{ 151{
655 printk("S3C2410 Power Management, (c) 2004 Simtec Electronics\n"); 152 return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_pm_driver);
656
657 pm_set_ops(&s3c2410_pm_ops);
658 return 0;
659} 153}
154
155arch_initcall(s3c2442_pm_drvinit);
156#endif
diff --git a/arch/arm/mach-s3c2410/s3c2410-clock.c b/arch/arm/mach-s3c2410/s3c2410-clock.c
deleted file mode 100644
index 992cc6af230e..000000000000
--- a/arch/arm/mach-s3c2410/s3c2410-clock.c
+++ /dev/null
@@ -1,276 +0,0 @@
1/* linux/arch/arm/mach-s3c2410/s3c2410-clock.c
2 *
3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2410,S3C2440,S3C2442 Clock control support
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 of the License, or
11 * (at your option) 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21*/
22
23#include <linux/init.h>
24#include <linux/module.h>
25#include <linux/kernel.h>
26#include <linux/list.h>
27#include <linux/errno.h>
28#include <linux/err.h>
29#include <linux/sysdev.h>
30#include <linux/clk.h>
31#include <linux/mutex.h>
32#include <linux/delay.h>
33#include <linux/serial_core.h>
34
35#include <asm/mach/map.h>
36
37#include <asm/hardware.h>
38#include <asm/io.h>
39
40#include <asm/arch/regs-serial.h>
41#include <asm/arch/regs-clock.h>
42#include <asm/arch/regs-gpio.h>
43
44#include "s3c2410.h"
45#include "clock.h"
46#include "cpu.h"
47
48int s3c2410_clkcon_enable(struct clk *clk, int enable)
49{
50 unsigned int clocks = clk->ctrlbit;
51 unsigned long clkcon;
52
53 clkcon = __raw_readl(S3C2410_CLKCON);
54
55 if (enable)
56 clkcon |= clocks;
57 else
58 clkcon &= ~clocks;
59
60 /* ensure none of the special function bits set */
61 clkcon &= ~(S3C2410_CLKCON_IDLE|S3C2410_CLKCON_POWER);
62
63 __raw_writel(clkcon, S3C2410_CLKCON);
64
65 return 0;
66}
67
68static int s3c2410_upll_enable(struct clk *clk, int enable)
69{
70 unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
71 unsigned long orig = clkslow;
72
73 if (enable)
74 clkslow &= ~S3C2410_CLKSLOW_UCLK_OFF;
75 else
76 clkslow |= S3C2410_CLKSLOW_UCLK_OFF;
77
78 __raw_writel(clkslow, S3C2410_CLKSLOW);
79
80 /* if we started the UPLL, then allow to settle */
81
82 if (enable && (orig & S3C2410_CLKSLOW_UCLK_OFF))
83 udelay(200);
84
85 return 0;
86}
87
88/* standard clock definitions */
89
90static struct clk init_clocks_disable[] = {
91 {
92 .name = "nand",
93 .id = -1,
94 .parent = &clk_h,
95 .enable = s3c2410_clkcon_enable,
96 .ctrlbit = S3C2410_CLKCON_NAND,
97 }, {
98 .name = "sdi",
99 .id = -1,
100 .parent = &clk_p,
101 .enable = s3c2410_clkcon_enable,
102 .ctrlbit = S3C2410_CLKCON_SDI,
103 }, {
104 .name = "adc",
105 .id = -1,
106 .parent = &clk_p,
107 .enable = s3c2410_clkcon_enable,
108 .ctrlbit = S3C2410_CLKCON_ADC,
109 }, {
110 .name = "i2c",
111 .id = -1,
112 .parent = &clk_p,
113 .enable = s3c2410_clkcon_enable,
114 .ctrlbit = S3C2410_CLKCON_IIC,
115 }, {
116 .name = "iis",
117 .id = -1,
118 .parent = &clk_p,
119 .enable = s3c2410_clkcon_enable,
120 .ctrlbit = S3C2410_CLKCON_IIS,
121 }, {
122 .name = "spi",
123 .id = -1,
124 .parent = &clk_p,
125 .enable = s3c2410_clkcon_enable,
126 .ctrlbit = S3C2410_CLKCON_SPI,
127 }
128};
129
130static struct clk init_clocks[] = {
131 {
132 .name = "lcd",
133 .id = -1,
134 .parent = &clk_h,
135 .enable = s3c2410_clkcon_enable,
136 .ctrlbit = S3C2410_CLKCON_LCDC,
137 }, {
138 .name = "gpio",
139 .id = -1,
140 .parent = &clk_p,
141 .enable = s3c2410_clkcon_enable,
142 .ctrlbit = S3C2410_CLKCON_GPIO,
143 }, {
144 .name = "usb-host",
145 .id = -1,
146 .parent = &clk_h,
147 .enable = s3c2410_clkcon_enable,
148 .ctrlbit = S3C2410_CLKCON_USBH,
149 }, {
150 .name = "usb-device",
151 .id = -1,
152 .parent = &clk_h,
153 .enable = s3c2410_clkcon_enable,
154 .ctrlbit = S3C2410_CLKCON_USBD,
155 }, {
156 .name = "timers",
157 .id = -1,
158 .parent = &clk_p,
159 .enable = s3c2410_clkcon_enable,
160 .ctrlbit = S3C2410_CLKCON_PWMT,
161 }, {
162 .name = "uart",
163 .id = 0,
164 .parent = &clk_p,
165 .enable = s3c2410_clkcon_enable,
166 .ctrlbit = S3C2410_CLKCON_UART0,
167 }, {
168 .name = "uart",
169 .id = 1,
170 .parent = &clk_p,
171 .enable = s3c2410_clkcon_enable,
172 .ctrlbit = S3C2410_CLKCON_UART1,
173 }, {
174 .name = "uart",
175 .id = 2,
176 .parent = &clk_p,
177 .enable = s3c2410_clkcon_enable,
178 .ctrlbit = S3C2410_CLKCON_UART2,
179 }, {
180 .name = "rtc",
181 .id = -1,
182 .parent = &clk_p,
183 .enable = s3c2410_clkcon_enable,
184 .ctrlbit = S3C2410_CLKCON_RTC,
185 }, {
186 .name = "watchdog",
187 .id = -1,
188 .parent = &clk_p,
189 .ctrlbit = 0,
190 }, {
191 .name = "usb-bus-host",
192 .id = -1,
193 .parent = &clk_usb_bus,
194 }, {
195 .name = "usb-bus-gadget",
196 .id = -1,
197 .parent = &clk_usb_bus,
198 },
199};
200
201/* s3c2410_baseclk_add()
202 *
203 * Add all the clocks used by the s3c2410 or compatible CPUs
204 * such as the S3C2440 and S3C2442.
205 *
206 * We cannot use a system device as we are needed before any
207 * of the init-calls that initialise the devices are actually
208 * done.
209*/
210
211int __init s3c2410_baseclk_add(void)
212{
213 unsigned long clkslow = __raw_readl(S3C2410_CLKSLOW);
214 unsigned long clkcon = __raw_readl(S3C2410_CLKCON);
215 struct clk *clkp;
216 struct clk *xtal;
217 int ret;
218 int ptr;
219
220 clk_upll.enable = s3c2410_upll_enable;
221
222 if (s3c24xx_register_clock(&clk_usb_bus) < 0)
223 printk(KERN_ERR "failed to register usb bus clock\n");
224
225 /* register clocks from clock array */
226
227 clkp = init_clocks;
228 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
229 /* ensure that we note the clock state */
230
231 clkp->usage = clkcon & clkp->ctrlbit ? 1 : 0;
232
233 ret = s3c24xx_register_clock(clkp);
234 if (ret < 0) {
235 printk(KERN_ERR "Failed to register clock %s (%d)\n",
236 clkp->name, ret);
237 }
238 }
239
240 /* We must be careful disabling the clocks we are not intending to
241 * be using at boot time, as subsytems such as the LCD which do
242 * their own DMA requests to the bus can cause the system to lockup
243 * if they where in the middle of requesting bus access.
244 *
245 * Disabling the LCD clock if the LCD is active is very dangerous,
246 * and therefore the bootloader should be careful to not enable
247 * the LCD clock if it is not needed.
248 */
249
250 /* install (and disable) the clocks we do not need immediately */
251
252 clkp = init_clocks_disable;
253 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
254
255 ret = s3c24xx_register_clock(clkp);
256 if (ret < 0) {
257 printk(KERN_ERR "Failed to register clock %s (%d)\n",
258 clkp->name, ret);
259 }
260
261 s3c2410_clkcon_enable(clkp, 0);
262 }
263
264 /* show the clock-slow value */
265
266 xtal = clk_get(NULL, "xtal");
267
268 printk("CLOCK: Slow mode (%ld.%ld MHz), %s, MPLL %s, UPLL %s\n",
269 print_mhz(clk_get_rate(xtal) /
270 ( 2 * S3C2410_CLKSLOW_GET_SLOWVAL(clkslow))),
271 (clkslow & S3C2410_CLKSLOW_SLOW) ? "slow" : "fast",
272 (clkslow & S3C2410_CLKSLOW_MPLL_OFF) ? "off" : "on",
273 (clkslow & S3C2410_CLKSLOW_UCLK_OFF) ? "off" : "on");
274
275 return 0;
276}
diff --git a/arch/arm/mach-s3c2410/s3c2410-dma.c b/arch/arm/mach-s3c2410/s3c2410-dma.c
deleted file mode 100644
index e67ba3911f11..000000000000
--- a/arch/arm/mach-s3c2410/s3c2410-dma.c
+++ /dev/null
@@ -1,161 +0,0 @@
1/* linux/arch/arm/mach-s3c2410/s3c2410-dma.c
2 *
3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2410 DMA selection
7 *
8 * http://armlinux.simtec.co.uk/
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 version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/sysdev.h>
18#include <linux/serial_core.h>
19
20#include <asm/dma.h>
21#include <asm/arch/dma.h>
22#include "dma.h"
23
24#include "cpu.h"
25
26#include <asm/arch/regs-serial.h>
27#include <asm/arch/regs-gpio.h>
28#include <asm/arch/regs-ac97.h>
29#include <asm/arch/regs-mem.h>
30#include <asm/arch/regs-lcd.h>
31#include <asm/arch/regs-sdi.h>
32#include <asm/arch/regs-iis.h>
33#include <asm/arch/regs-spi.h>
34
35static struct s3c24xx_dma_map __initdata s3c2410_dma_mappings[] = {
36 [DMACH_XD0] = {
37 .name = "xdreq0",
38 .channels[0] = S3C2410_DCON_CH0_XDREQ0 | DMA_CH_VALID,
39 },
40 [DMACH_XD1] = {
41 .name = "xdreq1",
42 .channels[1] = S3C2410_DCON_CH1_XDREQ1 | DMA_CH_VALID,
43 },
44 [DMACH_SDI] = {
45 .name = "sdi",
46 .channels[0] = S3C2410_DCON_CH0_SDI | DMA_CH_VALID,
47 .channels[2] = S3C2410_DCON_CH2_SDI | DMA_CH_VALID,
48 .channels[3] = S3C2410_DCON_CH3_SDI | DMA_CH_VALID,
49 .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO,
50 .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO,
51 },
52 [DMACH_SPI0] = {
53 .name = "spi0",
54 .channels[1] = S3C2410_DCON_CH1_SPI | DMA_CH_VALID,
55 .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT,
56 .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT,
57 },
58 [DMACH_SPI1] = {
59 .name = "spi1",
60 .channels[3] = S3C2410_DCON_CH3_SPI | DMA_CH_VALID,
61 .hw_addr.to = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
62 .hw_addr.from = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
63 },
64 [DMACH_UART0] = {
65 .name = "uart0",
66 .channels[0] = S3C2410_DCON_CH0_UART0 | DMA_CH_VALID,
67 .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH,
68 .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH,
69 },
70 [DMACH_UART1] = {
71 .name = "uart1",
72 .channels[1] = S3C2410_DCON_CH1_UART1 | DMA_CH_VALID,
73 .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH,
74 .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH,
75 },
76 [DMACH_UART2] = {
77 .name = "uart2",
78 .channels[3] = S3C2410_DCON_CH3_UART2 | DMA_CH_VALID,
79 .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH,
80 .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH,
81 },
82 [DMACH_TIMER] = {
83 .name = "timer",
84 .channels[0] = S3C2410_DCON_CH0_TIMER | DMA_CH_VALID,
85 .channels[2] = S3C2410_DCON_CH2_TIMER | DMA_CH_VALID,
86 .channels[3] = S3C2410_DCON_CH3_TIMER | DMA_CH_VALID,
87 },
88 [DMACH_I2S_IN] = {
89 .name = "i2s-sdi",
90 .channels[1] = S3C2410_DCON_CH1_I2SSDI | DMA_CH_VALID,
91 .channels[2] = S3C2410_DCON_CH2_I2SSDI | DMA_CH_VALID,
92 .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO,
93 },
94 [DMACH_I2S_OUT] = {
95 .name = "i2s-sdo",
96 .channels[2] = S3C2410_DCON_CH2_I2SSDO | DMA_CH_VALID,
97 .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO,
98 },
99 [DMACH_USB_EP1] = {
100 .name = "usb-ep1",
101 .channels[0] = S3C2410_DCON_CH0_USBEP1 | DMA_CH_VALID,
102 },
103 [DMACH_USB_EP2] = {
104 .name = "usb-ep2",
105 .channels[1] = S3C2410_DCON_CH1_USBEP2 | DMA_CH_VALID,
106 },
107 [DMACH_USB_EP3] = {
108 .name = "usb-ep3",
109 .channels[2] = S3C2410_DCON_CH2_USBEP3 | DMA_CH_VALID,
110 },
111 [DMACH_USB_EP4] = {
112 .name = "usb-ep4",
113 .channels[3] =S3C2410_DCON_CH3_USBEP4 | DMA_CH_VALID,
114 },
115};
116
117static void s3c2410_dma_select(struct s3c2410_dma_chan *chan,
118 struct s3c24xx_dma_map *map)
119{
120 chan->dcon = map->channels[chan->number] & ~DMA_CH_VALID;
121}
122
123static struct s3c24xx_dma_selection __initdata s3c2410_dma_sel = {
124 .select = s3c2410_dma_select,
125 .dcon_mask = 7 << 24,
126 .map = s3c2410_dma_mappings,
127 .map_size = ARRAY_SIZE(s3c2410_dma_mappings),
128};
129
130static int s3c2410_dma_add(struct sys_device *sysdev)
131{
132 return s3c24xx_dma_init_map(&s3c2410_dma_sel);
133}
134
135#if defined(CONFIG_CPU_S3C2410)
136static struct sysdev_driver s3c2410_dma_driver = {
137 .add = s3c2410_dma_add,
138};
139
140static int __init s3c2410_dma_init(void)
141{
142 return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_dma_driver);
143}
144
145arch_initcall(s3c2410_dma_init);
146#endif
147
148#if defined(CONFIG_CPU_S3C2442)
149/* S3C2442 DMA contains the same selection table as the S3C2410 */
150static struct sysdev_driver s3c2442_dma_driver = {
151 .add = s3c2410_dma_add,
152};
153
154static int __init s3c2442_dma_init(void)
155{
156 return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_dma_driver);
157}
158
159arch_initcall(s3c2442_dma_init);
160#endif
161
diff --git a/arch/arm/mach-s3c2410/s3c2410-gpio.c b/arch/arm/mach-s3c2410/s3c2410-gpio.c
deleted file mode 100644
index ec3a276cc3cf..000000000000
--- a/arch/arm/mach-s3c2410/s3c2410-gpio.c
+++ /dev/null
@@ -1,71 +0,0 @@
1/* linux/arch/arm/mach-s3c2410/s3c2410-gpio.c
2 *
3 * Copyright (c) 2004-2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2410 GPIO support
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 of the License, or
11 * (at your option) 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 */
22
23#include <linux/kernel.h>
24#include <linux/init.h>
25#include <linux/module.h>
26#include <linux/interrupt.h>
27#include <linux/ioport.h>
28
29#include <asm/hardware.h>
30#include <asm/irq.h>
31#include <asm/io.h>
32
33#include <asm/arch/regs-gpio.h>
34
35int s3c2410_gpio_irqfilter(unsigned int pin, unsigned int on,
36 unsigned int config)
37{
38 void __iomem *reg = S3C24XX_EINFLT0;
39 unsigned long flags;
40 unsigned long val;
41
42 if (pin < S3C2410_GPG8 || pin > S3C2410_GPG15)
43 return -1;
44
45 config &= 0xff;
46
47 pin -= S3C2410_GPG8;
48 reg += pin & ~3;
49
50 local_irq_save(flags);
51
52 /* update filter width and clock source */
53
54 val = __raw_readl(reg);
55 val &= ~(0xff << ((pin & 3) * 8));
56 val |= config << ((pin & 3) * 8);
57 __raw_writel(val, reg);
58
59 /* update filter enable */
60
61 val = __raw_readl(S3C24XX_EXTINT2);
62 val &= ~(1 << ((pin * 4) + 3));
63 val |= on << ((pin * 4) + 3);
64 __raw_writel(val, S3C24XX_EXTINT2);
65
66 local_irq_restore(flags);
67
68 return 0;
69}
70
71EXPORT_SYMBOL(s3c2410_gpio_irqfilter);
diff --git a/arch/arm/mach-s3c2410/s3c2410-irq.c b/arch/arm/mach-s3c2410/s3c2410-irq.c
deleted file mode 100644
index c796c9c76e78..000000000000
--- a/arch/arm/mach-s3c2410/s3c2410-irq.c
+++ /dev/null
@@ -1,48 +0,0 @@
1/* linux/arch/arm/mach-s3c2410/s3c2410-irq.c
2 *
3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
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
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/interrupt.h>
25#include <linux/ioport.h>
26#include <linux/ptrace.h>
27#include <linux/sysdev.h>
28
29#include "cpu.h"
30#include "pm.h"
31
32static int s3c2410_irq_add(struct sys_device *sysdev)
33{
34 return 0;
35}
36
37static struct sysdev_driver s3c2410_irq_driver = {
38 .add = s3c2410_irq_add,
39 .suspend = s3c24xx_irq_suspend,
40 .resume = s3c24xx_irq_resume,
41};
42
43static int s3c2410_irq_init(void)
44{
45 return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_irq_driver);
46}
47
48arch_initcall(s3c2410_irq_init);
diff --git a/arch/arm/mach-s3c2410/s3c2410-pm.c b/arch/arm/mach-s3c2410/s3c2410-pm.c
deleted file mode 100644
index 8bb6e5e21f59..000000000000
--- a/arch/arm/mach-s3c2410/s3c2410-pm.c
+++ /dev/null
@@ -1,156 +0,0 @@
1/* linux/arch/arm/mach-s3c2410/s3c2410-pm.c
2 *
3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2410 (and compatible) Power Manager (Suspend-To-RAM) support
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 of the License, or
11 * (at your option) 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21*/
22
23#include <linux/init.h>
24#include <linux/suspend.h>
25#include <linux/errno.h>
26#include <linux/time.h>
27#include <linux/sysdev.h>
28
29#include <asm/hardware.h>
30#include <asm/io.h>
31
32#include <asm/mach-types.h>
33
34#include <asm/arch/regs-gpio.h>
35#include <asm/arch/h1940.h>
36
37#include "cpu.h"
38#include "pm.h"
39
40#ifdef CONFIG_S3C2410_PM_DEBUG
41extern void pm_dbg(const char *fmt, ...);
42#define DBG(fmt...) pm_dbg(fmt)
43#else
44#define DBG(fmt...) printk(KERN_DEBUG fmt)
45#endif
46
47static void s3c2410_pm_prepare(void)
48{
49 /* ensure at least GSTATUS3 has the resume address */
50
51 __raw_writel(virt_to_phys(s3c2410_cpu_resume), S3C2410_GSTATUS3);
52
53 DBG("GSTATUS3 0x%08x\n", __raw_readl(S3C2410_GSTATUS3));
54 DBG("GSTATUS4 0x%08x\n", __raw_readl(S3C2410_GSTATUS4));
55
56 if (machine_is_h1940()) {
57 void *base = phys_to_virt(H1940_SUSPEND_CHECK);
58 unsigned long ptr;
59 unsigned long calc = 0;
60
61 /* generate check for the bootloader to check on resume */
62
63 for (ptr = 0; ptr < 0x40000; ptr += 0x400)
64 calc += __raw_readl(base+ptr);
65
66 __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
67 }
68
69 /* the RX3715 uses similar code and the same H1940 and the
70 * same offsets for resume and checksum pointers */
71
72 if (machine_is_rx3715()) {
73 void *base = phys_to_virt(H1940_SUSPEND_CHECK);
74 unsigned long ptr;
75 unsigned long calc = 0;
76
77 /* generate check for the bootloader to check on resume */
78
79 for (ptr = 0; ptr < 0x40000; ptr += 0x4)
80 calc += __raw_readl(base+ptr);
81
82 __raw_writel(calc, phys_to_virt(H1940_SUSPEND_CHECKSUM));
83 }
84
85 if ( machine_is_aml_m5900() )
86 s3c2410_gpio_setpin(S3C2410_GPF2, 1);
87
88}
89
90static int s3c2410_pm_resume(struct sys_device *dev)
91{
92 unsigned long tmp;
93
94 /* unset the return-from-sleep flag, to ensure reset */
95
96 tmp = __raw_readl(S3C2410_GSTATUS2);
97 tmp &= S3C2410_GSTATUS2_OFFRESET;
98 __raw_writel(tmp, S3C2410_GSTATUS2);
99
100 if ( machine_is_aml_m5900() )
101 s3c2410_gpio_setpin(S3C2410_GPF2, 0);
102
103 return 0;
104}
105
106static int s3c2410_pm_add(struct sys_device *dev)
107{
108 pm_cpu_prep = s3c2410_pm_prepare;
109 pm_cpu_sleep = s3c2410_cpu_suspend;
110
111 return 0;
112}
113
114#if defined(CONFIG_CPU_S3C2410)
115static struct sysdev_driver s3c2410_pm_driver = {
116 .add = s3c2410_pm_add,
117 .resume = s3c2410_pm_resume,
118};
119
120/* register ourselves */
121
122static int __init s3c2410_pm_drvinit(void)
123{
124 return sysdev_driver_register(&s3c2410_sysclass, &s3c2410_pm_driver);
125}
126
127arch_initcall(s3c2410_pm_drvinit);
128#endif
129
130#if defined(CONFIG_CPU_S3C2440)
131static struct sysdev_driver s3c2440_pm_driver = {
132 .add = s3c2410_pm_add,
133 .resume = s3c2410_pm_resume,
134};
135
136static int __init s3c2440_pm_drvinit(void)
137{
138 return sysdev_driver_register(&s3c2440_sysclass, &s3c2440_pm_driver);
139}
140
141arch_initcall(s3c2440_pm_drvinit);
142#endif
143
144#if defined(CONFIG_CPU_S3C2442)
145static struct sysdev_driver s3c2442_pm_driver = {
146 .add = s3c2410_pm_add,
147 .resume = s3c2410_pm_resume,
148};
149
150static int __init s3c2442_pm_drvinit(void)
151{
152 return sysdev_driver_register(&s3c2442_sysclass, &s3c2442_pm_driver);
153}
154
155arch_initcall(s3c2442_pm_drvinit);
156#endif
diff --git a/arch/arm/mach-s3c2410/s3c2410-sleep.S b/arch/arm/mach-s3c2410/s3c2410-sleep.S
deleted file mode 100644
index 9179a1024588..000000000000
--- a/arch/arm/mach-s3c2410/s3c2410-sleep.S
+++ /dev/null
@@ -1,68 +0,0 @@
1/* linux/arch/arm/mach-s3c2410/s3c2410-sleep.S
2 *
3 * Copyright (c) 2004 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2410 Power Manager (Suspend-To-RAM) support
7 *
8 * Based on PXA/SA1100 sleep code by:
9 * Nicolas Pitre, (c) 2002 Monta Vista Software Inc
10 * Cliff Brake, (c) 2001
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 as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25*/
26
27#include <linux/linkage.h>
28#include <asm/assembler.h>
29#include <asm/hardware.h>
30#include <asm/arch/map.h>
31
32#include <asm/arch/regs-gpio.h>
33#include <asm/arch/regs-clock.h>
34#include <asm/arch/regs-mem.h>
35#include <asm/arch/regs-serial.h>
36
37 /* s3c2410_cpu_suspend
38 *
39 * put the cpu into sleep mode
40 */
41
42ENTRY(s3c2410_cpu_suspend)
43 @@ prepare cpu to sleep
44
45 ldr r4, =S3C2410_REFRESH
46 ldr r5, =S3C24XX_MISCCR
47 ldr r6, =S3C2410_CLKCON
48 ldr r7, [ r4 ] @ get REFRESH (and ensure in TLB)
49 ldr r8, [ r5 ] @ get MISCCR (and ensure in TLB)
50 ldr r9, [ r6 ] @ get CLKCON (and ensure in TLB)
51
52 orr r7, r7, #S3C2410_REFRESH_SELF @ SDRAM sleep command
53 orr r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals
54 orr r9, r9, #S3C2410_CLKCON_POWER @ power down command
55
56 teq pc, #0 @ first as a trial-run to load cache
57 bl s3c2410_do_sleep
58 teq r0, r0 @ now do it for real
59 b s3c2410_do_sleep @
60
61 @@ align next bit of code to cache line
62 .align 8
63s3c2410_do_sleep:
64 streq r7, [ r4 ] @ SDRAM sleep command
65 streq r8, [ r5 ] @ SDRAM power-down config
66 streq r9, [ r6 ] @ CPU sleep
671: beq 1b
68 mov pc, r14
diff --git a/arch/arm/mach-s3c2410/s3c2410.c b/arch/arm/mach-s3c2410/s3c2410.c
index 4cdc0d70c19f..1a86a9803753 100644
--- a/arch/arm/mach-s3c2410/s3c2410.c
+++ b/arch/arm/mach-s3c2410/s3c2410.c
@@ -31,10 +31,10 @@
31#include <asm/arch/regs-clock.h> 31#include <asm/arch/regs-clock.h>
32#include <asm/arch/regs-serial.h> 32#include <asm/arch/regs-serial.h>
33 33
34#include "s3c2410.h" 34#include <asm/plat-s3c24xx/s3c2410.h>
35#include "cpu.h" 35#include <asm/plat-s3c24xx/cpu.h>
36#include "devs.h" 36#include <asm/plat-s3c24xx/devs.h>
37#include "clock.h" 37#include <asm/plat-s3c24xx/clock.h>
38 38
39/* Initial IO mappings */ 39/* Initial IO mappings */
40 40
@@ -110,7 +110,7 @@ static struct sys_device s3c2410_sysdev = {
110 110
111/* need to register class before we actually register the device, and 111/* need to register class before we actually register the device, and
112 * we also need to ensure that it has been initialised before any of the 112 * we also need to ensure that it has been initialised before any of the
113 * drivers even try to use it (even if not on an s3c2440 based system) 113 * drivers even try to use it (even if not on an s3c2410 based system)
114 * as a driver which may support both 2410 and 2440 may try and use it. 114 * as a driver which may support both 2410 and 2440 may try and use it.
115*/ 115*/
116 116
diff --git a/arch/arm/mach-s3c2410/sleep.S b/arch/arm/mach-s3c2410/sleep.S
index 2018c2e1dcc5..637aaba65390 100644
--- a/arch/arm/mach-s3c2410/sleep.S
+++ b/arch/arm/mach-s3c2410/sleep.S
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/sleep.S 1/* linux/arch/arm/mach-s3c2410/s3c2410-sleep.S
2 * 2 *
3 * Copyright (c) 2004 Simtec Electronics 3 * Copyright (c) 2004 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
@@ -34,126 +34,35 @@
34#include <asm/arch/regs-mem.h> 34#include <asm/arch/regs-mem.h>
35#include <asm/arch/regs-serial.h> 35#include <asm/arch/regs-serial.h>
36 36
37/* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not 37 /* s3c2410_cpu_suspend
38 * reset the UART configuration, only enable if you really need this!
39*/
40//#define CONFIG_DEBUG_RESUME
41
42 .text
43
44 /* s3c2410_cpu_save
45 *
46 * save enough of the CPU state to allow us to re-start
47 * pm.c code. as we store items like the sp/lr, we will
48 * end up returning from this function when the cpu resumes
49 * so the return value is set to mark this.
50 *
51 * This arangement means we avoid having to flush the cache
52 * from this code.
53 *
54 * entry:
55 * r0 = pointer to save block
56 *
57 * exit:
58 * r0 = 0 => we stored everything
59 * 1 => resumed from sleep
60 */
61
62ENTRY(s3c2410_cpu_save)
63 stmfd sp!, { r4 - r12, lr }
64
65 @@ store co-processor registers
66
67 mrc p15, 0, r4, c15, c1, 0 @ CP access register
68 mrc p15, 0, r5, c13, c0, 0 @ PID
69 mrc p15, 0, r6, c3, c0, 0 @ Domain ID
70 mrc p15, 0, r7, c2, c0, 0 @ translation table base address
71 mrc p15, 0, r8, c1, c0, 0 @ control register
72
73 stmia r0, { r4 - r13 }
74
75 mov r0, #0
76 ldmfd sp, { r4 - r12, pc }
77
78 @@ return to the caller, after having the MMU
79 @@ turned on, this restores the last bits from the
80 @@ stack
81resume_with_mmu:
82 mov r0, #1
83 ldmfd sp!, { r4 - r12, pc }
84
85 .ltorg
86
87 @@ the next bits sit in the .data segment, even though they
88 @@ happen to be code... the s3c2410_sleep_save_phys needs to be
89 @@ accessed by the resume code before it can restore the MMU.
90 @@ This means that the variable has to be close enough for the
91 @@ code to read it... since the .text segment needs to be RO,
92 @@ the data segment can be the only place to put this code.
93
94 .data
95
96 .global s3c2410_sleep_save_phys
97s3c2410_sleep_save_phys:
98 .word 0
99
100 /* s3c2410_cpu_resume
101 * 38 *
102 * resume code entry for bootloader to call 39 * put the cpu into sleep mode
103 *
104 * we must put this code here in the data segment as we have no
105 * other way of restoring the stack pointer after sleep, and we
106 * must not write to the code segment (code is read-only)
107 */ 40 */
108 41
109ENTRY(s3c2410_cpu_resume) 42ENTRY(s3c2410_cpu_suspend)
110 mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE 43 @@ prepare cpu to sleep
111 msr cpsr_c, r0 44
112 45 ldr r4, =S3C2410_REFRESH
113 @@ load UART to allow us to print the two characters for 46 ldr r5, =S3C24XX_MISCCR
114 @@ resume debug 47 ldr r6, =S3C2410_CLKCON
115 48 ldr r7, [ r4 ] @ get REFRESH (and ensure in TLB)
116 mov r2, #S3C24XX_PA_UART & 0xff000000 49 ldr r8, [ r5 ] @ get MISCCR (and ensure in TLB)
117 orr r2, r2, #S3C24XX_PA_UART & 0xff000 50 ldr r9, [ r6 ] @ get CLKCON (and ensure in TLB)
118 51
119#if 0 52 orr r7, r7, #S3C2410_REFRESH_SELF @ SDRAM sleep command
120 /* SMDK2440 LED set */ 53 orr r8, r8, #S3C2410_MISCCR_SDSLEEP @ SDRAM power-down signals
121 mov r14, #S3C24XX_PA_GPIO 54 orr r9, r9, #S3C2410_CLKCON_POWER @ power down command
122 ldr r12, [ r14, #0x54 ] 55
123 bic r12, r12, #3<<4 56 teq pc, #0 @ first as a trial-run to load cache
124 orr r12, r12, #1<<7 57 bl s3c2410_do_sleep
125 str r12, [ r14, #0x54 ] 58 teq r0, r0 @ now do it for real
126#endif 59 b s3c2410_do_sleep @
127 60
128#ifdef CONFIG_DEBUG_RESUME 61 @@ align next bit of code to cache line
129 mov r3, #'L' 62 .align 5
130 strb r3, [ r2, #S3C2410_UTXH ] 63s3c2410_do_sleep:
1311001: 64 streq r7, [ r4 ] @ SDRAM sleep command
132 ldrb r14, [ r3, #S3C2410_UTRSTAT ] 65 streq r8, [ r5 ] @ SDRAM power-down config
133 tst r14, #S3C2410_UTRSTAT_TXE 66 streq r9, [ r6 ] @ CPU sleep
134 beq 1001b 671: beq 1b
135#endif /* CONFIG_DEBUG_RESUME */ 68 mov pc, r14
136
137 mov r1, #0
138 mcr p15, 0, r1, c8, c7, 0 @@ invalidate I & D TLBs
139 mcr p15, 0, r1, c7, c7, 0 @@ invalidate I & D caches
140
141 ldr r0, s3c2410_sleep_save_phys @ address of restore block
142 ldmia r0, { r4 - r13 }
143
144 mcr p15, 0, r4, c15, c1, 0 @ CP access register
145 mcr p15, 0, r5, c13, c0, 0 @ PID
146 mcr p15, 0, r6, c3, c0, 0 @ Domain ID
147 mcr p15, 0, r7, c2, c0, 0 @ translation table base
148
149#ifdef CONFIG_DEBUG_RESUME
150 mov r3, #'R'
151 strb r3, [ r2, #S3C2410_UTXH ]
152#endif
153
154 ldr r2, =resume_with_mmu
155 mcr p15, 0, r8, c1, c0, 0 @ turn on MMU, etc
156 nop @ second-to-last before mmu
157 mov pc, r2 @ go back to virtual address
158
159 .ltorg
diff --git a/arch/arm/mach-s3c2410/usb-simtec.c b/arch/arm/mach-s3c2410/usb-simtec.c
index 22b0e1cdd4bf..bcd562ac1d3d 100644
--- a/arch/arm/mach-s3c2410/usb-simtec.c
+++ b/arch/arm/mach-s3c2410/usb-simtec.c
@@ -35,7 +35,7 @@
35#include <asm/io.h> 35#include <asm/io.h>
36#include <asm/irq.h> 36#include <asm/irq.h>
37 37
38#include "devs.h" 38#include <asm/plat-s3c24xx/devs.h>
39#include "usb-simtec.h" 39#include "usb-simtec.h"
40 40
41/* control power and monitor over-current events on various Simtec 41/* control power and monitor over-current events on various Simtec
diff --git a/arch/arm/mach-s3c2412/Kconfig b/arch/arm/mach-s3c2412/Kconfig
new file mode 100644
index 000000000000..befc5fdbb613
--- /dev/null
+++ b/arch/arm/mach-s3c2412/Kconfig
@@ -0,0 +1,58 @@
1# arch/arm/mach-s3c2412/Kconfig
2#
3# Copyright 2007 Simtec Electronics
4#
5# Licensed under GPLv2
6
7config CPU_S3C2412
8 bool
9 depends on ARCH_S3C2410
10 select S3C2412_PM if PM
11 select S3C2412_DMA if S3C2410_DMA
12 help
13 Support for the S3C2412 and S3C2413 SoCs from the S3C24XX line
14
15config CPU_S3C2412_ONLY
16 bool
17 depends on ARCH_S3C2410 && !CPU_S3C2400 && !CPU_S3C2410 && \
18 !CPU_S3C2440 && !CPU_S3C2442 && !CPU_S3C2443 && CPU_S3C2412
19 default y if CPU_S3C2412
20
21config S3C2412_DMA
22 bool
23 depends on CPU_S3C2412
24 help
25 Internal config node for S3C2412 DMA support
26
27config S3C2412_PM
28 bool
29 help
30 Internal config node to apply S3C2412 power management
31
32
33menu "S3C2412 Machines"
34
35config MACH_SMDK2413
36 bool "SMDK2413"
37 select CPU_S3C2412
38 select MACH_S3C2413
39 select MACH_SMDK
40 help
41 Say Y here if you are using an SMDK2413
42
43config MACH_S3C2413
44 bool
45 help
46 Internal node for S3C2413 version of SMDK2413, so that
47 machine_is_s3c2413() will work when MACH_SMDK2413 is
48 selected
49
50config MACH_VSTMS
51 bool "VMSTMS"
52 select CPU_S3C2412
53 help
54 Say Y here if you are using an VSTMS board
55
56
57endmenu
58
diff --git a/arch/arm/mach-s3c2412/Makefile b/arch/arm/mach-s3c2412/Makefile
new file mode 100644
index 000000000000..f8e011691b31
--- /dev/null
+++ b/arch/arm/mach-s3c2412/Makefile
@@ -0,0 +1,21 @@
1# arch/arm/mach-s3c2412/Makefile
2#
3# Copyright 2007 Simtec Electronics
4#
5# Licensed under GPLv2
6
7obj-y :=
8obj-m :=
9obj-n :=
10obj- :=
11
12obj-$(CONFIG_CPU_S3C2412) += s3c2412.o
13obj-$(CONFIG_CPU_S3C2412) += irq.o
14obj-$(CONFIG_CPU_S3C2412) += clock.o
15obj-$(CONFIG_S3C2412_DMA) += dma.o
16obj-$(CONFIG_S3C2412_PM) += pm.o
17
18# Machine support
19
20obj-$(CONFIG_MACH_SMDK2413) += mach-smdk2413.o
21obj-$(CONFIG_MACH_VSTMS) += mach-vstms.o
diff --git a/arch/arm/mach-s3c2410/s3c2412-clock.c b/arch/arm/mach-s3c2412/clock.c
index 8f94ad83901d..6a8e4448770b 100644
--- a/arch/arm/mach-s3c2410/s3c2412-clock.c
+++ b/arch/arm/mach-s3c2412/clock.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/s3c2412-clock.c 1/* linux/arch/arm/mach-s3c2412/clock.c
2 * 2 *
3 * Copyright (c) 2006 Simtec Electronics 3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
@@ -41,9 +41,9 @@
41#include <asm/arch/regs-clock.h> 41#include <asm/arch/regs-clock.h>
42#include <asm/arch/regs-gpio.h> 42#include <asm/arch/regs-gpio.h>
43 43
44#include "s3c2412.h" 44#include <asm/plat-s3c24xx/s3c2412.h>
45#include "clock.h" 45#include <asm/plat-s3c24xx/clock.h>
46#include "cpu.h" 46#include <asm/plat-s3c24xx/cpu.h>
47 47
48/* We currently have to assume that the system is running 48/* We currently have to assume that the system is running
49 * from the XTPll input, and that all ***REFCLKs are being 49 * from the XTPll input, and that all ***REFCLKs are being
diff --git a/arch/arm/mach-s3c2410/s3c2412-dma.c b/arch/arm/mach-s3c2412/dma.c
index 138f726ac6bf..d0f4695c09d9 100644
--- a/arch/arm/mach-s3c2410/s3c2412-dma.c
+++ b/arch/arm/mach-s3c2412/dma.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/s3c2412-dma.c 1/* linux/arch/arm/mach-s3c2412/dma.c
2 * 2 *
3 * Copyright (c) 2006 Simtec Electronics 3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
@@ -21,8 +21,8 @@
21#include <asm/arch/dma.h> 21#include <asm/arch/dma.h>
22#include <asm/io.h> 22#include <asm/io.h>
23 23
24#include "dma.h" 24#include <asm/plat-s3c24xx/dma.h>
25#include "cpu.h" 25#include <asm/plat-s3c24xx/cpu.h>
26 26
27#include <asm/arch/regs-serial.h> 27#include <asm/arch/regs-serial.h>
28#include <asm/arch/regs-gpio.h> 28#include <asm/arch/regs-gpio.h>
@@ -146,6 +146,7 @@ static struct s3c24xx_dma_selection __initdata s3c2412_dma_sel = {
146 146
147static int s3c2412_dma_add(struct sys_device *sysdev) 147static int s3c2412_dma_add(struct sys_device *sysdev)
148{ 148{
149 s3c2410_dma_init();
149 return s3c24xx_dma_init_map(&s3c2412_dma_sel); 150 return s3c24xx_dma_init_map(&s3c2412_dma_sel);
150} 151}
151 152
diff --git a/arch/arm/mach-s3c2410/s3c2412-irq.c b/arch/arm/mach-s3c2412/irq.c
index ffcc30b23a80..e89dbdcb1b7b 100644
--- a/arch/arm/mach-s3c2410/s3c2412-irq.c
+++ b/arch/arm/mach-s3c2412/irq.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2412/s3c2412-irq.c 1/* linux/arch/arm/mach-s3c2412/irq.c
2 * 2 *
3 * Copyright (c) 2006 Simtec Electronics 3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
@@ -35,9 +35,9 @@
35#include <asm/arch/regs-irq.h> 35#include <asm/arch/regs-irq.h>
36#include <asm/arch/regs-gpio.h> 36#include <asm/arch/regs-gpio.h>
37 37
38#include "cpu.h" 38#include <asm/plat-s3c24xx/cpu.h>
39#include "irq.h" 39#include <asm/plat-s3c24xx/irq.h>
40#include "pm.h" 40#include <asm/plat-s3c24xx/pm.h>
41 41
42/* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by 42/* the s3c2412 changes the behaviour of IRQ_EINT0 through IRQ_EINT3 by
43 * having them turn up in both the INT* and the EINT* registers. Whilst 43 * having them turn up in both the INT* and the EINT* registers. Whilst
diff --git a/arch/arm/mach-s3c2410/mach-smdk2413.c b/arch/arm/mach-s3c2412/mach-smdk2413.c
index 4f89abd7a6df..b5befce6c8d3 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2413.c
+++ b/arch/arm/mach-s3c2412/mach-smdk2413.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/mach-smdk2413.c 1/* linux/arch/arm/mach-s3c2412/mach-smdk2413.c
2 * 2 *
3 * Copyright (c) 2006 Simtec Electronics 3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
@@ -37,15 +37,16 @@
37#include <asm/arch/regs-lcd.h> 37#include <asm/arch/regs-lcd.h>
38 38
39#include <asm/arch/idle.h> 39#include <asm/arch/idle.h>
40#include <asm/arch/udc.h>
40#include <asm/arch/fb.h> 41#include <asm/arch/fb.h>
41 42
42#include "s3c2410.h" 43#include <asm/plat-s3c24xx/s3c2410.h>
43#include "s3c2412.h" 44#include <asm/plat-s3c24xx/s3c2412.h>
44#include "clock.h" 45#include <asm/plat-s3c24xx/clock.h>
45#include "devs.h" 46#include <asm/plat-s3c24xx/devs.h>
46#include "cpu.h" 47#include <asm/plat-s3c24xx/cpu.h>
47 48
48#include "common-smdk.h" 49#include <asm/plat-s3c24xx/common-smdk.h>
49 50
50static struct map_desc smdk2413_iodesc[] __initdata = { 51static struct map_desc smdk2413_iodesc[] __initdata = {
51}; 52};
@@ -75,12 +76,38 @@ static struct s3c2410_uartcfg smdk2413_uartcfgs[] __initdata = {
75 } 76 }
76}; 77};
77 78
79static void smdk2413_udc_pullup(enum s3c2410_udc_cmd_e cmd)
80{
81 printk(KERN_DEBUG "udc: pullup(%d)\n",cmd);
82
83 switch (cmd)
84 {
85 case S3C2410_UDC_P_ENABLE :
86 s3c2410_gpio_setpin(S3C2410_GPF2, 1);
87 break;
88 case S3C2410_UDC_P_DISABLE :
89 s3c2410_gpio_setpin(S3C2410_GPF2, 0);
90 break;
91 case S3C2410_UDC_P_RESET :
92 break;
93 default:
94 break;
95 }
96}
97
98
99static struct s3c2410_udc_mach_info smdk2413_udc_cfg __initdata = {
100 .udc_command = smdk2413_udc_pullup,
101};
102
103
78static struct platform_device *smdk2413_devices[] __initdata = { 104static struct platform_device *smdk2413_devices[] __initdata = {
79 &s3c_device_usb, 105 &s3c_device_usb,
80 //&s3c_device_lcd, 106 //&s3c_device_lcd,
81 &s3c_device_wdt, 107 &s3c_device_wdt,
82 &s3c_device_i2c, 108 &s3c_device_i2c,
83 &s3c_device_iis, 109 &s3c_device_iis,
110 &s3c_device_usbgadget,
84}; 111};
85 112
86static struct s3c24xx_board smdk2413_board __initdata = { 113static struct s3c24xx_board smdk2413_board __initdata = {
@@ -109,7 +136,19 @@ static void __init smdk2413_map_io(void)
109} 136}
110 137
111static void __init smdk2413_machine_init(void) 138static void __init smdk2413_machine_init(void)
112{ 139{ /* Turn off suspend on both USB ports, and switch the
140 * selectable USB port to USB device mode. */
141
142 s3c2410_gpio_setpin(S3C2410_GPF2, 0);
143 s3c2410_gpio_cfgpin(S3C2410_GPF2, S3C2410_GPIO_OUTPUT);
144
145 s3c2410_modify_misccr(S3C2410_MISCCR_USBHOST |
146 S3C2410_MISCCR_USBSUSPND0 |
147 S3C2410_MISCCR_USBSUSPND1, 0x0);
148
149
150 s3c24xx_udc_set_platdata(&smdk2413_udc_cfg);
151
113 smdk_machine_init(); 152 smdk_machine_init();
114} 153}
115 154
@@ -126,6 +165,19 @@ MACHINE_START(S3C2413, "S3C2413")
126 .timer = &s3c24xx_timer, 165 .timer = &s3c24xx_timer,
127MACHINE_END 166MACHINE_END
128 167
168MACHINE_START(SMDK2412, "SMDK2412")
169 /* Maintainer: Ben Dooks <ben@fluff.org> */
170 .phys_io = S3C2410_PA_UART,
171 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
172 .boot_params = S3C2410_SDRAM_PA + 0x100,
173
174 .fixup = smdk2413_fixup,
175 .init_irq = s3c24xx_init_irq,
176 .map_io = smdk2413_map_io,
177 .init_machine = smdk2413_machine_init,
178 .timer = &s3c24xx_timer,
179MACHINE_END
180
129MACHINE_START(SMDK2413, "SMDK2413") 181MACHINE_START(SMDK2413, "SMDK2413")
130 /* Maintainer: Ben Dooks <ben@fluff.org> */ 182 /* Maintainer: Ben Dooks <ben@fluff.org> */
131 .phys_io = S3C2410_PA_UART, 183 .phys_io = S3C2410_PA_UART,
diff --git a/arch/arm/mach-s3c2410/mach-vstms.c b/arch/arm/mach-s3c2412/mach-vstms.c
index 0360e1055bcd..4231b549d797 100644
--- a/arch/arm/mach-s3c2410/mach-vstms.c
+++ b/arch/arm/mach-s3c2412/mach-vstms.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/mach-vstms.c 1/* linux/arch/arm/mach-s3c2412/mach-vstms.c
2 * 2 *
3 * (C) 2006 Thomas Gleixner <tglx@linutronix.de> 3 * (C) 2006 Thomas Gleixner <tglx@linutronix.de>
4 * 4 *
@@ -28,7 +28,6 @@
28#include <asm/mach/irq.h> 28#include <asm/mach/irq.h>
29 29
30#include <asm/hardware.h> 30#include <asm/hardware.h>
31#include <asm/hardware/iomd.h>
32#include <asm/setup.h> 31#include <asm/setup.h>
33#include <asm/io.h> 32#include <asm/io.h>
34#include <asm/irq.h> 33#include <asm/irq.h>
@@ -43,11 +42,11 @@
43 42
44#include <asm/arch/nand.h> 43#include <asm/arch/nand.h>
45 44
46#include "s3c2410.h" 45#include <asm/plat-s3c24xx/s3c2410.h>
47#include "s3c2412.h" 46#include <asm/plat-s3c24xx/s3c2412.h>
48#include "clock.h" 47#include <asm/plat-s3c24xx/clock.h>
49#include "devs.h" 48#include <asm/plat-s3c24xx/devs.h>
50#include "cpu.h" 49#include <asm/plat-s3c24xx/cpu.h>
51 50
52 51
53static struct map_desc vstms_iodesc[] __initdata = { 52static struct map_desc vstms_iodesc[] __initdata = {
diff --git a/arch/arm/mach-s3c2410/s3c2412-pm.c b/arch/arm/mach-s3c2412/pm.c
index 19b63322d259..8988dac388a9 100644
--- a/arch/arm/mach-s3c2410/s3c2412-pm.c
+++ b/arch/arm/mach-s3c2412/pm.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/s3c2412-pm.c 1/* linux/arch/arm/mach-s3c2412/pm.c
2 * 2 *
3 * Copyright (c) 2006 Simtec Electronics 3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
@@ -28,10 +28,10 @@
28#include <asm/arch/regs-gpio.h> 28#include <asm/arch/regs-gpio.h>
29#include <asm/arch/regs-dsc.h> 29#include <asm/arch/regs-dsc.h>
30 30
31#include "cpu.h" 31#include <asm/plat-s3c24xx/cpu.h>
32#include "pm.h" 32#include <asm/plat-s3c24xx/pm.h>
33 33
34#include "s3c2412.h" 34#include <asm/plat-s3c24xx/s3c2412.h>
35 35
36static void s3c2412_cpu_suspend(void) 36static void s3c2412_cpu_suspend(void)
37{ 37{
diff --git a/arch/arm/mach-s3c2410/s3c2412.c b/arch/arm/mach-s3c2412/s3c2412.c
index 2f651a811ecd..aafe0bc593f1 100644
--- a/arch/arm/mach-s3c2410/s3c2412.c
+++ b/arch/arm/mach-s3c2412/s3c2412.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/s3c2412.c 1/* linux/arch/arm/mach-s3c2412/s3c2412.c
2 * 2 *
3 * Copyright (c) 2006 Simtec Electronics 3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
@@ -38,11 +38,11 @@
38#include <asm/arch/regs-gpioj.h> 38#include <asm/arch/regs-gpioj.h>
39#include <asm/arch/regs-dsc.h> 39#include <asm/arch/regs-dsc.h>
40 40
41#include "s3c2412.h" 41#include <asm/plat-s3c24xx/s3c2412.h>
42#include "cpu.h" 42#include <asm/plat-s3c24xx/cpu.h>
43#include "devs.h" 43#include <asm/plat-s3c24xx/devs.h>
44#include "clock.h" 44#include <asm/plat-s3c24xx/clock.h>
45#include "pm.h" 45#include <asm/plat-s3c24xx/pm.h>
46 46
47#ifndef CONFIG_CPU_S3C2412_ONLY 47#ifndef CONFIG_CPU_S3C2412_ONLY
48void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO; 48void __iomem *s3c24xx_va_gpio2 = S3C24XX_VA_GPIO;
diff --git a/arch/arm/mach-s3c2440/Kconfig b/arch/arm/mach-s3c2440/Kconfig
new file mode 100644
index 000000000000..e3bfda098c0f
--- /dev/null
+++ b/arch/arm/mach-s3c2440/Kconfig
@@ -0,0 +1,71 @@
1# arch/arm/mach-s3c2440/Kconfig
2#
3# Copyright 2007 Simtec Electronics
4#
5# Licensed under GPLv2
6
7config CPU_S3C2440
8 bool
9 depends on ARCH_S3C2410
10 select S3C2410_CLOCK
11 select S3C2410_PM if PM
12 select S3C2410_GPIO
13 select S3C2440_DMA if S3C2410_DMA
14 select CPU_S3C244X
15 help
16 Support for S3C2440 Samsung Mobile CPU based systems.
17
18config S3C2440_DMA
19 bool
20 depends on ARCH_S3C2410 && CPU_S3C24405B
21 help
22 Support for S3C2440 specific DMA code5A
23
24
25menu "S3C2440 Machines"
26
27config MACH_ANUBIS
28 bool "Simtec Electronics ANUBIS"
29 select CPU_S3C2440
30 select PM_SIMTEC if PM
31 help
32 Say Y here if you are using the Simtec Electronics ANUBIS
33 development system
34
35config MACH_OSIRIS
36 bool "Simtec IM2440D20 (OSIRIS) module"
37 select CPU_S3C2440
38 select PM_SIMTEC if PM
39 help
40 Say Y here if you are using the Simtec IM2440D20 module, also
41 known as the Osiris.
42
43config MACH_RX3715
44 bool "HP iPAQ rx3715"
45 select CPU_S3C2440
46 select PM_H1940 if PM
47 help
48 Say Y here if you are using the HP iPAQ rx3715.
49
50config ARCH_S3C2440
51 bool "SMDK2440"
52 select CPU_S3C2440
53 select MACH_SMDK
54 help
55 Say Y here if you are using the SMDK2440.
56
57config MACH_NEXCODER_2440
58 bool "NexVision NEXCODER 2440 Light Board"
59 select CPU_S3C2440
60 help
61 Say Y here if you are using the Nex Vision NEXCODER 2440 Light Board
62
63config SMDK2440_CPU2440
64 bool "SMDK2440 with S3C2440 CPU module"
65 depends on ARCH_S3C2440
66 default y if ARCH_S3C2440
67 select CPU_S3C2440
68
69
70endmenu
71
diff --git a/arch/arm/mach-s3c2440/Makefile b/arch/arm/mach-s3c2440/Makefile
new file mode 100644
index 000000000000..c81ed6248dcb
--- /dev/null
+++ b/arch/arm/mach-s3c2440/Makefile
@@ -0,0 +1,23 @@
1# arch/arm/mach-s3c2440/Makefile
2#
3# Copyright 2007 Simtec Electronics
4#
5# Licensed under GPLv2
6
7obj-y :=
8obj-m :=
9obj-n :=
10obj- :=
11
12obj-$(CONFIG_CPU_S3C2440) += s3c2440.o dsc.o
13obj-$(CONFIG_CPU_S3C2440) += irq.o
14obj-$(CONFIG_CPU_S3C2440) += clock.o
15obj-$(CONFIG_S3C2440_DMA) += dma.o
16
17# Machine support
18
19obj-$(CONFIG_MACH_ANUBIS) += mach-anubis.o
20obj-$(CONFIG_MACH_OSIRIS) += mach-osiris.o
21obj-$(CONFIG_MACH_RX3715) += mach-rx3715.o
22obj-$(CONFIG_ARCH_S3C2440) += mach-smdk2440.o
23obj-$(CONFIG_MACH_NEXCODER_2440) += mach-nexcoder.o
diff --git a/arch/arm/mach-s3c2410/s3c2440-clock.c b/arch/arm/mach-s3c2440/clock.c
index ba13c1d079d1..79e2ea4adaf3 100644
--- a/arch/arm/mach-s3c2410/s3c2440-clock.c
+++ b/arch/arm/mach-s3c2440/clock.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/s3c2440-clock.c 1/* linux/arch/arm/mach-s3c2440/clock.c
2 * 2 *
3 * Copyright (c) 2004-2005 Simtec Electronics 3 * Copyright (c) 2004-2005 Simtec Electronics
4 * http://armlinux.simtec.co.uk/ 4 * http://armlinux.simtec.co.uk/
@@ -41,8 +41,8 @@
41 41
42#include <asm/arch/regs-clock.h> 42#include <asm/arch/regs-clock.h>
43 43
44#include "clock.h" 44#include <asm/plat-s3c24xx/clock.h>
45#include "cpu.h" 45#include <asm/plat-s3c24xx/cpu.h>
46 46
47/* S3C2440 extended clock support */ 47/* S3C2440 extended clock support */
48 48
diff --git a/arch/arm/mach-s3c2410/s3c2440-dma.c b/arch/arm/mach-s3c2440/dma.c
index 47b861b9443d..cd035a3ec878 100644
--- a/arch/arm/mach-s3c2410/s3c2440-dma.c
+++ b/arch/arm/mach-s3c2440/dma.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/s3c2440-dma.c 1/* linux/arch/arm/mach-s3c2440/dma.c
2 * 2 *
3 * Copyright (c) 2006 Simtec Electronics 3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
@@ -19,9 +19,9 @@
19 19
20#include <asm/dma.h> 20#include <asm/dma.h>
21#include <asm/arch/dma.h> 21#include <asm/arch/dma.h>
22#include "dma.h"
23 22
24#include "cpu.h" 23#include <asm/plat-s3c24xx/dma.h>
24#include <asm/plat-s3c24xx/cpu.h>
25 25
26#include <asm/arch/regs-serial.h> 26#include <asm/arch/regs-serial.h>
27#include <asm/arch/regs-gpio.h> 27#include <asm/arch/regs-gpio.h>
@@ -147,8 +147,53 @@ static struct s3c24xx_dma_selection __initdata s3c2440_dma_sel = {
147 .map_size = ARRAY_SIZE(s3c2440_dma_mappings), 147 .map_size = ARRAY_SIZE(s3c2440_dma_mappings),
148}; 148};
149 149
150static struct s3c24xx_dma_order __initdata s3c2440_dma_order = {
151 .channels = {
152 [DMACH_SDI] = {
153 .list = {
154 [0] = 3 | DMA_CH_VALID,
155 [1] = 2 | DMA_CH_VALID,
156 [2] = 1 | DMA_CH_VALID,
157 [3] = 0 | DMA_CH_VALID,
158 },
159 },
160 [DMACH_I2S_IN] = {
161 .list = {
162 [0] = 1 | DMA_CH_VALID,
163 [1] = 2 | DMA_CH_VALID,
164 },
165 },
166 [DMACH_I2S_OUT] = {
167 .list = {
168 [0] = 2 | DMA_CH_VALID,
169 [1] = 1 | DMA_CH_VALID,
170 },
171 },
172 [DMACH_PCM_IN] = {
173 .list = {
174 [0] = 2 | DMA_CH_VALID,
175 [1] = 1 | DMA_CH_VALID,
176 },
177 },
178 [DMACH_PCM_OUT] = {
179 .list = {
180 [0] = 1 | DMA_CH_VALID,
181 [1] = 3 | DMA_CH_VALID,
182 },
183 },
184 [DMACH_MIC_IN] = {
185 .list = {
186 [0] = 3 | DMA_CH_VALID,
187 [1] = 2 | DMA_CH_VALID,
188 },
189 },
190 },
191};
192
150static int s3c2440_dma_add(struct sys_device *sysdev) 193static int s3c2440_dma_add(struct sys_device *sysdev)
151{ 194{
195 s3c2410_dma_init();
196 s3c24xx_dma_order_set(&s3c2440_dma_order);
152 return s3c24xx_dma_init_map(&s3c2440_dma_sel); 197 return s3c24xx_dma_init_map(&s3c2440_dma_sel);
153} 198}
154 199
diff --git a/arch/arm/mach-s3c2410/s3c2440-dsc.c b/arch/arm/mach-s3c2440/dsc.c
index c92ea66ba45e..2995ff5681bb 100644
--- a/arch/arm/mach-s3c2410/s3c2440-dsc.c
+++ b/arch/arm/mach-s3c2440/dsc.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/s3c2440-dsc.c 1/* linux/arch/arm/mach-s3c2440/dsc.c
2 * 2 *
3 * Copyright (c) 2004-2005 Simtec Electronics 3 * Copyright (c) 2004-2005 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
@@ -27,8 +27,8 @@
27#include <asm/arch/regs-gpio.h> 27#include <asm/arch/regs-gpio.h>
28#include <asm/arch/regs-dsc.h> 28#include <asm/arch/regs-dsc.h>
29 29
30#include "cpu.h" 30#include <asm/plat-s3c24xx/cpu.h>
31#include "s3c2440.h" 31#include <asm/plat-s3c24xx/s3c2440.h>
32 32
33int s3c2440_set_dsc(unsigned int pin, unsigned int value) 33int s3c2440_set_dsc(unsigned int pin, unsigned int value)
34{ 34{
diff --git a/arch/arm/mach-s3c2410/s3c2440-irq.c b/arch/arm/mach-s3c2440/irq.c
index 1ba19b27ab05..1069d13d8c57 100644
--- a/arch/arm/mach-s3c2410/s3c2440-irq.c
+++ b/arch/arm/mach-s3c2440/irq.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/s3c2440-irq.c 1/* linux/arch/arm/mach-s3c2440/irq.c
2 * 2 *
3 * Copyright (c) 2003,2004 Simtec Electronics 3 * Copyright (c) 2003,2004 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
@@ -35,9 +35,9 @@
35#include <asm/arch/regs-irq.h> 35#include <asm/arch/regs-irq.h>
36#include <asm/arch/regs-gpio.h> 36#include <asm/arch/regs-gpio.h>
37 37
38#include "cpu.h" 38#include <asm/plat-s3c24xx/cpu.h>
39#include "pm.h" 39#include <asm/plat-s3c24xx/pm.h>
40#include "irq.h" 40#include <asm/plat-s3c24xx/irq.h>
41 41
42/* WDT/AC97 */ 42/* WDT/AC97 */
43 43
diff --git a/arch/arm/mach-s3c2410/mach-anubis.c b/arch/arm/mach-s3c2440/mach-anubis.c
index 0fad0c2fe07b..3f0288eb1ed5 100644
--- a/arch/arm/mach-s3c2410/mach-anubis.c
+++ b/arch/arm/mach-s3c2440/mach-anubis.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/mach-anubis.c 1/* linux/arch/arm/mach-s3c2440/mach-anubis.c
2 * 2 *
3 * Copyright (c) 2003-2005 Simtec Electronics 3 * Copyright (c) 2003-2005 Simtec Electronics
4 * http://armlinux.simtec.co.uk/ 4 * http://armlinux.simtec.co.uk/
@@ -42,9 +42,9 @@
42#include <linux/mtd/nand_ecc.h> 42#include <linux/mtd/nand_ecc.h>
43#include <linux/mtd/partitions.h> 43#include <linux/mtd/partitions.h>
44 44
45#include "clock.h" 45#include <asm/plat-s3c24xx/clock.h>
46#include "devs.h" 46#include <asm/plat-s3c24xx/devs.h>
47#include "cpu.h" 47#include <asm/plat-s3c24xx/cpu.h>
48 48
49#define COPYRIGHT ", (c) 2005 Simtec Electronics" 49#define COPYRIGHT ", (c) 2005 Simtec Electronics"
50 50
diff --git a/arch/arm/mach-s3c2410/mach-nexcoder.c b/arch/arm/mach-s3c2440/mach-nexcoder.c
index d6dfdad8c90b..6d551d88330b 100644
--- a/arch/arm/mach-s3c2410/mach-nexcoder.c
+++ b/arch/arm/mach-s3c2440/mach-nexcoder.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/mach-nexcoder.c 1/* linux/arch/arm/mach-s3c2440/mach-nexcoder.c
2 * 2 *
3 * Copyright (c) 2004 Nex Vision 3 * Copyright (c) 2004 Nex Vision
4 * Guillaume GOURAT <guillaume.gourat@nexvision.tv> 4 * Guillaume GOURAT <guillaume.gourat@nexvision.tv>
@@ -38,11 +38,11 @@
38#include <asm/arch/regs-gpio.h> 38#include <asm/arch/regs-gpio.h>
39#include <asm/arch/regs-serial.h> 39#include <asm/arch/regs-serial.h>
40 40
41#include "s3c2410.h" 41#include <asm/plat-s3c24xx/s3c2410.h>
42#include "s3c2440.h" 42#include <asm/plat-s3c24xx/s3c2440.h>
43#include "clock.h" 43#include <asm/plat-s3c24xx/clock.h>
44#include "devs.h" 44#include <asm/plat-s3c24xx/devs.h>
45#include "cpu.h" 45#include <asm/plat-s3c24xx/cpu.h>
46 46
47static struct map_desc nexcoder_iodesc[] __initdata = { 47static struct map_desc nexcoder_iodesc[] __initdata = {
48 /* nothing here yet */ 48 /* nothing here yet */
diff --git a/arch/arm/mach-s3c2410/mach-osiris.c b/arch/arm/mach-s3c2440/mach-osiris.c
index 37b40850c9b9..2ed8e51f20c8 100644
--- a/arch/arm/mach-s3c2410/mach-osiris.c
+++ b/arch/arm/mach-s3c2440/mach-osiris.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/mach-osiris.c 1/* linux/arch/arm/mach-s3c2440/mach-osiris.c
2 * 2 *
3 * Copyright (c) 2005 Simtec Electronics 3 * Copyright (c) 2005 Simtec Electronics
4 * http://armlinux.simtec.co.uk/ 4 * http://armlinux.simtec.co.uk/
@@ -41,9 +41,9 @@
41#include <linux/mtd/nand_ecc.h> 41#include <linux/mtd/nand_ecc.h>
42#include <linux/mtd/partitions.h> 42#include <linux/mtd/partitions.h>
43 43
44#include "clock.h" 44#include <asm/plat-s3c24xx/clock.h>
45#include "devs.h" 45#include <asm/plat-s3c24xx/devs.h>
46#include "cpu.h" 46#include <asm/plat-s3c24xx/cpu.h>
47 47
48/* onboard perihpheral map */ 48/* onboard perihpheral map */
49 49
diff --git a/arch/arm/mach-s3c2410/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
index ecbcdf79d739..480ccde63fb4 100644
--- a/arch/arm/mach-s3c2410/mach-rx3715.c
+++ b/arch/arm/mach-s3c2440/mach-rx3715.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/mach-rx3715.c 1/* linux/arch/arm/mach-s3c2440/mach-rx3715.c
2 * 2 *
3 * Copyright (c) 2003,2004 Simtec Electronics 3 * Copyright (c) 2003,2004 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
@@ -33,7 +33,6 @@
33#include <asm/mach/irq.h> 33#include <asm/mach/irq.h>
34 34
35#include <asm/hardware.h> 35#include <asm/hardware.h>
36#include <asm/hardware/iomd.h>
37#include <asm/io.h> 36#include <asm/io.h>
38#include <asm/irq.h> 37#include <asm/irq.h>
39#include <asm/mach-types.h> 38#include <asm/mach-types.h>
@@ -46,10 +45,10 @@
46#include <asm/arch/nand.h> 45#include <asm/arch/nand.h>
47#include <asm/arch/fb.h> 46#include <asm/arch/fb.h>
48 47
49#include "clock.h" 48#include <asm/plat-s3c24xx/clock.h>
50#include "devs.h" 49#include <asm/plat-s3c24xx/devs.h>
51#include "cpu.h" 50#include <asm/plat-s3c24xx/cpu.h>
52#include "pm.h" 51#include <asm/plat-s3c24xx/pm.h>
53 52
54static struct map_desc rx3715_iodesc[] __initdata = { 53static struct map_desc rx3715_iodesc[] __initdata = {
55 /* dump ISA space somewhere unused */ 54 /* dump ISA space somewhere unused */
diff --git a/arch/arm/mach-s3c2410/mach-smdk2440.c b/arch/arm/mach-s3c2440/mach-smdk2440.c
index 2b61f4ed1da4..c17eb5b1f6b4 100644
--- a/arch/arm/mach-s3c2410/mach-smdk2440.c
+++ b/arch/arm/mach-s3c2440/mach-smdk2440.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/mach-smdk2440.c 1/* linux/arch/arm/mach-s3c2440/mach-smdk2440.c
2 * 2 *
3 * Copyright (c) 2004,2005 Simtec Electronics 3 * Copyright (c) 2004,2005 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
@@ -27,12 +27,10 @@
27#include <asm/mach/irq.h> 27#include <asm/mach/irq.h>
28 28
29#include <asm/hardware.h> 29#include <asm/hardware.h>
30#include <asm/hardware/iomd.h>
31#include <asm/io.h> 30#include <asm/io.h>
32#include <asm/irq.h> 31#include <asm/irq.h>
33#include <asm/mach-types.h> 32#include <asm/mach-types.h>
34 33
35//#include <asm/debug-ll.h>
36#include <asm/arch/regs-serial.h> 34#include <asm/arch/regs-serial.h>
37#include <asm/arch/regs-gpio.h> 35#include <asm/arch/regs-gpio.h>
38#include <asm/arch/regs-lcd.h> 36#include <asm/arch/regs-lcd.h>
@@ -40,13 +38,13 @@
40#include <asm/arch/idle.h> 38#include <asm/arch/idle.h>
41#include <asm/arch/fb.h> 39#include <asm/arch/fb.h>
42 40
43#include "s3c2410.h" 41#include <asm/plat-s3c24xx/s3c2410.h>
44#include "s3c2440.h" 42#include <asm/plat-s3c24xx/s3c2440.h>
45#include "clock.h" 43#include <asm/plat-s3c24xx/clock.h>
46#include "devs.h" 44#include <asm/plat-s3c24xx/devs.h>
47#include "cpu.h" 45#include <asm/plat-s3c24xx/cpu.h>
48 46
49#include "common-smdk.h" 47#include <asm/plat-s3c24xx/common-smdk.h>
50 48
51static struct map_desc smdk2440_iodesc[] __initdata = { 49static struct map_desc smdk2440_iodesc[] __initdata = {
52 /* ISA IO Space map (memory space selected by A24) */ 50 /* ISA IO Space map (memory space selected by A24) */
@@ -144,6 +142,7 @@ static struct s3c2410fb_mach_info smdk2440_lcd_cfg __initdata = {
144#endif 142#endif
145 143
146 .lpcsel = ((0xCE6) & ~7) | 1<<4, 144 .lpcsel = ((0xCE6) & ~7) | 1<<4,
145 .type = S3C2410_LCDCON1_TFT16BPP,
147 146
148 .width = 240, 147 .width = 240,
149 .height = 320, 148 .height = 320,
diff --git a/arch/arm/mach-s3c2410/s3c2440.c b/arch/arm/mach-s3c2440/s3c2440.c
index 344eb27cca48..90e1da61fbc3 100644
--- a/arch/arm/mach-s3c2410/s3c2440.c
+++ b/arch/arm/mach-s3c2440/s3c2440.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/s3c2440.c 1/* linux/arch/arm/mach-s3c2440/s3c2440.c
2 * 2 *
3 * Copyright (c) 2004-2006 Simtec Electronics 3 * Copyright (c) 2004-2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
@@ -29,9 +29,9 @@
29#include <asm/io.h> 29#include <asm/io.h>
30#include <asm/irq.h> 30#include <asm/irq.h>
31 31
32#include "s3c2440.h" 32#include <asm/plat-s3c24xx/s3c2440.h>
33#include "devs.h" 33#include <asm/plat-s3c24xx/devs.h>
34#include "cpu.h" 34#include <asm/plat-s3c24xx/cpu.h>
35 35
36static struct sys_device s3c2440_sysdev = { 36static struct sys_device s3c2440_sysdev = {
37 .cls = &s3c2440_sysclass, 37 .cls = &s3c2440_sysclass,
diff --git a/arch/arm/mach-s3c2442/Kconfig b/arch/arm/mach-s3c2442/Kconfig
new file mode 100644
index 000000000000..bf8d87abfab3
--- /dev/null
+++ b/arch/arm/mach-s3c2442/Kconfig
@@ -0,0 +1,27 @@
1# arch/arm/mach-s3c2442/Kconfig
2#
3# Copyright 2007 Simtec Electronics
4#
5# Licensed under GPLv2
6
7config CPU_S3C2442
8 bool
9 depends on ARCH_S3C2420
10 select S3C2410_CLOCK
11 select S3C2410_GPIO
12 select S3C2410_PM if PM
13 select CPU_S3C244X
14 help
15 Support for S3C2442 Samsung Mobile CPU based systems.
16
17
18menu "S3C2442 Machines"
19
20config SMDK2440_CPU2442
21 bool "SMDM2440 with S3C2442 CPU module"
22 depends on ARCH_S3C2440
23 select CPU_S3C2442
24
25
26endmenu
27
diff --git a/arch/arm/mach-s3c2442/Makefile b/arch/arm/mach-s3c2442/Makefile
new file mode 100644
index 000000000000..2a909c6c5798
--- /dev/null
+++ b/arch/arm/mach-s3c2442/Makefile
@@ -0,0 +1,16 @@
1# arch/arm/mach-s3c2442/Makefile
2#
3# Copyright 2007 Simtec Electronics
4#
5# Licensed under GPLv2
6
7obj-y :=
8obj-m :=
9obj-n :=
10obj- :=
11
12obj-$(CONFIG_CPU_S3C2442) += s3c2442.o
13obj-$(CONFIG_CPU_S3C2442) += clock.o
14
15# Machine support
16
diff --git a/arch/arm/mach-s3c2410/s3c2442-clock.c b/arch/arm/mach-s3c2442/clock.c
index 4e292ca7c9be..5b9e830ac4d3 100644
--- a/arch/arm/mach-s3c2410/s3c2442-clock.c
+++ b/arch/arm/mach-s3c2442/clock.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/s3c2442-clock.c 1/* linux/arch/arm/mach-s3c2442/clock.c
2 * 2 *
3 * Copyright (c) 2004-2005 Simtec Electronics 3 * Copyright (c) 2004-2005 Simtec Electronics
4 * http://armlinux.simtec.co.uk/ 4 * http://armlinux.simtec.co.uk/
@@ -41,8 +41,8 @@
41 41
42#include <asm/arch/regs-clock.h> 42#include <asm/arch/regs-clock.h>
43 43
44#include "clock.h" 44#include <asm/plat-s3c24xx/clock.h>
45#include "cpu.h" 45#include <asm/plat-s3c24xx/cpu.h>
46 46
47/* S3C2442 extended clock support */ 47/* S3C2442 extended clock support */
48 48
diff --git a/arch/arm/mach-s3c2410/s3c2442.c b/arch/arm/mach-s3c2442/s3c2442.c
index 428732ee68c4..fbf8264249da 100644
--- a/arch/arm/mach-s3c2410/s3c2442.c
+++ b/arch/arm/mach-s3c2442/s3c2442.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/s3c2442.c 1/* linux/arch/arm/mach-s3c2442/s3c2442.c
2 * 2 *
3 * Copyright (c) 2006 Simtec Electronics 3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
@@ -19,8 +19,8 @@
19#include <linux/serial_core.h> 19#include <linux/serial_core.h>
20#include <linux/sysdev.h> 20#include <linux/sysdev.h>
21 21
22#include "s3c2442.h" 22#include <asm/plat-s3c24xx/s3c2442.h>
23#include "cpu.h" 23#include <asm/plat-s3c24xx/cpu.h>
24 24
25static struct sys_device s3c2442_sysdev = { 25static struct sys_device s3c2442_sysdev = {
26 .cls = &s3c2442_sysclass, 26 .cls = &s3c2442_sysclass,
diff --git a/arch/arm/mach-s3c2443/Kconfig b/arch/arm/mach-s3c2443/Kconfig
new file mode 100644
index 000000000000..c649bb2e7ce8
--- /dev/null
+++ b/arch/arm/mach-s3c2443/Kconfig
@@ -0,0 +1,29 @@
1# arch/arm/mach-s3c2443/Kconfig
2#
3# Copyright 2007 Simtec Electronics
4#
5# Licensed under GPLv2
6
7config CPU_S3C2443
8 bool
9 depends on ARCH_S3C2410
10 select S3C2443_DMA if S3C2410_DMA
11 help
12 Support for the S3C2443 SoC from the S3C24XX line
13
14config S3C2443_DMA
15 bool
16 depends on CPU_S3C2443
17 help
18 Internal config node for S3C2443 DMA support
19
20menu "S3C2443 Machines"
21
22config MACH_SMDK2443
23 bool "SMDK2443"
24 select CPU_S3C2443
25 select MACH_SMDK
26 help
27 Say Y here if you are using an SMDK2443
28
29endmenu
diff --git a/arch/arm/mach-s3c2443/Makefile b/arch/arm/mach-s3c2443/Makefile
new file mode 100644
index 000000000000..d1843c9eb8bd
--- /dev/null
+++ b/arch/arm/mach-s3c2443/Makefile
@@ -0,0 +1,20 @@
1# arch/arm/mach-s3c2443/Makefile
2#
3# Copyright 2007 Simtec Electronics
4#
5# Licensed under GPLv2
6
7obj-y :=
8obj-m :=
9obj-n :=
10obj- :=
11
12obj-$(CONFIG_CPU_S3C2443) += s3c2443.o
13obj-$(CONFIG_CPU_S3C2443) += irq.o
14obj-$(CONFIG_CPU_S3C2443) += clock.o
15
16obj-$(CONFIG_S3C2443_DMA) += dma.o
17
18# Machine support
19
20obj-$(CONFIG_MACH_SMDK2443) += mach-smdk2443.o
diff --git a/arch/arm/mach-s3c2443/clock.c b/arch/arm/mach-s3c2443/clock.c
new file mode 100644
index 000000000000..dd2272fb1131
--- /dev/null
+++ b/arch/arm/mach-s3c2443/clock.c
@@ -0,0 +1,1007 @@
1/* linux/arch/arm/mach-s3c2443/clock.c
2 *
3 * Copyright (c) 2007 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2443 Clock control support
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 of the License, or
11 * (at your option) 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21*/
22
23#include <linux/init.h>
24#include <linux/module.h>
25#include <linux/kernel.h>
26#include <linux/list.h>
27#include <linux/errno.h>
28#include <linux/err.h>
29#include <linux/sysdev.h>
30#include <linux/clk.h>
31#include <linux/mutex.h>
32#include <linux/delay.h>
33#include <linux/serial_core.h>
34
35#include <asm/mach/map.h>
36
37#include <asm/hardware.h>
38#include <asm/io.h>
39
40#include <asm/arch/regs-s3c2443-clock.h>
41
42#include <asm/plat-s3c24xx/s3c2443.h>
43#include <asm/plat-s3c24xx/clock.h>
44#include <asm/plat-s3c24xx/cpu.h>
45
46/* We currently have to assume that the system is running
47 * from the XTPll input, and that all ***REFCLKs are being
48 * fed from it, as we cannot read the state of OM[4] from
49 * software.
50 *
51 * It would be possible for each board initialisation to
52 * set the correct muxing at initialisation
53*/
54
55static int s3c2443_clkcon_enable_h(struct clk *clk, int enable)
56{
57 unsigned int clocks = clk->ctrlbit;
58 unsigned long clkcon;
59
60 clkcon = __raw_readl(S3C2443_HCLKCON);
61
62 if (enable)
63 clkcon |= clocks;
64 else
65 clkcon &= ~clocks;
66
67 __raw_writel(clkcon, S3C2443_HCLKCON);
68
69 return 0;
70}
71
72static int s3c2443_clkcon_enable_p(struct clk *clk, int enable)
73{
74 unsigned int clocks = clk->ctrlbit;
75 unsigned long clkcon;
76
77 clkcon = __raw_readl(S3C2443_PCLKCON);
78
79 if (enable)
80 clkcon |= clocks;
81 else
82 clkcon &= ~clocks;
83
84 __raw_writel(clkcon, S3C2443_HCLKCON);
85
86 return 0;
87}
88
89static int s3c2443_clkcon_enable_s(struct clk *clk, int enable)
90{
91 unsigned int clocks = clk->ctrlbit;
92 unsigned long clkcon;
93
94 clkcon = __raw_readl(S3C2443_SCLKCON);
95
96 if (enable)
97 clkcon |= clocks;
98 else
99 clkcon &= ~clocks;
100
101 __raw_writel(clkcon, S3C2443_SCLKCON);
102
103 return 0;
104}
105
106static unsigned long s3c2443_roundrate_clksrc(struct clk *clk,
107 unsigned long rate,
108 unsigned int max)
109{
110 unsigned long parent_rate = clk_get_rate(clk->parent);
111 int div;
112
113 if (rate > parent_rate)
114 return parent_rate;
115
116 /* note, we remove the +/- 1 calculations as they cancel out */
117
118 div = (rate / parent_rate);
119
120 if (div < 1)
121 div = 1;
122 else if (div > max)
123 div = max;
124
125 return parent_rate / div;
126}
127
128static unsigned long s3c2443_roundrate_clksrc4(struct clk *clk,
129 unsigned long rate)
130{
131 return s3c2443_roundrate_clksrc(clk, rate, 4);
132}
133
134static unsigned long s3c2443_roundrate_clksrc16(struct clk *clk,
135 unsigned long rate)
136{
137 return s3c2443_roundrate_clksrc(clk, rate, 16);
138}
139
140static unsigned long s3c2443_roundrate_clksrc256(struct clk *clk,
141 unsigned long rate)
142{
143 return s3c2443_roundrate_clksrc(clk, rate, 256);
144}
145
146/* clock selections */
147
148/* CPU EXTCLK input */
149static struct clk clk_ext = {
150 .name = "ext",
151 .id = -1,
152};
153
154static struct clk clk_mpllref = {
155 .name = "mpllref",
156 .parent = &clk_xtal,
157 .id = -1,
158};
159
160#if 0
161static struct clk clk_mpll = {
162 .name = "mpll",
163 .parent = &clk_mpllref,
164 .id = -1,
165};
166#endif
167
168static struct clk clk_epllref;
169
170static struct clk clk_epll = {
171 .name = "epll",
172 .parent = &clk_epllref,
173 .id = -1,
174};
175
176static struct clk clk_i2s_ext = {
177 .name = "i2s-ext",
178 .id = -1,
179};
180
181static int s3c2443_setparent_epllref(struct clk *clk, struct clk *parent)
182{
183 unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
184
185 clksrc &= ~S3C2443_CLKSRC_EPLLREF_MASK;
186
187 if (parent == &clk_xtal)
188 clksrc |= S3C2443_CLKSRC_EPLLREF_XTAL;
189 else if (parent == &clk_ext)
190 clksrc |= S3C2443_CLKSRC_EPLLREF_EXTCLK;
191 else if (parent != &clk_mpllref)
192 return -EINVAL;
193
194 __raw_writel(clksrc, S3C2443_CLKSRC);
195 clk->parent = parent;
196
197 return 0;
198}
199
200static struct clk clk_epllref = {
201 .name = "epllref",
202 .id = -1,
203 .set_parent = s3c2443_setparent_epllref,
204};
205
206static unsigned long s3c2443_getrate_mdivclk(struct clk *clk)
207{
208 unsigned long parent_rate = clk_get_rate(clk->parent);
209 unsigned long div = __raw_readl(S3C2443_CLKDIV0);
210
211 div &= S3C2443_CLKDIV0_EXTDIV_MASK;
212 div >>= (S3C2443_CLKDIV0_EXTDIV_SHIFT-1); /* x2 */
213
214 return parent_rate / (div + 1);
215}
216
217static struct clk clk_mdivclk = {
218 .name = "mdivclk",
219 .parent = &clk_mpllref,
220 .id = -1,
221 .get_rate = s3c2443_getrate_mdivclk,
222};
223
224
225static int s3c2443_setparent_msysclk(struct clk *clk, struct clk *parent)
226{
227 unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
228
229 clksrc &= ~(S3C2443_CLKSRC_MSYSCLK_MPLL |
230 S3C2443_CLKSRC_EXTCLK_DIV);
231
232 if (parent == &clk_mpll)
233 clksrc |= S3C2443_CLKSRC_MSYSCLK_MPLL;
234 else if (parent == &clk_mdivclk)
235 clksrc |= S3C2443_CLKSRC_EXTCLK_DIV;
236 else if (parent != &clk_mpllref)
237 return -EINVAL;
238
239 __raw_writel(clksrc, S3C2443_CLKSRC);
240 clk->parent = parent;
241
242 return 0;
243}
244
245static struct clk clk_msysclk = {
246 .name = "msysclk",
247 .parent = &clk_xtal,
248 .id = -1,
249 .set_parent = s3c2443_setparent_msysclk,
250};
251
252
253/* esysclk
254 *
255 * this is sourced from either the EPLL or the EPLLref clock
256*/
257
258static int s3c2443_setparent_esysclk(struct clk *clk, struct clk *parent)
259{
260 unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
261
262 if (parent == &clk_epll)
263 clksrc |= S3C2443_CLKSRC_ESYSCLK_EPLL;
264 else if (parent == &clk_epllref)
265 clksrc &= ~S3C2443_CLKSRC_ESYSCLK_EPLL;
266 else
267 return -EINVAL;
268
269 __raw_writel(clksrc, S3C2443_CLKSRC);
270 clk->parent = parent;
271
272 return 0;
273}
274
275static struct clk clk_esysclk = {
276 .name = "esysclk",
277 .parent = &clk_epll,
278 .id = -1,
279 .set_parent = s3c2443_setparent_esysclk,
280};
281
282/* uartclk
283 *
284 * UART baud-rate clock sourced from esysclk via a divisor
285*/
286
287static unsigned long s3c2443_getrate_uart(struct clk *clk)
288{
289 unsigned long parent_rate = clk_get_rate(clk->parent);
290 unsigned long div = __raw_readl(S3C2443_CLKDIV1);
291
292 div &= S3C2443_CLKDIV1_UARTDIV_MASK;
293 div >>= S3C2443_CLKDIV1_UARTDIV_SHIFT;
294
295 return parent_rate / (div + 1);
296}
297
298
299static int s3c2443_setrate_uart(struct clk *clk, unsigned long rate)
300{
301 unsigned long parent_rate = clk_get_rate(clk->parent);
302 unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
303
304 rate = s3c2443_roundrate_clksrc16(clk, rate);
305 rate = parent_rate / rate;
306
307 clkdivn &= ~S3C2443_CLKDIV1_UARTDIV_MASK;
308 clkdivn |= (rate - 1) << S3C2443_CLKDIV1_UARTDIV_SHIFT;
309
310 __raw_writel(clkdivn, S3C2443_CLKDIV1);
311 return 0;
312}
313
314static struct clk clk_uart = {
315 .name = "uartclk",
316 .id = -1,
317 .parent = &clk_esysclk,
318 .get_rate = s3c2443_getrate_uart,
319 .set_rate = s3c2443_setrate_uart,
320 .round_rate = s3c2443_roundrate_clksrc16,
321};
322
323/* hsspi
324 *
325 * high-speed spi clock, sourced from esysclk
326*/
327
328static unsigned long s3c2443_getrate_hsspi(struct clk *clk)
329{
330 unsigned long parent_rate = clk_get_rate(clk->parent);
331 unsigned long div = __raw_readl(S3C2443_CLKDIV1);
332
333 div &= S3C2443_CLKDIV1_HSSPIDIV_MASK;
334 div >>= S3C2443_CLKDIV1_HSSPIDIV_SHIFT;
335
336 return parent_rate / (div + 1);
337}
338
339
340static int s3c2443_setrate_hsspi(struct clk *clk, unsigned long rate)
341{
342 unsigned long parent_rate = clk_get_rate(clk->parent);
343 unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
344
345 rate = s3c2443_roundrate_clksrc4(clk, rate);
346 rate = parent_rate / rate;
347
348 clkdivn &= ~S3C2443_CLKDIV1_HSSPIDIV_MASK;
349 clkdivn |= (rate - 1) << S3C2443_CLKDIV1_HSSPIDIV_SHIFT;
350
351 __raw_writel(clkdivn, S3C2443_CLKDIV1);
352 return 0;
353}
354
355static struct clk clk_hsspi = {
356 .name = "hsspi",
357 .id = -1,
358 .parent = &clk_esysclk,
359 .ctrlbit = S3C2443_SCLKCON_HSSPICLK,
360 .enable = s3c2443_clkcon_enable_s,
361 .get_rate = s3c2443_getrate_hsspi,
362 .set_rate = s3c2443_setrate_hsspi,
363 .round_rate = s3c2443_roundrate_clksrc4,
364};
365
366/* usbhost
367 *
368 * usb host bus-clock, usually 48MHz to provide USB bus clock timing
369*/
370
371static unsigned long s3c2443_getrate_usbhost(struct clk *clk)
372{
373 unsigned long parent_rate = clk_get_rate(clk->parent);
374 unsigned long div = __raw_readl(S3C2443_CLKDIV1);
375
376 div &= S3C2443_CLKDIV1_USBHOSTDIV_MASK;
377 div >>= S3C2443_CLKDIV1_USBHOSTDIV_SHIFT;
378
379 return parent_rate / (div + 1);
380}
381
382static int s3c2443_setrate_usbhost(struct clk *clk, unsigned long rate)
383{
384 unsigned long parent_rate = clk_get_rate(clk->parent);
385 unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
386
387 rate = s3c2443_roundrate_clksrc4(clk, rate);
388 rate = parent_rate / rate;
389
390 clkdivn &= ~S3C2443_CLKDIV1_USBHOSTDIV_MASK;
391 clkdivn |= (rate - 1) << S3C2443_CLKDIV1_USBHOSTDIV_SHIFT;
392
393 __raw_writel(clkdivn, S3C2443_CLKDIV1);
394 return 0;
395}
396
397struct clk clk_usb_bus_host = {
398 .name = "usb-bus-host-parent",
399 .id = -1,
400 .parent = &clk_esysclk,
401 .ctrlbit = S3C2443_SCLKCON_USBHOST,
402 .enable = s3c2443_clkcon_enable_s,
403 .get_rate = s3c2443_getrate_usbhost,
404 .set_rate = s3c2443_setrate_usbhost,
405 .round_rate = s3c2443_roundrate_clksrc4,
406};
407
408/* clk_hsmcc_div
409 *
410 * this clock is sourced from epll, and is fed through a divider,
411 * to a mux controlled by sclkcon where either it or a extclk can
412 * be fed to the hsmmc block
413*/
414
415static unsigned long s3c2443_getrate_hsmmc_div(struct clk *clk)
416{
417 unsigned long parent_rate = clk_get_rate(clk->parent);
418 unsigned long div = __raw_readl(S3C2443_CLKDIV1);
419
420 div &= S3C2443_CLKDIV1_HSMMCDIV_MASK;
421 div >>= S3C2443_CLKDIV1_HSMMCDIV_SHIFT;
422
423 return parent_rate / (div + 1);
424}
425
426static int s3c2443_setrate_hsmmc_div(struct clk *clk, unsigned long rate)
427{
428 unsigned long parent_rate = clk_get_rate(clk->parent);
429 unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
430
431 rate = s3c2443_roundrate_clksrc4(clk, rate);
432 rate = parent_rate / rate;
433
434 clkdivn &= ~S3C2443_CLKDIV1_HSMMCDIV_MASK;
435 clkdivn |= (rate - 1) << S3C2443_CLKDIV1_HSMMCDIV_SHIFT;
436
437 __raw_writel(clkdivn, S3C2443_CLKDIV1);
438 return 0;
439}
440
441static struct clk clk_hsmmc_div = {
442 .name = "hsmmc-div",
443 .id = -1,
444 .parent = &clk_esysclk,
445 .get_rate = s3c2443_getrate_hsmmc_div,
446 .set_rate = s3c2443_setrate_hsmmc_div,
447 .round_rate = s3c2443_roundrate_clksrc4,
448};
449
450static int s3c2443_setparent_hsmmc(struct clk *clk, struct clk *parent)
451{
452 unsigned long clksrc = __raw_readl(S3C2443_SCLKCON);
453
454 clksrc &= ~(S3C2443_SCLKCON_HSMMCCLK_EXT |
455 S3C2443_SCLKCON_HSMMCCLK_EPLL);
456
457 if (parent == &clk_epll)
458 clksrc |= S3C2443_SCLKCON_HSMMCCLK_EPLL;
459 else if (parent == &clk_ext)
460 clksrc |= S3C2443_SCLKCON_HSMMCCLK_EXT;
461 else
462 return -EINVAL;
463
464 if (clk->usage > 0) {
465 __raw_writel(clksrc, S3C2443_SCLKCON);
466 }
467
468 clk->parent = parent;
469 return 0;
470}
471
472static int s3c2443_enable_hsmmc(struct clk *clk, int enable)
473{
474 return s3c2443_setparent_hsmmc(clk, clk->parent);
475}
476
477static struct clk clk_hsmmc = {
478 .name = "hsmmc-if",
479 .id = -1,
480 .parent = &clk_hsmmc_div,
481 .enable = s3c2443_enable_hsmmc,
482 .set_parent = s3c2443_setparent_hsmmc,
483};
484
485/* i2s_eplldiv
486 *
487 * this clock is the output from the i2s divisor of esysclk
488*/
489
490static unsigned long s3c2443_getrate_i2s_eplldiv(struct clk *clk)
491{
492 unsigned long parent_rate = clk_get_rate(clk->parent);
493 unsigned long div = __raw_readl(S3C2443_CLKDIV1);
494
495 div &= S3C2443_CLKDIV1_I2SDIV_MASK;
496 div >>= S3C2443_CLKDIV1_I2SDIV_SHIFT;
497
498 return parent_rate / (div + 1);
499}
500
501static int s3c2443_setrate_i2s_eplldiv(struct clk *clk, unsigned long rate)
502{
503 unsigned long parent_rate = clk_get_rate(clk->parent);
504 unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
505
506 rate = s3c2443_roundrate_clksrc16(clk, rate);
507 rate = parent_rate / rate;
508
509 clkdivn &= ~S3C2443_CLKDIV1_I2SDIV_MASK;
510 clkdivn |= (rate - 1) << S3C2443_CLKDIV1_I2SDIV_SHIFT;
511
512 __raw_writel(clkdivn, S3C2443_CLKDIV1);
513 return 0;
514}
515
516static struct clk clk_i2s_eplldiv = {
517 .name = "i2s-eplldiv",
518 .id = -1,
519 .parent = &clk_esysclk,
520 .get_rate = s3c2443_getrate_i2s_eplldiv,
521 .set_rate = s3c2443_setrate_i2s_eplldiv,
522 .round_rate = s3c2443_roundrate_clksrc16,
523};
524
525/* i2s-ref
526 *
527 * i2s bus reference clock, selectable from external, esysclk or epllref
528*/
529
530static int s3c2443_setparent_i2s(struct clk *clk, struct clk *parent)
531{
532 unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
533
534 clksrc &= ~S3C2443_CLKSRC_I2S_MASK;
535
536 if (parent == &clk_epllref)
537 clksrc |= S3C2443_CLKSRC_I2S_EPLLREF;
538 else if (parent == &clk_i2s_ext)
539 clksrc |= S3C2443_CLKSRC_I2S_EXT;
540 else if (parent != &clk_i2s_eplldiv)
541 return -EINVAL;
542
543 clk->parent = parent;
544 __raw_writel(clksrc, S3C2443_CLKSRC);
545
546 return 0;
547}
548
549static struct clk clk_i2s = {
550 .name = "i2s-if",
551 .id = -1,
552 .parent = &clk_i2s_eplldiv,
553 .ctrlbit = S3C2443_SCLKCON_I2SCLK,
554 .enable = s3c2443_clkcon_enable_s,
555 .set_parent = s3c2443_setparent_i2s,
556};
557
558/* cam-if
559 *
560 * camera interface bus-clock, divided down from esysclk
561*/
562
563static unsigned long s3c2443_getrate_cam(struct clk *clk)
564{
565 unsigned long parent_rate = clk_get_rate(clk->parent);
566 unsigned long div = __raw_readl(S3C2443_CLKDIV1);
567
568 div &= S3C2443_CLKDIV1_CAMDIV_MASK;
569 div >>= S3C2443_CLKDIV1_CAMDIV_SHIFT;
570
571 return parent_rate / (div + 1);
572}
573
574static int s3c2443_setrate_cam(struct clk *clk, unsigned long rate)
575{
576 unsigned long parent_rate = clk_get_rate(clk->parent);
577 unsigned long clkdiv1 = __raw_readl(S3C2443_CLKDIV1);
578
579 rate = s3c2443_roundrate_clksrc16(clk, rate);
580 rate = parent_rate / rate;
581
582 clkdiv1 &= ~S3C2443_CLKDIV1_CAMDIV_MASK;
583 clkdiv1 |= (rate - 1) << S3C2443_CLKDIV1_CAMDIV_SHIFT;
584
585 __raw_writel(clkdiv1, S3C2443_CLKDIV1);
586 return 0;
587}
588
589static struct clk clk_cam = {
590 .name = "camif-upll", /* same as 2440 name */
591 .id = -1,
592 .parent = &clk_esysclk,
593 .ctrlbit = S3C2443_SCLKCON_CAMCLK,
594 .enable = s3c2443_clkcon_enable_s,
595 .get_rate = s3c2443_getrate_cam,
596 .set_rate = s3c2443_setrate_cam,
597 .round_rate = s3c2443_roundrate_clksrc16,
598};
599
600/* display-if
601 *
602 * display interface clock, divided from esysclk
603*/
604
605static unsigned long s3c2443_getrate_display(struct clk *clk)
606{
607 unsigned long parent_rate = clk_get_rate(clk->parent);
608 unsigned long div = __raw_readl(S3C2443_CLKDIV1);
609
610 div &= S3C2443_CLKDIV1_DISPDIV_MASK;
611 div >>= S3C2443_CLKDIV1_DISPDIV_SHIFT;
612
613 return parent_rate / (div + 1);
614}
615
616static int s3c2443_setrate_display(struct clk *clk, unsigned long rate)
617{
618 unsigned long parent_rate = clk_get_rate(clk->parent);
619 unsigned long clkdivn = __raw_readl(S3C2443_CLKDIV1);
620
621 rate = s3c2443_roundrate_clksrc256(clk, rate);
622 rate = parent_rate / rate;
623
624 clkdivn &= ~S3C2443_CLKDIV1_UARTDIV_MASK;
625 clkdivn |= (rate - 1) << S3C2443_CLKDIV1_UARTDIV_SHIFT;
626
627 __raw_writel(clkdivn, S3C2443_CLKDIV1);
628 return 0;
629}
630
631static struct clk clk_display = {
632 .name = "display-if",
633 .id = -1,
634 .parent = &clk_esysclk,
635 .ctrlbit = S3C2443_SCLKCON_DISPCLK,
636 .enable = s3c2443_clkcon_enable_s,
637 .get_rate = s3c2443_getrate_display,
638 .set_rate = s3c2443_setrate_display,
639 .round_rate = s3c2443_roundrate_clksrc256,
640};
641
642/* standard clock definitions */
643
644static struct clk init_clocks_disable[] = {
645 {
646 .name = "nand",
647 .id = -1,
648 .parent = &clk_h,
649 }, {
650 .name = "sdi",
651 .id = -1,
652 .parent = &clk_p,
653 .enable = s3c2443_clkcon_enable_p,
654 .ctrlbit = S3C2443_PCLKCON_SDI,
655 }, {
656 .name = "adc",
657 .id = -1,
658 .parent = &clk_p,
659 .enable = s3c2443_clkcon_enable_p,
660 .ctrlbit = S3C2443_PCLKCON_ADC,
661 }, {
662 .name = "i2c",
663 .id = -1,
664 .parent = &clk_p,
665 .enable = s3c2443_clkcon_enable_p,
666 .ctrlbit = S3C2443_PCLKCON_IIC,
667 }, {
668 .name = "iis",
669 .id = -1,
670 .parent = &clk_p,
671 .enable = s3c2443_clkcon_enable_p,
672 .ctrlbit = S3C2443_PCLKCON_IIS,
673 }, {
674 .name = "spi",
675 .id = 0,
676 .parent = &clk_p,
677 .enable = s3c2443_clkcon_enable_p,
678 .ctrlbit = S3C2443_PCLKCON_SPI0,
679 }, {
680 .name = "spi",
681 .id = 1,
682 .parent = &clk_p,
683 .enable = s3c2443_clkcon_enable_p,
684 .ctrlbit = S3C2443_PCLKCON_SPI1,
685 }
686};
687
688static struct clk init_clocks[] = {
689 {
690 .name = "dma",
691 .id = 0,
692 .parent = &clk_h,
693 .enable = s3c2443_clkcon_enable_h,
694 .ctrlbit = S3C2443_HCLKCON_DMA0,
695 }, {
696 .name = "dma",
697 .id = 1,
698 .parent = &clk_h,
699 .enable = s3c2443_clkcon_enable_h,
700 .ctrlbit = S3C2443_HCLKCON_DMA1,
701 }, {
702 .name = "dma",
703 .id = 2,
704 .parent = &clk_h,
705 .enable = s3c2443_clkcon_enable_h,
706 .ctrlbit = S3C2443_HCLKCON_DMA2,
707 }, {
708 .name = "dma",
709 .id = 3,
710 .parent = &clk_h,
711 .enable = s3c2443_clkcon_enable_h,
712 .ctrlbit = S3C2443_HCLKCON_DMA3,
713 }, {
714 .name = "dma",
715 .id = 4,
716 .parent = &clk_h,
717 .enable = s3c2443_clkcon_enable_h,
718 .ctrlbit = S3C2443_HCLKCON_DMA4,
719 }, {
720 .name = "dma",
721 .id = 5,
722 .parent = &clk_h,
723 .enable = s3c2443_clkcon_enable_h,
724 .ctrlbit = S3C2443_HCLKCON_DMA5,
725 }, {
726 .name = "lcd",
727 .id = -1,
728 .parent = &clk_h,
729 .enable = s3c2443_clkcon_enable_h,
730 .ctrlbit = S3C2443_HCLKCON_LCDC,
731 }, {
732 .name = "gpio",
733 .id = -1,
734 .parent = &clk_p,
735 .enable = s3c2443_clkcon_enable_p,
736 .ctrlbit = S3C2443_PCLKCON_GPIO,
737 }, {
738 .name = "usb-host",
739 .id = -1,
740 .parent = &clk_h,
741 .enable = s3c2443_clkcon_enable_h,
742 .ctrlbit = S3C2443_HCLKCON_USBH,
743 }, {
744 .name = "usb-device",
745 .id = -1,
746 .parent = &clk_h,
747 .enable = s3c2443_clkcon_enable_h,
748 .ctrlbit = S3C2443_HCLKCON_USBD,
749 }, {
750 .name = "timers",
751 .id = -1,
752 .parent = &clk_p,
753 .enable = s3c2443_clkcon_enable_p,
754 .ctrlbit = S3C2443_PCLKCON_PWMT,
755 }, {
756 .name = "uart",
757 .id = 0,
758 .parent = &clk_p,
759 .enable = s3c2443_clkcon_enable_p,
760 .ctrlbit = S3C2443_PCLKCON_UART0,
761 }, {
762 .name = "uart",
763 .id = 1,
764 .parent = &clk_p,
765 .enable = s3c2443_clkcon_enable_p,
766 .ctrlbit = S3C2443_PCLKCON_UART1,
767 }, {
768 .name = "uart",
769 .id = 2,
770 .parent = &clk_p,
771 .enable = s3c2443_clkcon_enable_p,
772 .ctrlbit = S3C2443_PCLKCON_UART2,
773 }, {
774 .name = "uart",
775 .id = 3,
776 .parent = &clk_p,
777 .enable = s3c2443_clkcon_enable_p,
778 .ctrlbit = S3C2443_PCLKCON_UART3,
779 }, {
780 .name = "rtc",
781 .id = -1,
782 .parent = &clk_p,
783 .enable = s3c2443_clkcon_enable_p,
784 .ctrlbit = S3C2443_PCLKCON_RTC,
785 }, {
786 .name = "watchdog",
787 .id = -1,
788 .parent = &clk_p,
789 .ctrlbit = S3C2443_PCLKCON_WDT,
790 }, {
791 .name = "usb-bus-host",
792 .id = -1,
793 .parent = &clk_usb_bus_host,
794 }
795};
796
797/* clocks to add where we need to check their parentage */
798
799/* s3c2443_clk_initparents
800 *
801 * Initialise the parents for the clocks that we get at start-time
802*/
803
804static int __init clk_init_set_parent(struct clk *clk, struct clk *parent)
805{
806 printk(KERN_DEBUG "clock %s: parent %s\n", clk->name, parent->name);
807 return clk_set_parent(clk, parent);
808}
809
810static void __init s3c2443_clk_initparents(void)
811{
812 unsigned long clksrc = __raw_readl(S3C2443_CLKSRC);
813 struct clk *parent;
814
815 switch (clksrc & S3C2443_CLKSRC_EPLLREF_MASK) {
816 case S3C2443_CLKSRC_EPLLREF_EXTCLK:
817 parent = &clk_ext;
818 break;
819
820 case S3C2443_CLKSRC_EPLLREF_XTAL:
821 default:
822 parent = &clk_xtal;
823 break;
824
825 case S3C2443_CLKSRC_EPLLREF_MPLLREF:
826 case S3C2443_CLKSRC_EPLLREF_MPLLREF2:
827 parent = &clk_mpllref;
828 break;
829 }
830
831 clk_init_set_parent(&clk_epllref, parent);
832
833 switch (clksrc & S3C2443_CLKSRC_I2S_MASK) {
834 case S3C2443_CLKSRC_I2S_EXT:
835 parent = &clk_i2s_ext;
836 break;
837
838 case S3C2443_CLKSRC_I2S_EPLLDIV:
839 default:
840 parent = &clk_i2s_eplldiv;
841 break;
842
843 case S3C2443_CLKSRC_I2S_EPLLREF:
844 case S3C2443_CLKSRC_I2S_EPLLREF3:
845 parent = &clk_epllref;
846 }
847
848 clk_init_set_parent(&clk_i2s, &clk_epllref);
849
850 /* esysclk source */
851
852 parent = (clksrc & S3C2443_CLKSRC_ESYSCLK_EPLL) ?
853 &clk_epll : &clk_epllref;
854
855 clk_init_set_parent(&clk_esysclk, parent);
856
857 /* msysclk source */
858
859 if (clksrc & S3C2443_CLKSRC_MSYSCLK_MPLL) {
860 parent = &clk_mpll;
861 } else {
862 parent = (clksrc & S3C2443_CLKSRC_EXTCLK_DIV) ?
863 &clk_mdivclk : &clk_mpllref;
864 }
865
866 clk_init_set_parent(&clk_msysclk, parent);
867}
868
869/* armdiv divisor table */
870
871static unsigned int armdiv[16] = {
872 [S3C2443_CLKDIV0_ARMDIV_1 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 1,
873 [S3C2443_CLKDIV0_ARMDIV_2 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 2,
874 [S3C2443_CLKDIV0_ARMDIV_3 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 3,
875 [S3C2443_CLKDIV0_ARMDIV_4 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 4,
876 [S3C2443_CLKDIV0_ARMDIV_6 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 6,
877 [S3C2443_CLKDIV0_ARMDIV_8 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 8,
878 [S3C2443_CLKDIV0_ARMDIV_12 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 12,
879 [S3C2443_CLKDIV0_ARMDIV_16 >> S3C2443_CLKDIV0_ARMDIV_SHIFT] = 16,
880};
881
882static inline unsigned int s3c2443_fclk_div(unsigned long clkcon0)
883{
884 clkcon0 &= S3C2443_CLKDIV0_ARMDIV_MASK;
885
886 return armdiv[clkcon0 >> S3C2443_CLKDIV0_ARMDIV_SHIFT];
887}
888
889static inline unsigned long s3c2443_get_prediv(unsigned long clkcon0)
890{
891 clkcon0 &= S3C2443_CLKDIV0_PREDIV_MASK;
892 clkcon0 >>= S3C2443_CLKDIV0_PREDIV_SHIFT;
893
894 return clkcon0 + 1;
895}
896
897/* clocks to add straight away */
898
899static struct clk *clks[] __initdata = {
900 &clk_ext,
901 &clk_epll,
902 &clk_usb_bus_host,
903 &clk_usb_bus,
904 &clk_esysclk,
905 &clk_epllref,
906 &clk_mpllref,
907 &clk_msysclk,
908 &clk_uart,
909 &clk_display,
910 &clk_cam,
911 &clk_i2s_eplldiv,
912 &clk_i2s,
913 &clk_hsspi,
914 &clk_hsmmc_div,
915 &clk_hsmmc,
916};
917
918void __init s3c2443_init_clocks(int xtal)
919{
920 unsigned long epllcon = __raw_readl(S3C2443_EPLLCON);
921 unsigned long mpllcon = __raw_readl(S3C2443_MPLLCON);
922 unsigned long clkdiv0 = __raw_readl(S3C2443_CLKDIV0);
923 unsigned long pll;
924 unsigned long fclk;
925 unsigned long hclk;
926 unsigned long pclk;
927 struct clk *clkp;
928 int ret;
929 int ptr;
930
931 pll = s3c2443_get_mpll(mpllcon, xtal);
932
933 fclk = pll / s3c2443_fclk_div(clkdiv0);
934 hclk = fclk / s3c2443_get_prediv(clkdiv0);
935 hclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_HCLK) ? 2 : 1);
936 pclk = hclk / ((clkdiv0 & S3C2443_CLKDIV0_HALF_PCLK) ? 2 : 1);
937
938 s3c24xx_setup_clocks(xtal, fclk, hclk, pclk);
939
940 printk("S3C2443: mpll %s %ld.%03ld MHz, cpu %ld.%03ld MHz, mem %ld.%03ld MHz, pclk %ld.%03ld MHz\n",
941 (mpllcon & S3C2443_PLLCON_OFF) ? "off":"on",
942 print_mhz(pll), print_mhz(fclk),
943 print_mhz(hclk), print_mhz(pclk));
944
945 s3c2443_clk_initparents();
946
947 for (ptr = 0; ptr < ARRAY_SIZE(clks); ptr++) {
948 clkp = clks[ptr];
949
950 ret = s3c24xx_register_clock(clkp);
951 if (ret < 0) {
952 printk(KERN_ERR "Failed to register clock %s (%d)\n",
953 clkp->name, ret);
954 }
955 }
956
957 clk_epll.rate = s3c2443_get_epll(epllcon, xtal);
958
959 clk_usb_bus.parent = &clk_usb_bus_host;
960
961 /* ensure usb bus clock is within correct rate of 48MHz */
962
963 if (clk_get_rate(&clk_usb_bus_host) != (48 * 1000 * 1000)) {
964 printk(KERN_INFO "Warning: USB host bus not at 48MHz\n");
965 clk_set_rate(&clk_usb_bus_host, 48*1000*1000);
966 }
967
968 printk("S3C2443: epll %s %ld.%03ld MHz, usb-bus %ld.%03ld MHz\n",
969 (epllcon & S3C2443_PLLCON_OFF) ? "off":"on",
970 print_mhz(clk_get_rate(&clk_epll)),
971 print_mhz(clk_get_rate(&clk_usb_bus)));
972
973 /* register clocks from clock array */
974
975 clkp = init_clocks;
976 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks); ptr++, clkp++) {
977 ret = s3c24xx_register_clock(clkp);
978 if (ret < 0) {
979 printk(KERN_ERR "Failed to register clock %s (%d)\n",
980 clkp->name, ret);
981 }
982 }
983
984 /* We must be careful disabling the clocks we are not intending to
985 * be using at boot time, as subsytems such as the LCD which do
986 * their own DMA requests to the bus can cause the system to lockup
987 * if they where in the middle of requesting bus access.
988 *
989 * Disabling the LCD clock if the LCD is active is very dangerous,
990 * and therefore the bootloader should be careful to not enable
991 * the LCD clock if it is not needed.
992 */
993
994 /* install (and disable) the clocks we do not need immediately */
995
996 clkp = init_clocks_disable;
997 for (ptr = 0; ptr < ARRAY_SIZE(init_clocks_disable); ptr++, clkp++) {
998
999 ret = s3c24xx_register_clock(clkp);
1000 if (ret < 0) {
1001 printk(KERN_ERR "Failed to register clock %s (%d)\n",
1002 clkp->name, ret);
1003 }
1004
1005 (clkp->enable)(clkp, 0);
1006 }
1007}
diff --git a/arch/arm/mach-s3c2443/dma.c b/arch/arm/mach-s3c2443/dma.c
new file mode 100644
index 000000000000..f70e8ccffc3d
--- /dev/null
+++ b/arch/arm/mach-s3c2443/dma.c
@@ -0,0 +1,180 @@
1/* linux/arch/arm/mach-s3c2443/dma.c
2 *
3 * Copyright (c) 2007 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2443 DMA selection
7 *
8 * http://armlinux.simtec.co.uk/
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 version 2 as
12 * published by the Free Software Foundation.
13*/
14
15#include <linux/kernel.h>
16#include <linux/init.h>
17#include <linux/sysdev.h>
18#include <linux/serial_core.h>
19
20#include <asm/dma.h>
21#include <asm/arch/dma.h>
22#include <asm/io.h>
23
24#include <asm/plat-s3c24xx/dma.h>
25#include <asm/plat-s3c24xx/cpu.h>
26
27#include <asm/arch/regs-serial.h>
28#include <asm/arch/regs-gpio.h>
29#include <asm/arch/regs-ac97.h>
30#include <asm/arch/regs-mem.h>
31#include <asm/arch/regs-lcd.h>
32#include <asm/arch/regs-sdi.h>
33#include <asm/arch/regs-iis.h>
34#include <asm/arch/regs-spi.h>
35
36#define MAP(x) { \
37 [0] = (x) | DMA_CH_VALID, \
38 [1] = (x) | DMA_CH_VALID, \
39 [2] = (x) | DMA_CH_VALID, \
40 [3] = (x) | DMA_CH_VALID, \
41 [4] = (x) | DMA_CH_VALID, \
42 [5] = (x) | DMA_CH_VALID, \
43 }
44
45static struct s3c24xx_dma_map __initdata s3c2443_dma_mappings[] = {
46 [DMACH_XD0] = {
47 .name = "xdreq0",
48 .channels = MAP(S3C2443_DMAREQSEL_XDREQ0),
49 },
50 [DMACH_XD1] = {
51 .name = "xdreq1",
52 .channels = MAP(S3C2443_DMAREQSEL_XDREQ1),
53 },
54 [DMACH_SDI] = {
55 .name = "sdi",
56 .channels = MAP(S3C2443_DMAREQSEL_SDI),
57 .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO,
58 .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO,
59 },
60 [DMACH_SPI0] = {
61 .name = "spi0",
62 .channels = MAP(S3C2443_DMAREQSEL_SPI0TX),
63 .hw_addr.to = S3C2410_PA_SPI + S3C2410_SPTDAT,
64 .hw_addr.from = S3C2410_PA_SPI + S3C2410_SPRDAT,
65 },
66 [DMACH_SPI1] = {
67 .name = "spi1",
68 .channels = MAP(S3C2443_DMAREQSEL_SPI1TX),
69 .hw_addr.to = S3C2410_PA_SPI + 0x20 + S3C2410_SPTDAT,
70 .hw_addr.from = S3C2410_PA_SPI + 0x20 + S3C2410_SPRDAT,
71 },
72 [DMACH_UART0] = {
73 .name = "uart0",
74 .channels = MAP(S3C2443_DMAREQSEL_UART0_0),
75 .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH,
76 .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH,
77 },
78 [DMACH_UART1] = {
79 .name = "uart1",
80 .channels = MAP(S3C2443_DMAREQSEL_UART1_0),
81 .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH,
82 .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH,
83 },
84 [DMACH_UART2] = {
85 .name = "uart2",
86 .channels = MAP(S3C2443_DMAREQSEL_UART2_0),
87 .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH,
88 .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH,
89 },
90 [DMACH_UART3] = {
91 .name = "uart3",
92 .channels = MAP(S3C2443_DMAREQSEL_UART3_0),
93 .hw_addr.to = S3C2443_PA_UART3 + S3C2410_UTXH,
94 .hw_addr.from = S3C2443_PA_UART3 + S3C2410_URXH,
95 },
96 [DMACH_UART0_SRC2] = {
97 .name = "uart0",
98 .channels = MAP(S3C2443_DMAREQSEL_UART0_1),
99 .hw_addr.to = S3C2410_PA_UART0 + S3C2410_UTXH,
100 .hw_addr.from = S3C2410_PA_UART0 + S3C2410_URXH,
101 },
102 [DMACH_UART1_SRC2] = {
103 .name = "uart1",
104 .channels = MAP(S3C2443_DMAREQSEL_UART1_1),
105 .hw_addr.to = S3C2410_PA_UART1 + S3C2410_UTXH,
106 .hw_addr.from = S3C2410_PA_UART1 + S3C2410_URXH,
107 },
108 [DMACH_UART2_SRC2] = {
109 .name = "uart2",
110 .channels = MAP(S3C2443_DMAREQSEL_UART2_1),
111 .hw_addr.to = S3C2410_PA_UART2 + S3C2410_UTXH,
112 .hw_addr.from = S3C2410_PA_UART2 + S3C2410_URXH,
113 },
114 [DMACH_UART3_SRC2] = {
115 .name = "uart3",
116 .channels = MAP(S3C2443_DMAREQSEL_UART3_1),
117 .hw_addr.to = S3C2443_PA_UART3 + S3C2410_UTXH,
118 .hw_addr.from = S3C2443_PA_UART3 + S3C2410_URXH,
119 },
120 [DMACH_TIMER] = {
121 .name = "timer",
122 .channels = MAP(S3C2443_DMAREQSEL_TIMER),
123 },
124 [DMACH_I2S_IN] = {
125 .name = "i2s-sdi",
126 .channels = MAP(S3C2443_DMAREQSEL_I2SRX),
127 .hw_addr.from = S3C2410_PA_IIS + S3C2410_IISFIFO,
128 },
129 [DMACH_I2S_OUT] = {
130 .name = "i2s-sdo",
131 .channels = MAP(S3C2443_DMAREQSEL_I2STX),
132 .hw_addr.to = S3C2410_PA_IIS + S3C2410_IISFIFO,
133 },
134 [DMACH_PCM_IN] = {
135 .name = "pcm-in",
136 .channels = MAP(S3C2443_DMAREQSEL_PCMIN),
137 .hw_addr.from = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
138 },
139 [DMACH_PCM_OUT] = {
140 .name = "pcm-out",
141 .channels = MAP(S3C2443_DMAREQSEL_PCMOUT),
142 .hw_addr.to = S3C2440_PA_AC97 + S3C_AC97_PCM_DATA,
143 },
144 [DMACH_MIC_IN] = {
145 .name = "mic-in",
146 .channels = MAP(S3C2443_DMAREQSEL_MICIN),
147 .hw_addr.from = S3C2440_PA_AC97 + S3C_AC97_MIC_DATA,
148 },
149};
150
151static void s3c2443_dma_select(struct s3c2410_dma_chan *chan,
152 struct s3c24xx_dma_map *map)
153{
154 writel(map->channels[0] | S3C2443_DMAREQSEL_HW,
155 chan->regs + S3C2443_DMA_DMAREQSEL);
156}
157
158static struct s3c24xx_dma_selection __initdata s3c2443_dma_sel = {
159 .select = s3c2443_dma_select,
160 .dcon_mask = 0,
161 .map = s3c2443_dma_mappings,
162 .map_size = ARRAY_SIZE(s3c2443_dma_mappings),
163};
164
165static int s3c2443_dma_add(struct sys_device *sysdev)
166{
167 s3c24xx_dma_init(6, IRQ_S3C2443_DMA0, 0x100);
168 return s3c24xx_dma_init_map(&s3c2443_dma_sel);
169}
170
171static struct sysdev_driver s3c2443_dma_driver = {
172 .add = s3c2443_dma_add,
173};
174
175static int __init s3c2443_dma_init(void)
176{
177 return sysdev_driver_register(&s3c2443_sysclass, &s3c2443_dma_driver);
178}
179
180arch_initcall(s3c2443_dma_init);
diff --git a/arch/arm/mach-s3c2443/irq.c b/arch/arm/mach-s3c2443/irq.c
new file mode 100644
index 000000000000..7a45b6dcb73e
--- /dev/null
+++ b/arch/arm/mach-s3c2443/irq.c
@@ -0,0 +1,290 @@
1/* linux/arch/arm/mach-s3c2443/irq.c
2 *
3 * Copyright (c) 2007 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
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
22#include <linux/init.h>
23#include <linux/module.h>
24#include <linux/interrupt.h>
25#include <linux/ioport.h>
26#include <linux/ptrace.h>
27#include <linux/sysdev.h>
28
29#include <asm/hardware.h>
30#include <asm/irq.h>
31#include <asm/io.h>
32
33#include <asm/mach/irq.h>
34
35#include <asm/arch/regs-irq.h>
36#include <asm/arch/regs-gpio.h>
37
38#include <asm/plat-s3c24xx/cpu.h>
39#include <asm/plat-s3c24xx/pm.h>
40#include <asm/plat-s3c24xx/irq.h>
41
42#define INTMSK(start, end) ((1 << ((end) + 1 - (start))) - 1)
43
44static inline void s3c2443_irq_demux(unsigned int irq, unsigned int len)
45{
46 unsigned int subsrc, submsk;
47 unsigned int end;
48 struct irq_desc *mydesc;
49
50 /* read the current pending interrupts, and the mask
51 * for what it is available */
52
53 subsrc = __raw_readl(S3C2410_SUBSRCPND);
54 submsk = __raw_readl(S3C2410_INTSUBMSK);
55
56 subsrc &= ~submsk;
57 subsrc >>= (irq - S3C2410_IRQSUB(0));
58 subsrc &= (1 << len)-1;
59
60 end = len + irq;
61 mydesc = irq_desc + irq;
62
63 for (; irq < end && subsrc; irq++) {
64 if (subsrc & 1)
65 desc_handle_irq(irq, mydesc);
66
67 mydesc++;
68 subsrc >>= 1;
69 }
70}
71
72/* WDT/AC97 sub interrupts */
73
74static void s3c2443_irq_demux_wdtac97(unsigned int irq, struct irq_desc *desc)
75{
76 s3c2443_irq_demux(IRQ_S3C2443_WDT, 4);
77}
78
79#define INTMSK_WDTAC97 (1UL << (IRQ_WDT - IRQ_EINT0))
80#define SUBMSK_WDTAC97 INTMSK(IRQ_S3C2443_WDT, IRQ_S3C2443_AC97)
81
82static void s3c2443_irq_wdtac97_mask(unsigned int irqno)
83{
84 s3c_irqsub_mask(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
85}
86
87static void s3c2443_irq_wdtac97_unmask(unsigned int irqno)
88{
89 s3c_irqsub_unmask(irqno, INTMSK_WDTAC97);
90}
91
92static void s3c2443_irq_wdtac97_ack(unsigned int irqno)
93{
94 s3c_irqsub_maskack(irqno, INTMSK_WDTAC97, SUBMSK_WDTAC97);
95}
96
97static struct irq_chip s3c2443_irq_wdtac97 = {
98 .mask = s3c2443_irq_wdtac97_mask,
99 .unmask = s3c2443_irq_wdtac97_unmask,
100 .ack = s3c2443_irq_wdtac97_ack,
101};
102
103
104/* LCD sub interrupts */
105
106static void s3c2443_irq_demux_lcd(unsigned int irq, struct irq_desc *desc)
107{
108 s3c2443_irq_demux(IRQ_S3C2443_LCD1, 4);
109}
110
111#define INTMSK_LCD (1UL << (IRQ_LCD - IRQ_EINT0))
112#define SUBMSK_LCD INTMSK(IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4)
113
114static void s3c2443_irq_lcd_mask(unsigned int irqno)
115{
116 s3c_irqsub_mask(irqno, INTMSK_LCD, SUBMSK_LCD);
117}
118
119static void s3c2443_irq_lcd_unmask(unsigned int irqno)
120{
121 s3c_irqsub_unmask(irqno, INTMSK_LCD);
122}
123
124static void s3c2443_irq_lcd_ack(unsigned int irqno)
125{
126 s3c_irqsub_maskack(irqno, INTMSK_LCD, SUBMSK_LCD);
127}
128
129static struct irq_chip s3c2443_irq_lcd = {
130 .mask = s3c2443_irq_lcd_mask,
131 .unmask = s3c2443_irq_lcd_unmask,
132 .ack = s3c2443_irq_lcd_ack,
133};
134
135
136/* DMA sub interrupts */
137
138static void s3c2443_irq_demux_dma(unsigned int irq, struct irq_desc *desc)
139{
140 s3c2443_irq_demux(IRQ_S3C2443_DMA1, 6);
141}
142
143#define INTMSK_DMA (1UL << (IRQ_S3C2443_DMA - IRQ_EINT0))
144#define SUBMSK_DMA INTMSK(IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5)
145
146
147static void s3c2443_irq_dma_mask(unsigned int irqno)
148{
149 s3c_irqsub_mask(irqno, INTMSK_DMA, SUBMSK_DMA);
150}
151
152static void s3c2443_irq_dma_unmask(unsigned int irqno)
153{
154 s3c_irqsub_unmask(irqno, INTMSK_DMA);
155}
156
157static void s3c2443_irq_dma_ack(unsigned int irqno)
158{
159 s3c_irqsub_maskack(irqno, INTMSK_DMA, SUBMSK_DMA);
160}
161
162static struct irq_chip s3c2443_irq_dma = {
163 .mask = s3c2443_irq_dma_mask,
164 .unmask = s3c2443_irq_dma_unmask,
165 .ack = s3c2443_irq_dma_ack,
166};
167
168
169/* UART3 sub interrupts */
170
171static void s3c2443_irq_demux_uart3(unsigned int irq, struct irq_desc *desc)
172{
173 s3c2443_irq_demux(IRQ_S3C2443_UART3, 3);
174}
175
176#define INTMSK_UART3 (1UL << (IRQ_S3C2443_UART3 - IRQ_EINT0))
177#define SUBMSK_UART3 (0xf << (IRQ_S3C2443_RX3 - S3C2410_IRQSUB(0)))
178
179
180static void s3c2443_irq_uart3_mask(unsigned int irqno)
181{
182 s3c_irqsub_mask(irqno, INTMSK_UART3, SUBMSK_UART3);
183}
184
185static void s3c2443_irq_uart3_unmask(unsigned int irqno)
186{
187 s3c_irqsub_unmask(irqno, INTMSK_UART3);
188}
189
190static void s3c2443_irq_uart3_ack(unsigned int irqno)
191{
192 s3c_irqsub_maskack(irqno, INTMSK_UART3, SUBMSK_UART3);
193}
194
195static struct irq_chip s3c2443_irq_uart3 = {
196 .mask = s3c2443_irq_uart3_mask,
197 .unmask = s3c2443_irq_uart3_unmask,
198 .ack = s3c2443_irq_uart3_ack,
199};
200
201
202/* CAM sub interrupts */
203
204static void s3c2443_irq_demux_cam(unsigned int irq, struct irq_desc *desc)
205{
206 s3c2443_irq_demux(IRQ_S3C2440_CAM_C, 4);
207}
208
209#define INTMSK_CAM (1UL << (IRQ_CAM - IRQ_EINT0))
210#define SUBMSK_CAM INTMSK(IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P)
211
212static void s3c2443_irq_cam_mask(unsigned int irqno)
213{
214 s3c_irqsub_mask(irqno, INTMSK_CAM, SUBMSK_CAM);
215}
216
217static void s3c2443_irq_cam_unmask(unsigned int irqno)
218{
219 s3c_irqsub_unmask(irqno, INTMSK_CAM);
220}
221
222static void s3c2443_irq_cam_ack(unsigned int irqno)
223{
224 s3c_irqsub_maskack(irqno, INTMSK_CAM, SUBMSK_CAM);
225}
226
227static struct irq_chip s3c2443_irq_cam = {
228 .mask = s3c2443_irq_cam_mask,
229 .unmask = s3c2443_irq_cam_unmask,
230 .ack = s3c2443_irq_cam_ack,
231};
232
233/* IRQ initialisation code */
234
235static int __init s3c2443_add_sub(unsigned int base,
236 void (*demux)(unsigned int,
237 struct irq_desc *),
238 struct irq_chip *chip,
239 unsigned int start, unsigned int end)
240{
241 unsigned int irqno;
242
243 set_irq_chip(base, &s3c_irq_level_chip);
244 set_irq_handler(base, handle_level_irq);
245 set_irq_chained_handler(base, demux);
246
247 for (irqno = start; irqno <= end; irqno++) {
248 set_irq_chip(irqno, chip);
249 set_irq_handler(irqno, handle_level_irq);
250 set_irq_flags(irqno, IRQF_VALID);
251 }
252
253 return 0;
254}
255
256static int s3c2443_irq_add(struct sys_device *sysdev)
257{
258 printk("S3C2443: IRQ Support\n");
259
260 s3c2443_add_sub(IRQ_CAM, s3c2443_irq_demux_cam, &s3c2443_irq_cam,
261 IRQ_S3C2440_CAM_C, IRQ_S3C2440_CAM_P);
262
263 s3c2443_add_sub(IRQ_LCD, s3c2443_irq_demux_lcd, &s3c2443_irq_lcd,
264 IRQ_S3C2443_LCD1, IRQ_S3C2443_LCD4);
265
266 s3c2443_add_sub(IRQ_S3C2443_DMA, s3c2443_irq_demux_dma,
267 &s3c2443_irq_dma, IRQ_S3C2443_DMA0, IRQ_S3C2443_DMA5);
268
269 s3c2443_add_sub(IRQ_S3C2443_UART3, s3c2443_irq_demux_uart3,
270 &s3c2443_irq_uart3,
271 IRQ_S3C2443_RX3, IRQ_S3C2443_ERR3);
272
273 s3c2443_add_sub(IRQ_WDT, s3c2443_irq_demux_wdtac97,
274 &s3c2443_irq_wdtac97,
275 IRQ_S3C2443_WDT, IRQ_S3C2443_AC97);
276
277 return 0;
278}
279
280static struct sysdev_driver s3c2443_irq_driver = {
281 .add = s3c2443_irq_add,
282};
283
284static int s3c2443_irq_init(void)
285{
286 return sysdev_driver_register(&s3c2443_sysclass, &s3c2443_irq_driver);
287}
288
289arch_initcall(s3c2443_irq_init);
290
diff --git a/arch/arm/mach-s3c2443/mach-smdk2443.c b/arch/arm/mach-s3c2443/mach-smdk2443.c
new file mode 100644
index 000000000000..e82aaff7dee4
--- /dev/null
+++ b/arch/arm/mach-s3c2443/mach-smdk2443.c
@@ -0,0 +1,137 @@
1/* linux/arch/arm/mach-s3c2443/mach-smdk2443.c
2 *
3 * Copyright (c) 2007 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * http://www.fluff.org/ben/smdk2443/
7 *
8 * Thanks to Samsung for the loan of an SMDK2443
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 version 2 as
12 * published by the Free Software Foundation.
13 *
14*/
15
16#include <linux/kernel.h>
17#include <linux/types.h>
18#include <linux/interrupt.h>
19#include <linux/list.h>
20#include <linux/timer.h>
21#include <linux/init.h>
22#include <linux/serial_core.h>
23#include <linux/platform_device.h>
24
25#include <asm/mach/arch.h>
26#include <asm/mach/map.h>
27#include <asm/mach/irq.h>
28
29#include <asm/hardware.h>
30#include <asm/io.h>
31#include <asm/irq.h>
32#include <asm/mach-types.h>
33
34#include <asm/arch/regs-serial.h>
35#include <asm/arch/regs-gpio.h>
36#include <asm/arch/regs-lcd.h>
37
38#include <asm/arch/idle.h>
39#include <asm/arch/fb.h>
40
41#include <asm/plat-s3c24xx/s3c2410.h>
42#include <asm/plat-s3c24xx/s3c2440.h>
43#include <asm/plat-s3c24xx/clock.h>
44#include <asm/plat-s3c24xx/devs.h>
45#include <asm/plat-s3c24xx/cpu.h>
46
47#include <asm/plat-s3c24xx/common-smdk.h>
48
49static struct map_desc smdk2443_iodesc[] __initdata = {
50 /* ISA IO Space map (memory space selected by A24) */
51
52 {
53 .virtual = (u32)S3C24XX_VA_ISA_WORD,
54 .pfn = __phys_to_pfn(S3C2410_CS2),
55 .length = 0x10000,
56 .type = MT_DEVICE,
57 }, {
58 .virtual = (u32)S3C24XX_VA_ISA_WORD + 0x10000,
59 .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
60 .length = SZ_4M,
61 .type = MT_DEVICE,
62 }, {
63 .virtual = (u32)S3C24XX_VA_ISA_BYTE,
64 .pfn = __phys_to_pfn(S3C2410_CS2),
65 .length = 0x10000,
66 .type = MT_DEVICE,
67 }, {
68 .virtual = (u32)S3C24XX_VA_ISA_BYTE + 0x10000,
69 .pfn = __phys_to_pfn(S3C2410_CS2 + (1<<24)),
70 .length = SZ_4M,
71 .type = MT_DEVICE,
72 }
73};
74
75#define UCON S3C2410_UCON_DEFAULT | S3C2410_UCON_UCLK
76#define ULCON S3C2410_LCON_CS8 | S3C2410_LCON_PNONE | S3C2410_LCON_STOPB
77#define UFCON S3C2410_UFCON_RXTRIG8 | S3C2410_UFCON_FIFOMODE
78
79static struct s3c2410_uartcfg smdk2443_uartcfgs[] __initdata = {
80 [0] = {
81 .hwport = 0,
82 .flags = 0,
83 .ucon = 0x3c5,
84 .ulcon = 0x03,
85 .ufcon = 0x51,
86 },
87 [1] = {
88 .hwport = 1,
89 .flags = 0,
90 .ucon = 0x3c5,
91 .ulcon = 0x03,
92 .ufcon = 0x51,
93 },
94 /* IR port */
95 [2] = {
96 .hwport = 2,
97 .flags = 0,
98 .ucon = 0x3c5,
99 .ulcon = 0x43,
100 .ufcon = 0x51,
101 }
102};
103
104static struct platform_device *smdk2443_devices[] __initdata = {
105 &s3c_device_wdt,
106 &s3c_device_i2c,
107};
108
109static struct s3c24xx_board smdk2443_board __initdata = {
110 .devices = smdk2443_devices,
111 .devices_count = ARRAY_SIZE(smdk2443_devices)
112};
113
114static void __init smdk2443_map_io(void)
115{
116 s3c24xx_init_io(smdk2443_iodesc, ARRAY_SIZE(smdk2443_iodesc));
117 s3c24xx_init_clocks(12000000);
118 s3c24xx_init_uarts(smdk2443_uartcfgs, ARRAY_SIZE(smdk2443_uartcfgs));
119 s3c24xx_set_board(&smdk2443_board);
120}
121
122static void __init smdk2443_machine_init(void)
123{
124 smdk_machine_init();
125}
126
127MACHINE_START(SMDK2443, "SMDK2443")
128 /* Maintainer: Ben Dooks <ben@fluff.org> */
129 .phys_io = S3C2410_PA_UART,
130 .io_pg_offst = (((u32)S3C24XX_VA_UART) >> 18) & 0xfffc,
131 .boot_params = S3C2410_SDRAM_PA + 0x100,
132
133 .init_irq = s3c24xx_init_irq,
134 .map_io = smdk2443_map_io,
135 .init_machine = smdk2443_machine_init,
136 .timer = &s3c24xx_timer,
137MACHINE_END
diff --git a/arch/arm/mach-s3c2443/s3c2443.c b/arch/arm/mach-s3c2443/s3c2443.c
new file mode 100644
index 000000000000..11b1d0b310c3
--- /dev/null
+++ b/arch/arm/mach-s3c2443/s3c2443.c
@@ -0,0 +1,97 @@
1/* linux/arch/arm/mach-s3c2443/s3c2443.c
2 *
3 * Copyright (c) 2007 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * Samsung S3C2443 Mobile CPU support
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 version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#include <linux/kernel.h>
14#include <linux/types.h>
15#include <linux/interrupt.h>
16#include <linux/list.h>
17#include <linux/timer.h>
18#include <linux/init.h>
19#include <linux/platform_device.h>
20#include <linux/serial_core.h>
21#include <linux/sysdev.h>
22#include <linux/clk.h>
23
24#include <asm/mach/arch.h>
25#include <asm/mach/map.h>
26#include <asm/mach/irq.h>
27
28#include <asm/hardware.h>
29#include <asm/io.h>
30#include <asm/irq.h>
31
32#include <asm/arch/regs-s3c2443-clock.h>
33#include <asm/arch/reset.h>
34
35#include <asm/plat-s3c24xx/s3c2443.h>
36#include <asm/plat-s3c24xx/devs.h>
37#include <asm/plat-s3c24xx/cpu.h>
38
39static struct map_desc s3c2443_iodesc[] __initdata = {
40 IODESC_ENT(WATCHDOG),
41 IODESC_ENT(CLKPWR),
42 IODESC_ENT(TIMER),
43};
44
45struct sysdev_class s3c2443_sysclass = {
46 set_kset_name("s3c2443-core"),
47};
48
49static struct sys_device s3c2443_sysdev = {
50 .cls = &s3c2443_sysclass,
51};
52
53static void s3c2443_hard_reset(void)
54{
55 __raw_writel(S3C2443_SWRST_RESET, S3C2443_SWRST);
56}
57
58int __init s3c2443_init(void)
59{
60 printk("S3C2443: Initialising architecture\n");
61
62 s3c24xx_reset_hook = s3c2443_hard_reset;
63
64 s3c_device_nand.name = "s3c2412-nand";
65
66 return sysdev_register(&s3c2443_sysdev);
67}
68
69void __init s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no)
70{
71 s3c24xx_init_uartdevs("s3c2440-uart", s3c2410_uart_resources, cfg, no);
72}
73
74/* s3c2443_map_io
75 *
76 * register the standard cpu IO areas, and any passed in from the
77 * machine specific initialisation.
78 */
79
80void __init s3c2443_map_io(struct map_desc *mach_desc, int mach_size)
81{
82 iotable_init(s3c2443_iodesc, ARRAY_SIZE(s3c2443_iodesc));
83 iotable_init(mach_desc, mach_size);
84}
85
86/* need to register class before we actually register the device, and
87 * we also need to ensure that it has been initialised before any of the
88 * drivers even try to use it (even if not on an s3c2443 based system)
89 * as a driver which may support both 2443 and 2440 may try and use it.
90*/
91
92static int __init s3c2443_core_init(void)
93{
94 return sysdev_class_register(&s3c2443_sysclass);
95}
96
97core_initcall(s3c2443_core_init);
diff --git a/arch/arm/mm/Kconfig b/arch/arm/mm/Kconfig
index aade2f72c920..4b277199d0e8 100644
--- a/arch/arm/mm/Kconfig
+++ b/arch/arm/mm/Kconfig
@@ -171,8 +171,8 @@ config CPU_ARM925T
171# ARM926T 171# ARM926T
172config CPU_ARM926T 172config CPU_ARM926T
173 bool "Support ARM926T processor" 173 bool "Support ARM926T processor"
174 depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 174 depends on ARCH_INTEGRATOR || ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || MACH_REALVIEW_EB || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_NS9XXX
175 default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 175 default y if ARCH_VERSATILE_PB || MACH_VERSATILE_AB || ARCH_OMAP730 || ARCH_OMAP16XX || ARCH_PNX4008 || ARCH_NETX || CPU_S3C2412 || ARCH_AT91SAM9260 || ARCH_AT91SAM9261 || ARCH_AT91SAM9263 || ARCH_NS9XXX
176 select CPU_32v5 176 select CPU_32v5
177 select CPU_ABRT_EV5TJ 177 select CPU_ABRT_EV5TJ
178 select CPU_CACHE_VIVT 178 select CPU_CACHE_VIVT
@@ -609,3 +609,10 @@ config NEEDS_SYSCALL_FOR_CMPXCHG
609 Forget about fast user space cmpxchg support. 609 Forget about fast user space cmpxchg support.
610 It is just not possible. 610 It is just not possible.
611 611
612config OUTER_CACHE
613 bool
614 default n
615
616config CACHE_L2X0
617 bool
618 select OUTER_CACHE
diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile
index d2f5672ecf62..2f8b95947774 100644
--- a/arch/arm/mm/Makefile
+++ b/arch/arm/mm/Makefile
@@ -66,3 +66,5 @@ obj-$(CONFIG_CPU_SA1100) += proc-sa1100.o
66obj-$(CONFIG_CPU_XSCALE) += proc-xscale.o 66obj-$(CONFIG_CPU_XSCALE) += proc-xscale.o
67obj-$(CONFIG_CPU_XSC3) += proc-xsc3.o 67obj-$(CONFIG_CPU_XSC3) += proc-xsc3.o
68obj-$(CONFIG_CPU_V6) += proc-v6.o 68obj-$(CONFIG_CPU_V6) += proc-v6.o
69
70obj-$(CONFIG_CACHE_L2X0) += cache-l2x0.o
diff --git a/arch/arm/mm/cache-l2x0.c b/arch/arm/mm/cache-l2x0.c
new file mode 100644
index 000000000000..08a36f1b35d2
--- /dev/null
+++ b/arch/arm/mm/cache-l2x0.c
@@ -0,0 +1,104 @@
1/*
2 * arch/arm/mm/cache-l2x0.c - L210/L220 cache controller support
3 *
4 * Copyright (C) 2007 ARM Limited
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
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 the
13 * 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#include <linux/init.h>
20
21#include <asm/cacheflush.h>
22#include <asm/io.h>
23#include <asm/hardware/cache-l2x0.h>
24
25#define CACHE_LINE_SIZE 32
26
27static void __iomem *l2x0_base;
28
29static inline void sync_writel(unsigned long val, unsigned long reg,
30 unsigned long complete_mask)
31{
32 writel(val, l2x0_base + reg);
33 /* wait for the operation to complete */
34 while (readl(l2x0_base + reg) & complete_mask)
35 ;
36}
37
38static inline void cache_sync(void)
39{
40 sync_writel(0, L2X0_CACHE_SYNC, 1);
41}
42
43static inline void l2x0_inv_all(void)
44{
45 /* invalidate all ways */
46 sync_writel(0xff, L2X0_INV_WAY, 0xff);
47 cache_sync();
48}
49
50static void l2x0_inv_range(unsigned long start, unsigned long end)
51{
52 unsigned long addr;
53
54 start &= ~(CACHE_LINE_SIZE - 1);
55 for (addr = start; addr < end; addr += CACHE_LINE_SIZE)
56 sync_writel(addr, L2X0_INV_LINE_PA, 1);
57 cache_sync();
58}
59
60static void l2x0_clean_range(unsigned long start, unsigned long end)
61{
62 unsigned long addr;
63
64 start &= ~(CACHE_LINE_SIZE - 1);
65 for (addr = start; addr < end; addr += CACHE_LINE_SIZE)
66 sync_writel(addr, L2X0_CLEAN_LINE_PA, 1);
67 cache_sync();
68}
69
70static void l2x0_flush_range(unsigned long start, unsigned long end)
71{
72 unsigned long addr;
73
74 start &= ~(CACHE_LINE_SIZE - 1);
75 for (addr = start; addr < end; addr += CACHE_LINE_SIZE)
76 sync_writel(addr, L2X0_CLEAN_INV_LINE_PA, 1);
77 cache_sync();
78}
79
80void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask)
81{
82 __u32 aux;
83
84 l2x0_base = base;
85
86 /* disable L2X0 */
87 writel(0, l2x0_base + L2X0_CTRL);
88
89 aux = readl(l2x0_base + L2X0_AUX_CTRL);
90 aux &= aux_mask;
91 aux |= aux_val;
92 writel(aux, l2x0_base + L2X0_AUX_CTRL);
93
94 l2x0_inv_all();
95
96 /* enable L2X0 */
97 writel(1, l2x0_base + L2X0_CTRL);
98
99 outer_cache.inv_range = l2x0_inv_range;
100 outer_cache.clean_range = l2x0_clean_range;
101 outer_cache.flush_range = l2x0_flush_range;
102
103 printk(KERN_INFO "L2X0 cache controller enabled\n");
104}
diff --git a/arch/arm/mm/consistent.c b/arch/arm/mm/consistent.c
index 6a9c362fef5e..1f9f94f9af4b 100644
--- a/arch/arm/mm/consistent.c
+++ b/arch/arm/mm/consistent.c
@@ -205,9 +205,10 @@ __dma_alloc(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp,
205 * kernel direct-mapped region for device DMA. 205 * kernel direct-mapped region for device DMA.
206 */ 206 */
207 { 207 {
208 unsigned long kaddr = (unsigned long)page_address(page); 208 void *ptr = page_address(page);
209 memset(page_address(page), 0, size); 209 memset(ptr, 0, size);
210 dmac_flush_range(kaddr, kaddr + size); 210 dmac_flush_range(ptr, ptr + size);
211 outer_flush_range(__pa(ptr), __pa(ptr) + size);
211 } 212 }
212 213
213 /* 214 /*
@@ -480,20 +481,24 @@ core_initcall(consistent_init);
480 * platforms with CONFIG_DMABOUNCE. 481 * platforms with CONFIG_DMABOUNCE.
481 * Use the driver DMA support - see dma-mapping.h (dma_sync_*) 482 * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
482 */ 483 */
483void consistent_sync(void *vaddr, size_t size, int direction) 484void consistent_sync(const void *start, size_t size, int direction)
484{ 485{
485 unsigned long start = (unsigned long)vaddr; 486 const void *end = start + size;
486 unsigned long end = start + size; 487
488 BUG_ON(!virt_addr_valid(start) || !virt_addr_valid(end - 1));
487 489
488 switch (direction) { 490 switch (direction) {
489 case DMA_FROM_DEVICE: /* invalidate only */ 491 case DMA_FROM_DEVICE: /* invalidate only */
490 dmac_inv_range(start, end); 492 dmac_inv_range(start, end);
493 outer_inv_range(__pa(start), __pa(end));
491 break; 494 break;
492 case DMA_TO_DEVICE: /* writeback only */ 495 case DMA_TO_DEVICE: /* writeback only */
493 dmac_clean_range(start, end); 496 dmac_clean_range(start, end);
497 outer_clean_range(__pa(start), __pa(end));
494 break; 498 break;
495 case DMA_BIDIRECTIONAL: /* writeback and invalidate */ 499 case DMA_BIDIRECTIONAL: /* writeback and invalidate */
496 dmac_flush_range(start, end); 500 dmac_flush_range(start, end);
501 outer_flush_range(__pa(start), __pa(end));
497 break; 502 break;
498 default: 503 default:
499 BUG(); 504 BUG();
diff --git a/arch/arm/mm/context.c b/arch/arm/mm/context.c
index 79e800202424..9da43a0fdcdf 100644
--- a/arch/arm/mm/context.c
+++ b/arch/arm/mm/context.c
@@ -19,7 +19,8 @@ unsigned int cpu_last_asid = { 1 << ASID_BITS };
19/* 19/*
20 * We fork()ed a process, and we need a new context for the child 20 * We fork()ed a process, and we need a new context for the child
21 * to run in. We reserve version 0 for initial tasks so we will 21 * to run in. We reserve version 0 for initial tasks so we will
22 * always allocate an ASID. 22 * always allocate an ASID. The ASID 0 is reserved for the TTBR
23 * register changing sequence.
23 */ 24 */
24void __init_new_context(struct task_struct *tsk, struct mm_struct *mm) 25void __init_new_context(struct task_struct *tsk, struct mm_struct *mm)
25{ 26{
@@ -38,8 +39,15 @@ void __new_context(struct mm_struct *mm)
38 * If we've used up all our ASIDs, we need 39 * If we've used up all our ASIDs, we need
39 * to start a new version and flush the TLB. 40 * to start a new version and flush the TLB.
40 */ 41 */
41 if ((asid & ~ASID_MASK) == 0) 42 if ((asid & ~ASID_MASK) == 0) {
43 asid = ++cpu_last_asid;
44 /* set the reserved ASID before flushing the TLB */
45 asm("mcr p15, 0, %0, c13, c0, 1 @ set reserved context ID\n"
46 :
47 : "r" (0));
48 isb();
42 flush_tlb_all(); 49 flush_tlb_all();
50 }
43 51
44 mm->context.id = asid; 52 mm->context.id = asid;
45} 53}
diff --git a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
index cf95c5d0ce4c..44558d5f9313 100644
--- a/arch/arm/mm/fault-armv.c
+++ b/arch/arm/mm/fault-armv.c
@@ -119,8 +119,6 @@ make_coherent(struct address_space *mapping, struct vm_area_struct *vma, unsigne
119 flush_cache_page(vma, addr, pfn); 119 flush_cache_page(vma, addr, pfn);
120} 120}
121 121
122void __flush_dcache_page(struct address_space *mapping, struct page *page);
123
124/* 122/*
125 * Take care of architecture specific things when placing a new PTE into 123 * Take care of architecture specific things when placing a new PTE into
126 * a page table, or changing an existing PTE. Basically, there are two 124 * a page table, or changing an existing PTE. Basically, there are two
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 655c8376f0b5..94fd4bf5cb9e 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -49,8 +49,10 @@ pmd_t *top_pmd;
49 49
50static unsigned int cachepolicy __initdata = CPOLICY_WRITEBACK; 50static unsigned int cachepolicy __initdata = CPOLICY_WRITEBACK;
51static unsigned int ecc_mask __initdata = 0; 51static unsigned int ecc_mask __initdata = 0;
52pgprot_t pgprot_user;
52pgprot_t pgprot_kernel; 53pgprot_t pgprot_kernel;
53 54
55EXPORT_SYMBOL(pgprot_user);
54EXPORT_SYMBOL(pgprot_kernel); 56EXPORT_SYMBOL(pgprot_kernel);
55 57
56struct cachepolicy { 58struct cachepolicy {
@@ -345,6 +347,7 @@ static void __init build_mem_type_table(void)
345 mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1); 347 mem_types[MT_MINICLEAN].prot_sect &= ~PMD_SECT_TEX(1);
346 } 348 }
347 349
350 pgprot_user = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | user_pgprot);
348 pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG | 351 pgprot_kernel = __pgprot(L_PTE_PRESENT | L_PTE_YOUNG |
349 L_PTE_DIRTY | L_PTE_WRITE | 352 L_PTE_DIRTY | L_PTE_WRITE |
350 L_PTE_EXEC | kern_pgprot); 353 L_PTE_EXEC | kern_pgprot);
diff --git a/arch/arm/mm/proc-v6.S b/arch/arm/mm/proc-v6.S
index 7b1843befb9c..eb42e5b94863 100644
--- a/arch/arm/mm/proc-v6.S
+++ b/arch/arm/mm/proc-v6.S
@@ -14,10 +14,13 @@
14#include <asm/assembler.h> 14#include <asm/assembler.h>
15#include <asm/asm-offsets.h> 15#include <asm/asm-offsets.h>
16#include <asm/elf.h> 16#include <asm/elf.h>
17#include <asm/hardware/arm_scu.h>
18#include <asm/pgtable-hwdef.h> 17#include <asm/pgtable-hwdef.h>
19#include <asm/pgtable.h> 18#include <asm/pgtable.h>
20 19
20#ifdef CONFIG_SMP
21#include <asm/hardware/arm_scu.h>
22#endif
23
21#include "proc-macros.S" 24#include "proc-macros.S"
22 25
23#define D_CACHE_LINE_SIZE 32 26#define D_CACHE_LINE_SIZE 32
@@ -30,6 +33,12 @@
30#define TTB_RGN_WT (2 << 3) 33#define TTB_RGN_WT (2 << 3)
31#define TTB_RGN_WB (3 << 3) 34#define TTB_RGN_WB (3 << 3)
32 35
36#ifndef CONFIG_SMP
37#define TTB_FLAGS TTB_RGN_WBWA
38#else
39#define TTB_FLAGS TTB_RGN_WBWA|TTB_S
40#endif
41
33ENTRY(cpu_v6_proc_init) 42ENTRY(cpu_v6_proc_init)
34 mov pc, lr 43 mov pc, lr
35 44
@@ -92,9 +101,7 @@ ENTRY(cpu_v6_switch_mm)
92#ifdef CONFIG_MMU 101#ifdef CONFIG_MMU
93 mov r2, #0 102 mov r2, #0
94 ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id 103 ldr r1, [r1, #MM_CONTEXT_ID] @ get mm->context.id
95#ifdef CONFIG_SMP 104 orr r0, r0, #TTB_FLAGS
96 orr r0, r0, #TTB_RGN_WBWA|TTB_S @ mark PTWs shared, outer cacheable
97#endif
98 mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB 105 mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB
99 mcr p15, 0, r2, c7, c10, 4 @ drain write buffer 106 mcr p15, 0, r2, c7, c10, 4 @ drain write buffer
100 mcr p15, 0, r0, c2, c0, 0 @ set TTB 0 107 mcr p15, 0, r0, c2, c0, 0 @ set TTB 0
@@ -183,8 +190,7 @@ __v6_setup:
183 /* Set up the SCU on core 0 only */ 190 /* Set up the SCU on core 0 only */
184 mrc p15, 0, r0, c0, c0, 5 @ CPU core number 191 mrc p15, 0, r0, c0, c0, 5 @ CPU core number
185 ands r0, r0, #15 192 ands r0, r0, #15
186 moveq r0, #0x10000000 @ SCU_BASE 193 ldreq r0, =SCU_BASE
187 orreq r0, r0, #0x00100000
188 ldreq r5, [r0, #SCU_CTRL] 194 ldreq r5, [r0, #SCU_CTRL]
189 orreq r5, r5, #1 195 orreq r5, r5, #1
190 streq r5, [r0, #SCU_CTRL] 196 streq r5, [r0, #SCU_CTRL]
@@ -204,9 +210,7 @@ __v6_setup:
204#ifdef CONFIG_MMU 210#ifdef CONFIG_MMU
205 mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs 211 mcr p15, 0, r0, c8, c7, 0 @ invalidate I + D TLBs
206 mcr p15, 0, r0, c2, c0, 2 @ TTB control register 212 mcr p15, 0, r0, c2, c0, 2 @ TTB control register
207#ifdef CONFIG_SMP 213 orr r4, r4, #TTB_FLAGS
208 orr r4, r4, #TTB_RGN_WBWA|TTB_S @ mark PTWs shared, outer cacheable
209#endif
210 mcr p15, 0, r4, c2, c0, 1 @ load TTB1 214 mcr p15, 0, r4, c2, c0, 1 @ load TTB1
211#endif /* CONFIG_MMU */ 215#endif /* CONFIG_MMU */
212 adr r5, v6_crval 216 adr r5, v6_crval
diff --git a/arch/arm/mm/proc-xsc3.S b/arch/arm/mm/proc-xsc3.S
index 94a58455f346..d95921a2ab99 100644
--- a/arch/arm/mm/proc-xsc3.S
+++ b/arch/arm/mm/proc-xsc3.S
@@ -5,23 +5,23 @@
5 * Current Maintainer: Lennert Buytenhek <buytenh@wantstofly.org> 5 * Current Maintainer: Lennert Buytenhek <buytenh@wantstofly.org>
6 * 6 *
7 * Copyright 2004 (C) Intel Corp. 7 * Copyright 2004 (C) Intel Corp.
8 * Copyright 2005 (c) MontaVista Software, Inc. 8 * Copyright 2005 (C) MontaVista Software, Inc.
9 * 9 *
10 * This program is free software; you can redistribute it and/or modify 10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2 as 11 * it under the terms of the GNU General Public License version 2 as
12 * published by the Free Software Foundation. 12 * published by the Free Software Foundation.
13 * 13 *
14 * MMU functions for the Intel XScale3 Core (XSC3). The XSC3 core is an 14 * MMU functions for the Intel XScale3 Core (XSC3). The XSC3 core is
15 * extension to Intel's original XScale core that adds the following 15 * an extension to Intel's original XScale core that adds the following
16 * features: 16 * features:
17 * 17 *
18 * - ARMv6 Supersections 18 * - ARMv6 Supersections
19 * - Low Locality Reference pages (replaces mini-cache) 19 * - Low Locality Reference pages (replaces mini-cache)
20 * - 36-bit addressing 20 * - 36-bit addressing
21 * - L2 cache 21 * - L2 cache
22 * - Cache-coherency if chipset supports it 22 * - Cache coherency if chipset supports it
23 * 23 *
24 * Based on orignal XScale code by Nicolas Pitre 24 * Based on original XScale code by Nicolas Pitre.
25 */ 25 */
26 26
27#include <linux/linkage.h> 27#include <linux/linkage.h>
@@ -42,12 +42,12 @@
42#define MAX_AREA_SIZE 32768 42#define MAX_AREA_SIZE 32768
43 43
44/* 44/*
45 * The cache line size of the I and D cache. 45 * The cache line size of the L1 I, L1 D and unified L2 cache.
46 */ 46 */
47#define CACHELINESIZE 32 47#define CACHELINESIZE 32
48 48
49/* 49/*
50 * The size of the data cache. 50 * The size of the L1 D cache.
51 */ 51 */
52#define CACHESIZE 32768 52#define CACHESIZE 32768
53 53
@@ -57,9 +57,9 @@
57#define L2_CACHE_ENABLE 1 57#define L2_CACHE_ENABLE 1
58 58
59/* 59/*
60 * This macro is used to wait for a CP15 write and is needed 60 * This macro is used to wait for a CP15 write and is needed when we
61 * when we have to ensure that the last operation to the co-pro 61 * have to ensure that the last operation to the coprocessor was
62 * was completed before continuing with operation. 62 * completed before continuing with operation.
63 */ 63 */
64 .macro cpwait_ret, lr, rd 64 .macro cpwait_ret, lr, rd
65 mrc p15, 0, \rd, c2, c0, 0 @ arbitrary read of cp15 65 mrc p15, 0, \rd, c2, c0, 0 @ arbitrary read of cp15
@@ -68,13 +68,13 @@
68 .endm 68 .endm
69 69
70/* 70/*
71 * This macro cleans & invalidates the entire xsc3 dcache by set & way. 71 * This macro cleans and invalidates the entire L1 D cache.
72 */ 72 */
73 73
74 .macro clean_d_cache rd, rs 74 .macro clean_d_cache rd, rs
75 mov \rd, #0x1f00 75 mov \rd, #0x1f00
76 orr \rd, \rd, #0x00e0 76 orr \rd, \rd, #0x00e0
771: mcr p15, 0, \rd, c7, c14, 2 @ clean/inv set/way 771: mcr p15, 0, \rd, c7, c14, 2 @ clean/invalidate L1 D line
78 adds \rd, \rd, #0x40000000 78 adds \rd, \rd, #0x40000000
79 bcc 1b 79 bcc 1b
80 subs \rd, \rd, #0x20 80 subs \rd, \rd, #0x20
@@ -119,15 +119,15 @@ ENTRY(cpu_xsc3_reset)
119 mov r1, #PSR_F_BIT|PSR_I_BIT|SVC_MODE 119 mov r1, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
120 msr cpsr_c, r1 @ reset CPSR 120 msr cpsr_c, r1 @ reset CPSR
121 mrc p15, 0, r1, c1, c0, 0 @ ctrl register 121 mrc p15, 0, r1, c1, c0, 0 @ ctrl register
122 bic r1, r1, #0x0086 @ ........B....CA.
123 bic r1, r1, #0x3900 @ ..VIZ..S........ 122 bic r1, r1, #0x3900 @ ..VIZ..S........
123 bic r1, r1, #0x0086 @ ........B....CA.
124 mcr p15, 0, r1, c1, c0, 0 @ ctrl register 124 mcr p15, 0, r1, c1, c0, 0 @ ctrl register
125 mcr p15, 0, ip, c7, c7, 0 @ invalidate I,D caches & BTB 125 mcr p15, 0, ip, c7, c7, 0 @ invalidate L1 caches and BTB
126 bic r1, r1, #0x0001 @ ...............M 126 bic r1, r1, #0x0001 @ ...............M
127 mcr p15, 0, r1, c1, c0, 0 @ ctrl register 127 mcr p15, 0, r1, c1, c0, 0 @ ctrl register
128 @ CAUTION: MMU turned off from this point. We count on the pipeline 128 @ CAUTION: MMU turned off from this point. We count on the pipeline
129 @ already containing those two last instructions to survive. 129 @ already containing those two last instructions to survive.
130 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs 130 mcr p15, 0, ip, c8, c7, 0 @ invalidate I and D TLBs
131 mov pc, r0 131 mov pc, r0
132 132
133/* 133/*
@@ -139,14 +139,12 @@ ENTRY(cpu_xsc3_reset)
139 * 139 *
140 * XScale supports clock switching, but using idle mode support 140 * XScale supports clock switching, but using idle mode support
141 * allows external hardware to react to system state changes. 141 * allows external hardware to react to system state changes.
142
143 MMG: Come back to this one.
144 */ 142 */
145 .align 5 143 .align 5
146 144
147ENTRY(cpu_xsc3_do_idle) 145ENTRY(cpu_xsc3_do_idle)
148 mov r0, #1 146 mov r0, #1
149 mcr p14, 0, r0, c7, c0, 0 @ Go to IDLE 147 mcr p14, 0, r0, c7, c0, 0 @ go to idle
150 mov pc, lr 148 mov pc, lr
151 149
152/* ================================= CACHE ================================ */ 150/* ================================= CACHE ================================ */
@@ -171,9 +169,9 @@ ENTRY(xsc3_flush_kern_cache_all)
171__flush_whole_cache: 169__flush_whole_cache:
172 clean_d_cache r0, r1 170 clean_d_cache r0, r1
173 tst r2, #VM_EXEC 171 tst r2, #VM_EXEC
174 mcrne p15, 0, ip, c7, c5, 0 @ Invalidate I cache & BTB 172 mcrne p15, 0, ip, c7, c5, 0 @ invalidate L1 I cache and BTB
175 mcrne p15, 0, ip, c7, c10, 4 @ Drain Write Buffer 173 mcrne p15, 0, ip, c7, c10, 4 @ data write barrier
176 mcrne p15, 0, ip, c7, c5, 4 @ Prefetch Flush 174 mcrne p15, 0, ip, c7, c5, 4 @ prefetch flush
177 mov pc, lr 175 mov pc, lr
178 176
179/* 177/*
@@ -194,21 +192,21 @@ ENTRY(xsc3_flush_user_cache_range)
194 bhs __flush_whole_cache 192 bhs __flush_whole_cache
195 193
1961: tst r2, #VM_EXEC 1941: tst r2, #VM_EXEC
197 mcrne p15, 0, r0, c7, c5, 1 @ Invalidate I cache line 195 mcrne p15, 0, r0, c7, c5, 1 @ invalidate L1 I line
198 mcr p15, 0, r0, c7, c14, 1 @ Clean/invalidate D cache line 196 mcr p15, 0, r0, c7, c14, 1 @ clean/invalidate L1 D line
199 add r0, r0, #CACHELINESIZE 197 add r0, r0, #CACHELINESIZE
200 cmp r0, r1 198 cmp r0, r1
201 blo 1b 199 blo 1b
202 tst r2, #VM_EXEC 200 tst r2, #VM_EXEC
203 mcrne p15, 0, ip, c7, c5, 6 @ Invalidate BTB 201 mcrne p15, 0, ip, c7, c5, 6 @ invalidate BTB
204 mcrne p15, 0, ip, c7, c10, 4 @ Drain Write Buffer 202 mcrne p15, 0, ip, c7, c10, 4 @ data write barrier
205 mcrne p15, 0, ip, c7, c5, 4 @ Prefetch Flush 203 mcrne p15, 0, ip, c7, c5, 4 @ prefetch flush
206 mov pc, lr 204 mov pc, lr
207 205
208/* 206/*
209 * coherent_kern_range(start, end) 207 * coherent_kern_range(start, end)
210 * 208 *
211 * Ensure coherency between the Icache and the Dcache in the 209 * Ensure coherency between the I cache and the D cache in the
212 * region described by start. If you have non-snooping 210 * region described by start. If you have non-snooping
213 * Harvard caches, you need to implement this function. 211 * Harvard caches, you need to implement this function.
214 * 212 *
@@ -222,34 +220,34 @@ ENTRY(xsc3_coherent_kern_range)
222/* FALLTHROUGH */ 220/* FALLTHROUGH */
223ENTRY(xsc3_coherent_user_range) 221ENTRY(xsc3_coherent_user_range)
224 bic r0, r0, #CACHELINESIZE - 1 222 bic r0, r0, #CACHELINESIZE - 1
2251: mcr p15, 0, r0, c7, c10, 1 @ clean D entry 2231: mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line
226 add r0, r0, #CACHELINESIZE 224 add r0, r0, #CACHELINESIZE
227 cmp r0, r1 225 cmp r0, r1
228 blo 1b 226 blo 1b
229 mov r0, #0 227 mov r0, #0
230 mcr p15, 0, r0, c7, c5, 0 @ Invalidate I cache & BTB 228 mcr p15, 0, r0, c7, c5, 0 @ invalidate L1 I cache and BTB
231 mcr p15, 0, r0, c7, c10, 4 @ Drain Write Buffer 229 mcr p15, 0, r0, c7, c10, 4 @ data write barrier
232 mcr p15, 0, r0, c7, c5, 4 @ Prefetch Flush 230 mcr p15, 0, r0, c7, c5, 4 @ prefetch flush
233 mov pc, lr 231 mov pc, lr
234 232
235/* 233/*
236 * flush_kern_dcache_page(void *page) 234 * flush_kern_dcache_page(void *page)
237 * 235 *
238 * Ensure no D cache aliasing occurs, either with itself or 236 * Ensure no D cache aliasing occurs, either with itself or
239 * the I cache 237 * the I cache.
240 * 238 *
241 * - addr - page aligned address 239 * - addr - page aligned address
242 */ 240 */
243ENTRY(xsc3_flush_kern_dcache_page) 241ENTRY(xsc3_flush_kern_dcache_page)
244 add r1, r0, #PAGE_SZ 242 add r1, r0, #PAGE_SZ
2451: mcr p15, 0, r0, c7, c14, 1 @ Clean/Invalidate D Cache line 2431: mcr p15, 0, r0, c7, c14, 1 @ clean/invalidate L1 D line
246 add r0, r0, #CACHELINESIZE 244 add r0, r0, #CACHELINESIZE
247 cmp r0, r1 245 cmp r0, r1
248 blo 1b 246 blo 1b
249 mov r0, #0 247 mov r0, #0
250 mcr p15, 0, r0, c7, c5, 0 @ Invalidate I cache & BTB 248 mcr p15, 0, r0, c7, c5, 0 @ invalidate L1 I cache and BTB
251 mcr p15, 0, r0, c7, c10, 4 @ Drain Write Buffer 249 mcr p15, 0, r0, c7, c10, 4 @ data write barrier
252 mcr p15, 0, r0, c7, c5, 4 @ Prefetch Flush 250 mcr p15, 0, r0, c7, c5, 4 @ prefetch flush
253 mov pc, lr 251 mov pc, lr
254 252
255/* 253/*
@@ -266,17 +264,17 @@ ENTRY(xsc3_flush_kern_dcache_page)
266ENTRY(xsc3_dma_inv_range) 264ENTRY(xsc3_dma_inv_range)
267 tst r0, #CACHELINESIZE - 1 265 tst r0, #CACHELINESIZE - 1
268 bic r0, r0, #CACHELINESIZE - 1 266 bic r0, r0, #CACHELINESIZE - 1
269 mcrne p15, 0, r0, c7, c10, 1 @ clean L1 D entry 267 mcrne p15, 0, r0, c7, c10, 1 @ clean L1 D line
270 mcrne p15, 1, r0, c7, c11, 1 @ clean L2 D entry 268 mcrne p15, 1, r0, c7, c11, 1 @ clean L2 line
271 tst r1, #CACHELINESIZE - 1 269 tst r1, #CACHELINESIZE - 1
272 mcrne p15, 0, r1, c7, c10, 1 @ clean L1 D entry 270 mcrne p15, 0, r1, c7, c10, 1 @ clean L1 D line
273 mcrne p15, 1, r1, c7, c11, 1 @ clean L2 D entry 271 mcrne p15, 1, r1, c7, c11, 1 @ clean L2 line
2741: mcr p15, 0, r0, c7, c6, 1 @ invalidate L1 D entry 2721: mcr p15, 0, r0, c7, c6, 1 @ invalidate L1 D line
275 mcr p15, 1, r0, c7, c7, 1 @ Invalidate L2 D cache line 273 mcr p15, 1, r0, c7, c7, 1 @ invalidate L2 line
276 add r0, r0, #CACHELINESIZE 274 add r0, r0, #CACHELINESIZE
277 cmp r0, r1 275 cmp r0, r1
278 blo 1b 276 blo 1b
279 mcr p15, 0, r0, c7, c10, 4 @ Drain Write Buffer 277 mcr p15, 0, r0, c7, c10, 4 @ data write barrier
280 mov pc, lr 278 mov pc, lr
281 279
282/* 280/*
@@ -289,12 +287,12 @@ ENTRY(xsc3_dma_inv_range)
289 */ 287 */
290ENTRY(xsc3_dma_clean_range) 288ENTRY(xsc3_dma_clean_range)
291 bic r0, r0, #CACHELINESIZE - 1 289 bic r0, r0, #CACHELINESIZE - 1
2921: mcr p15, 0, r0, c7, c10, 1 @ clean L1 D entry 2901: mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line
293 mcr p15, 1, r0, c7, c11, 1 @ clean L2 D entry 291 mcr p15, 1, r0, c7, c11, 1 @ clean L2 line
294 add r0, r0, #CACHELINESIZE 292 add r0, r0, #CACHELINESIZE
295 cmp r0, r1 293 cmp r0, r1
296 blo 1b 294 blo 1b
297 mcr p15, 0, r0, c7, c10, 4 @ Drain Write Buffer 295 mcr p15, 0, r0, c7, c10, 4 @ data write barrier
298 mov pc, lr 296 mov pc, lr
299 297
300/* 298/*
@@ -307,13 +305,13 @@ ENTRY(xsc3_dma_clean_range)
307 */ 305 */
308ENTRY(xsc3_dma_flush_range) 306ENTRY(xsc3_dma_flush_range)
309 bic r0, r0, #CACHELINESIZE - 1 307 bic r0, r0, #CACHELINESIZE - 1
3101: mcr p15, 0, r0, c7, c14, 1 @ Clean/invalidate L1 D cache line 3081: mcr p15, 0, r0, c7, c14, 1 @ clean/invalidate L1 D line
311 mcr p15, 1, r0, c7, c11, 1 @ Clean L2 D cache line 309 mcr p15, 1, r0, c7, c11, 1 @ clean L2 line
312 mcr p15, 1, r0, c7, c7, 1 @ Invalidate L2 D cache line 310 mcr p15, 1, r0, c7, c7, 1 @ invalidate L2 line
313 add r0, r0, #CACHELINESIZE 311 add r0, r0, #CACHELINESIZE
314 cmp r0, r1 312 cmp r0, r1
315 blo 1b 313 blo 1b
316 mcr p15, 0, r0, c7, c10, 4 @ Drain Write Buffer 314 mcr p15, 0, r0, c7, c10, 4 @ data write barrier
317 mov pc, lr 315 mov pc, lr
318 316
319ENTRY(xsc3_cache_fns) 317ENTRY(xsc3_cache_fns)
@@ -328,7 +326,7 @@ ENTRY(xsc3_cache_fns)
328 .long xsc3_dma_flush_range 326 .long xsc3_dma_flush_range
329 327
330ENTRY(cpu_xsc3_dcache_clean_area) 328ENTRY(cpu_xsc3_dcache_clean_area)
3311: mcr p15, 0, r0, c7, c10, 1 @ clean D entry 3291: mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line
332 add r0, r0, #CACHELINESIZE 330 add r0, r0, #CACHELINESIZE
333 subs r1, r1, #CACHELINESIZE 331 subs r1, r1, #CACHELINESIZE
334 bhi 1b 332 bhi 1b
@@ -346,14 +344,14 @@ ENTRY(cpu_xsc3_dcache_clean_area)
346 .align 5 344 .align 5
347ENTRY(cpu_xsc3_switch_mm) 345ENTRY(cpu_xsc3_switch_mm)
348 clean_d_cache r1, r2 346 clean_d_cache r1, r2
349 mcr p15, 0, ip, c7, c5, 0 @ Invalidate I cache & BTB 347 mcr p15, 0, ip, c7, c5, 0 @ invalidate L1 I cache and BTB
350 mcr p15, 0, ip, c7, c10, 4 @ Drain Write Buffer 348 mcr p15, 0, ip, c7, c10, 4 @ data write barrier
351 mcr p15, 0, ip, c7, c5, 4 @ Prefetch Flush 349 mcr p15, 0, ip, c7, c5, 4 @ prefetch flush
352#ifdef L2_CACHE_ENABLE 350#ifdef L2_CACHE_ENABLE
353 orr r0, r0, #0x18 @ cache the page table in L2 351 orr r0, r0, #0x18 @ cache the page table in L2
354#endif 352#endif
355 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer 353 mcr p15, 0, r0, c2, c0, 0 @ load page table pointer
356 mcr p15, 0, ip, c8, c7, 0 @ invalidate I & D TLBs 354 mcr p15, 0, ip, c8, c7, 0 @ invalidate I and D TLBs
357 cpwait_ret lr, ip 355 cpwait_ret lr, ip
358 356
359/* 357/*
@@ -366,34 +364,34 @@ ENTRY(cpu_xsc3_switch_mm)
366ENTRY(cpu_xsc3_set_pte_ext) 364ENTRY(cpu_xsc3_set_pte_ext)
367 str r1, [r0], #-2048 @ linux version 365 str r1, [r0], #-2048 @ linux version
368 366
369 bic r2, r1, #0xff0 @ Keep C, B bits 367 bic r2, r1, #0xff0 @ keep C, B bits
370 orr r2, r2, #PTE_TYPE_EXT @ extended page 368 orr r2, r2, #PTE_TYPE_EXT @ extended page
371 tst r1, #L_PTE_SHARED @ Shared? 369 tst r1, #L_PTE_SHARED @ shared?
372 orrne r2, r2, #0x200 370 orrne r2, r2, #0x200
373 371
374 eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY 372 eor r3, r1, #L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_WRITE | L_PTE_DIRTY
375 373
376 tst r3, #L_PTE_USER @ User? 374 tst r3, #L_PTE_USER @ user?
377 orrne r2, r2, #PTE_EXT_AP_URO_SRW @ yes -> user r/o, system r/w 375 orrne r2, r2, #PTE_EXT_AP_URO_SRW @ yes -> user r/o, system r/w
378 376
379 tst r3, #L_PTE_WRITE | L_PTE_DIRTY @ Write and Dirty? 377 tst r3, #L_PTE_WRITE | L_PTE_DIRTY @ write and dirty?
380 orreq r2, r2, #PTE_EXT_AP_UNO_SRW @ yes -> user n/a, system r/w 378 orreq r2, r2, #PTE_EXT_AP_UNO_SRW @ yes -> user n/a, system r/w
381 @ combined with user -> user r/w 379 @ combined with user -> user r/w
382 380
383#if L2_CACHE_ENABLE 381#if L2_CACHE_ENABLE
384 @ If its cacheable it needs to be in L2 also. 382 @ If it's cacheable, it needs to be in L2 also.
385 eor ip, r1, #L_PTE_CACHEABLE 383 eor ip, r1, #L_PTE_CACHEABLE
386 tst ip, #L_PTE_CACHEABLE 384 tst ip, #L_PTE_CACHEABLE
387 orreq r2, r2, #PTE_EXT_TEX(0x5) 385 orreq r2, r2, #PTE_EXT_TEX(0x5)
388#endif 386#endif
389 387
390 tst r3, #L_PTE_PRESENT | L_PTE_YOUNG @ Present and Young? 388 tst r3, #L_PTE_PRESENT | L_PTE_YOUNG @ present and young?
391 movne r2, #0 @ no -> fault 389 movne r2, #0 @ no -> fault
392 390
393 str r2, [r0] @ hardware version 391 str r2, [r0] @ hardware version
394 mov ip, #0 392 mov ip, #0
395 mcr p15, 0, r0, c7, c10, 1 @ Clean D cache line mcr 393 mcr p15, 0, r0, c7, c10, 1 @ clean L1 D line
396 mcr p15, 0, ip, c7, c10, 4 @ Drain Write Buffer 394 mcr p15, 0, ip, c7, c10, 4 @ data write barrier
397 mov pc, lr 395 mov pc, lr
398 396
399 .ltorg 397 .ltorg
@@ -406,17 +404,18 @@ ENTRY(cpu_xsc3_set_pte_ext)
406__xsc3_setup: 404__xsc3_setup:
407 mov r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE 405 mov r0, #PSR_F_BIT|PSR_I_BIT|SVC_MODE
408 msr cpsr_c, r0 406 msr cpsr_c, r0
409 mcr p15, 0, ip, c7, c7, 0 @ invalidate I, D caches & BTB 407 mcr p15, 0, ip, c7, c7, 0 @ invalidate L1 caches and BTB
410 mcr p15, 0, ip, c7, c10, 4 @ Drain Write Buffer 408 mcr p15, 0, ip, c7, c10, 4 @ data write barrier
411 mcr p15, 0, ip, c7, c5, 4 @ Prefetch Flush 409 mcr p15, 0, ip, c7, c5, 4 @ prefetch flush
412 mcr p15, 0, ip, c8, c7, 0 @ invalidate I, D TLBs 410 mcr p15, 0, ip, c8, c7, 0 @ invalidate I and D TLBs
413#if L2_CACHE_ENABLE 411#if L2_CACHE_ENABLE
414 orr r4, r4, #0x18 @ cache the page table in L2 412 orr r4, r4, #0x18 @ cache the page table in L2
415#endif 413#endif
416 mcr p15, 0, r4, c2, c0, 0 @ load page table pointer 414 mcr p15, 0, r4, c2, c0, 0 @ load page table pointer
417 mov r0, #1 @ Allow access to CP0 and CP13 415
418 orr r0, r0, #1 << 13 @ Its undefined whether this 416 mov r0, #0 @ don't allow CP access
419 mcr p15, 0, r0, c15, c1, 0 @ affects USR or SVC modes 417 mcr p15, 0, r0, c15, c1, 0 @ write CP access register
418
420 mrc p15, 0, r0, c1, c0, 1 @ get auxiliary control reg 419 mrc p15, 0, r0, c1, c0, 1 @ get auxiliary control reg
421 and r0, r0, #2 @ preserve bit P bit setting 420 and r0, r0, #2 @ preserve bit P bit setting
422#if L2_CACHE_ENABLE 421#if L2_CACHE_ENABLE
@@ -427,9 +426,9 @@ __xsc3_setup:
427 adr r5, xsc3_crval 426 adr r5, xsc3_crval
428 ldmia r5, {r5, r6} 427 ldmia r5, {r5, r6}
429 mrc p15, 0, r0, c1, c0, 0 @ get control register 428 mrc p15, 0, r0, c1, c0, 0 @ get control register
430 bic r0, r0, r5 @ .... .... .... ..A. 429 bic r0, r0, r5 @ ..V. ..R. .... ..A.
431 orr r0, r0, r6 @ .... .... .... .C.M 430 orr r0, r0, r6 @ ..VI Z..S .... .C.M (mmu)
432 orr r0, r0, #0x00000800 @ ..VI Z..S .... .... 431 @ ...I Z..S .... .... (uc)
433#if L2_CACHE_ENABLE 432#if L2_CACHE_ENABLE
434 orr r0, r0, #0x04000000 @ L2 enable 433 orr r0, r0, #0x04000000 @ L2 enable
435#endif 434#endif
@@ -439,7 +438,7 @@ __xsc3_setup:
439 438
440 .type xsc3_crval, #object 439 .type xsc3_crval, #object
441xsc3_crval: 440xsc3_crval:
442 crval clear=0x04003b02, mmuset=0x00003105, ucset=0x00001100 441 crval clear=0x04002202, mmuset=0x00003905, ucset=0x00001900
443 442
444 __INITDATA 443 __INITDATA
445 444
@@ -474,7 +473,7 @@ cpu_elf_name:
474 473
475 .type cpu_xsc3_name, #object 474 .type cpu_xsc3_name, #object
476cpu_xsc3_name: 475cpu_xsc3_name:
477 .asciz "XScale-Core3" 476 .asciz "XScale-V3 based processor"
478 .size cpu_xsc3_name, . - cpu_xsc3_name 477 .size cpu_xsc3_name, . - cpu_xsc3_name
479 478
480 .align 479 .align
@@ -490,7 +489,7 @@ __xsc3_proc_info:
490 PMD_SECT_CACHEABLE | \ 489 PMD_SECT_CACHEABLE | \
491 PMD_SECT_AP_WRITE | \ 490 PMD_SECT_AP_WRITE | \
492 PMD_SECT_AP_READ 491 PMD_SECT_AP_READ
493 .long PMD_TYPE_SECT | \ 492 .long PMD_TYPE_SECT | \
494 PMD_SECT_AP_WRITE | \ 493 PMD_SECT_AP_WRITE | \
495 PMD_SECT_AP_READ 494 PMD_SECT_AP_READ
496 b __xsc3_setup 495 b __xsc3_setup
diff --git a/arch/arm/mm/tlb-v6.S b/arch/arm/mm/tlb-v6.S
index fd6adde39091..20f84bbaa9bb 100644
--- a/arch/arm/mm/tlb-v6.S
+++ b/arch/arm/mm/tlb-v6.S
@@ -53,6 +53,8 @@ ENTRY(v6wbi_flush_user_tlb_range)
53 add r0, r0, #PAGE_SZ 53 add r0, r0, #PAGE_SZ
54 cmp r0, r1 54 cmp r0, r1
55 blo 1b 55 blo 1b
56 mcr p15, 0, ip, c7, c5, 6 @ flush BTAC/BTB
57 mcr p15, 0, ip, c7, c10, 4 @ data synchronization barrier
56 mov pc, lr 58 mov pc, lr
57 59
58/* 60/*
@@ -80,7 +82,9 @@ ENTRY(v6wbi_flush_kern_tlb_range)
80 add r0, r0, #PAGE_SZ 82 add r0, r0, #PAGE_SZ
81 cmp r0, r1 83 cmp r0, r1
82 blo 1b 84 blo 1b
85 mcr p15, 0, r2, c7, c5, 6 @ flush BTAC/BTB
83 mcr p15, 0, r2, c7, c10, 4 @ data synchronization barrier 86 mcr p15, 0, r2, c7, c10, 4 @ data synchronization barrier
87 mcr p15, 0, r2, c7, c5, 4 @ prefetch flush
84 mov pc, lr 88 mov pc, lr
85 89
86 .section ".text.init", #alloc, #execinstr 90 .section ".text.init", #alloc, #execinstr
diff --git a/arch/arm/oprofile/Kconfig b/arch/arm/oprofile/Kconfig
index 19d37730b664..afd93ad02feb 100644
--- a/arch/arm/oprofile/Kconfig
+++ b/arch/arm/oprofile/Kconfig
@@ -19,5 +19,24 @@ config OPROFILE
19 19
20 If unsure, say N. 20 If unsure, say N.
21 21
22if OPROFILE
23
24config OPROFILE_ARMV6
25 bool
26 depends on CPU_V6 && !SMP
27 default y
28 select OPROFILE_ARM11_CORE
29
30config OPROFILE_MPCORE
31 bool
32 depends on CPU_V6 && SMP
33 default y
34 select OPROFILE_ARM11_CORE
35
36config OPROFILE_ARM11_CORE
37 bool
38
39endif
40
22endmenu 41endmenu
23 42
diff --git a/arch/arm/oprofile/Makefile b/arch/arm/oprofile/Makefile
index 6a94e54848fd..e61d0cc520b7 100644
--- a/arch/arm/oprofile/Makefile
+++ b/arch/arm/oprofile/Makefile
@@ -8,4 +8,6 @@ DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \
8 8
9oprofile-y := $(DRIVER_OBJS) common.o backtrace.o 9oprofile-y := $(DRIVER_OBJS) common.o backtrace.o
10oprofile-$(CONFIG_CPU_XSCALE) += op_model_xscale.o 10oprofile-$(CONFIG_CPU_XSCALE) += op_model_xscale.o
11 11oprofile-$(CONFIG_OPROFILE_ARM11_CORE) += op_model_arm11_core.o
12oprofile-$(CONFIG_OPROFILE_ARMV6) += op_model_v6.o
13oprofile-$(CONFIG_OPROFILE_MPCORE) += op_model_mpcore.o
diff --git a/arch/arm/oprofile/common.c b/arch/arm/oprofile/common.c
index 6f833358cd06..0a007b931f63 100644
--- a/arch/arm/oprofile/common.c
+++ b/arch/arm/oprofile/common.c
@@ -135,6 +135,14 @@ int __init oprofile_arch_init(struct oprofile_operations *ops)
135 spec = &op_xscale_spec; 135 spec = &op_xscale_spec;
136#endif 136#endif
137 137
138#ifdef CONFIG_OPROFILE_ARMV6
139 spec = &op_armv6_spec;
140#endif
141
142#ifdef CONFIG_OPROFILE_MPCORE
143 spec = &op_mpcore_spec;
144#endif
145
138 if (spec) { 146 if (spec) {
139 ret = spec->init(); 147 ret = spec->init();
140 if (ret < 0) 148 if (ret < 0)
diff --git a/arch/arm/oprofile/op_arm_model.h b/arch/arm/oprofile/op_arm_model.h
index 38c6ad158547..4899c629aa03 100644
--- a/arch/arm/oprofile/op_arm_model.h
+++ b/arch/arm/oprofile/op_arm_model.h
@@ -24,6 +24,9 @@ struct op_arm_model_spec {
24extern struct op_arm_model_spec op_xscale_spec; 24extern struct op_arm_model_spec op_xscale_spec;
25#endif 25#endif
26 26
27extern struct op_arm_model_spec op_armv6_spec;
28extern struct op_arm_model_spec op_mpcore_spec;
29
27extern void arm_backtrace(struct pt_regs * const regs, unsigned int depth); 30extern void arm_backtrace(struct pt_regs * const regs, unsigned int depth);
28 31
29extern int __init op_arm_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec); 32extern int __init op_arm_init(struct oprofile_operations *ops, struct op_arm_model_spec *spec);
diff --git a/arch/arm/oprofile/op_model_arm11_core.c b/arch/arm/oprofile/op_model_arm11_core.c
new file mode 100644
index 000000000000..ad80752cb9fb
--- /dev/null
+++ b/arch/arm/oprofile/op_model_arm11_core.c
@@ -0,0 +1,162 @@
1/**
2 * @file op_model_arm11_core.c
3 * ARM11 Event Monitor Driver
4 * @remark Copyright 2004 ARM SMP Development Team
5 */
6#include <linux/types.h>
7#include <linux/errno.h>
8#include <linux/oprofile.h>
9#include <linux/interrupt.h>
10#include <linux/irq.h>
11#include <linux/smp.h>
12
13#include "op_counter.h"
14#include "op_arm_model.h"
15#include "op_model_arm11_core.h"
16
17/*
18 * ARM11 PMU support
19 */
20static inline void arm11_write_pmnc(u32 val)
21{
22 /* upper 4bits and 7, 11 are write-as-0 */
23 val &= 0x0ffff77f;
24 asm volatile("mcr p15, 0, %0, c15, c12, 0" : : "r" (val));
25}
26
27static inline u32 arm11_read_pmnc(void)
28{
29 u32 val;
30 asm volatile("mrc p15, 0, %0, c15, c12, 0" : "=r" (val));
31 return val;
32}
33
34static void arm11_reset_counter(unsigned int cnt)
35{
36 u32 val = -(u32)counter_config[CPU_COUNTER(smp_processor_id(), cnt)].count;
37 switch (cnt) {
38 case CCNT:
39 asm volatile("mcr p15, 0, %0, c15, c12, 1" : : "r" (val));
40 break;
41
42 case PMN0:
43 asm volatile("mcr p15, 0, %0, c15, c12, 2" : : "r" (val));
44 break;
45
46 case PMN1:
47 asm volatile("mcr p15, 0, %0, c15, c12, 3" : : "r" (val));
48 break;
49 }
50}
51
52int arm11_setup_pmu(void)
53{
54 unsigned int cnt;
55 u32 pmnc;
56
57 if (arm11_read_pmnc() & PMCR_E) {
58 printk(KERN_ERR "oprofile: CPU%u PMU still enabled when setup new event counter.\n", smp_processor_id());
59 return -EBUSY;
60 }
61
62 /* initialize PMNC, reset overflow, D bit, C bit and P bit. */
63 arm11_write_pmnc(PMCR_OFL_PMN0 | PMCR_OFL_PMN1 | PMCR_OFL_CCNT |
64 PMCR_C | PMCR_P);
65
66 for (pmnc = 0, cnt = PMN0; cnt <= CCNT; cnt++) {
67 unsigned long event;
68
69 if (!counter_config[CPU_COUNTER(smp_processor_id(), cnt)].enabled)
70 continue;
71
72 event = counter_config[CPU_COUNTER(smp_processor_id(), cnt)].event & 255;
73
74 /*
75 * Set event (if destined for PMNx counters)
76 */
77 if (cnt == PMN0) {
78 pmnc |= event << 20;
79 } else if (cnt == PMN1) {
80 pmnc |= event << 12;
81 }
82
83 /*
84 * We don't need to set the event if it's a cycle count
85 * Enable interrupt for this counter
86 */
87 pmnc |= PMCR_IEN_PMN0 << cnt;
88 arm11_reset_counter(cnt);
89 }
90 arm11_write_pmnc(pmnc);
91
92 return 0;
93}
94
95int arm11_start_pmu(void)
96{
97 arm11_write_pmnc(arm11_read_pmnc() | PMCR_E);
98 return 0;
99}
100
101int arm11_stop_pmu(void)
102{
103 unsigned int cnt;
104
105 arm11_write_pmnc(arm11_read_pmnc() & ~PMCR_E);
106
107 for (cnt = PMN0; cnt <= CCNT; cnt++)
108 arm11_reset_counter(cnt);
109
110 return 0;
111}
112
113/*
114 * CPU counters' IRQ handler (one IRQ per CPU)
115 */
116static irqreturn_t arm11_pmu_interrupt(int irq, void *arg)
117{
118 struct pt_regs *regs = get_irq_regs();
119 unsigned int cnt;
120 u32 pmnc;
121
122 pmnc = arm11_read_pmnc();
123
124 for (cnt = PMN0; cnt <= CCNT; cnt++) {
125 if ((pmnc & (PMCR_OFL_PMN0 << cnt)) && (pmnc & (PMCR_IEN_PMN0 << cnt))) {
126 arm11_reset_counter(cnt);
127 oprofile_add_sample(regs, CPU_COUNTER(smp_processor_id(), cnt));
128 }
129 }
130 /* Clear counter flag(s) */
131 arm11_write_pmnc(pmnc);
132 return IRQ_HANDLED;
133}
134
135int arm11_request_interrupts(int *irqs, int nr)
136{
137 unsigned int i;
138 int ret = 0;
139
140 for(i = 0; i < nr; i++) {
141 ret = request_irq(irqs[i], arm11_pmu_interrupt, IRQF_DISABLED, "CP15 PMU", NULL);
142 if (ret != 0) {
143 printk(KERN_ERR "oprofile: unable to request IRQ%u for MPCORE-EM\n",
144 irqs[i]);
145 break;
146 }
147 }
148
149 if (i != nr)
150 while (i-- != 0)
151 free_irq(irqs[i], NULL);
152
153 return ret;
154}
155
156void arm11_release_interrupts(int *irqs, int nr)
157{
158 unsigned int i;
159
160 for (i = 0; i < nr; i++)
161 free_irq(irqs[i], NULL);
162}
diff --git a/arch/arm/oprofile/op_model_arm11_core.h b/arch/arm/oprofile/op_model_arm11_core.h
new file mode 100644
index 000000000000..6f8538e5a960
--- /dev/null
+++ b/arch/arm/oprofile/op_model_arm11_core.h
@@ -0,0 +1,45 @@
1/**
2 * @file op_model_arm11_core.h
3 * ARM11 Event Monitor Driver
4 * @remark Copyright 2004 ARM SMP Development Team
5 * @remark Copyright 2000-2004 Deepak Saxena <dsaxena@mvista.com>
6 * @remark Copyright 2000-2004 MontaVista Software Inc
7 * @remark Copyright 2004 Dave Jiang <dave.jiang@intel.com>
8 * @remark Copyright 2004 Intel Corporation
9 * @remark Copyright 2004 Zwane Mwaikambo <zwane@arm.linux.org.uk>
10 * @remark Copyright 2004 Oprofile Authors
11 *
12 * @remark Read the file COPYING
13 *
14 * @author Zwane Mwaikambo
15 */
16#ifndef OP_MODEL_ARM11_CORE_H
17#define OP_MODEL_ARM11_CORE_H
18
19/*
20 * Per-CPU PMCR
21 */
22#define PMCR_E (1 << 0) /* Enable */
23#define PMCR_P (1 << 1) /* Count reset */
24#define PMCR_C (1 << 2) /* Cycle counter reset */
25#define PMCR_D (1 << 3) /* Cycle counter counts every 64th cpu cycle */
26#define PMCR_IEN_PMN0 (1 << 4) /* Interrupt enable count reg 0 */
27#define PMCR_IEN_PMN1 (1 << 5) /* Interrupt enable count reg 1 */
28#define PMCR_IEN_CCNT (1 << 6) /* Interrupt enable cycle counter */
29#define PMCR_OFL_PMN0 (1 << 8) /* Count reg 0 overflow */
30#define PMCR_OFL_PMN1 (1 << 9) /* Count reg 1 overflow */
31#define PMCR_OFL_CCNT (1 << 10) /* Cycle counter overflow */
32
33#define PMN0 0
34#define PMN1 1
35#define CCNT 2
36
37#define CPU_COUNTER(cpu, counter) ((cpu) * 3 + (counter))
38
39int arm11_setup_pmu(void);
40int arm11_start_pmu(void);
41int arm11_stop_pmu(void);
42int arm11_request_interrupts(int *, int);
43void arm11_release_interrupts(int *, int);
44
45#endif
diff --git a/arch/arm/oprofile/op_model_mpcore.c b/arch/arm/oprofile/op_model_mpcore.c
new file mode 100644
index 000000000000..898500718249
--- /dev/null
+++ b/arch/arm/oprofile/op_model_mpcore.c
@@ -0,0 +1,296 @@
1/**
2 * @file op_model_mpcore.c
3 * MPCORE Event Monitor Driver
4 * @remark Copyright 2004 ARM SMP Development Team
5 * @remark Copyright 2000-2004 Deepak Saxena <dsaxena@mvista.com>
6 * @remark Copyright 2000-2004 MontaVista Software Inc
7 * @remark Copyright 2004 Dave Jiang <dave.jiang@intel.com>
8 * @remark Copyright 2004 Intel Corporation
9 * @remark Copyright 2004 Zwane Mwaikambo <zwane@arm.linux.org.uk>
10 * @remark Copyright 2004 Oprofile Authors
11 *
12 * @remark Read the file COPYING
13 *
14 * @author Zwane Mwaikambo
15 *
16 * Counters:
17 * 0: PMN0 on CPU0, per-cpu configurable event counter
18 * 1: PMN1 on CPU0, per-cpu configurable event counter
19 * 2: CCNT on CPU0
20 * 3: PMN0 on CPU1
21 * 4: PMN1 on CPU1
22 * 5: CCNT on CPU1
23 * 6: PMN0 on CPU1
24 * 7: PMN1 on CPU1
25 * 8: CCNT on CPU1
26 * 9: PMN0 on CPU1
27 * 10: PMN1 on CPU1
28 * 11: CCNT on CPU1
29 * 12-19: configurable SCU event counters
30 */
31
32/* #define DEBUG */
33#include <linux/types.h>
34#include <linux/errno.h>
35#include <linux/sched.h>
36#include <linux/oprofile.h>
37#include <linux/interrupt.h>
38#include <linux/smp.h>
39
40#include <asm/io.h>
41#include <asm/irq.h>
42#include <asm/mach/irq.h>
43#include <asm/hardware.h>
44#include <asm/system.h>
45
46#include "op_counter.h"
47#include "op_arm_model.h"
48#include "op_model_arm11_core.h"
49#include "op_model_mpcore.h"
50
51/*
52 * MPCore SCU event monitor support
53 */
54#define SCU_EVENTMONITORS_VA_BASE __io_address(REALVIEW_MPCORE_SCU_BASE + 0x10)
55
56/*
57 * Bitmask of used SCU counters
58 */
59static unsigned int scu_em_used;
60
61/*
62 * 2 helper fns take a counter number from 0-7 (not the userspace-visible counter number)
63 */
64static inline void scu_reset_counter(struct eventmonitor __iomem *emc, unsigned int n)
65{
66 writel(-(u32)counter_config[SCU_COUNTER(n)].count, &emc->MC[n]);
67}
68
69static inline void scu_set_event(struct eventmonitor __iomem *emc, unsigned int n, u32 event)
70{
71 event &= 0xff;
72 writeb(event, &emc->MCEB[n]);
73}
74
75/*
76 * SCU counters' IRQ handler (one IRQ per counter => 2 IRQs per CPU)
77 */
78static irqreturn_t scu_em_interrupt(int irq, void *arg)
79{
80 struct eventmonitor __iomem *emc = SCU_EVENTMONITORS_VA_BASE;
81 unsigned int cnt;
82
83 cnt = irq - IRQ_PMU_SCU0;
84 oprofile_add_sample(get_irq_regs(), SCU_COUNTER(cnt));
85 scu_reset_counter(emc, cnt);
86
87 /* Clear overflow flag for this counter */
88 writel(1 << (cnt + 16), &emc->PMCR);
89
90 return IRQ_HANDLED;
91}
92
93/* Configure just the SCU counters that the user has requested */
94static void scu_setup(void)
95{
96 struct eventmonitor __iomem *emc = SCU_EVENTMONITORS_VA_BASE;
97 unsigned int i;
98
99 scu_em_used = 0;
100
101 for (i = 0; i < NUM_SCU_COUNTERS; i++) {
102 if (counter_config[SCU_COUNTER(i)].enabled &&
103 counter_config[SCU_COUNTER(i)].event) {
104 scu_set_event(emc, i, 0); /* disable counter for now */
105 scu_em_used |= 1 << i;
106 }
107 }
108}
109
110static int scu_start(void)
111{
112 struct eventmonitor __iomem *emc = SCU_EVENTMONITORS_VA_BASE;
113 unsigned int temp, i;
114 unsigned long event;
115 int ret = 0;
116
117 /*
118 * request the SCU counter interrupts that we need
119 */
120 for (i = 0; i < NUM_SCU_COUNTERS; i++) {
121 if (scu_em_used & (1 << i)) {
122 ret = request_irq(IRQ_PMU_SCU0 + i, scu_em_interrupt, IRQF_DISABLED, "SCU PMU", NULL);
123 if (ret) {
124 printk(KERN_ERR "oprofile: unable to request IRQ%u for SCU Event Monitor\n",
125 IRQ_PMU_SCU0 + i);
126 goto err_free_scu;
127 }
128 }
129 }
130
131 /*
132 * clear overflow and enable interrupt for all used counters
133 */
134 temp = readl(&emc->PMCR);
135 for (i = 0; i < NUM_SCU_COUNTERS; i++) {
136 if (scu_em_used & (1 << i)) {
137 scu_reset_counter(emc, i);
138 event = counter_config[SCU_COUNTER(i)].event;
139 scu_set_event(emc, i, event);
140
141 /* clear overflow/interrupt */
142 temp |= 1 << (i + 16);
143 /* enable interrupt*/
144 temp |= 1 << (i + 8);
145 }
146 }
147
148 /* Enable all 8 counters */
149 temp |= PMCR_E;
150 writel(temp, &emc->PMCR);
151
152 return 0;
153
154 err_free_scu:
155 while (i--)
156 free_irq(IRQ_PMU_SCU0 + i, NULL);
157 return ret;
158}
159
160static void scu_stop(void)
161{
162 struct eventmonitor __iomem *emc = SCU_EVENTMONITORS_VA_BASE;
163 unsigned int temp, i;
164
165 /* Disable counter interrupts */
166 /* Don't disable all 8 counters (with the E bit) as they may be in use */
167 temp = readl(&emc->PMCR);
168 for (i = 0; i < NUM_SCU_COUNTERS; i++) {
169 if (scu_em_used & (1 << i))
170 temp &= ~(1 << (i + 8));
171 }
172 writel(temp, &emc->PMCR);
173
174 /* Free counter interrupts and reset counters */
175 for (i = 0; i < NUM_SCU_COUNTERS; i++) {
176 if (scu_em_used & (1 << i)) {
177 scu_reset_counter(emc, i);
178 free_irq(IRQ_PMU_SCU0 + i, NULL);
179 }
180 }
181}
182
183struct em_function_data {
184 int (*fn)(void);
185 int ret;
186};
187
188static void em_func(void *data)
189{
190 struct em_function_data *d = data;
191 int ret = d->fn();
192 if (ret)
193 d->ret = ret;
194}
195
196static int em_call_function(int (*fn)(void))
197{
198 struct em_function_data data;
199
200 data.fn = fn;
201 data.ret = 0;
202
203 smp_call_function(em_func, &data, 1, 1);
204 em_func(&data);
205
206 return data.ret;
207}
208
209/*
210 * Glue to stick the individual ARM11 PMUs and the SCU
211 * into the oprofile framework.
212 */
213static int em_setup_ctrs(void)
214{
215 int ret;
216
217 /* Configure CPU counters by cross-calling to the other CPUs */
218 ret = em_call_function(arm11_setup_pmu);
219 if (ret == 0)
220 scu_setup();
221
222 return 0;
223}
224
225static int arm11_irqs[] = {
226 [0] = IRQ_PMU_CPU0,
227 [1] = IRQ_PMU_CPU1,
228 [2] = IRQ_PMU_CPU2,
229 [3] = IRQ_PMU_CPU3
230};
231
232static int em_start(void)
233{
234 int ret;
235
236 ret = arm11_request_interrupts(arm11_irqs, ARRAY_SIZE(arm11_irqs));
237 if (ret == 0) {
238 em_call_function(arm11_start_pmu);
239
240 ret = scu_start();
241 if (ret)
242 arm11_release_interrupts(arm11_irqs, ARRAY_SIZE(arm11_irqs));
243 }
244 return ret;
245}
246
247static void em_stop(void)
248{
249 em_call_function(arm11_stop_pmu);
250 arm11_release_interrupts(arm11_irqs, ARRAY_SIZE(arm11_irqs));
251 scu_stop();
252}
253
254/*
255 * Why isn't there a function to route an IRQ to a specific CPU in
256 * genirq?
257 */
258static void em_route_irq(int irq, unsigned int cpu)
259{
260 irq_desc[irq].affinity = cpumask_of_cpu(cpu);
261 irq_desc[irq].chip->set_affinity(irq, cpumask_of_cpu(cpu));
262}
263
264static int em_setup(void)
265{
266 /*
267 * Send SCU PMU interrupts to the "owner" CPU.
268 */
269 em_route_irq(IRQ_PMU_SCU0, 0);
270 em_route_irq(IRQ_PMU_SCU1, 0);
271 em_route_irq(IRQ_PMU_SCU2, 1);
272 em_route_irq(IRQ_PMU_SCU3, 1);
273 em_route_irq(IRQ_PMU_SCU4, 2);
274 em_route_irq(IRQ_PMU_SCU5, 2);
275 em_route_irq(IRQ_PMU_SCU6, 3);
276 em_route_irq(IRQ_PMU_SCU7, 3);
277
278 /*
279 * Send CP15 PMU interrupts to the owner CPU.
280 */
281 em_route_irq(IRQ_PMU_CPU0, 0);
282 em_route_irq(IRQ_PMU_CPU1, 1);
283 em_route_irq(IRQ_PMU_CPU2, 2);
284 em_route_irq(IRQ_PMU_CPU3, 3);
285
286 return 0;
287}
288
289struct op_arm_model_spec op_mpcore_spec = {
290 .init = em_setup,
291 .num_counters = MPCORE_NUM_COUNTERS,
292 .setup_ctrs = em_setup_ctrs,
293 .start = em_start,
294 .stop = em_stop,
295 .name = "arm/mpcore",
296};
diff --git a/arch/arm/oprofile/op_model_mpcore.h b/arch/arm/oprofile/op_model_mpcore.h
new file mode 100644
index 000000000000..73d811023688
--- /dev/null
+++ b/arch/arm/oprofile/op_model_mpcore.h
@@ -0,0 +1,61 @@
1/**
2 * @file op_model_mpcore.c
3 * MPCORE Event Monitor Driver
4 * @remark Copyright 2004 ARM SMP Development Team
5 * @remark Copyright 2000-2004 Deepak Saxena <dsaxena@mvista.com>
6 * @remark Copyright 2000-2004 MontaVista Software Inc
7 * @remark Copyright 2004 Dave Jiang <dave.jiang@intel.com>
8 * @remark Copyright 2004 Intel Corporation
9 * @remark Copyright 2004 Zwane Mwaikambo <zwane@arm.linux.org.uk>
10 * @remark Copyright 2004 Oprofile Authors
11 *
12 * @remark Read the file COPYING
13 *
14 * @author Zwane Mwaikambo
15 */
16#ifndef OP_MODEL_MPCORE_H
17#define OP_MODEL_MPCORE_H
18
19struct eventmonitor {
20 unsigned long PMCR;
21 unsigned char MCEB[8];
22 unsigned long MC[8];
23};
24
25/*
26 * List of userspace counter numbers: note that the structure is important.
27 * The code relies on CPUn's counters being CPU0's counters + 3n
28 * and on CPU0's counters starting at 0
29 */
30
31#define COUNTER_CPU0_PMN0 0
32#define COUNTER_CPU0_PMN1 1
33#define COUNTER_CPU0_CCNT 2
34
35#define COUNTER_CPU1_PMN0 3
36#define COUNTER_CPU1_PMN1 4
37#define COUNTER_CPU1_CCNT 5
38
39#define COUNTER_CPU2_PMN0 6
40#define COUNTER_CPU2_PMN1 7
41#define COUNTER_CPU2_CCNT 8
42
43#define COUNTER_CPU3_PMN0 9
44#define COUNTER_CPU3_PMN1 10
45#define COUNTER_CPU3_CCNT 11
46
47#define COUNTER_SCU_MN0 12
48#define COUNTER_SCU_MN1 13
49#define COUNTER_SCU_MN2 14
50#define COUNTER_SCU_MN3 15
51#define COUNTER_SCU_MN4 16
52#define COUNTER_SCU_MN5 17
53#define COUNTER_SCU_MN6 18
54#define COUNTER_SCU_MN7 19
55#define NUM_SCU_COUNTERS 8
56
57#define SCU_COUNTER(number) ((number) + COUNTER_SCU_MN0)
58
59#define MPCORE_NUM_COUNTERS SCU_COUNTER(NUM_SCU_COUNTERS)
60
61#endif
diff --git a/arch/arm/oprofile/op_model_v6.c b/arch/arm/oprofile/op_model_v6.c
new file mode 100644
index 000000000000..fe581383d3e2
--- /dev/null
+++ b/arch/arm/oprofile/op_model_v6.c
@@ -0,0 +1,67 @@
1/**
2 * @file op_model_v6.c
3 * ARM11 Performance Monitor Driver
4 *
5 * Based on op_model_xscale.c
6 *
7 * @remark Copyright 2000-2004 Deepak Saxena <dsaxena@mvista.com>
8 * @remark Copyright 2000-2004 MontaVista Software Inc
9 * @remark Copyright 2004 Dave Jiang <dave.jiang@intel.com>
10 * @remark Copyright 2004 Intel Corporation
11 * @remark Copyright 2004 Zwane Mwaikambo <zwane@arm.linux.org.uk>
12 * @remark Copyright 2004 OProfile Authors
13 *
14 * @remark Read the file COPYING
15 *
16 * @author Tony Lindgren <tony@atomide.com>
17 */
18
19/* #define DEBUG */
20#include <linux/types.h>
21#include <linux/errno.h>
22#include <linux/sched.h>
23#include <linux/oprofile.h>
24#include <linux/interrupt.h>
25#include <asm/irq.h>
26#include <asm/system.h>
27
28#include "op_counter.h"
29#include "op_arm_model.h"
30#include "op_model_arm11_core.h"
31
32static int irqs[] = {
33#ifdef CONFIG_ARCH_OMAP2
34 3,
35#endif
36};
37
38static void armv6_pmu_stop(void)
39{
40 arm11_stop_pmu();
41 arm11_release_interrupts(irqs, ARRAY_SIZE(irqs));
42}
43
44static int armv6_pmu_start(void)
45{
46 int ret;
47
48 ret = arm11_request_interrupts(irqs, ARRAY_SIZE(irqs));
49 if (ret >= 0)
50 ret = arm11_start_pmu();
51
52 return ret;
53}
54
55static int armv6_detect_pmu(void)
56{
57 return 0;
58}
59
60struct op_arm_model_spec op_armv6_spec = {
61 .init = armv6_detect_pmu,
62 .num_counters = 3,
63 .setup_ctrs = arm11_setup_pmu,
64 .start = armv6_pmu_start,
65 .stop = armv6_pmu_stop,
66 .name = "arm/armv6",
67};
diff --git a/arch/arm/plat-iop/Makefile b/arch/arm/plat-iop/Makefile
index 23da00b11517..3250d732a171 100644
--- a/arch/arm/plat-iop/Makefile
+++ b/arch/arm/plat-iop/Makefile
@@ -2,7 +2,29 @@
2# Makefile for the linux kernel. 2# Makefile for the linux kernel.
3# 3#
4 4
5obj-y := gpio.o i2c.o pci.o setup.o time.o 5obj-y :=
6obj-m := 6
7obj-n := 7# IOP32X
8obj- := 8obj-$(CONFIG_ARCH_IOP32X) += gpio.o
9obj-$(CONFIG_ARCH_IOP32X) += i2c.o
10obj-$(CONFIG_ARCH_IOP32X) += pci.o
11obj-$(CONFIG_ARCH_IOP32X) += setup.o
12obj-$(CONFIG_ARCH_IOP32X) += time.o
13obj-$(CONFIG_ARCH_IOP32X) += io.o
14obj-$(CONFIG_ARCH_IOP32X) += cp6.o
15
16# IOP33X
17obj-$(CONFIG_ARCH_IOP33X) += gpio.o
18obj-$(CONFIG_ARCH_IOP33X) += i2c.o
19obj-$(CONFIG_ARCH_IOP33X) += pci.o
20obj-$(CONFIG_ARCH_IOP33X) += setup.o
21obj-$(CONFIG_ARCH_IOP33X) += time.o
22obj-$(CONFIG_ARCH_IOP33X) += io.o
23obj-$(CONFIG_ARCH_IOP33X) += cp6.o
24
25# IOP13XX
26obj-$(CONFIG_ARCH_IOP13XX) += cp6.o
27
28obj-m :=
29obj-n :=
30obj- :=
diff --git a/arch/arm/plat-iop/cp6.c b/arch/arm/plat-iop/cp6.c
new file mode 100644
index 000000000000..9612a87e2a88
--- /dev/null
+++ b/arch/arm/plat-iop/cp6.c
@@ -0,0 +1,50 @@
1/*
2 * IOP Coprocessor-6 access handler
3 * Copyright (c) 2006, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16 * Place - Suite 330, Boston, MA 02111-1307 USA.
17 *
18 */
19#include <linux/init.h>
20#include <asm/traps.h>
21
22static int cp6_trap(struct pt_regs *regs, unsigned int instr)
23{
24 u32 temp;
25
26 /* enable cp6 access */
27 asm volatile (
28 "mrc p15, 0, %0, c15, c1, 0\n\t"
29 "orr %0, %0, #(1 << 6)\n\t"
30 "mcr p15, 0, %0, c15, c1, 0\n\t"
31 : "=r"(temp));
32
33 return 0;
34}
35
36/* permit kernel space cp6 access
37 * deny user space cp6 access
38 */
39static struct undef_hook cp6_hook = {
40 .instr_mask = 0x0f000ff0,
41 .instr_val = 0x0e000610,
42 .cpsr_mask = MODE_MASK,
43 .cpsr_val = SVC_MODE,
44 .fn = cp6_trap,
45};
46
47void __init iop_init_cp6_handler(void)
48{
49 register_undef_hook(&cp6_hook);
50}
diff --git a/arch/arm/plat-iop/io.c b/arch/arm/plat-iop/io.c
new file mode 100644
index 000000000000..f7eccecf2e47
--- /dev/null
+++ b/arch/arm/plat-iop/io.c
@@ -0,0 +1,58 @@
1/*
2 * iop3xx custom ioremap implementation
3 * Copyright (c) 2006, Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
16 * Place - Suite 330, Boston, MA 02111-1307 USA.
17 *
18 */
19#include <linux/kernel.h>
20#include <linux/module.h>
21#include <asm/hardware.h>
22#include <asm/io.h>
23
24void * __iomem __iop3xx_ioremap(unsigned long cookie, size_t size,
25 unsigned long flags)
26{
27 void __iomem * retval;
28
29 switch (cookie) {
30 case IOP3XX_PCI_LOWER_IO_PA ... IOP3XX_PCI_UPPER_IO_PA:
31 retval = (void *) IOP3XX_PCI_IO_PHYS_TO_VIRT(cookie);
32 break;
33 case IOP3XX_PERIPHERAL_PHYS_BASE ... IOP3XX_PERIPHERAL_UPPER_PA:
34 retval = (void *) IOP3XX_PMMR_PHYS_TO_VIRT(cookie);
35 break;
36 default:
37 retval = __ioremap(cookie, size, flags);
38 }
39
40 return retval;
41}
42EXPORT_SYMBOL(__iop3xx_ioremap);
43
44void __iop3xx_iounmap(void __iomem *addr)
45{
46 extern void __iounmap(volatile void __iomem *addr);
47
48 switch ((u32) addr) {
49 case IOP3XX_PCI_LOWER_IO_VA ... IOP3XX_PCI_UPPER_IO_VA:
50 case IOP3XX_PERIPHERAL_VIRT_BASE ... IOP3XX_PERIPHERAL_UPPER_VA:
51 goto skip;
52 }
53 __iounmap(addr);
54
55skip:
56 return;
57}
58EXPORT_SYMBOL(__iop3xx_iounmap);
diff --git a/arch/arm/plat-iop/pci.c b/arch/arm/plat-iop/pci.c
index e647812654f2..b5f6ec35aafb 100644
--- a/arch/arm/plat-iop/pci.c
+++ b/arch/arm/plat-iop/pci.c
@@ -196,8 +196,8 @@ int iop3xx_pci_setup(int nr, struct pci_sys_data *sys)
196 if (!res) 196 if (!res)
197 panic("PCI: unable to alloc resources"); 197 panic("PCI: unable to alloc resources");
198 198
199 res[0].start = IOP3XX_PCI_LOWER_IO_VA; 199 res[0].start = IOP3XX_PCI_LOWER_IO_PA;
200 res[0].end = IOP3XX_PCI_LOWER_IO_VA + IOP3XX_PCI_IO_WINDOW_SIZE - 1; 200 res[0].end = IOP3XX_PCI_LOWER_IO_PA + IOP3XX_PCI_IO_WINDOW_SIZE - 1;
201 res[0].name = "IOP3XX PCI I/O Space"; 201 res[0].name = "IOP3XX PCI I/O Space";
202 res[0].flags = IORESOURCE_IO; 202 res[0].flags = IORESOURCE_IO;
203 request_resource(&ioport_resource, &res[0]); 203 request_resource(&ioport_resource, &res[0]);
@@ -209,7 +209,7 @@ int iop3xx_pci_setup(int nr, struct pci_sys_data *sys)
209 request_resource(&iomem_resource, &res[1]); 209 request_resource(&iomem_resource, &res[1]);
210 210
211 sys->mem_offset = IOP3XX_PCI_LOWER_MEM_PA - IOP3XX_PCI_LOWER_MEM_BA; 211 sys->mem_offset = IOP3XX_PCI_LOWER_MEM_PA - IOP3XX_PCI_LOWER_MEM_BA;
212 sys->io_offset = IOP3XX_PCI_LOWER_IO_VA - IOP3XX_PCI_LOWER_IO_BA; 212 sys->io_offset = IOP3XX_PCI_LOWER_IO_PA - IOP3XX_PCI_LOWER_IO_BA;
213 213
214 sys->resource[0] = &res[0]; 214 sys->resource[0] = &res[0];
215 sys->resource[1] = &res[1]; 215 sys->resource[1] = &res[1];
diff --git a/arch/arm/plat-s3c24xx/Kconfig b/arch/arm/plat-s3c24xx/Kconfig
new file mode 100644
index 000000000000..e22343160634
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/Kconfig
@@ -0,0 +1,99 @@
1# arch/arm/plat-s3c24xx/Kconfig
2#
3# Copyright 2007 Simtec Electronics
4#
5# Licensed under GPLv2
6
7config PLAT_S3C24XX
8 bool
9 depends on ARCH_S3C2410
10 default y if ARCH_S3C2410
11 help
12 Base platform code for any Samsung S3C device
13
14if PLAT_S3C24XX
15
16config CPU_S3C244X
17 bool
18 depends on ARCH_S3C2410 && (CPU_S3C2440 || CPU_S3C2442)
19 help
20 Support for S3C2440 and S3C2442 Samsung Mobile CPU based systems.
21
22config PM_SIMTEC
23 bool
24 help
25 Common power management code for systems that are
26 compatible with the Simtec style of power management
27
28config S3C2410_BOOT_WATCHDOG
29 bool "S3C2410 Initialisation watchdog"
30 depends on ARCH_S3C2410 && S3C2410_WATCHDOG
31 help
32 Say y to enable the watchdog during the kernel decompression
33 stage. If the kernel fails to uncompress, then the watchdog
34 will trigger a reset and the system should restart.
35
36config S3C2410_BOOT_ERROR_RESET
37 bool "S3C2410 Reboot on decompression error"
38 depends on ARCH_S3C2410
39 help
40 Say y here to use the watchdog to reset the system if the
41 kernel decompressor detects an error during decompression.
42
43config S3C2410_PM_DEBUG
44 bool "S3C2410 PM Suspend debug"
45 depends on ARCH_S3C2410 && PM
46 help
47 Say Y here if you want verbose debugging from the PM Suspend and
48 Resume code. See <file:Documentation/arm/Samsung-S3C24XX/Suspend.txt>
49 for more information.
50
51config S3C2410_PM_CHECK
52 bool "S3C2410 PM Suspend Memory CRC"
53 depends on ARCH_S3C2410 && PM && CRC32
54 help
55 Enable the PM code's memory area checksum over sleep. This option
56 will generate CRCs of all blocks of memory, and store them before
57 going to sleep. The blocks are then checked on resume for any
58 errors.
59
60config S3C2410_PM_CHECK_CHUNKSIZE
61 int "S3C2410 PM Suspend CRC Chunksize (KiB)"
62 depends on ARCH_S3C2410 && PM && S3C2410_PM_CHECK
63 default 64
64 help
65 Set the chunksize in Kilobytes of the CRC for checking memory
66 corruption over suspend and resume. A smaller value will mean that
67 the CRC data block will take more memory, but wil identify any
68 faults with better precision.
69
70config S3C2410_LOWLEVEL_UART_PORT
71 int "S3C2410 UART to use for low-level messages"
72 default 0
73 help
74 Choice of which UART port to use for the low-level messages,
75 such as the `Uncompressing...` at start time. The value of
76 this configuration should be between zero and two. The port
77 must have been initialised by the boot-loader before use.
78
79config S3C2410_DMA
80 bool "S3C2410 DMA support"
81 depends on ARCH_S3C2410
82 help
83 S3C2410 DMA support. This is needed for drivers like sound which
84 use the S3C2410's DMA system to move data to and from the
85 peripheral blocks.
86
87config S3C2410_DMA_DEBUG
88 bool "S3C2410 DMA support debug"
89 depends on ARCH_S3C2410 && S3C2410_DMA
90 help
91 Enable debugging output for the DMA code. This option sends info
92 to the kernel log, at priority KERN_DEBUG.
93
94config MACH_SMDK
95 bool
96 help
97 Common machine code for SMDK2410 and SMDK2440
98
99endif
diff --git a/arch/arm/plat-s3c24xx/Makefile b/arch/arm/plat-s3c24xx/Makefile
new file mode 100644
index 000000000000..8e5ccaa1f03c
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/Makefile
@@ -0,0 +1,30 @@
1# arch/arm/plat-s3c24xx/Makefile
2#
3# Copyright 2007 Simtec Electronics
4#
5# Licensed under GPLv2
6
7obj-y :=
8obj-m :=
9obj-n :=
10obj- :=
11
12
13# Core files
14
15obj-y += cpu.o
16obj-y += irq.o
17obj-y += devs.o
18obj-y += gpio.o
19obj-y += time.o
20obj-y += clock.o
21
22# Architecture dependant builds
23
24obj-$(CONFIG_CPU_S3C244X) += s3c244x.o
25obj-$(CONFIG_CPU_S3C244X) += s3c244x-irq.o
26obj-$(CONFIG_PM_SIMTEC) += pm-simtec.o
27obj-$(CONFIG_PM) += pm.o
28obj-$(CONFIG_PM) += sleep.o
29obj-$(CONFIG_S3C2410_DMA) += dma.o
30obj-$(CONFIG_MACH_SMDK) += common-smdk.o
diff --git a/arch/arm/plat-s3c24xx/clock.c b/arch/arm/plat-s3c24xx/clock.c
new file mode 100644
index 000000000000..d3dc03a7383a
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/clock.c
@@ -0,0 +1,449 @@
1/* linux/arch/arm/plat-s3c24xx/clock.c
2 *
3 * Copyright (c) 2004-2005 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C24XX Core clock control support
7 *
8 * Based on, and code from linux/arch/arm/mach-versatile/clock.c
9 **
10 ** Copyright (C) 2004 ARM Limited.
11 ** Written by Deep Blue Solutions Limited.
12 *
13 *
14 * This program is free software; you can redistribute it and/or modify
15 * it under the terms of the GNU General Public License as published by
16 * the Free Software Foundation; either version 2 of the License, or
17 * (at your option) any later version.
18 *
19 * This program is distributed in the hope that it will be useful,
20 * but WITHOUT ANY WARRANTY; without even the implied warranty of
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 * GNU General Public License for more details.
23 *
24 * You should have received a copy of the GNU General Public License
25 * along with this program; if not, write to the Free Software
26 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
27*/
28
29#include <linux/init.h>
30#include <linux/module.h>
31#include <linux/kernel.h>
32#include <linux/list.h>
33#include <linux/errno.h>
34#include <linux/err.h>
35#include <linux/platform_device.h>
36#include <linux/sysdev.h>
37#include <linux/interrupt.h>
38#include <linux/ioport.h>
39#include <linux/clk.h>
40#include <linux/mutex.h>
41#include <linux/delay.h>
42
43#include <asm/hardware.h>
44#include <asm/irq.h>
45#include <asm/io.h>
46
47#include <asm/arch/regs-clock.h>
48#include <asm/arch/regs-gpio.h>
49
50#include <asm/plat-s3c24xx/clock.h>
51#include <asm/plat-s3c24xx/cpu.h>
52
53/* clock information */
54
55static LIST_HEAD(clocks);
56
57DEFINE_MUTEX(clocks_mutex);
58
59/* enable and disable calls for use with the clk struct */
60
61static int clk_null_enable(struct clk *clk, int enable)
62{
63 return 0;
64}
65
66/* Clock API calls */
67
68struct clk *clk_get(struct device *dev, const char *id)
69{
70 struct clk *p;
71 struct clk *clk = ERR_PTR(-ENOENT);
72 int idno;
73
74 if (dev == NULL || dev->bus != &platform_bus_type)
75 idno = -1;
76 else
77 idno = to_platform_device(dev)->id;
78
79 mutex_lock(&clocks_mutex);
80
81 list_for_each_entry(p, &clocks, list) {
82 if (p->id == idno &&
83 strcmp(id, p->name) == 0 &&
84 try_module_get(p->owner)) {
85 clk = p;
86 break;
87 }
88 }
89
90 /* check for the case where a device was supplied, but the
91 * clock that was being searched for is not device specific */
92
93 if (IS_ERR(clk)) {
94 list_for_each_entry(p, &clocks, list) {
95 if (p->id == -1 && strcmp(id, p->name) == 0 &&
96 try_module_get(p->owner)) {
97 clk = p;
98 break;
99 }
100 }
101 }
102
103 mutex_unlock(&clocks_mutex);
104 return clk;
105}
106
107void clk_put(struct clk *clk)
108{
109 module_put(clk->owner);
110}
111
112int clk_enable(struct clk *clk)
113{
114 if (IS_ERR(clk) || clk == NULL)
115 return -EINVAL;
116
117 clk_enable(clk->parent);
118
119 mutex_lock(&clocks_mutex);
120
121 if ((clk->usage++) == 0)
122 (clk->enable)(clk, 1);
123
124 mutex_unlock(&clocks_mutex);
125 return 0;
126}
127
128void clk_disable(struct clk *clk)
129{
130 if (IS_ERR(clk) || clk == NULL)
131 return;
132
133 mutex_lock(&clocks_mutex);
134
135 if ((--clk->usage) == 0)
136 (clk->enable)(clk, 0);
137
138 mutex_unlock(&clocks_mutex);
139 clk_disable(clk->parent);
140}
141
142
143unsigned long clk_get_rate(struct clk *clk)
144{
145 if (IS_ERR(clk))
146 return 0;
147
148 if (clk->rate != 0)
149 return clk->rate;
150
151 if (clk->get_rate != NULL)
152 return (clk->get_rate)(clk);
153
154 if (clk->parent != NULL)
155 return clk_get_rate(clk->parent);
156
157 return clk->rate;
158}
159
160long clk_round_rate(struct clk *clk, unsigned long rate)
161{
162 if (!IS_ERR(clk) && clk->round_rate)
163 return (clk->round_rate)(clk, rate);
164
165 return rate;
166}
167
168int clk_set_rate(struct clk *clk, unsigned long rate)
169{
170 int ret;
171
172 if (IS_ERR(clk))
173 return -EINVAL;
174
175 mutex_lock(&clocks_mutex);
176 ret = (clk->set_rate)(clk, rate);
177 mutex_unlock(&clocks_mutex);
178
179 return ret;
180}
181
182struct clk *clk_get_parent(struct clk *clk)
183{
184 return clk->parent;
185}
186
187int clk_set_parent(struct clk *clk, struct clk *parent)
188{
189 int ret = 0;
190
191 if (IS_ERR(clk))
192 return -EINVAL;
193
194 mutex_lock(&clocks_mutex);
195
196 if (clk->set_parent)
197 ret = (clk->set_parent)(clk, parent);
198
199 mutex_unlock(&clocks_mutex);
200
201 return ret;
202}
203
204EXPORT_SYMBOL(clk_get);
205EXPORT_SYMBOL(clk_put);
206EXPORT_SYMBOL(clk_enable);
207EXPORT_SYMBOL(clk_disable);
208EXPORT_SYMBOL(clk_get_rate);
209EXPORT_SYMBOL(clk_round_rate);
210EXPORT_SYMBOL(clk_set_rate);
211EXPORT_SYMBOL(clk_get_parent);
212EXPORT_SYMBOL(clk_set_parent);
213
214/* base clocks */
215
216struct clk clk_xtal = {
217 .name = "xtal",
218 .id = -1,
219 .rate = 0,
220 .parent = NULL,
221 .ctrlbit = 0,
222};
223
224struct clk clk_mpll = {
225 .name = "mpll",
226 .id = -1,
227};
228
229struct clk clk_upll = {
230 .name = "upll",
231 .id = -1,
232 .parent = NULL,
233 .ctrlbit = 0,
234};
235
236struct clk clk_f = {
237 .name = "fclk",
238 .id = -1,
239 .rate = 0,
240 .parent = &clk_mpll,
241 .ctrlbit = 0,
242};
243
244struct clk clk_h = {
245 .name = "hclk",
246 .id = -1,
247 .rate = 0,
248 .parent = NULL,
249 .ctrlbit = 0,
250};
251
252struct clk clk_p = {
253 .name = "pclk",
254 .id = -1,
255 .rate = 0,
256 .parent = NULL,
257 .ctrlbit = 0,
258};
259
260struct clk clk_usb_bus = {
261 .name = "usb-bus",
262 .id = -1,
263 .rate = 0,
264 .parent = &clk_upll,
265};
266
267/* clocks that could be registered by external code */
268
269static int s3c24xx_dclk_enable(struct clk *clk, int enable)
270{
271 unsigned long dclkcon = __raw_readl(S3C24XX_DCLKCON);
272
273 if (enable)
274 dclkcon |= clk->ctrlbit;
275 else
276 dclkcon &= ~clk->ctrlbit;
277
278 __raw_writel(dclkcon, S3C24XX_DCLKCON);
279
280 return 0;
281}
282
283static int s3c24xx_dclk_setparent(struct clk *clk, struct clk *parent)
284{
285 unsigned long dclkcon;
286 unsigned int uclk;
287
288 if (parent == &clk_upll)
289 uclk = 1;
290 else if (parent == &clk_p)
291 uclk = 0;
292 else
293 return -EINVAL;
294
295 clk->parent = parent;
296
297 dclkcon = __raw_readl(S3C24XX_DCLKCON);
298
299 if (clk->ctrlbit == S3C2410_DCLKCON_DCLK0EN) {
300 if (uclk)
301 dclkcon |= S3C2410_DCLKCON_DCLK0_UCLK;
302 else
303 dclkcon &= ~S3C2410_DCLKCON_DCLK0_UCLK;
304 } else {
305 if (uclk)
306 dclkcon |= S3C2410_DCLKCON_DCLK1_UCLK;
307 else
308 dclkcon &= ~S3C2410_DCLKCON_DCLK1_UCLK;
309 }
310
311 __raw_writel(dclkcon, S3C24XX_DCLKCON);
312
313 return 0;
314}
315
316
317static int s3c24xx_clkout_setparent(struct clk *clk, struct clk *parent)
318{
319 unsigned long mask;
320 unsigned long source;
321
322 /* calculate the MISCCR setting for the clock */
323
324 if (parent == &clk_xtal)
325 source = S3C2410_MISCCR_CLK0_MPLL;
326 else if (parent == &clk_upll)
327 source = S3C2410_MISCCR_CLK0_UPLL;
328 else if (parent == &clk_f)
329 source = S3C2410_MISCCR_CLK0_FCLK;
330 else if (parent == &clk_h)
331 source = S3C2410_MISCCR_CLK0_HCLK;
332 else if (parent == &clk_p)
333 source = S3C2410_MISCCR_CLK0_PCLK;
334 else if (clk == &s3c24xx_clkout0 && parent == &s3c24xx_dclk0)
335 source = S3C2410_MISCCR_CLK0_DCLK0;
336 else if (clk == &s3c24xx_clkout1 && parent == &s3c24xx_dclk1)
337 source = S3C2410_MISCCR_CLK0_DCLK0;
338 else
339 return -EINVAL;
340
341 clk->parent = parent;
342
343 if (clk == &s3c24xx_dclk0)
344 mask = S3C2410_MISCCR_CLK0_MASK;
345 else {
346 source <<= 4;
347 mask = S3C2410_MISCCR_CLK1_MASK;
348 }
349
350 s3c2410_modify_misccr(mask, source);
351 return 0;
352}
353
354/* external clock definitions */
355
356struct clk s3c24xx_dclk0 = {
357 .name = "dclk0",
358 .id = -1,
359 .ctrlbit = S3C2410_DCLKCON_DCLK0EN,
360 .enable = s3c24xx_dclk_enable,
361 .set_parent = s3c24xx_dclk_setparent,
362};
363
364struct clk s3c24xx_dclk1 = {
365 .name = "dclk1",
366 .id = -1,
367 .ctrlbit = S3C2410_DCLKCON_DCLK0EN,
368 .enable = s3c24xx_dclk_enable,
369 .set_parent = s3c24xx_dclk_setparent,
370};
371
372struct clk s3c24xx_clkout0 = {
373 .name = "clkout0",
374 .id = -1,
375 .set_parent = s3c24xx_clkout_setparent,
376};
377
378struct clk s3c24xx_clkout1 = {
379 .name = "clkout1",
380 .id = -1,
381 .set_parent = s3c24xx_clkout_setparent,
382};
383
384struct clk s3c24xx_uclk = {
385 .name = "uclk",
386 .id = -1,
387};
388
389/* initialise the clock system */
390
391int s3c24xx_register_clock(struct clk *clk)
392{
393 clk->owner = THIS_MODULE;
394
395 if (clk->enable == NULL)
396 clk->enable = clk_null_enable;
397
398 /* add to the list of available clocks */
399
400 mutex_lock(&clocks_mutex);
401 list_add(&clk->list, &clocks);
402 mutex_unlock(&clocks_mutex);
403
404 return 0;
405}
406
407/* initalise all the clocks */
408
409int __init s3c24xx_setup_clocks(unsigned long xtal,
410 unsigned long fclk,
411 unsigned long hclk,
412 unsigned long pclk)
413{
414 printk(KERN_INFO "S3C24XX Clocks, (c) 2004 Simtec Electronics\n");
415
416 /* initialise the main system clocks */
417
418 clk_xtal.rate = xtal;
419 clk_upll.rate = s3c2410_get_pll(__raw_readl(S3C2410_UPLLCON), xtal);
420
421 clk_mpll.rate = fclk;
422 clk_h.rate = hclk;
423 clk_p.rate = pclk;
424 clk_f.rate = fclk;
425
426 /* assume uart clocks are correctly setup */
427
428 /* register our clocks */
429
430 if (s3c24xx_register_clock(&clk_xtal) < 0)
431 printk(KERN_ERR "failed to register master xtal\n");
432
433 if (s3c24xx_register_clock(&clk_mpll) < 0)
434 printk(KERN_ERR "failed to register mpll clock\n");
435
436 if (s3c24xx_register_clock(&clk_upll) < 0)
437 printk(KERN_ERR "failed to register upll clock\n");
438
439 if (s3c24xx_register_clock(&clk_f) < 0)
440 printk(KERN_ERR "failed to register cpu fclk\n");
441
442 if (s3c24xx_register_clock(&clk_h) < 0)
443 printk(KERN_ERR "failed to register cpu hclk\n");
444
445 if (s3c24xx_register_clock(&clk_p) < 0)
446 printk(KERN_ERR "failed to register cpu pclk\n");
447
448 return 0;
449}
diff --git a/arch/arm/mach-s3c2410/common-smdk.c b/arch/arm/plat-s3c24xx/common-smdk.c
index a40eaa656177..908efa7d745f 100644
--- a/arch/arm/mach-s3c2410/common-smdk.c
+++ b/arch/arm/plat-s3c24xx/common-smdk.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/common-smdk.c 1/* linux/arch/arm/plat-s3c24xx/common-smdk.c
2 * 2 *
3 * Copyright (c) 2006 Simtec Electronics 3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
@@ -38,9 +38,9 @@
38 38
39#include <asm/arch/nand.h> 39#include <asm/arch/nand.h>
40 40
41#include "common-smdk.h" 41#include <asm/plat-s3c24xx/common-smdk.h>
42#include "devs.h" 42#include <asm/plat-s3c24xx/devs.h>
43#include "pm.h" 43#include <asm/plat-s3c24xx/pm.h>
44 44
45/* LED devices */ 45/* LED devices */
46 46
diff --git a/arch/arm/mach-s3c2410/cpu.c b/arch/arm/plat-s3c24xx/cpu.c
index ae1f5bb63f7a..6a2d1070e5a0 100644
--- a/arch/arm/mach-s3c2410/cpu.c
+++ b/arch/arm/plat-s3c24xx/cpu.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/cpu.c 1/* linux/arch/arm/plat-s3c24xx/cpu.c
2 * 2 *
3 * Copyright (c) 2004-2005 Simtec Electronics 3 * Copyright (c) 2004-2005 Simtec Electronics
4 * http://www.simtec.co.uk/products/SWLINUX/ 4 * http://www.simtec.co.uk/products/SWLINUX/
@@ -40,15 +40,16 @@
40#include <asm/arch/regs-gpio.h> 40#include <asm/arch/regs-gpio.h>
41#include <asm/arch/regs-serial.h> 41#include <asm/arch/regs-serial.h>
42 42
43#include "cpu.h" 43#include <asm/plat-s3c24xx/cpu.h>
44#include "devs.h" 44#include <asm/plat-s3c24xx/devs.h>
45#include "clock.h" 45#include <asm/plat-s3c24xx/clock.h>
46#include "s3c2400.h" 46#include <asm/plat-s3c24xx/s3c2400.h>
47#include "s3c2410.h" 47#include <asm/plat-s3c24xx/s3c2410.h>
48#include "s3c2412.h" 48#include <asm/plat-s3c24xx/s3c2412.h>
49#include "s3c244x.h" 49#include "s3c244x.h"
50#include "s3c2440.h" 50#include <asm/plat-s3c24xx/s3c2440.h>
51#include "s3c2442.h" 51#include <asm/plat-s3c24xx/s3c2442.h>
52#include <asm/plat-s3c24xx/s3c2443.h>
52 53
53struct cpu_table { 54struct cpu_table {
54 unsigned long idcode; 55 unsigned long idcode;
@@ -67,6 +68,7 @@ static const char name_s3c2410[] = "S3C2410";
67static const char name_s3c2412[] = "S3C2412"; 68static const char name_s3c2412[] = "S3C2412";
68static const char name_s3c2440[] = "S3C2440"; 69static const char name_s3c2440[] = "S3C2440";
69static const char name_s3c2442[] = "S3C2442"; 70static const char name_s3c2442[] = "S3C2442";
71static const char name_s3c2443[] = "S3C2443";
70static const char name_s3c2410a[] = "S3C2410A"; 72static const char name_s3c2410a[] = "S3C2410A";
71static const char name_s3c2440a[] = "S3C2440A"; 73static const char name_s3c2440a[] = "S3C2440A";
72 74
@@ -135,6 +137,15 @@ static struct cpu_table cpu_ids[] __initdata = {
135 .name = name_s3c2412, 137 .name = name_s3c2412,
136 }, 138 },
137 { 139 {
140 .idcode = 0x32443001,
141 .idmask = 0xffffffff,
142 .map_io = s3c2443_map_io,
143 .init_clocks = s3c2443_init_clocks,
144 .init_uarts = s3c2443_init_uarts,
145 .init = s3c2443_init,
146 .name = name_s3c2443,
147 },
148 {
138 .idcode = 0x0, /* S3C2400 doesn't have an idcode */ 149 .idcode = 0x0, /* S3C2400 doesn't have an idcode */
139 .idmask = 0xffffffff, 150 .idmask = 0xffffffff,
140 .map_io = s3c2400_map_io, 151 .map_io = s3c2400_map_io,
diff --git a/arch/arm/mach-s3c2410/devs.c b/arch/arm/plat-s3c24xx/devs.c
index faccde2092d2..0fe53b39cb2f 100644
--- a/arch/arm/mach-s3c2410/devs.c
+++ b/arch/arm/plat-s3c24xx/devs.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/devs.c 1/* linux/arch/arm/plat-s3c24xx/devs.c
2 * 2 *
3 * Copyright (c) 2004 Simtec Electronics 3 * Copyright (c) 2004 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
@@ -29,9 +29,10 @@
29#include <asm/irq.h> 29#include <asm/irq.h>
30 30
31#include <asm/arch/regs-serial.h> 31#include <asm/arch/regs-serial.h>
32#include <asm/arch/udc.h>
32 33
33#include "devs.h" 34#include <asm/plat-s3c24xx/devs.h>
34#include "cpu.h" 35#include <asm/plat-s3c24xx/cpu.h>
35 36
36/* Serial port registrations */ 37/* Serial port registrations */
37 38
@@ -230,6 +231,20 @@ struct platform_device s3c_device_usbgadget = {
230 231
231EXPORT_SYMBOL(s3c_device_usbgadget); 232EXPORT_SYMBOL(s3c_device_usbgadget);
232 233
234void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *pd)
235{
236 struct s3c2410_udc_mach_info *npd;
237
238 npd = kmalloc(sizeof(*npd), GFP_KERNEL);
239 if (npd) {
240 memcpy(npd, pd, sizeof(*npd));
241 s3c_device_usbgadget.dev.platform_data = npd;
242 } else {
243 printk(KERN_ERR "no memory for udc platform data\n");
244 }
245}
246
247
233/* Watchdog */ 248/* Watchdog */
234 249
235static struct resource s3c_wdt_resource[] = { 250static struct resource s3c_wdt_resource[] = {
diff --git a/arch/arm/plat-s3c24xx/dma.c b/arch/arm/plat-s3c24xx/dma.c
new file mode 100644
index 000000000000..4540a806f522
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/dma.c
@@ -0,0 +1,1499 @@
1/* linux/arch/arm/plat-s3c24xx/dma.c
2 *
3 * Copyright (c) 2003-2005,2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2410 DMA core
7 *
8 * http://armlinux.simtec.co.uk/
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 version 2 as
12 * published by the Free Software Foundation.
13*/
14
15
16#ifdef CONFIG_S3C2410_DMA_DEBUG
17#define DEBUG
18#endif
19
20#include <linux/module.h>
21#include <linux/init.h>
22#include <linux/sched.h>
23#include <linux/spinlock.h>
24#include <linux/interrupt.h>
25#include <linux/sysdev.h>
26#include <linux/slab.h>
27#include <linux/errno.h>
28#include <linux/delay.h>
29
30#include <asm/system.h>
31#include <asm/irq.h>
32#include <asm/hardware.h>
33#include <asm/io.h>
34#include <asm/dma.h>
35
36#include <asm/mach/dma.h>
37#include <asm/arch/map.h>
38
39#include <asm/plat-s3c24xx/dma.h>
40
41/* io map for dma */
42static void __iomem *dma_base;
43static struct kmem_cache *dma_kmem;
44
45static int dma_channels;
46
47struct s3c24xx_dma_selection dma_sel;
48
49/* dma channel state information */
50struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];
51
52/* debugging functions */
53
54#define BUF_MAGIC (0xcafebabe)
55
56#define dmawarn(fmt...) printk(KERN_DEBUG fmt)
57
58#define dma_regaddr(chan, reg) ((chan)->regs + (reg))
59
60#if 1
61#define dma_wrreg(chan, reg, val) writel((val), (chan)->regs + (reg))
62#else
63static inline void
64dma_wrreg(struct s3c2410_dma_chan *chan, int reg, unsigned long val)
65{
66 pr_debug("writing %08x to register %08x\n",(unsigned int)val,reg);
67 writel(val, dma_regaddr(chan, reg));
68}
69#endif
70
71#define dma_rdreg(chan, reg) readl((chan)->regs + (reg))
72
73/* captured register state for debug */
74
75struct s3c2410_dma_regstate {
76 unsigned long dcsrc;
77 unsigned long disrc;
78 unsigned long dstat;
79 unsigned long dcon;
80 unsigned long dmsktrig;
81};
82
83#ifdef CONFIG_S3C2410_DMA_DEBUG
84
85/* dmadbg_showregs
86 *
87 * simple debug routine to print the current state of the dma registers
88*/
89
90static void
91dmadbg_capture(struct s3c2410_dma_chan *chan, struct s3c2410_dma_regstate *regs)
92{
93 regs->dcsrc = dma_rdreg(chan, S3C2410_DMA_DCSRC);
94 regs->disrc = dma_rdreg(chan, S3C2410_DMA_DISRC);
95 regs->dstat = dma_rdreg(chan, S3C2410_DMA_DSTAT);
96 regs->dcon = dma_rdreg(chan, S3C2410_DMA_DCON);
97 regs->dmsktrig = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
98}
99
100static void
101dmadbg_dumpregs(const char *fname, int line, struct s3c2410_dma_chan *chan,
102 struct s3c2410_dma_regstate *regs)
103{
104 printk(KERN_DEBUG "dma%d: %s:%d: DCSRC=%08lx, DISRC=%08lx, DSTAT=%08lx DMT=%02lx, DCON=%08lx\n",
105 chan->number, fname, line,
106 regs->dcsrc, regs->disrc, regs->dstat, regs->dmsktrig,
107 regs->dcon);
108}
109
110static void
111dmadbg_showchan(const char *fname, int line, struct s3c2410_dma_chan *chan)
112{
113 struct s3c2410_dma_regstate state;
114
115 dmadbg_capture(chan, &state);
116
117 printk(KERN_DEBUG "dma%d: %s:%d: ls=%d, cur=%p, %p %p\n",
118 chan->number, fname, line, chan->load_state,
119 chan->curr, chan->next, chan->end);
120
121 dmadbg_dumpregs(fname, line, chan, &state);
122}
123
124static void
125dmadbg_showregs(const char *fname, int line, struct s3c2410_dma_chan *chan)
126{
127 struct s3c2410_dma_regstate state;
128
129 dmadbg_capture(chan, &state);
130 dmadbg_dumpregs(fname, line, chan, &state);
131}
132
133#define dbg_showregs(chan) dmadbg_showregs(__FUNCTION__, __LINE__, (chan))
134#define dbg_showchan(chan) dmadbg_showchan(__FUNCTION__, __LINE__, (chan))
135#else
136#define dbg_showregs(chan) do { } while(0)
137#define dbg_showchan(chan) do { } while(0)
138#endif /* CONFIG_S3C2410_DMA_DEBUG */
139
140static struct s3c2410_dma_chan *dma_chan_map[DMACH_MAX];
141
142/* lookup_dma_channel
143 *
144 * change the dma channel number given into a real dma channel id
145*/
146
147static struct s3c2410_dma_chan *lookup_dma_channel(unsigned int channel)
148{
149 if (channel & DMACH_LOW_LEVEL)
150 return &s3c2410_chans[channel & ~DMACH_LOW_LEVEL];
151 else
152 return dma_chan_map[channel];
153}
154
155/* s3c2410_dma_stats_timeout
156 *
157 * Update DMA stats from timeout info
158*/
159
160static void
161s3c2410_dma_stats_timeout(struct s3c2410_dma_stats *stats, int val)
162{
163 if (stats == NULL)
164 return;
165
166 if (val > stats->timeout_longest)
167 stats->timeout_longest = val;
168 if (val < stats->timeout_shortest)
169 stats->timeout_shortest = val;
170
171 stats->timeout_avg += val;
172}
173
174/* s3c2410_dma_waitforload
175 *
176 * wait for the DMA engine to load a buffer, and update the state accordingly
177*/
178
179static int
180s3c2410_dma_waitforload(struct s3c2410_dma_chan *chan, int line)
181{
182 int timeout = chan->load_timeout;
183 int took;
184
185 if (chan->load_state != S3C2410_DMALOAD_1LOADED) {
186 printk(KERN_ERR "dma%d: s3c2410_dma_waitforload() called in loadstate %d from line %d\n", chan->number, chan->load_state, line);
187 return 0;
188 }
189
190 if (chan->stats != NULL)
191 chan->stats->loads++;
192
193 while (--timeout > 0) {
194 if ((dma_rdreg(chan, S3C2410_DMA_DSTAT) << (32-20)) != 0) {
195 took = chan->load_timeout - timeout;
196
197 s3c2410_dma_stats_timeout(chan->stats, took);
198
199 switch (chan->load_state) {
200 case S3C2410_DMALOAD_1LOADED:
201 chan->load_state = S3C2410_DMALOAD_1RUNNING;
202 break;
203
204 default:
205 printk(KERN_ERR "dma%d: unknown load_state in s3c2410_dma_waitforload() %d\n", chan->number, chan->load_state);
206 }
207
208 return 1;
209 }
210 }
211
212 if (chan->stats != NULL) {
213 chan->stats->timeout_failed++;
214 }
215
216 return 0;
217}
218
219
220
221/* s3c2410_dma_loadbuffer
222 *
223 * load a buffer, and update the channel state
224*/
225
226static inline int
227s3c2410_dma_loadbuffer(struct s3c2410_dma_chan *chan,
228 struct s3c2410_dma_buf *buf)
229{
230 unsigned long reload;
231
232 pr_debug("s3c2410_chan_loadbuffer: loading buff %p (0x%08lx,0x%06x)\n",
233 buf, (unsigned long)buf->data, buf->size);
234
235 if (buf == NULL) {
236 dmawarn("buffer is NULL\n");
237 return -EINVAL;
238 }
239
240 /* check the state of the channel before we do anything */
241
242 if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
243 dmawarn("load_state is S3C2410_DMALOAD_1LOADED\n");
244 }
245
246 if (chan->load_state == S3C2410_DMALOAD_1LOADED_1RUNNING) {
247 dmawarn("state is S3C2410_DMALOAD_1LOADED_1RUNNING\n");
248 }
249
250 /* it would seem sensible if we are the last buffer to not bother
251 * with the auto-reload bit, so that the DMA engine will not try
252 * and load another transfer after this one has finished...
253 */
254 if (chan->load_state == S3C2410_DMALOAD_NONE) {
255 pr_debug("load_state is none, checking for noreload (next=%p)\n",
256 buf->next);
257 reload = (buf->next == NULL) ? S3C2410_DCON_NORELOAD : 0;
258 } else {
259 //pr_debug("load_state is %d => autoreload\n", chan->load_state);
260 reload = S3C2410_DCON_AUTORELOAD;
261 }
262
263 if ((buf->data & 0xf0000000) != 0x30000000) {
264 dmawarn("dmaload: buffer is %p\n", (void *)buf->data);
265 }
266
267 writel(buf->data, chan->addr_reg);
268
269 dma_wrreg(chan, S3C2410_DMA_DCON,
270 chan->dcon | reload | (buf->size/chan->xfer_unit));
271
272 chan->next = buf->next;
273
274 /* update the state of the channel */
275
276 switch (chan->load_state) {
277 case S3C2410_DMALOAD_NONE:
278 chan->load_state = S3C2410_DMALOAD_1LOADED;
279 break;
280
281 case S3C2410_DMALOAD_1RUNNING:
282 chan->load_state = S3C2410_DMALOAD_1LOADED_1RUNNING;
283 break;
284
285 default:
286 dmawarn("dmaload: unknown state %d in loadbuffer\n",
287 chan->load_state);
288 break;
289 }
290
291 return 0;
292}
293
294/* s3c2410_dma_call_op
295 *
296 * small routine to call the op routine with the given op if it has been
297 * registered
298*/
299
300static void
301s3c2410_dma_call_op(struct s3c2410_dma_chan *chan, enum s3c2410_chan_op op)
302{
303 if (chan->op_fn != NULL) {
304 (chan->op_fn)(chan, op);
305 }
306}
307
308/* s3c2410_dma_buffdone
309 *
310 * small wrapper to check if callback routine needs to be called, and
311 * if so, call it
312*/
313
314static inline void
315s3c2410_dma_buffdone(struct s3c2410_dma_chan *chan, struct s3c2410_dma_buf *buf,
316 enum s3c2410_dma_buffresult result)
317{
318#if 0
319 pr_debug("callback_fn=%p, buf=%p, id=%p, size=%d, result=%d\n",
320 chan->callback_fn, buf, buf->id, buf->size, result);
321#endif
322
323 if (chan->callback_fn != NULL) {
324 (chan->callback_fn)(chan, buf->id, buf->size, result);
325 }
326}
327
328/* s3c2410_dma_start
329 *
330 * start a dma channel going
331*/
332
333static int s3c2410_dma_start(struct s3c2410_dma_chan *chan)
334{
335 unsigned long tmp;
336 unsigned long flags;
337
338 pr_debug("s3c2410_start_dma: channel=%d\n", chan->number);
339
340 local_irq_save(flags);
341
342 if (chan->state == S3C2410_DMA_RUNNING) {
343 pr_debug("s3c2410_start_dma: already running (%d)\n", chan->state);
344 local_irq_restore(flags);
345 return 0;
346 }
347
348 chan->state = S3C2410_DMA_RUNNING;
349
350 /* check wether there is anything to load, and if not, see
351 * if we can find anything to load
352 */
353
354 if (chan->load_state == S3C2410_DMALOAD_NONE) {
355 if (chan->next == NULL) {
356 printk(KERN_ERR "dma%d: channel has nothing loaded\n",
357 chan->number);
358 chan->state = S3C2410_DMA_IDLE;
359 local_irq_restore(flags);
360 return -EINVAL;
361 }
362
363 s3c2410_dma_loadbuffer(chan, chan->next);
364 }
365
366 dbg_showchan(chan);
367
368 /* enable the channel */
369
370 if (!chan->irq_enabled) {
371 enable_irq(chan->irq);
372 chan->irq_enabled = 1;
373 }
374
375 /* start the channel going */
376
377 tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
378 tmp &= ~S3C2410_DMASKTRIG_STOP;
379 tmp |= S3C2410_DMASKTRIG_ON;
380 dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
381
382 pr_debug("dma%d: %08lx to DMASKTRIG\n", chan->number, tmp);
383
384#if 0
385 /* the dma buffer loads should take care of clearing the AUTO
386 * reloading feature */
387 tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
388 tmp &= ~S3C2410_DCON_NORELOAD;
389 dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
390#endif
391
392 s3c2410_dma_call_op(chan, S3C2410_DMAOP_START);
393
394 dbg_showchan(chan);
395
396 /* if we've only loaded one buffer onto the channel, then chec
397 * to see if we have another, and if so, try and load it so when
398 * the first buffer is finished, the new one will be loaded onto
399 * the channel */
400
401 if (chan->next != NULL) {
402 if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
403
404 if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
405 pr_debug("%s: buff not yet loaded, no more todo\n",
406 __FUNCTION__);
407 } else {
408 chan->load_state = S3C2410_DMALOAD_1RUNNING;
409 s3c2410_dma_loadbuffer(chan, chan->next);
410 }
411
412 } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
413 s3c2410_dma_loadbuffer(chan, chan->next);
414 }
415 }
416
417
418 local_irq_restore(flags);
419
420 return 0;
421}
422
423/* s3c2410_dma_canload
424 *
425 * work out if we can queue another buffer into the DMA engine
426*/
427
428static int
429s3c2410_dma_canload(struct s3c2410_dma_chan *chan)
430{
431 if (chan->load_state == S3C2410_DMALOAD_NONE ||
432 chan->load_state == S3C2410_DMALOAD_1RUNNING)
433 return 1;
434
435 return 0;
436}
437
438/* s3c2410_dma_enqueue
439 *
440 * queue an given buffer for dma transfer.
441 *
442 * id the device driver's id information for this buffer
443 * data the physical address of the buffer data
444 * size the size of the buffer in bytes
445 *
446 * If the channel is not running, then the flag S3C2410_DMAF_AUTOSTART
447 * is checked, and if set, the channel is started. If this flag isn't set,
448 * then an error will be returned.
449 *
450 * It is possible to queue more than one DMA buffer onto a channel at
451 * once, and the code will deal with the re-loading of the next buffer
452 * when necessary.
453*/
454
455int s3c2410_dma_enqueue(unsigned int channel, void *id,
456 dma_addr_t data, int size)
457{
458 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
459 struct s3c2410_dma_buf *buf;
460 unsigned long flags;
461
462 if (chan == NULL)
463 return -EINVAL;
464
465 pr_debug("%s: id=%p, data=%08x, size=%d\n",
466 __FUNCTION__, id, (unsigned int)data, size);
467
468 buf = kmem_cache_alloc(dma_kmem, GFP_ATOMIC);
469 if (buf == NULL) {
470 pr_debug("%s: out of memory (%ld alloc)\n",
471 __FUNCTION__, (long)sizeof(*buf));
472 return -ENOMEM;
473 }
474
475 //pr_debug("%s: new buffer %p\n", __FUNCTION__, buf);
476 //dbg_showchan(chan);
477
478 buf->next = NULL;
479 buf->data = buf->ptr = data;
480 buf->size = size;
481 buf->id = id;
482 buf->magic = BUF_MAGIC;
483
484 local_irq_save(flags);
485
486 if (chan->curr == NULL) {
487 /* we've got nothing loaded... */
488 pr_debug("%s: buffer %p queued onto empty channel\n",
489 __FUNCTION__, buf);
490
491 chan->curr = buf;
492 chan->end = buf;
493 chan->next = NULL;
494 } else {
495 pr_debug("dma%d: %s: buffer %p queued onto non-empty channel\n",
496 chan->number, __FUNCTION__, buf);
497
498 if (chan->end == NULL)
499 pr_debug("dma%d: %s: %p not empty, and chan->end==NULL?\n",
500 chan->number, __FUNCTION__, chan);
501
502 chan->end->next = buf;
503 chan->end = buf;
504 }
505
506 /* if necessary, update the next buffer field */
507 if (chan->next == NULL)
508 chan->next = buf;
509
510 /* check to see if we can load a buffer */
511 if (chan->state == S3C2410_DMA_RUNNING) {
512 if (chan->load_state == S3C2410_DMALOAD_1LOADED && 1) {
513 if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
514 printk(KERN_ERR "dma%d: loadbuffer:"
515 "timeout loading buffer\n",
516 chan->number);
517 dbg_showchan(chan);
518 local_irq_restore(flags);
519 return -EINVAL;
520 }
521 }
522
523 while (s3c2410_dma_canload(chan) && chan->next != NULL) {
524 s3c2410_dma_loadbuffer(chan, chan->next);
525 }
526 } else if (chan->state == S3C2410_DMA_IDLE) {
527 if (chan->flags & S3C2410_DMAF_AUTOSTART) {
528 s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_START);
529 }
530 }
531
532 local_irq_restore(flags);
533 return 0;
534}
535
536EXPORT_SYMBOL(s3c2410_dma_enqueue);
537
538static inline void
539s3c2410_dma_freebuf(struct s3c2410_dma_buf *buf)
540{
541 int magicok = (buf->magic == BUF_MAGIC);
542
543 buf->magic = -1;
544
545 if (magicok) {
546 kmem_cache_free(dma_kmem, buf);
547 } else {
548 printk("s3c2410_dma_freebuf: buff %p with bad magic\n", buf);
549 }
550}
551
552/* s3c2410_dma_lastxfer
553 *
554 * called when the system is out of buffers, to ensure that the channel
555 * is prepared for shutdown.
556*/
557
558static inline void
559s3c2410_dma_lastxfer(struct s3c2410_dma_chan *chan)
560{
561#if 0
562 pr_debug("dma%d: s3c2410_dma_lastxfer: load_state %d\n",
563 chan->number, chan->load_state);
564#endif
565
566 switch (chan->load_state) {
567 case S3C2410_DMALOAD_NONE:
568 break;
569
570 case S3C2410_DMALOAD_1LOADED:
571 if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
572 /* flag error? */
573 printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
574 chan->number, __FUNCTION__);
575 return;
576 }
577 break;
578
579 case S3C2410_DMALOAD_1LOADED_1RUNNING:
580 /* I belive in this case we do not have anything to do
581 * until the next buffer comes along, and we turn off the
582 * reload */
583 return;
584
585 default:
586 pr_debug("dma%d: lastxfer: unhandled load_state %d with no next\n",
587 chan->number, chan->load_state);
588 return;
589
590 }
591
592 /* hopefully this'll shut the damned thing up after the transfer... */
593 dma_wrreg(chan, S3C2410_DMA_DCON, chan->dcon | S3C2410_DCON_NORELOAD);
594}
595
596
597#define dmadbg2(x...)
598
599static irqreturn_t
600s3c2410_dma_irq(int irq, void *devpw)
601{
602 struct s3c2410_dma_chan *chan = (struct s3c2410_dma_chan *)devpw;
603 struct s3c2410_dma_buf *buf;
604
605 buf = chan->curr;
606
607 dbg_showchan(chan);
608
609 /* modify the channel state */
610
611 switch (chan->load_state) {
612 case S3C2410_DMALOAD_1RUNNING:
613 /* TODO - if we are running only one buffer, we probably
614 * want to reload here, and then worry about the buffer
615 * callback */
616
617 chan->load_state = S3C2410_DMALOAD_NONE;
618 break;
619
620 case S3C2410_DMALOAD_1LOADED:
621 /* iirc, we should go back to NONE loaded here, we
622 * had a buffer, and it was never verified as being
623 * loaded.
624 */
625
626 chan->load_state = S3C2410_DMALOAD_NONE;
627 break;
628
629 case S3C2410_DMALOAD_1LOADED_1RUNNING:
630 /* we'll worry about checking to see if another buffer is
631 * ready after we've called back the owner. This should
632 * ensure we do not wait around too long for the DMA
633 * engine to start the next transfer
634 */
635
636 chan->load_state = S3C2410_DMALOAD_1LOADED;
637 break;
638
639 case S3C2410_DMALOAD_NONE:
640 printk(KERN_ERR "dma%d: IRQ with no loaded buffer?\n",
641 chan->number);
642 break;
643
644 default:
645 printk(KERN_ERR "dma%d: IRQ in invalid load_state %d\n",
646 chan->number, chan->load_state);
647 break;
648 }
649
650 if (buf != NULL) {
651 /* update the chain to make sure that if we load any more
652 * buffers when we call the callback function, things should
653 * work properly */
654
655 chan->curr = buf->next;
656 buf->next = NULL;
657
658 if (buf->magic != BUF_MAGIC) {
659 printk(KERN_ERR "dma%d: %s: buf %p incorrect magic\n",
660 chan->number, __FUNCTION__, buf);
661 return IRQ_HANDLED;
662 }
663
664 s3c2410_dma_buffdone(chan, buf, S3C2410_RES_OK);
665
666 /* free resouces */
667 s3c2410_dma_freebuf(buf);
668 } else {
669 }
670
671 /* only reload if the channel is still running... our buffer done
672 * routine may have altered the state by requesting the dma channel
673 * to stop or shutdown... */
674
675 /* todo: check that when the channel is shut-down from inside this
676 * function, we cope with unsetting reload, etc */
677
678 if (chan->next != NULL && chan->state != S3C2410_DMA_IDLE) {
679 unsigned long flags;
680
681 switch (chan->load_state) {
682 case S3C2410_DMALOAD_1RUNNING:
683 /* don't need to do anything for this state */
684 break;
685
686 case S3C2410_DMALOAD_NONE:
687 /* can load buffer immediately */
688 break;
689
690 case S3C2410_DMALOAD_1LOADED:
691 if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
692 /* flag error? */
693 printk(KERN_ERR "dma%d: timeout waiting for load (%s)\n",
694 chan->number, __FUNCTION__);
695 return IRQ_HANDLED;
696 }
697
698 break;
699
700 case S3C2410_DMALOAD_1LOADED_1RUNNING:
701 goto no_load;
702
703 default:
704 printk(KERN_ERR "dma%d: unknown load_state in irq, %d\n",
705 chan->number, chan->load_state);
706 return IRQ_HANDLED;
707 }
708
709 local_irq_save(flags);
710 s3c2410_dma_loadbuffer(chan, chan->next);
711 local_irq_restore(flags);
712 } else {
713 s3c2410_dma_lastxfer(chan);
714
715 /* see if we can stop this channel.. */
716 if (chan->load_state == S3C2410_DMALOAD_NONE) {
717 pr_debug("dma%d: end of transfer, stopping channel (%ld)\n",
718 chan->number, jiffies);
719 s3c2410_dma_ctrl(chan->number | DMACH_LOW_LEVEL,
720 S3C2410_DMAOP_STOP);
721 }
722 }
723
724 no_load:
725 return IRQ_HANDLED;
726}
727
728static struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel);
729
730/* s3c2410_request_dma
731 *
732 * get control of an dma channel
733*/
734
735int s3c2410_dma_request(unsigned int channel,
736 struct s3c2410_dma_client *client,
737 void *dev)
738{
739 struct s3c2410_dma_chan *chan;
740 unsigned long flags;
741 int err;
742
743 pr_debug("dma%d: s3c2410_request_dma: client=%s, dev=%p\n",
744 channel, client->name, dev);
745
746 local_irq_save(flags);
747
748 chan = s3c2410_dma_map_channel(channel);
749 if (chan == NULL) {
750 local_irq_restore(flags);
751 return -EBUSY;
752 }
753
754 dbg_showchan(chan);
755
756 chan->client = client;
757 chan->in_use = 1;
758
759 if (!chan->irq_claimed) {
760 pr_debug("dma%d: %s : requesting irq %d\n",
761 channel, __FUNCTION__, chan->irq);
762
763 chan->irq_claimed = 1;
764 local_irq_restore(flags);
765
766 err = request_irq(chan->irq, s3c2410_dma_irq, IRQF_DISABLED,
767 client->name, (void *)chan);
768
769 local_irq_save(flags);
770
771 if (err) {
772 chan->in_use = 0;
773 chan->irq_claimed = 0;
774 local_irq_restore(flags);
775
776 printk(KERN_ERR "%s: cannot get IRQ %d for DMA %d\n",
777 client->name, chan->irq, chan->number);
778 return err;
779 }
780
781 chan->irq_enabled = 1;
782 }
783
784 local_irq_restore(flags);
785
786 /* need to setup */
787
788 pr_debug("%s: channel initialised, %p\n", __FUNCTION__, chan);
789
790 return 0;
791}
792
793EXPORT_SYMBOL(s3c2410_dma_request);
794
795/* s3c2410_dma_free
796 *
797 * release the given channel back to the system, will stop and flush
798 * any outstanding transfers, and ensure the channel is ready for the
799 * next claimant.
800 *
801 * Note, although a warning is currently printed if the freeing client
802 * info is not the same as the registrant's client info, the free is still
803 * allowed to go through.
804*/
805
806int s3c2410_dma_free(dmach_t channel, struct s3c2410_dma_client *client)
807{
808 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
809 unsigned long flags;
810
811 if (chan == NULL)
812 return -EINVAL;
813
814 local_irq_save(flags);
815
816 if (chan->client != client) {
817 printk(KERN_WARNING "dma%d: possible free from different client (channel %p, passed %p)\n",
818 channel, chan->client, client);
819 }
820
821 /* sort out stopping and freeing the channel */
822
823 if (chan->state != S3C2410_DMA_IDLE) {
824 pr_debug("%s: need to stop dma channel %p\n",
825 __FUNCTION__, chan);
826
827 /* possibly flush the channel */
828 s3c2410_dma_ctrl(channel, S3C2410_DMAOP_STOP);
829 }
830
831 chan->client = NULL;
832 chan->in_use = 0;
833
834 if (chan->irq_claimed)
835 free_irq(chan->irq, (void *)chan);
836
837 chan->irq_claimed = 0;
838
839 if (!(channel & DMACH_LOW_LEVEL))
840 dma_chan_map[channel] = NULL;
841
842 local_irq_restore(flags);
843
844 return 0;
845}
846
847EXPORT_SYMBOL(s3c2410_dma_free);
848
849static int s3c2410_dma_dostop(struct s3c2410_dma_chan *chan)
850{
851 unsigned long flags;
852 unsigned long tmp;
853
854 pr_debug("%s:\n", __FUNCTION__);
855
856 dbg_showchan(chan);
857
858 local_irq_save(flags);
859
860 s3c2410_dma_call_op(chan, S3C2410_DMAOP_STOP);
861
862 tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
863 tmp |= S3C2410_DMASKTRIG_STOP;
864 //tmp &= ~S3C2410_DMASKTRIG_ON;
865 dma_wrreg(chan, S3C2410_DMA_DMASKTRIG, tmp);
866
867#if 0
868 /* should also clear interrupts, according to WinCE BSP */
869 tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
870 tmp |= S3C2410_DCON_NORELOAD;
871 dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
872#endif
873
874 /* should stop do this, or should we wait for flush? */
875 chan->state = S3C2410_DMA_IDLE;
876 chan->load_state = S3C2410_DMALOAD_NONE;
877
878 local_irq_restore(flags);
879
880 return 0;
881}
882
883void s3c2410_dma_waitforstop(struct s3c2410_dma_chan *chan)
884{
885 unsigned long tmp;
886 unsigned int timeout = 0x10000;
887
888 while (timeout-- > 0) {
889 tmp = dma_rdreg(chan, S3C2410_DMA_DMASKTRIG);
890
891 if (!(tmp & S3C2410_DMASKTRIG_ON))
892 return;
893 }
894
895 pr_debug("dma%d: failed to stop?\n", chan->number);
896}
897
898
899/* s3c2410_dma_flush
900 *
901 * stop the channel, and remove all current and pending transfers
902*/
903
904static int s3c2410_dma_flush(struct s3c2410_dma_chan *chan)
905{
906 struct s3c2410_dma_buf *buf, *next;
907 unsigned long flags;
908
909 pr_debug("%s: chan %p (%d)\n", __FUNCTION__, chan, chan->number);
910
911 dbg_showchan(chan);
912
913 local_irq_save(flags);
914
915 if (chan->state != S3C2410_DMA_IDLE) {
916 pr_debug("%s: stopping channel...\n", __FUNCTION__ );
917 s3c2410_dma_ctrl(chan->number, S3C2410_DMAOP_STOP);
918 }
919
920 buf = chan->curr;
921 if (buf == NULL)
922 buf = chan->next;
923
924 chan->curr = chan->next = chan->end = NULL;
925
926 if (buf != NULL) {
927 for ( ; buf != NULL; buf = next) {
928 next = buf->next;
929
930 pr_debug("%s: free buffer %p, next %p\n",
931 __FUNCTION__, buf, buf->next);
932
933 s3c2410_dma_buffdone(chan, buf, S3C2410_RES_ABORT);
934 s3c2410_dma_freebuf(buf);
935 }
936 }
937
938 dbg_showregs(chan);
939
940 s3c2410_dma_waitforstop(chan);
941
942#if 0
943 /* should also clear interrupts, according to WinCE BSP */
944 {
945 unsigned long tmp;
946
947 tmp = dma_rdreg(chan, S3C2410_DMA_DCON);
948 tmp |= S3C2410_DCON_NORELOAD;
949 dma_wrreg(chan, S3C2410_DMA_DCON, tmp);
950 }
951#endif
952
953 dbg_showregs(chan);
954
955 local_irq_restore(flags);
956
957 return 0;
958}
959
960int
961s3c2410_dma_started(struct s3c2410_dma_chan *chan)
962{
963 unsigned long flags;
964
965 local_irq_save(flags);
966
967 dbg_showchan(chan);
968
969 /* if we've only loaded one buffer onto the channel, then chec
970 * to see if we have another, and if so, try and load it so when
971 * the first buffer is finished, the new one will be loaded onto
972 * the channel */
973
974 if (chan->next != NULL) {
975 if (chan->load_state == S3C2410_DMALOAD_1LOADED) {
976
977 if (s3c2410_dma_waitforload(chan, __LINE__) == 0) {
978 pr_debug("%s: buff not yet loaded, no more todo\n",
979 __FUNCTION__);
980 } else {
981 chan->load_state = S3C2410_DMALOAD_1RUNNING;
982 s3c2410_dma_loadbuffer(chan, chan->next);
983 }
984
985 } else if (chan->load_state == S3C2410_DMALOAD_1RUNNING) {
986 s3c2410_dma_loadbuffer(chan, chan->next);
987 }
988 }
989
990
991 local_irq_restore(flags);
992
993 return 0;
994
995}
996
997int
998s3c2410_dma_ctrl(dmach_t channel, enum s3c2410_chan_op op)
999{
1000 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
1001
1002 if (chan == NULL)
1003 return -EINVAL;
1004
1005 switch (op) {
1006 case S3C2410_DMAOP_START:
1007 return s3c2410_dma_start(chan);
1008
1009 case S3C2410_DMAOP_STOP:
1010 return s3c2410_dma_dostop(chan);
1011
1012 case S3C2410_DMAOP_PAUSE:
1013 case S3C2410_DMAOP_RESUME:
1014 return -ENOENT;
1015
1016 case S3C2410_DMAOP_FLUSH:
1017 return s3c2410_dma_flush(chan);
1018
1019 case S3C2410_DMAOP_STARTED:
1020 return s3c2410_dma_started(chan);
1021
1022 case S3C2410_DMAOP_TIMEOUT:
1023 return 0;
1024
1025 }
1026
1027 return -ENOENT; /* unknown, don't bother */
1028}
1029
1030EXPORT_SYMBOL(s3c2410_dma_ctrl);
1031
1032/* DMA configuration for each channel
1033 *
1034 * DISRCC -> source of the DMA (AHB,APB)
1035 * DISRC -> source address of the DMA
1036 * DIDSTC -> destination of the DMA (AHB,APD)
1037 * DIDST -> destination address of the DMA
1038*/
1039
1040/* s3c2410_dma_config
1041 *
1042 * xfersize: size of unit in bytes (1,2,4)
1043 * dcon: base value of the DCONx register
1044*/
1045
1046int s3c2410_dma_config(dmach_t channel,
1047 int xferunit,
1048 int dcon)
1049{
1050 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
1051
1052 pr_debug("%s: chan=%d, xfer_unit=%d, dcon=%08x\n",
1053 __FUNCTION__, channel, xferunit, dcon);
1054
1055 if (chan == NULL)
1056 return -EINVAL;
1057
1058 pr_debug("%s: Initial dcon is %08x\n", __FUNCTION__, dcon);
1059
1060 dcon |= chan->dcon & dma_sel.dcon_mask;
1061
1062 pr_debug("%s: New dcon is %08x\n", __FUNCTION__, dcon);
1063
1064 switch (xferunit) {
1065 case 1:
1066 dcon |= S3C2410_DCON_BYTE;
1067 break;
1068
1069 case 2:
1070 dcon |= S3C2410_DCON_HALFWORD;
1071 break;
1072
1073 case 4:
1074 dcon |= S3C2410_DCON_WORD;
1075 break;
1076
1077 default:
1078 pr_debug("%s: bad transfer size %d\n", __FUNCTION__, xferunit);
1079 return -EINVAL;
1080 }
1081
1082 dcon |= S3C2410_DCON_HWTRIG;
1083 dcon |= S3C2410_DCON_INTREQ;
1084
1085 pr_debug("%s: dcon now %08x\n", __FUNCTION__, dcon);
1086
1087 chan->dcon = dcon;
1088 chan->xfer_unit = xferunit;
1089
1090 return 0;
1091}
1092
1093EXPORT_SYMBOL(s3c2410_dma_config);
1094
1095int s3c2410_dma_setflags(dmach_t channel, unsigned int flags)
1096{
1097 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
1098
1099 if (chan == NULL)
1100 return -EINVAL;
1101
1102 pr_debug("%s: chan=%p, flags=%08x\n", __FUNCTION__, chan, flags);
1103
1104 chan->flags = flags;
1105
1106 return 0;
1107}
1108
1109EXPORT_SYMBOL(s3c2410_dma_setflags);
1110
1111
1112/* do we need to protect the settings of the fields from
1113 * irq?
1114*/
1115
1116int s3c2410_dma_set_opfn(dmach_t channel, s3c2410_dma_opfn_t rtn)
1117{
1118 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
1119
1120 if (chan == NULL)
1121 return -EINVAL;
1122
1123 pr_debug("%s: chan=%p, op rtn=%p\n", __FUNCTION__, chan, rtn);
1124
1125 chan->op_fn = rtn;
1126
1127 return 0;
1128}
1129
1130EXPORT_SYMBOL(s3c2410_dma_set_opfn);
1131
1132int s3c2410_dma_set_buffdone_fn(dmach_t channel, s3c2410_dma_cbfn_t rtn)
1133{
1134 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
1135
1136 if (chan == NULL)
1137 return -EINVAL;
1138
1139 pr_debug("%s: chan=%p, callback rtn=%p\n", __FUNCTION__, chan, rtn);
1140
1141 chan->callback_fn = rtn;
1142
1143 return 0;
1144}
1145
1146EXPORT_SYMBOL(s3c2410_dma_set_buffdone_fn);
1147
1148/* s3c2410_dma_devconfig
1149 *
1150 * configure the dma source/destination hardware type and address
1151 *
1152 * source: S3C2410_DMASRC_HW: source is hardware
1153 * S3C2410_DMASRC_MEM: source is memory
1154 *
1155 * hwcfg: the value for xxxSTCn register,
1156 * bit 0: 0=increment pointer, 1=leave pointer
1157 * bit 1: 0=soucre is AHB, 1=soucre is APB
1158 *
1159 * devaddr: physical address of the source
1160*/
1161
1162int s3c2410_dma_devconfig(int channel,
1163 enum s3c2410_dmasrc source,
1164 int hwcfg,
1165 unsigned long devaddr)
1166{
1167 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
1168
1169 if (chan == NULL)
1170 return -EINVAL;
1171
1172 pr_debug("%s: source=%d, hwcfg=%08x, devaddr=%08lx\n",
1173 __FUNCTION__, (int)source, hwcfg, devaddr);
1174
1175 chan->source = source;
1176 chan->dev_addr = devaddr;
1177
1178 switch (source) {
1179 case S3C2410_DMASRC_HW:
1180 /* source is hardware */
1181 pr_debug("%s: hw source, devaddr=%08lx, hwcfg=%d\n",
1182 __FUNCTION__, devaddr, hwcfg);
1183 dma_wrreg(chan, S3C2410_DMA_DISRCC, hwcfg & 3);
1184 dma_wrreg(chan, S3C2410_DMA_DISRC, devaddr);
1185 dma_wrreg(chan, S3C2410_DMA_DIDSTC, (0<<1) | (0<<0));
1186
1187 chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DIDST);
1188 return 0;
1189
1190 case S3C2410_DMASRC_MEM:
1191 /* source is memory */
1192 pr_debug( "%s: mem source, devaddr=%08lx, hwcfg=%d\n",
1193 __FUNCTION__, devaddr, hwcfg);
1194 dma_wrreg(chan, S3C2410_DMA_DISRCC, (0<<1) | (0<<0));
1195 dma_wrreg(chan, S3C2410_DMA_DIDST, devaddr);
1196 dma_wrreg(chan, S3C2410_DMA_DIDSTC, hwcfg & 3);
1197
1198 chan->addr_reg = dma_regaddr(chan, S3C2410_DMA_DISRC);
1199 return 0;
1200 }
1201
1202 printk(KERN_ERR "dma%d: invalid source type (%d)\n", channel, source);
1203 return -EINVAL;
1204}
1205
1206EXPORT_SYMBOL(s3c2410_dma_devconfig);
1207
1208/* s3c2410_dma_getposition
1209 *
1210 * returns the current transfer points for the dma source and destination
1211*/
1212
1213int s3c2410_dma_getposition(dmach_t channel, dma_addr_t *src, dma_addr_t *dst)
1214{
1215 struct s3c2410_dma_chan *chan = lookup_dma_channel(channel);
1216
1217 if (chan == NULL)
1218 return -EINVAL;
1219
1220 if (src != NULL)
1221 *src = dma_rdreg(chan, S3C2410_DMA_DCSRC);
1222
1223 if (dst != NULL)
1224 *dst = dma_rdreg(chan, S3C2410_DMA_DCDST);
1225
1226 return 0;
1227}
1228
1229EXPORT_SYMBOL(s3c2410_dma_getposition);
1230
1231
1232/* system device class */
1233
1234#ifdef CONFIG_PM
1235
1236static int s3c2410_dma_suspend(struct sys_device *dev, pm_message_t state)
1237{
1238 struct s3c2410_dma_chan *cp = container_of(dev, struct s3c2410_dma_chan, dev);
1239
1240 printk(KERN_DEBUG "suspending dma channel %d\n", cp->number);
1241
1242 if (dma_rdreg(cp, S3C2410_DMA_DMASKTRIG) & S3C2410_DMASKTRIG_ON) {
1243 /* the dma channel is still working, which is probably
1244 * a bad thing to do over suspend/resume. We stop the
1245 * channel and assume that the client is either going to
1246 * retry after resume, or that it is broken.
1247 */
1248
1249 printk(KERN_INFO "dma: stopping channel %d due to suspend\n",
1250 cp->number);
1251
1252 s3c2410_dma_dostop(cp);
1253 }
1254
1255 return 0;
1256}
1257
1258static int s3c2410_dma_resume(struct sys_device *dev)
1259{
1260 return 0;
1261}
1262
1263#else
1264#define s3c2410_dma_suspend NULL
1265#define s3c2410_dma_resume NULL
1266#endif /* CONFIG_PM */
1267
1268struct sysdev_class dma_sysclass = {
1269 set_kset_name("s3c24xx-dma"),
1270 .suspend = s3c2410_dma_suspend,
1271 .resume = s3c2410_dma_resume,
1272};
1273
1274/* kmem cache implementation */
1275
1276static void s3c2410_dma_cache_ctor(void *p, struct kmem_cache *c, unsigned long f)
1277{
1278 memset(p, 0, sizeof(struct s3c2410_dma_buf));
1279}
1280
1281/* initialisation code */
1282
1283int __init s3c24xx_dma_sysclass_init(void)
1284{
1285 int ret = sysdev_class_register(&dma_sysclass);
1286
1287 if (ret != 0)
1288 printk(KERN_ERR "dma sysclass registration failed\n");
1289
1290 return ret;
1291}
1292
1293core_initcall(s3c24xx_dma_sysclass_init);
1294
1295int __init s3c24xx_dma_sysdev_register(void)
1296{
1297 struct s3c2410_dma_chan *cp = s3c2410_chans;
1298 int channel, ret;
1299
1300 for (channel = 0; channel < dma_channels; cp++, channel++) {
1301 cp->dev.cls = &dma_sysclass;
1302 cp->dev.id = channel;
1303 ret = sysdev_register(&cp->dev);
1304
1305 if (ret) {
1306 printk(KERN_ERR "error registering dev for dma %d\n",
1307 channel);
1308 return ret;
1309 }
1310 }
1311
1312 return 0;
1313}
1314
1315late_initcall(s3c24xx_dma_sysdev_register);
1316
1317int __init s3c24xx_dma_init(unsigned int channels, unsigned int irq,
1318 unsigned int stride)
1319{
1320 struct s3c2410_dma_chan *cp;
1321 int channel;
1322 int ret;
1323
1324 printk("S3C24XX DMA Driver, (c) 2003-2004,2006 Simtec Electronics\n");
1325
1326 dma_channels = channels;
1327
1328 dma_base = ioremap(S3C24XX_PA_DMA, stride * channels);
1329 if (dma_base == NULL) {
1330 printk(KERN_ERR "dma failed to remap register block\n");
1331 return -ENOMEM;
1332 }
1333
1334 dma_kmem = kmem_cache_create("dma_desc",
1335 sizeof(struct s3c2410_dma_buf), 0,
1336 SLAB_HWCACHE_ALIGN,
1337 s3c2410_dma_cache_ctor, NULL);
1338
1339 if (dma_kmem == NULL) {
1340 printk(KERN_ERR "dma failed to make kmem cache\n");
1341 ret = -ENOMEM;
1342 goto err;
1343 }
1344
1345 for (channel = 0; channel < channels; channel++) {
1346 cp = &s3c2410_chans[channel];
1347
1348 memset(cp, 0, sizeof(struct s3c2410_dma_chan));
1349
1350 /* dma channel irqs are in order.. */
1351 cp->number = channel;
1352 cp->irq = channel + irq;
1353 cp->regs = dma_base + (channel * stride);
1354
1355 /* point current stats somewhere */
1356 cp->stats = &cp->stats_store;
1357 cp->stats_store.timeout_shortest = LONG_MAX;
1358
1359 /* basic channel configuration */
1360
1361 cp->load_timeout = 1<<18;
1362
1363 printk("DMA channel %d at %p, irq %d\n",
1364 cp->number, cp->regs, cp->irq);
1365 }
1366
1367 return 0;
1368
1369 err:
1370 kmem_cache_destroy(dma_kmem);
1371 iounmap(dma_base);
1372 dma_base = NULL;
1373 return ret;
1374}
1375
1376int s3c2410_dma_init(void)
1377{
1378 return s3c24xx_dma_init(4, IRQ_DMA0, 0x40);
1379}
1380
1381static inline int is_channel_valid(unsigned int channel)
1382{
1383 return (channel & DMA_CH_VALID);
1384}
1385
1386static struct s3c24xx_dma_order *dma_order;
1387
1388
1389/* s3c2410_dma_map_channel()
1390 *
1391 * turn the virtual channel number into a real, and un-used hardware
1392 * channel.
1393 *
1394 * first, try the dma ordering given to us by either the relevant
1395 * dma code, or the board. Then just find the first usable free
1396 * channel
1397*/
1398
1399struct s3c2410_dma_chan *s3c2410_dma_map_channel(int channel)
1400{
1401 struct s3c24xx_dma_order_ch *ord = NULL;
1402 struct s3c24xx_dma_map *ch_map;
1403 struct s3c2410_dma_chan *dmach;
1404 int ch;
1405
1406 if (dma_sel.map == NULL || channel > dma_sel.map_size)
1407 return NULL;
1408
1409 ch_map = dma_sel.map + channel;
1410
1411 /* first, try the board mapping */
1412
1413 if (dma_order) {
1414 ord = &dma_order->channels[channel];
1415
1416 for (ch = 0; ch < dma_channels; ch++) {
1417 if (!is_channel_valid(ord->list[ch]))
1418 continue;
1419
1420 if (s3c2410_chans[ord->list[ch]].in_use == 0) {
1421 ch = ord->list[ch] & ~DMA_CH_VALID;
1422 goto found;
1423 }
1424 }
1425
1426 if (ord->flags & DMA_CH_NEVER)
1427 return NULL;
1428 }
1429
1430 /* second, search the channel map for first free */
1431
1432 for (ch = 0; ch < dma_channels; ch++) {
1433 if (!is_channel_valid(ch_map->channels[ch]))
1434 continue;
1435
1436 if (s3c2410_chans[ch].in_use == 0) {
1437 printk("mapped channel %d to %d\n", channel, ch);
1438 break;
1439 }
1440 }
1441
1442 if (ch >= dma_channels)
1443 return NULL;
1444
1445 /* update our channel mapping */
1446
1447 found:
1448 dmach = &s3c2410_chans[ch];
1449 dma_chan_map[channel] = dmach;
1450
1451 /* select the channel */
1452
1453 (dma_sel.select)(dmach, ch_map);
1454
1455 return dmach;
1456}
1457
1458static int s3c24xx_dma_check_entry(struct s3c24xx_dma_map *map, int ch)
1459{
1460 return 0;
1461}
1462
1463int __init s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel)
1464{
1465 struct s3c24xx_dma_map *nmap;
1466 size_t map_sz = sizeof(*nmap) * sel->map_size;
1467 int ptr;
1468
1469 nmap = kmalloc(map_sz, GFP_KERNEL);
1470 if (nmap == NULL)
1471 return -ENOMEM;
1472
1473 memcpy(nmap, sel->map, map_sz);
1474 memcpy(&dma_sel, sel, sizeof(*sel));
1475
1476 dma_sel.map = nmap;
1477
1478 for (ptr = 0; ptr < sel->map_size; ptr++)
1479 s3c24xx_dma_check_entry(nmap+ptr, ptr);
1480
1481 return 0;
1482}
1483
1484int __init s3c24xx_dma_order_set(struct s3c24xx_dma_order *ord)
1485{
1486 struct s3c24xx_dma_order *nord = dma_order;
1487
1488 if (nord == NULL)
1489 nord = kmalloc(sizeof(struct s3c24xx_dma_order), GFP_KERNEL);
1490
1491 if (nord == NULL) {
1492 printk(KERN_ERR "no memory to store dma channel order\n");
1493 return -ENOMEM;
1494 }
1495
1496 dma_order = nord;
1497 memcpy(nord, ord, sizeof(struct s3c24xx_dma_order));
1498 return 0;
1499}
diff --git a/arch/arm/plat-s3c24xx/gpio.c b/arch/arm/plat-s3c24xx/gpio.c
new file mode 100644
index 000000000000..ec3a09c4d181
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/gpio.c
@@ -0,0 +1,188 @@
1/* linux/arch/arm/plat-s3c24xx/gpio.c
2 *
3 * Copyright (c) 2004-2005 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C24XX GPIO support
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 of the License, or
11 * (at your option) 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21*/
22
23
24#include <linux/kernel.h>
25#include <linux/init.h>
26#include <linux/module.h>
27#include <linux/interrupt.h>
28#include <linux/ioport.h>
29
30#include <asm/hardware.h>
31#include <asm/irq.h>
32#include <asm/io.h>
33
34#include <asm/arch/regs-gpio.h>
35
36void s3c2410_gpio_cfgpin(unsigned int pin, unsigned int function)
37{
38 void __iomem *base = S3C24XX_GPIO_BASE(pin);
39 unsigned long mask;
40 unsigned long con;
41 unsigned long flags;
42
43 if (pin < S3C2410_GPIO_BANKB) {
44 mask = 1 << S3C2410_GPIO_OFFSET(pin);
45 } else {
46 mask = 3 << S3C2410_GPIO_OFFSET(pin)*2;
47 }
48
49 switch (function) {
50 case S3C2410_GPIO_LEAVE:
51 mask = 0;
52 function = 0;
53 break;
54
55 case S3C2410_GPIO_INPUT:
56 case S3C2410_GPIO_OUTPUT:
57 case S3C2410_GPIO_SFN2:
58 case S3C2410_GPIO_SFN3:
59 if (pin < S3C2410_GPIO_BANKB) {
60 function -= 1;
61 function &= 1;
62 function <<= S3C2410_GPIO_OFFSET(pin);
63 } else {
64 function &= 3;
65 function <<= S3C2410_GPIO_OFFSET(pin)*2;
66 }
67 }
68
69 /* modify the specified register wwith IRQs off */
70
71 local_irq_save(flags);
72
73 con = __raw_readl(base + 0x00);
74 con &= ~mask;
75 con |= function;
76
77 __raw_writel(con, base + 0x00);
78
79 local_irq_restore(flags);
80}
81
82EXPORT_SYMBOL(s3c2410_gpio_cfgpin);
83
84unsigned int s3c2410_gpio_getcfg(unsigned int pin)
85{
86 void __iomem *base = S3C24XX_GPIO_BASE(pin);
87 unsigned long val = __raw_readl(base);
88
89 if (pin < S3C2410_GPIO_BANKB) {
90 val >>= S3C2410_GPIO_OFFSET(pin);
91 val &= 1;
92 val += 1;
93 } else {
94 val >>= S3C2410_GPIO_OFFSET(pin)*2;
95 val &= 3;
96 }
97
98 return val | S3C2410_GPIO_INPUT;
99}
100
101EXPORT_SYMBOL(s3c2410_gpio_getcfg);
102
103void s3c2410_gpio_pullup(unsigned int pin, unsigned int to)
104{
105 void __iomem *base = S3C24XX_GPIO_BASE(pin);
106 unsigned long offs = S3C2410_GPIO_OFFSET(pin);
107 unsigned long flags;
108 unsigned long up;
109
110 if (pin < S3C2410_GPIO_BANKB)
111 return;
112
113 local_irq_save(flags);
114
115 up = __raw_readl(base + 0x08);
116 up &= ~(1L << offs);
117 up |= to << offs;
118 __raw_writel(up, base + 0x08);
119
120 local_irq_restore(flags);
121}
122
123EXPORT_SYMBOL(s3c2410_gpio_pullup);
124
125void s3c2410_gpio_setpin(unsigned int pin, unsigned int to)
126{
127 void __iomem *base = S3C24XX_GPIO_BASE(pin);
128 unsigned long offs = S3C2410_GPIO_OFFSET(pin);
129 unsigned long flags;
130 unsigned long dat;
131
132 local_irq_save(flags);
133
134 dat = __raw_readl(base + 0x04);
135 dat &= ~(1 << offs);
136 dat |= to << offs;
137 __raw_writel(dat, base + 0x04);
138
139 local_irq_restore(flags);
140}
141
142EXPORT_SYMBOL(s3c2410_gpio_setpin);
143
144unsigned int s3c2410_gpio_getpin(unsigned int pin)
145{
146 void __iomem *base = S3C24XX_GPIO_BASE(pin);
147 unsigned long offs = S3C2410_GPIO_OFFSET(pin);
148
149 return __raw_readl(base + 0x04) & (1<< offs);
150}
151
152EXPORT_SYMBOL(s3c2410_gpio_getpin);
153
154unsigned int s3c2410_modify_misccr(unsigned int clear, unsigned int change)
155{
156 unsigned long flags;
157 unsigned long misccr;
158
159 local_irq_save(flags);
160 misccr = __raw_readl(S3C24XX_MISCCR);
161 misccr &= ~clear;
162 misccr ^= change;
163 __raw_writel(misccr, S3C24XX_MISCCR);
164 local_irq_restore(flags);
165
166 return misccr;
167}
168
169EXPORT_SYMBOL(s3c2410_modify_misccr);
170
171int s3c2410_gpio_getirq(unsigned int pin)
172{
173 if (pin < S3C2410_GPF0 || pin > S3C2410_GPG15)
174 return -1; /* not valid interrupts */
175
176 if (pin < S3C2410_GPG0 && pin > S3C2410_GPF7)
177 return -1; /* not valid pin */
178
179 if (pin < S3C2410_GPF4)
180 return (pin - S3C2410_GPF0) + IRQ_EINT0;
181
182 if (pin < S3C2410_GPG0)
183 return (pin - S3C2410_GPF4) + IRQ_EINT4;
184
185 return (pin - S3C2410_GPG0) + IRQ_EINT8;
186}
187
188EXPORT_SYMBOL(s3c2410_gpio_getirq);
diff --git a/arch/arm/plat-s3c24xx/irq.c b/arch/arm/plat-s3c24xx/irq.c
new file mode 100644
index 000000000000..ce186398e3fd
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/irq.c
@@ -0,0 +1,801 @@
1/* linux/arch/arm/plat-s3c24xx/irq.c
2 *
3 * Copyright (c) 2003,2004 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
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 * Changelog:
21 *
22 * 22-Jul-2004 Ben Dooks <ben@simtec.co.uk>
23 * Fixed compile warnings
24 *
25 * 22-Jul-2004 Roc Wu <cooloney@yahoo.com.cn>
26 * Fixed s3c_extirq_type
27 *
28 * 21-Jul-2004 Arnaud Patard (Rtp) <arnaud.patard@rtp-net.org>
29 * Addition of ADC/TC demux
30 *
31 * 04-Oct-2004 Klaus Fetscher <k.fetscher@fetron.de>
32 * Fix for set_irq_type() on low EINT numbers
33 *
34 * 05-Oct-2004 Ben Dooks <ben@simtec.co.uk>
35 * Tidy up KF's patch and sort out new release
36 *
37 * 05-Oct-2004 Ben Dooks <ben@simtec.co.uk>
38 * Add support for power management controls
39 *
40 * 04-Nov-2004 Ben Dooks
41 * Fix standard IRQ wake for EINT0..4 and RTC
42 *
43 * 22-Feb-2005 Ben Dooks
44 * Fixed edge-triggering on ADC IRQ
45 *
46 * 28-Jun-2005 Ben Dooks
47 * Mark IRQ_LCD valid
48 *
49 * 25-Jul-2005 Ben Dooks
50 * Split the S3C2440 IRQ code to seperate file
51*/
52
53#include <linux/init.h>
54#include <linux/module.h>
55#include <linux/interrupt.h>
56#include <linux/ioport.h>
57#include <linux/ptrace.h>
58#include <linux/sysdev.h>
59
60#include <asm/hardware.h>
61#include <asm/irq.h>
62#include <asm/io.h>
63
64#include <asm/mach/irq.h>
65
66#include <asm/arch/regs-irq.h>
67#include <asm/arch/regs-gpio.h>
68
69#include <asm/plat-s3c24xx/cpu.h>
70#include <asm/plat-s3c24xx/pm.h>
71#include <asm/plat-s3c24xx/irq.h>
72
73/* wakeup irq control */
74
75#ifdef CONFIG_PM
76
77/* state for IRQs over sleep */
78
79/* default is to allow for EINT0..EINT15, and IRQ_RTC as wakeup sources
80 *
81 * set bit to 1 in allow bitfield to enable the wakeup settings on it
82*/
83
84unsigned long s3c_irqwake_intallow = 1L << (IRQ_RTC - IRQ_EINT0) | 0xfL;
85unsigned long s3c_irqwake_intmask = 0xffffffffL;
86unsigned long s3c_irqwake_eintallow = 0x0000fff0L;
87unsigned long s3c_irqwake_eintmask = 0xffffffffL;
88
89int
90s3c_irq_wake(unsigned int irqno, unsigned int state)
91{
92 unsigned long irqbit = 1 << (irqno - IRQ_EINT0);
93
94 if (!(s3c_irqwake_intallow & irqbit))
95 return -ENOENT;
96
97 printk(KERN_INFO "wake %s for irq %d\n",
98 state ? "enabled" : "disabled", irqno);
99
100 if (!state)
101 s3c_irqwake_intmask |= irqbit;
102 else
103 s3c_irqwake_intmask &= ~irqbit;
104
105 return 0;
106}
107
108static int
109s3c_irqext_wake(unsigned int irqno, unsigned int state)
110{
111 unsigned long bit = 1L << (irqno - EXTINT_OFF);
112
113 if (!(s3c_irqwake_eintallow & bit))
114 return -ENOENT;
115
116 printk(KERN_INFO "wake %s for irq %d\n",
117 state ? "enabled" : "disabled", irqno);
118
119 if (!state)
120 s3c_irqwake_eintmask |= bit;
121 else
122 s3c_irqwake_eintmask &= ~bit;
123
124 return 0;
125}
126
127#else
128#define s3c_irqext_wake NULL
129#define s3c_irq_wake NULL
130#endif
131
132
133static void
134s3c_irq_mask(unsigned int irqno)
135{
136 unsigned long mask;
137
138 irqno -= IRQ_EINT0;
139
140 mask = __raw_readl(S3C2410_INTMSK);
141 mask |= 1UL << irqno;
142 __raw_writel(mask, S3C2410_INTMSK);
143}
144
145static inline void
146s3c_irq_ack(unsigned int irqno)
147{
148 unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
149
150 __raw_writel(bitval, S3C2410_SRCPND);
151 __raw_writel(bitval, S3C2410_INTPND);
152}
153
154static inline void
155s3c_irq_maskack(unsigned int irqno)
156{
157 unsigned long bitval = 1UL << (irqno - IRQ_EINT0);
158 unsigned long mask;
159
160 mask = __raw_readl(S3C2410_INTMSK);
161 __raw_writel(mask|bitval, S3C2410_INTMSK);
162
163 __raw_writel(bitval, S3C2410_SRCPND);
164 __raw_writel(bitval, S3C2410_INTPND);
165}
166
167
168static void
169s3c_irq_unmask(unsigned int irqno)
170{
171 unsigned long mask;
172
173 if (irqno != IRQ_TIMER4 && irqno != IRQ_EINT8t23)
174 irqdbf2("s3c_irq_unmask %d\n", irqno);
175
176 irqno -= IRQ_EINT0;
177
178 mask = __raw_readl(S3C2410_INTMSK);
179 mask &= ~(1UL << irqno);
180 __raw_writel(mask, S3C2410_INTMSK);
181}
182
183struct irq_chip s3c_irq_level_chip = {
184 .name = "s3c-level",
185 .ack = s3c_irq_maskack,
186 .mask = s3c_irq_mask,
187 .unmask = s3c_irq_unmask,
188 .set_wake = s3c_irq_wake
189};
190
191static struct irq_chip s3c_irq_chip = {
192 .name = "s3c",
193 .ack = s3c_irq_ack,
194 .mask = s3c_irq_mask,
195 .unmask = s3c_irq_unmask,
196 .set_wake = s3c_irq_wake
197};
198
199static void
200s3c_irqext_mask(unsigned int irqno)
201{
202 unsigned long mask;
203
204 irqno -= EXTINT_OFF;
205
206 mask = __raw_readl(S3C24XX_EINTMASK);
207 mask |= ( 1UL << irqno);
208 __raw_writel(mask, S3C24XX_EINTMASK);
209}
210
211static void
212s3c_irqext_ack(unsigned int irqno)
213{
214 unsigned long req;
215 unsigned long bit;
216 unsigned long mask;
217
218 bit = 1UL << (irqno - EXTINT_OFF);
219
220 mask = __raw_readl(S3C24XX_EINTMASK);
221
222 __raw_writel(bit, S3C24XX_EINTPEND);
223
224 req = __raw_readl(S3C24XX_EINTPEND);
225 req &= ~mask;
226
227 /* not sure if we should be acking the parent irq... */
228
229 if (irqno <= IRQ_EINT7 ) {
230 if ((req & 0xf0) == 0)
231 s3c_irq_ack(IRQ_EINT4t7);
232 } else {
233 if ((req >> 8) == 0)
234 s3c_irq_ack(IRQ_EINT8t23);
235 }
236}
237
238static void
239s3c_irqext_unmask(unsigned int irqno)
240{
241 unsigned long mask;
242
243 irqno -= EXTINT_OFF;
244
245 mask = __raw_readl(S3C24XX_EINTMASK);
246 mask &= ~( 1UL << irqno);
247 __raw_writel(mask, S3C24XX_EINTMASK);
248}
249
250int
251s3c_irqext_type(unsigned int irq, unsigned int type)
252{
253 void __iomem *extint_reg;
254 void __iomem *gpcon_reg;
255 unsigned long gpcon_offset, extint_offset;
256 unsigned long newvalue = 0, value;
257
258 if ((irq >= IRQ_EINT0) && (irq <= IRQ_EINT3))
259 {
260 gpcon_reg = S3C2410_GPFCON;
261 extint_reg = S3C24XX_EXTINT0;
262 gpcon_offset = (irq - IRQ_EINT0) * 2;
263 extint_offset = (irq - IRQ_EINT0) * 4;
264 }
265 else if ((irq >= IRQ_EINT4) && (irq <= IRQ_EINT7))
266 {
267 gpcon_reg = S3C2410_GPFCON;
268 extint_reg = S3C24XX_EXTINT0;
269 gpcon_offset = (irq - (EXTINT_OFF)) * 2;
270 extint_offset = (irq - (EXTINT_OFF)) * 4;
271 }
272 else if ((irq >= IRQ_EINT8) && (irq <= IRQ_EINT15))
273 {
274 gpcon_reg = S3C2410_GPGCON;
275 extint_reg = S3C24XX_EXTINT1;
276 gpcon_offset = (irq - IRQ_EINT8) * 2;
277 extint_offset = (irq - IRQ_EINT8) * 4;
278 }
279 else if ((irq >= IRQ_EINT16) && (irq <= IRQ_EINT23))
280 {
281 gpcon_reg = S3C2410_GPGCON;
282 extint_reg = S3C24XX_EXTINT2;
283 gpcon_offset = (irq - IRQ_EINT8) * 2;
284 extint_offset = (irq - IRQ_EINT16) * 4;
285 } else
286 return -1;
287
288 /* Set the GPIO to external interrupt mode */
289 value = __raw_readl(gpcon_reg);
290 value = (value & ~(3 << gpcon_offset)) | (0x02 << gpcon_offset);
291 __raw_writel(value, gpcon_reg);
292
293 /* Set the external interrupt to pointed trigger type */
294 switch (type)
295 {
296 case IRQT_NOEDGE:
297 printk(KERN_WARNING "No edge setting!\n");
298 break;
299
300 case IRQT_RISING:
301 newvalue = S3C2410_EXTINT_RISEEDGE;
302 break;
303
304 case IRQT_FALLING:
305 newvalue = S3C2410_EXTINT_FALLEDGE;
306 break;
307
308 case IRQT_BOTHEDGE:
309 newvalue = S3C2410_EXTINT_BOTHEDGE;
310 break;
311
312 case IRQT_LOW:
313 newvalue = S3C2410_EXTINT_LOWLEV;
314 break;
315
316 case IRQT_HIGH:
317 newvalue = S3C2410_EXTINT_HILEV;
318 break;
319
320 default:
321 printk(KERN_ERR "No such irq type %d", type);
322 return -1;
323 }
324
325 value = __raw_readl(extint_reg);
326 value = (value & ~(7 << extint_offset)) | (newvalue << extint_offset);
327 __raw_writel(value, extint_reg);
328
329 return 0;
330}
331
332static struct irq_chip s3c_irqext_chip = {
333 .name = "s3c-ext",
334 .mask = s3c_irqext_mask,
335 .unmask = s3c_irqext_unmask,
336 .ack = s3c_irqext_ack,
337 .set_type = s3c_irqext_type,
338 .set_wake = s3c_irqext_wake
339};
340
341static struct irq_chip s3c_irq_eint0t4 = {
342 .name = "s3c-ext0",
343 .ack = s3c_irq_ack,
344 .mask = s3c_irq_mask,
345 .unmask = s3c_irq_unmask,
346 .set_wake = s3c_irq_wake,
347 .set_type = s3c_irqext_type,
348};
349
350/* mask values for the parent registers for each of the interrupt types */
351
352#define INTMSK_UART0 (1UL << (IRQ_UART0 - IRQ_EINT0))
353#define INTMSK_UART1 (1UL << (IRQ_UART1 - IRQ_EINT0))
354#define INTMSK_UART2 (1UL << (IRQ_UART2 - IRQ_EINT0))
355#define INTMSK_ADCPARENT (1UL << (IRQ_ADCPARENT - IRQ_EINT0))
356
357
358/* UART0 */
359
360static void
361s3c_irq_uart0_mask(unsigned int irqno)
362{
363 s3c_irqsub_mask(irqno, INTMSK_UART0, 7);
364}
365
366static void
367s3c_irq_uart0_unmask(unsigned int irqno)
368{
369 s3c_irqsub_unmask(irqno, INTMSK_UART0);
370}
371
372static void
373s3c_irq_uart0_ack(unsigned int irqno)
374{
375 s3c_irqsub_maskack(irqno, INTMSK_UART0, 7);
376}
377
378static struct irq_chip s3c_irq_uart0 = {
379 .name = "s3c-uart0",
380 .mask = s3c_irq_uart0_mask,
381 .unmask = s3c_irq_uart0_unmask,
382 .ack = s3c_irq_uart0_ack,
383};
384
385/* UART1 */
386
387static void
388s3c_irq_uart1_mask(unsigned int irqno)
389{
390 s3c_irqsub_mask(irqno, INTMSK_UART1, 7 << 3);
391}
392
393static void
394s3c_irq_uart1_unmask(unsigned int irqno)
395{
396 s3c_irqsub_unmask(irqno, INTMSK_UART1);
397}
398
399static void
400s3c_irq_uart1_ack(unsigned int irqno)
401{
402 s3c_irqsub_maskack(irqno, INTMSK_UART1, 7 << 3);
403}
404
405static struct irq_chip s3c_irq_uart1 = {
406 .name = "s3c-uart1",
407 .mask = s3c_irq_uart1_mask,
408 .unmask = s3c_irq_uart1_unmask,
409 .ack = s3c_irq_uart1_ack,
410};
411
412/* UART2 */
413
414static void
415s3c_irq_uart2_mask(unsigned int irqno)
416{
417 s3c_irqsub_mask(irqno, INTMSK_UART2, 7 << 6);
418}
419
420static void
421s3c_irq_uart2_unmask(unsigned int irqno)
422{
423 s3c_irqsub_unmask(irqno, INTMSK_UART2);
424}
425
426static void
427s3c_irq_uart2_ack(unsigned int irqno)
428{
429 s3c_irqsub_maskack(irqno, INTMSK_UART2, 7 << 6);
430}
431
432static struct irq_chip s3c_irq_uart2 = {
433 .name = "s3c-uart2",
434 .mask = s3c_irq_uart2_mask,
435 .unmask = s3c_irq_uart2_unmask,
436 .ack = s3c_irq_uart2_ack,
437};
438
439/* ADC and Touchscreen */
440
441static void
442s3c_irq_adc_mask(unsigned int irqno)
443{
444 s3c_irqsub_mask(irqno, INTMSK_ADCPARENT, 3 << 9);
445}
446
447static void
448s3c_irq_adc_unmask(unsigned int irqno)
449{
450 s3c_irqsub_unmask(irqno, INTMSK_ADCPARENT);
451}
452
453static void
454s3c_irq_adc_ack(unsigned int irqno)
455{
456 s3c_irqsub_ack(irqno, INTMSK_ADCPARENT, 3 << 9);
457}
458
459static struct irq_chip s3c_irq_adc = {
460 .name = "s3c-adc",
461 .mask = s3c_irq_adc_mask,
462 .unmask = s3c_irq_adc_unmask,
463 .ack = s3c_irq_adc_ack,
464};
465
466/* irq demux for adc */
467static void s3c_irq_demux_adc(unsigned int irq,
468 struct irq_desc *desc)
469{
470 unsigned int subsrc, submsk;
471 unsigned int offset = 9;
472 struct irq_desc *mydesc;
473
474 /* read the current pending interrupts, and the mask
475 * for what it is available */
476
477 subsrc = __raw_readl(S3C2410_SUBSRCPND);
478 submsk = __raw_readl(S3C2410_INTSUBMSK);
479
480 subsrc &= ~submsk;
481 subsrc >>= offset;
482 subsrc &= 3;
483
484 if (subsrc != 0) {
485 if (subsrc & 1) {
486 mydesc = irq_desc + IRQ_TC;
487 desc_handle_irq(IRQ_TC, mydesc);
488 }
489 if (subsrc & 2) {
490 mydesc = irq_desc + IRQ_ADC;
491 desc_handle_irq(IRQ_ADC, mydesc);
492 }
493 }
494}
495
496static void s3c_irq_demux_uart(unsigned int start)
497{
498 unsigned int subsrc, submsk;
499 unsigned int offset = start - IRQ_S3CUART_RX0;
500 struct irq_desc *desc;
501
502 /* read the current pending interrupts, and the mask
503 * for what it is available */
504
505 subsrc = __raw_readl(S3C2410_SUBSRCPND);
506 submsk = __raw_readl(S3C2410_INTSUBMSK);
507
508 irqdbf2("s3c_irq_demux_uart: start=%d (%d), subsrc=0x%08x,0x%08x\n",
509 start, offset, subsrc, submsk);
510
511 subsrc &= ~submsk;
512 subsrc >>= offset;
513 subsrc &= 7;
514
515 if (subsrc != 0) {
516 desc = irq_desc + start;
517
518 if (subsrc & 1)
519 desc_handle_irq(start, desc);
520
521 desc++;
522
523 if (subsrc & 2)
524 desc_handle_irq(start+1, desc);
525
526 desc++;
527
528 if (subsrc & 4)
529 desc_handle_irq(start+2, desc);
530 }
531}
532
533/* uart demux entry points */
534
535static void
536s3c_irq_demux_uart0(unsigned int irq,
537 struct irq_desc *desc)
538{
539 irq = irq;
540 s3c_irq_demux_uart(IRQ_S3CUART_RX0);
541}
542
543static void
544s3c_irq_demux_uart1(unsigned int irq,
545 struct irq_desc *desc)
546{
547 irq = irq;
548 s3c_irq_demux_uart(IRQ_S3CUART_RX1);
549}
550
551static void
552s3c_irq_demux_uart2(unsigned int irq,
553 struct irq_desc *desc)
554{
555 irq = irq;
556 s3c_irq_demux_uart(IRQ_S3CUART_RX2);
557}
558
559static void
560s3c_irq_demux_extint8(unsigned int irq,
561 struct irq_desc *desc)
562{
563 unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
564 unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
565
566 eintpnd &= ~eintmsk;
567 eintpnd &= ~0xff; /* ignore lower irqs */
568
569 /* we may as well handle all the pending IRQs here */
570
571 while (eintpnd) {
572 irq = __ffs(eintpnd);
573 eintpnd &= ~(1<<irq);
574
575 irq += (IRQ_EINT4 - 4);
576 desc_handle_irq(irq, irq_desc + irq);
577 }
578
579}
580
581static void
582s3c_irq_demux_extint4t7(unsigned int irq,
583 struct irq_desc *desc)
584{
585 unsigned long eintpnd = __raw_readl(S3C24XX_EINTPEND);
586 unsigned long eintmsk = __raw_readl(S3C24XX_EINTMASK);
587
588 eintpnd &= ~eintmsk;
589 eintpnd &= 0xff; /* only lower irqs */
590
591 /* we may as well handle all the pending IRQs here */
592
593 while (eintpnd) {
594 irq = __ffs(eintpnd);
595 eintpnd &= ~(1<<irq);
596
597 irq += (IRQ_EINT4 - 4);
598
599 desc_handle_irq(irq, irq_desc + irq);
600 }
601}
602
603#ifdef CONFIG_PM
604
605static struct sleep_save irq_save[] = {
606 SAVE_ITEM(S3C2410_INTMSK),
607 SAVE_ITEM(S3C2410_INTSUBMSK),
608};
609
610/* the extint values move between the s3c2410/s3c2440 and the s3c2412
611 * so we use an array to hold them, and to calculate the address of
612 * the register at run-time
613*/
614
615static unsigned long save_extint[3];
616static unsigned long save_eintflt[4];
617static unsigned long save_eintmask;
618
619int s3c24xx_irq_suspend(struct sys_device *dev, pm_message_t state)
620{
621 unsigned int i;
622
623 for (i = 0; i < ARRAY_SIZE(save_extint); i++)
624 save_extint[i] = __raw_readl(S3C24XX_EXTINT0 + (i*4));
625
626 for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
627 save_eintflt[i] = __raw_readl(S3C24XX_EINFLT0 + (i*4));
628
629 s3c2410_pm_do_save(irq_save, ARRAY_SIZE(irq_save));
630 save_eintmask = __raw_readl(S3C24XX_EINTMASK);
631
632 return 0;
633}
634
635int s3c24xx_irq_resume(struct sys_device *dev)
636{
637 unsigned int i;
638
639 for (i = 0; i < ARRAY_SIZE(save_extint); i++)
640 __raw_writel(save_extint[i], S3C24XX_EXTINT0 + (i*4));
641
642 for (i = 0; i < ARRAY_SIZE(save_eintflt); i++)
643 __raw_writel(save_eintflt[i], S3C24XX_EINFLT0 + (i*4));
644
645 s3c2410_pm_do_restore(irq_save, ARRAY_SIZE(irq_save));
646 __raw_writel(save_eintmask, S3C24XX_EINTMASK);
647
648 return 0;
649}
650
651#else
652#define s3c24xx_irq_suspend NULL
653#define s3c24xx_irq_resume NULL
654#endif
655
656/* s3c24xx_init_irq
657 *
658 * Initialise S3C2410 IRQ system
659*/
660
661void __init s3c24xx_init_irq(void)
662{
663 unsigned long pend;
664 unsigned long last;
665 int irqno;
666 int i;
667
668 irqdbf("s3c2410_init_irq: clearing interrupt status flags\n");
669
670 /* first, clear all interrupts pending... */
671
672 last = 0;
673 for (i = 0; i < 4; i++) {
674 pend = __raw_readl(S3C24XX_EINTPEND);
675
676 if (pend == 0 || pend == last)
677 break;
678
679 __raw_writel(pend, S3C24XX_EINTPEND);
680 printk("irq: clearing pending ext status %08x\n", (int)pend);
681 last = pend;
682 }
683
684 last = 0;
685 for (i = 0; i < 4; i++) {
686 pend = __raw_readl(S3C2410_INTPND);
687
688 if (pend == 0 || pend == last)
689 break;
690
691 __raw_writel(pend, S3C2410_SRCPND);
692 __raw_writel(pend, S3C2410_INTPND);
693 printk("irq: clearing pending status %08x\n", (int)pend);
694 last = pend;
695 }
696
697 last = 0;
698 for (i = 0; i < 4; i++) {
699 pend = __raw_readl(S3C2410_SUBSRCPND);
700
701 if (pend == 0 || pend == last)
702 break;
703
704 printk("irq: clearing subpending status %08x\n", (int)pend);
705 __raw_writel(pend, S3C2410_SUBSRCPND);
706 last = pend;
707 }
708
709 /* register the main interrupts */
710
711 irqdbf("s3c2410_init_irq: registering s3c2410 interrupt handlers\n");
712
713 for (irqno = IRQ_EINT4t7; irqno <= IRQ_ADCPARENT; irqno++) {
714 /* set all the s3c2410 internal irqs */
715
716 switch (irqno) {
717 /* deal with the special IRQs (cascaded) */
718
719 case IRQ_EINT4t7:
720 case IRQ_EINT8t23:
721 case IRQ_UART0:
722 case IRQ_UART1:
723 case IRQ_UART2:
724 case IRQ_ADCPARENT:
725 set_irq_chip(irqno, &s3c_irq_level_chip);
726 set_irq_handler(irqno, handle_level_irq);
727 break;
728
729 case IRQ_RESERVED6:
730 case IRQ_RESERVED24:
731 /* no IRQ here */
732 break;
733
734 default:
735 //irqdbf("registering irq %d (s3c irq)\n", irqno);
736 set_irq_chip(irqno, &s3c_irq_chip);
737 set_irq_handler(irqno, handle_edge_irq);
738 set_irq_flags(irqno, IRQF_VALID);
739 }
740 }
741
742 /* setup the cascade irq handlers */
743
744 set_irq_chained_handler(IRQ_EINT4t7, s3c_irq_demux_extint4t7);
745 set_irq_chained_handler(IRQ_EINT8t23, s3c_irq_demux_extint8);
746
747 set_irq_chained_handler(IRQ_UART0, s3c_irq_demux_uart0);
748 set_irq_chained_handler(IRQ_UART1, s3c_irq_demux_uart1);
749 set_irq_chained_handler(IRQ_UART2, s3c_irq_demux_uart2);
750 set_irq_chained_handler(IRQ_ADCPARENT, s3c_irq_demux_adc);
751
752 /* external interrupts */
753
754 for (irqno = IRQ_EINT0; irqno <= IRQ_EINT3; irqno++) {
755 irqdbf("registering irq %d (ext int)\n", irqno);
756 set_irq_chip(irqno, &s3c_irq_eint0t4);
757 set_irq_handler(irqno, handle_edge_irq);
758 set_irq_flags(irqno, IRQF_VALID);
759 }
760
761 for (irqno = IRQ_EINT4; irqno <= IRQ_EINT23; irqno++) {
762 irqdbf("registering irq %d (extended s3c irq)\n", irqno);
763 set_irq_chip(irqno, &s3c_irqext_chip);
764 set_irq_handler(irqno, handle_edge_irq);
765 set_irq_flags(irqno, IRQF_VALID);
766 }
767
768 /* register the uart interrupts */
769
770 irqdbf("s3c2410: registering external interrupts\n");
771
772 for (irqno = IRQ_S3CUART_RX0; irqno <= IRQ_S3CUART_ERR0; irqno++) {
773 irqdbf("registering irq %d (s3c uart0 irq)\n", irqno);
774 set_irq_chip(irqno, &s3c_irq_uart0);
775 set_irq_handler(irqno, handle_level_irq);
776 set_irq_flags(irqno, IRQF_VALID);
777 }
778
779 for (irqno = IRQ_S3CUART_RX1; irqno <= IRQ_S3CUART_ERR1; irqno++) {
780 irqdbf("registering irq %d (s3c uart1 irq)\n", irqno);
781 set_irq_chip(irqno, &s3c_irq_uart1);
782 set_irq_handler(irqno, handle_level_irq);
783 set_irq_flags(irqno, IRQF_VALID);
784 }
785
786 for (irqno = IRQ_S3CUART_RX2; irqno <= IRQ_S3CUART_ERR2; irqno++) {
787 irqdbf("registering irq %d (s3c uart2 irq)\n", irqno);
788 set_irq_chip(irqno, &s3c_irq_uart2);
789 set_irq_handler(irqno, handle_level_irq);
790 set_irq_flags(irqno, IRQF_VALID);
791 }
792
793 for (irqno = IRQ_TC; irqno <= IRQ_ADC; irqno++) {
794 irqdbf("registering irq %d (s3c adc irq)\n", irqno);
795 set_irq_chip(irqno, &s3c_irq_adc);
796 set_irq_handler(irqno, handle_edge_irq);
797 set_irq_flags(irqno, IRQF_VALID);
798 }
799
800 irqdbf("s3c2410: registered interrupt handlers\n");
801}
diff --git a/arch/arm/mach-s3c2410/pm-simtec.c b/arch/arm/plat-s3c24xx/pm-simtec.c
index 619133eb7168..bd965f2feeca 100644
--- a/arch/arm/mach-s3c2410/pm-simtec.c
+++ b/arch/arm/plat-s3c24xx/pm-simtec.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/pm-simtec.c 1/* linux/arch/arm/plat-s3c24xx/pm-simtec.c
2 * 2 *
3 * Copyright (c) 2004 Simtec Electronics 3 * Copyright (c) 2004 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
@@ -32,7 +32,7 @@
32 32
33#include <asm/mach-types.h> 33#include <asm/mach-types.h>
34 34
35#include "pm.h" 35#include <asm/plat-s3c24xx/pm.h>
36 36
37#define COPYRIGHT ", (c) 2005 Simtec Electronics" 37#define COPYRIGHT ", (c) 2005 Simtec Electronics"
38 38
diff --git a/arch/arm/plat-s3c24xx/pm.c b/arch/arm/plat-s3c24xx/pm.c
new file mode 100644
index 000000000000..ecf68d611904
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/pm.c
@@ -0,0 +1,659 @@
1/* linux/arch/arm/plat-s3c24xx/pm.c
2 *
3 * Copyright (c) 2004,2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C24XX Power Manager (Suspend-To-RAM) support
7 *
8 * See Documentation/arm/Samsung-S3C24XX/Suspend.txt for more information
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 of the License, or
13 * (at your option) 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23 *
24 * Parts based on arch/arm/mach-pxa/pm.c
25 *
26 * Thanks to Dimitry Andric for debugging
27*/
28
29#include <linux/init.h>
30#include <linux/suspend.h>
31#include <linux/errno.h>
32#include <linux/time.h>
33#include <linux/interrupt.h>
34#include <linux/crc32.h>
35#include <linux/ioport.h>
36#include <linux/delay.h>
37#include <linux/serial_core.h>
38
39#include <asm/cacheflush.h>
40#include <asm/hardware.h>
41#include <asm/io.h>
42
43#include <asm/arch/regs-serial.h>
44#include <asm/arch/regs-clock.h>
45#include <asm/arch/regs-gpio.h>
46#include <asm/arch/regs-mem.h>
47#include <asm/arch/regs-irq.h>
48
49#include <asm/mach/time.h>
50
51#include <asm/plat-s3c24xx/pm.h>
52
53/* for external use */
54
55unsigned long s3c_pm_flags;
56
57#define PFX "s3c24xx-pm: "
58
59static struct sleep_save core_save[] = {
60 SAVE_ITEM(S3C2410_LOCKTIME),
61 SAVE_ITEM(S3C2410_CLKCON),
62
63 /* we restore the timings here, with the proviso that the board
64 * brings the system up in an slower, or equal frequency setting
65 * to the original system.
66 *
67 * if we cannot guarantee this, then things are going to go very
68 * wrong here, as we modify the refresh and both pll settings.
69 */
70
71 SAVE_ITEM(S3C2410_BWSCON),
72 SAVE_ITEM(S3C2410_BANKCON0),
73 SAVE_ITEM(S3C2410_BANKCON1),
74 SAVE_ITEM(S3C2410_BANKCON2),
75 SAVE_ITEM(S3C2410_BANKCON3),
76 SAVE_ITEM(S3C2410_BANKCON4),
77 SAVE_ITEM(S3C2410_BANKCON5),
78
79 SAVE_ITEM(S3C2410_CLKDIVN),
80 SAVE_ITEM(S3C2410_MPLLCON),
81 SAVE_ITEM(S3C2410_UPLLCON),
82 SAVE_ITEM(S3C2410_CLKSLOW),
83 SAVE_ITEM(S3C2410_REFRESH),
84};
85
86static struct sleep_save gpio_save[] = {
87 SAVE_ITEM(S3C2410_GPACON),
88 SAVE_ITEM(S3C2410_GPADAT),
89
90 SAVE_ITEM(S3C2410_GPBCON),
91 SAVE_ITEM(S3C2410_GPBDAT),
92 SAVE_ITEM(S3C2410_GPBUP),
93
94 SAVE_ITEM(S3C2410_GPCCON),
95 SAVE_ITEM(S3C2410_GPCDAT),
96 SAVE_ITEM(S3C2410_GPCUP),
97
98 SAVE_ITEM(S3C2410_GPDCON),
99 SAVE_ITEM(S3C2410_GPDDAT),
100 SAVE_ITEM(S3C2410_GPDUP),
101
102 SAVE_ITEM(S3C2410_GPECON),
103 SAVE_ITEM(S3C2410_GPEDAT),
104 SAVE_ITEM(S3C2410_GPEUP),
105
106 SAVE_ITEM(S3C2410_GPFCON),
107 SAVE_ITEM(S3C2410_GPFDAT),
108 SAVE_ITEM(S3C2410_GPFUP),
109
110 SAVE_ITEM(S3C2410_GPGCON),
111 SAVE_ITEM(S3C2410_GPGDAT),
112 SAVE_ITEM(S3C2410_GPGUP),
113
114 SAVE_ITEM(S3C2410_GPHCON),
115 SAVE_ITEM(S3C2410_GPHDAT),
116 SAVE_ITEM(S3C2410_GPHUP),
117
118 SAVE_ITEM(S3C2410_DCLKCON),
119};
120
121#ifdef CONFIG_S3C2410_PM_DEBUG
122
123#define SAVE_UART(va) \
124 SAVE_ITEM((va) + S3C2410_ULCON), \
125 SAVE_ITEM((va) + S3C2410_UCON), \
126 SAVE_ITEM((va) + S3C2410_UFCON), \
127 SAVE_ITEM((va) + S3C2410_UMCON), \
128 SAVE_ITEM((va) + S3C2410_UBRDIV)
129
130static struct sleep_save uart_save[] = {
131 SAVE_UART(S3C24XX_VA_UART0),
132 SAVE_UART(S3C24XX_VA_UART1),
133#ifndef CONFIG_CPU_S3C2400
134 SAVE_UART(S3C24XX_VA_UART2),
135#endif
136};
137
138/* debug
139 *
140 * we send the debug to printascii() to allow it to be seen if the
141 * system never wakes up from the sleep
142*/
143
144extern void printascii(const char *);
145
146void pm_dbg(const char *fmt, ...)
147{
148 va_list va;
149 char buff[256];
150
151 va_start(va, fmt);
152 vsprintf(buff, fmt, va);
153 va_end(va);
154
155 printascii(buff);
156}
157
158static void s3c2410_pm_debug_init(void)
159{
160 unsigned long tmp = __raw_readl(S3C2410_CLKCON);
161
162 /* re-start uart clocks */
163 tmp |= S3C2410_CLKCON_UART0;
164 tmp |= S3C2410_CLKCON_UART1;
165 tmp |= S3C2410_CLKCON_UART2;
166
167 __raw_writel(tmp, S3C2410_CLKCON);
168 udelay(10);
169}
170
171#define DBG(fmt...) pm_dbg(fmt)
172#else
173#define DBG(fmt...) printk(KERN_DEBUG fmt)
174
175#define s3c2410_pm_debug_init() do { } while(0)
176
177static struct sleep_save uart_save[] = {};
178#endif
179
180#if defined(CONFIG_S3C2410_PM_CHECK) && CONFIG_S3C2410_PM_CHECK_CHUNKSIZE != 0
181
182/* suspend checking code...
183 *
184 * this next area does a set of crc checks over all the installed
185 * memory, so the system can verify if the resume was ok.
186 *
187 * CONFIG_S3C2410_PM_CHECK_CHUNKSIZE defines the block-size for the CRC,
188 * increasing it will mean that the area corrupted will be less easy to spot,
189 * and reducing the size will cause the CRC save area to grow
190*/
191
192#define CHECK_CHUNKSIZE (CONFIG_S3C2410_PM_CHECK_CHUNKSIZE * 1024)
193
194static u32 crc_size; /* size needed for the crc block */
195static u32 *crcs; /* allocated over suspend/resume */
196
197typedef u32 *(run_fn_t)(struct resource *ptr, u32 *arg);
198
199/* s3c2410_pm_run_res
200 *
201 * go thorugh the given resource list, and look for system ram
202*/
203
204static void s3c2410_pm_run_res(struct resource *ptr, run_fn_t fn, u32 *arg)
205{
206 while (ptr != NULL) {
207 if (ptr->child != NULL)
208 s3c2410_pm_run_res(ptr->child, fn, arg);
209
210 if ((ptr->flags & IORESOURCE_MEM) &&
211 strcmp(ptr->name, "System RAM") == 0) {
212 DBG("Found system RAM at %08lx..%08lx\n",
213 ptr->start, ptr->end);
214 arg = (fn)(ptr, arg);
215 }
216
217 ptr = ptr->sibling;
218 }
219}
220
221static void s3c2410_pm_run_sysram(run_fn_t fn, u32 *arg)
222{
223 s3c2410_pm_run_res(&iomem_resource, fn, arg);
224}
225
226static u32 *s3c2410_pm_countram(struct resource *res, u32 *val)
227{
228 u32 size = (u32)(res->end - res->start)+1;
229
230 size += CHECK_CHUNKSIZE-1;
231 size /= CHECK_CHUNKSIZE;
232
233 DBG("Area %08lx..%08lx, %d blocks\n", res->start, res->end, size);
234
235 *val += size * sizeof(u32);
236 return val;
237}
238
239/* s3c2410_pm_prepare_check
240 *
241 * prepare the necessary information for creating the CRCs. This
242 * must be done before the final save, as it will require memory
243 * allocating, and thus touching bits of the kernel we do not
244 * know about.
245*/
246
247static void s3c2410_pm_check_prepare(void)
248{
249 crc_size = 0;
250
251 s3c2410_pm_run_sysram(s3c2410_pm_countram, &crc_size);
252
253 DBG("s3c2410_pm_prepare_check: %u checks needed\n", crc_size);
254
255 crcs = kmalloc(crc_size+4, GFP_KERNEL);
256 if (crcs == NULL)
257 printk(KERN_ERR "Cannot allocated CRC save area\n");
258}
259
260static u32 *s3c2410_pm_makecheck(struct resource *res, u32 *val)
261{
262 unsigned long addr, left;
263
264 for (addr = res->start; addr < res->end;
265 addr += CHECK_CHUNKSIZE) {
266 left = res->end - addr;
267
268 if (left > CHECK_CHUNKSIZE)
269 left = CHECK_CHUNKSIZE;
270
271 *val = crc32_le(~0, phys_to_virt(addr), left);
272 val++;
273 }
274
275 return val;
276}
277
278/* s3c2410_pm_check_store
279 *
280 * compute the CRC values for the memory blocks before the final
281 * sleep.
282*/
283
284static void s3c2410_pm_check_store(void)
285{
286 if (crcs != NULL)
287 s3c2410_pm_run_sysram(s3c2410_pm_makecheck, crcs);
288}
289
290/* in_region
291 *
292 * return TRUE if the area defined by ptr..ptr+size contatins the
293 * what..what+whatsz
294*/
295
296static inline int in_region(void *ptr, int size, void *what, size_t whatsz)
297{
298 if ((what+whatsz) < ptr)
299 return 0;
300
301 if (what > (ptr+size))
302 return 0;
303
304 return 1;
305}
306
307static u32 *s3c2410_pm_runcheck(struct resource *res, u32 *val)
308{
309 void *save_at = phys_to_virt(s3c2410_sleep_save_phys);
310 unsigned long addr;
311 unsigned long left;
312 void *ptr;
313 u32 calc;
314
315 for (addr = res->start; addr < res->end;
316 addr += CHECK_CHUNKSIZE) {
317 left = res->end - addr;
318
319 if (left > CHECK_CHUNKSIZE)
320 left = CHECK_CHUNKSIZE;
321
322 ptr = phys_to_virt(addr);
323
324 if (in_region(ptr, left, crcs, crc_size)) {
325 DBG("skipping %08lx, has crc block in\n", addr);
326 goto skip_check;
327 }
328
329 if (in_region(ptr, left, save_at, 32*4 )) {
330 DBG("skipping %08lx, has save block in\n", addr);
331 goto skip_check;
332 }
333
334 /* calculate and check the checksum */
335
336 calc = crc32_le(~0, ptr, left);
337 if (calc != *val) {
338 printk(KERN_ERR PFX "Restore CRC error at "
339 "%08lx (%08x vs %08x)\n", addr, calc, *val);
340
341 DBG("Restore CRC error at %08lx (%08x vs %08x)\n",
342 addr, calc, *val);
343 }
344
345 skip_check:
346 val++;
347 }
348
349 return val;
350}
351
352/* s3c2410_pm_check_restore
353 *
354 * check the CRCs after the restore event and free the memory used
355 * to hold them
356*/
357
358static void s3c2410_pm_check_restore(void)
359{
360 if (crcs != NULL) {
361 s3c2410_pm_run_sysram(s3c2410_pm_runcheck, crcs);
362 kfree(crcs);
363 crcs = NULL;
364 }
365}
366
367#else
368
369#define s3c2410_pm_check_prepare() do { } while(0)
370#define s3c2410_pm_check_restore() do { } while(0)
371#define s3c2410_pm_check_store() do { } while(0)
372#endif
373
374/* helper functions to save and restore register state */
375
376void s3c2410_pm_do_save(struct sleep_save *ptr, int count)
377{
378 for (; count > 0; count--, ptr++) {
379 ptr->val = __raw_readl(ptr->reg);
380 DBG("saved %p value %08lx\n", ptr->reg, ptr->val);
381 }
382}
383
384/* s3c2410_pm_do_restore
385 *
386 * restore the system from the given list of saved registers
387 *
388 * Note, we do not use DBG() in here, as the system may not have
389 * restore the UARTs state yet
390*/
391
392void s3c2410_pm_do_restore(struct sleep_save *ptr, int count)
393{
394 for (; count > 0; count--, ptr++) {
395 printk(KERN_DEBUG "restore %p (restore %08lx, was %08x)\n",
396 ptr->reg, ptr->val, __raw_readl(ptr->reg));
397
398 __raw_writel(ptr->val, ptr->reg);
399 }
400}
401
402/* s3c2410_pm_do_restore_core
403 *
404 * similar to s3c2410_pm_do_restore_core
405 *
406 * WARNING: Do not put any debug in here that may effect memory or use
407 * peripherals, as things may be changing!
408*/
409
410static void s3c2410_pm_do_restore_core(struct sleep_save *ptr, int count)
411{
412 for (; count > 0; count--, ptr++) {
413 __raw_writel(ptr->val, ptr->reg);
414 }
415}
416
417/* s3c2410_pm_show_resume_irqs
418 *
419 * print any IRQs asserted at resume time (ie, we woke from)
420*/
421
422static void s3c2410_pm_show_resume_irqs(int start, unsigned long which,
423 unsigned long mask)
424{
425 int i;
426
427 which &= ~mask;
428
429 for (i = 0; i <= 31; i++) {
430 if ((which) & (1L<<i)) {
431 DBG("IRQ %d asserted at resume\n", start+i);
432 }
433 }
434}
435
436/* s3c2410_pm_check_resume_pin
437 *
438 * check to see if the pin is configured correctly for sleep mode, and
439 * make any necessary adjustments if it is not
440*/
441
442static void s3c2410_pm_check_resume_pin(unsigned int pin, unsigned int irqoffs)
443{
444 unsigned long irqstate;
445 unsigned long pinstate;
446 int irq = s3c2410_gpio_getirq(pin);
447
448 if (irqoffs < 4)
449 irqstate = s3c_irqwake_intmask & (1L<<irqoffs);
450 else
451 irqstate = s3c_irqwake_eintmask & (1L<<irqoffs);
452
453 pinstate = s3c2410_gpio_getcfg(pin);
454
455 if (!irqstate) {
456 if (pinstate == S3C2410_GPIO_IRQ)
457 DBG("Leaving IRQ %d (pin %d) enabled\n", irq, pin);
458 } else {
459 if (pinstate == S3C2410_GPIO_IRQ) {
460 DBG("Disabling IRQ %d (pin %d)\n", irq, pin);
461 s3c2410_gpio_cfgpin(pin, S3C2410_GPIO_INPUT);
462 }
463 }
464}
465
466/* s3c2410_pm_configure_extint
467 *
468 * configure all external interrupt pins
469*/
470
471static void s3c2410_pm_configure_extint(void)
472{
473 int pin;
474
475 /* for each of the external interrupts (EINT0..EINT15) we
476 * need to check wether it is an external interrupt source,
477 * and then configure it as an input if it is not
478 */
479
480 for (pin = S3C2410_GPF0; pin <= S3C2410_GPF7; pin++) {
481 s3c2410_pm_check_resume_pin(pin, pin - S3C2410_GPF0);
482 }
483
484 for (pin = S3C2410_GPG0; pin <= S3C2410_GPG7; pin++) {
485 s3c2410_pm_check_resume_pin(pin, (pin - S3C2410_GPG0)+8);
486 }
487}
488
489void (*pm_cpu_prep)(void);
490void (*pm_cpu_sleep)(void);
491
492#define any_allowed(mask, allow) (((mask) & (allow)) != (allow))
493
494/* s3c2410_pm_enter
495 *
496 * central control for sleep/resume process
497*/
498
499static int s3c2410_pm_enter(suspend_state_t state)
500{
501 unsigned long regs_save[16];
502
503 /* ensure the debug is initialised (if enabled) */
504
505 s3c2410_pm_debug_init();
506
507 DBG("s3c2410_pm_enter(%d)\n", state);
508
509 if (pm_cpu_prep == NULL || pm_cpu_sleep == NULL) {
510 printk(KERN_ERR PFX "error: no cpu sleep functions set\n");
511 return -EINVAL;
512 }
513
514 if (state != PM_SUSPEND_MEM) {
515 printk(KERN_ERR PFX "error: only PM_SUSPEND_MEM supported\n");
516 return -EINVAL;
517 }
518
519 /* check if we have anything to wake-up with... bad things seem
520 * to happen if you suspend with no wakeup (system will often
521 * require a full power-cycle)
522 */
523
524 if (!any_allowed(s3c_irqwake_intmask, s3c_irqwake_intallow) &&
525 !any_allowed(s3c_irqwake_eintmask, s3c_irqwake_eintallow)) {
526 printk(KERN_ERR PFX "No sources enabled for wake-up!\n");
527 printk(KERN_ERR PFX "Aborting sleep\n");
528 return -EINVAL;
529 }
530
531 /* prepare check area if configured */
532
533 s3c2410_pm_check_prepare();
534
535 /* store the physical address of the register recovery block */
536
537 s3c2410_sleep_save_phys = virt_to_phys(regs_save);
538
539 DBG("s3c2410_sleep_save_phys=0x%08lx\n", s3c2410_sleep_save_phys);
540
541 /* save all necessary core registers not covered by the drivers */
542
543 s3c2410_pm_do_save(gpio_save, ARRAY_SIZE(gpio_save));
544 s3c2410_pm_do_save(core_save, ARRAY_SIZE(core_save));
545 s3c2410_pm_do_save(uart_save, ARRAY_SIZE(uart_save));
546
547 /* set the irq configuration for wake */
548
549 s3c2410_pm_configure_extint();
550
551 DBG("sleep: irq wakeup masks: %08lx,%08lx\n",
552 s3c_irqwake_intmask, s3c_irqwake_eintmask);
553
554 __raw_writel(s3c_irqwake_intmask, S3C2410_INTMSK);
555 __raw_writel(s3c_irqwake_eintmask, S3C2410_EINTMASK);
556
557 /* ack any outstanding external interrupts before we go to sleep */
558
559 __raw_writel(__raw_readl(S3C2410_EINTPEND), S3C2410_EINTPEND);
560 __raw_writel(__raw_readl(S3C2410_INTPND), S3C2410_INTPND);
561 __raw_writel(__raw_readl(S3C2410_SRCPND), S3C2410_SRCPND);
562
563 /* call cpu specific preperation */
564
565 pm_cpu_prep();
566
567 /* flush cache back to ram */
568
569 flush_cache_all();
570
571 s3c2410_pm_check_store();
572
573 /* send the cpu to sleep... */
574
575 __raw_writel(0x00, S3C2410_CLKCON); /* turn off clocks over sleep */
576
577 /* s3c2410_cpu_save will also act as our return point from when
578 * we resume as it saves its own register state, so use the return
579 * code to differentiate return from save and return from sleep */
580
581 if (s3c2410_cpu_save(regs_save) == 0) {
582 flush_cache_all();
583 pm_cpu_sleep();
584 }
585
586 /* restore the cpu state */
587
588 cpu_init();
589
590 /* restore the system state */
591
592 s3c2410_pm_do_restore_core(core_save, ARRAY_SIZE(core_save));
593 s3c2410_pm_do_restore(gpio_save, ARRAY_SIZE(gpio_save));
594 s3c2410_pm_do_restore(uart_save, ARRAY_SIZE(uart_save));
595
596 s3c2410_pm_debug_init();
597
598 /* check what irq (if any) restored the system */
599
600 DBG("post sleep: IRQs 0x%08x, 0x%08x\n",
601 __raw_readl(S3C2410_SRCPND),
602 __raw_readl(S3C2410_EINTPEND));
603
604 s3c2410_pm_show_resume_irqs(IRQ_EINT0, __raw_readl(S3C2410_SRCPND),
605 s3c_irqwake_intmask);
606
607 s3c2410_pm_show_resume_irqs(IRQ_EINT4-4, __raw_readl(S3C2410_EINTPEND),
608 s3c_irqwake_eintmask);
609
610 DBG("post sleep, preparing to return\n");
611
612 s3c2410_pm_check_restore();
613
614 /* ok, let's return from sleep */
615
616 DBG("S3C2410 PM Resume (post-restore)\n");
617 return 0;
618}
619
620/*
621 * Called after processes are frozen, but before we shut down devices.
622 */
623static int s3c2410_pm_prepare(suspend_state_t state)
624{
625 return 0;
626}
627
628/*
629 * Called after devices are re-setup, but before processes are thawed.
630 */
631static int s3c2410_pm_finish(suspend_state_t state)
632{
633 return 0;
634}
635
636/*
637 * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk.
638 */
639static struct pm_ops s3c2410_pm_ops = {
640 .pm_disk_mode = PM_DISK_FIRMWARE,
641 .prepare = s3c2410_pm_prepare,
642 .enter = s3c2410_pm_enter,
643 .finish = s3c2410_pm_finish,
644};
645
646/* s3c2410_pm_init
647 *
648 * Attach the power management functions. This should be called
649 * from the board specific initialisation if the board supports
650 * it.
651*/
652
653int __init s3c2410_pm_init(void)
654{
655 printk("S3C2410 Power Management, (c) 2004 Simtec Electronics\n");
656
657 pm_set_ops(&s3c2410_pm_ops);
658 return 0;
659}
diff --git a/arch/arm/mach-s3c2410/s3c244x-irq.c b/arch/arm/plat-s3c24xx/s3c244x-irq.c
index ede94636a72a..a0e39d894014 100644
--- a/arch/arm/mach-s3c2410/s3c244x-irq.c
+++ b/arch/arm/plat-s3c24xx/s3c244x-irq.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/s3c244x-irq.c 1/* linux/arch/arm/plat-s3c24xx/s3c244x-irq.c
2 * 2 *
3 * Copyright (c) 2003,2004 Simtec Electronics 3 * Copyright (c) 2003,2004 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
@@ -35,9 +35,9 @@
35#include <asm/arch/regs-irq.h> 35#include <asm/arch/regs-irq.h>
36#include <asm/arch/regs-gpio.h> 36#include <asm/arch/regs-gpio.h>
37 37
38#include "cpu.h" 38#include <asm/plat-s3c24xx/cpu.h>
39#include "pm.h" 39#include <asm/plat-s3c24xx/pm.h>
40#include "irq.h" 40#include <asm/plat-s3c24xx/irq.h>
41 41
42/* camera irq */ 42/* camera irq */
43 43
diff --git a/arch/arm/mach-s3c2410/s3c244x.c b/arch/arm/plat-s3c24xx/s3c244x.c
index 23c7494ad10d..767f2e9a3a55 100644
--- a/arch/arm/mach-s3c2410/s3c244x.c
+++ b/arch/arm/plat-s3c24xx/s3c244x.c
@@ -1,9 +1,9 @@
1/* linux/arch/arm/mach-s3c2410/s3c244x.c 1/* linux/arch/arm/plat-s3c24xx/s3c244x.c
2 * 2 *
3 * Copyright (c) 2004-2006 Simtec Electronics 3 * Copyright (c) 2004-2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
5 * 5 *
6 * Samsung S3C2440 and S3C2442 Mobile CPU support 6 * Samsung S3C2440 and S3C2442 Mobile CPU support (not S3C2443)
7 * 7 *
8 * This program is free software; you can redistribute it and/or modify 8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License version 2 as 9 * it under the terms of the GNU General Public License version 2 as
@@ -35,13 +35,13 @@
35#include <asm/arch/regs-gpioj.h> 35#include <asm/arch/regs-gpioj.h>
36#include <asm/arch/regs-dsc.h> 36#include <asm/arch/regs-dsc.h>
37 37
38#include "s3c2410.h" 38#include <asm/plat-s3c24xx/s3c2410.h>
39#include "s3c2440.h" 39#include <asm/plat-s3c24xx/s3c2440.h>
40#include "s3c244x.h" 40#include "s3c244x.h"
41#include "clock.h" 41#include <asm/plat-s3c24xx/clock.h>
42#include "devs.h" 42#include <asm/plat-s3c24xx/devs.h>
43#include "cpu.h" 43#include <asm/plat-s3c24xx/cpu.h>
44#include "pm.h" 44#include <asm/plat-s3c24xx/pm.h>
45 45
46static struct map_desc s3c244x_iodesc[] __initdata = { 46static struct map_desc s3c244x_iodesc[] __initdata = {
47 IODESC_ENT(CLKPWR), 47 IODESC_ENT(CLKPWR),
diff --git a/arch/arm/mach-s3c2410/s3c244x.h b/arch/arm/plat-s3c24xx/s3c244x.h
index 1488c1eb37e6..f8ed17676a35 100644
--- a/arch/arm/mach-s3c2410/s3c244x.h
+++ b/arch/arm/plat-s3c24xx/s3c244x.h
@@ -1,4 +1,4 @@
1/* arch/arm/mach-s3c2410/s3c244x.h 1/* linux/arch/arm/plat-s3c24xx/s3c244x.h
2 * 2 *
3 * Copyright (c) 2004-2005 Simtec Electronics 3 * Copyright (c) 2004-2005 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/plat-s3c24xx/sleep.S b/arch/arm/plat-s3c24xx/sleep.S
new file mode 100644
index 000000000000..435349dc3243
--- /dev/null
+++ b/arch/arm/plat-s3c24xx/sleep.S
@@ -0,0 +1,157 @@
1/* linux/arch/arm/mach-s3c2410/sleep.S
2 *
3 * Copyright (c) 2004 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * S3C2410 Power Manager (Suspend-To-RAM) support
7 *
8 * Based on PXA/SA1100 sleep code by:
9 * Nicolas Pitre, (c) 2002 Monta Vista Software Inc
10 * Cliff Brake, (c) 2001
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 as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25*/
26
27#include <linux/linkage.h>
28#include <asm/assembler.h>
29#include <asm/hardware.h>
30#include <asm/arch/map.h>
31
32#include <asm/arch/regs-gpio.h>
33#include <asm/arch/regs-clock.h>
34#include <asm/arch/regs-mem.h>
35#include <asm/arch/regs-serial.h>
36
37/* CONFIG_DEBUG_RESUME is dangerous if your bootloader does not
38 * reset the UART configuration, only enable if you really need this!
39*/
40//#define CONFIG_DEBUG_RESUME
41
42 .text
43
44 /* s3c2410_cpu_save
45 *
46 * save enough of the CPU state to allow us to re-start
47 * pm.c code. as we store items like the sp/lr, we will
48 * end up returning from this function when the cpu resumes
49 * so the return value is set to mark this.
50 *
51 * This arangement means we avoid having to flush the cache
52 * from this code.
53 *
54 * entry:
55 * r0 = pointer to save block
56 *
57 * exit:
58 * r0 = 0 => we stored everything
59 * 1 => resumed from sleep
60 */
61
62ENTRY(s3c2410_cpu_save)
63 stmfd sp!, { r4 - r12, lr }
64
65 @@ store co-processor registers
66
67 mrc p15, 0, r4, c13, c0, 0 @ PID
68 mrc p15, 0, r5, c3, c0, 0 @ Domain ID
69 mrc p15, 0, r6, c2, c0, 0 @ translation table base address
70 mrc p15, 0, r7, c1, c0, 0 @ control register
71
72 stmia r0, { r4 - r13 }
73
74 mov r0, #0
75 ldmfd sp, { r4 - r12, pc }
76
77 @@ return to the caller, after having the MMU
78 @@ turned on, this restores the last bits from the
79 @@ stack
80resume_with_mmu:
81 mov r0, #1
82 ldmfd sp!, { r4 - r12, pc }
83
84 .ltorg
85
86 @@ the next bits sit in the .data segment, even though they
87 @@ happen to be code... the s3c2410_sleep_save_phys needs to be
88 @@ accessed by the resume code before it can restore the MMU.
89 @@ This means that the variable has to be close enough for the
90 @@ code to read it... since the .text segment needs to be RO,
91 @@ the data segment can be the only place to put this code.
92
93 .data
94
95 .global s3c2410_sleep_save_phys
96s3c2410_sleep_save_phys:
97 .word 0
98
99 /* s3c2410_cpu_resume
100 *
101 * resume code entry for bootloader to call
102 *
103 * we must put this code here in the data segment as we have no
104 * other way of restoring the stack pointer after sleep, and we
105 * must not write to the code segment (code is read-only)
106 */
107
108ENTRY(s3c2410_cpu_resume)
109 mov r0, #PSR_I_BIT | PSR_F_BIT | SVC_MODE
110 msr cpsr_c, r0
111
112 @@ load UART to allow us to print the two characters for
113 @@ resume debug
114
115 mov r2, #S3C24XX_PA_UART & 0xff000000
116 orr r2, r2, #S3C24XX_PA_UART & 0xff000
117
118#if 0
119 /* SMDK2440 LED set */
120 mov r14, #S3C24XX_PA_GPIO
121 ldr r12, [ r14, #0x54 ]
122 bic r12, r12, #3<<4
123 orr r12, r12, #1<<7
124 str r12, [ r14, #0x54 ]
125#endif
126
127#ifdef CONFIG_DEBUG_RESUME
128 mov r3, #'L'
129 strb r3, [ r2, #S3C2410_UTXH ]
1301001:
131 ldrb r14, [ r3, #S3C2410_UTRSTAT ]
132 tst r14, #S3C2410_UTRSTAT_TXE
133 beq 1001b
134#endif /* CONFIG_DEBUG_RESUME */
135
136 mov r1, #0
137 mcr p15, 0, r1, c8, c7, 0 @@ invalidate I & D TLBs
138 mcr p15, 0, r1, c7, c7, 0 @@ invalidate I & D caches
139
140 ldr r0, s3c2410_sleep_save_phys @ address of restore block
141 ldmia r0, { r4 - r13 }
142
143 mcr p15, 0, r4, c13, c0, 0 @ PID
144 mcr p15, 0, r5, c3, c0, 0 @ Domain ID
145 mcr p15, 0, r6, c2, c0, 0 @ translation table base
146
147#ifdef CONFIG_DEBUG_RESUME
148 mov r3, #'R'
149 strb r3, [ r2, #S3C2410_UTXH ]
150#endif
151
152 ldr r2, =resume_with_mmu
153 mcr p15, 0, r7, c1, c0, 0 @ turn on MMU, etc
154 nop @ second-to-last before mmu
155 mov pc, r2 @ go back to virtual address
156
157 .ltorg
diff --git a/arch/arm/mach-s3c2410/time.c b/arch/arm/plat-s3c24xx/time.c
index 9910bf0f2cea..c523d1c9cce5 100644
--- a/arch/arm/mach-s3c2410/time.c
+++ b/arch/arm/plat-s3c24xx/time.c
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/time.c 1/* linux/arch/arm/plat-s3c24xx/time.c
2 * 2 *
3 * Copyright (C) 2003-2005 Simtec Electronics 3 * Copyright (C) 2003-2005 Simtec Electronics
4 * Ben Dooks, <ben@simtec.co.uk> 4 * Ben Dooks, <ben@simtec.co.uk>
@@ -37,8 +37,8 @@
37#include <asm/arch/regs-irq.h> 37#include <asm/arch/regs-irq.h>
38#include <asm/mach/time.h> 38#include <asm/mach/time.h>
39 39
40#include "clock.h" 40#include <asm/plat-s3c24xx/clock.h>
41#include "cpu.h" 41#include <asm/plat-s3c24xx/cpu.h>
42 42
43static unsigned long timer_startval; 43static unsigned long timer_startval;
44static unsigned long timer_usec_ticks; 44static unsigned long timer_usec_ticks;
diff --git a/arch/avr32/mach-at32ap/clock.c b/arch/avr32/mach-at32ap/clock.c
index 49e7b12fe710..00c435452d7e 100644
--- a/arch/avr32/mach-at32ap/clock.c
+++ b/arch/avr32/mach-at32ap/clock.c
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2006 Atmel Corporation 4 * Copyright (C) 2006 Atmel Corporation
5 * 5 *
6 * Based on arch/arm/mach-at91rm9200/clock.c 6 * Based on arch/arm/mach-at91/clock.c
7 * Copyright (C) 2005 David Brownell 7 * Copyright (C) 2005 David Brownell
8 * Copyright (C) 2005 Ivan Kokshaysky 8 * Copyright (C) 2005 Ivan Kokshaysky
9 * 9 *
diff --git a/arch/avr32/mach-at32ap/clock.h b/arch/avr32/mach-at32ap/clock.h
index f953f044ba4d..bb8e1f295835 100644
--- a/arch/avr32/mach-at32ap/clock.h
+++ b/arch/avr32/mach-at32ap/clock.h
@@ -3,7 +3,7 @@
3 * 3 *
4 * Copyright (C) 2006 Atmel Corporation 4 * Copyright (C) 2006 Atmel Corporation
5 * 5 *
6 * Based on arch/arm/mach-at91rm9200/clock.c 6 * Based on arch/arm/mach-at91/clock.c
7 * Copyright (C) 2005 David Brownell 7 * Copyright (C) 2005 David Brownell
8 * Copyright (C) 2005 Ivan Kokshaysky 8 * Copyright (C) 2005 Ivan Kokshaysky
9 * 9 *
diff --git a/arch/i386/kernel/acpi/boot.c b/arch/i386/kernel/acpi/boot.c
index fb3e72328a5a..e5eb97a910ed 100644
--- a/arch/i386/kernel/acpi/boot.c
+++ b/arch/i386/kernel/acpi/boot.c
@@ -850,10 +850,9 @@ static inline int acpi_parse_madt_ioapic_entries(void)
850static void __init acpi_process_madt(void) 850static void __init acpi_process_madt(void)
851{ 851{
852#ifdef CONFIG_X86_LOCAL_APIC 852#ifdef CONFIG_X86_LOCAL_APIC
853 int count, error; 853 int error;
854 854
855 count = acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt); 855 if (!acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) {
856 if (count >= 1) {
857 856
858 /* 857 /*
859 * Parse MADT LAPIC entries 858 * Parse MADT LAPIC entries
diff --git a/arch/i386/pci/common.c b/arch/i386/pci/common.c
index 53ca6e897984..1bb069372143 100644
--- a/arch/i386/pci/common.c
+++ b/arch/i386/pci/common.c
@@ -191,6 +191,94 @@ static struct dmi_system_id __devinitdata pciprobe_dmi_table[] = {
191 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2950"), 191 DMI_MATCH(DMI_PRODUCT_NAME, "PowerEdge 2950"),
192 }, 192 },
193 }, 193 },
194 {
195 .callback = set_bf_sort,
196 .ident = "HP ProLiant BL20p G3",
197 .matches = {
198 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
199 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL20p G3"),
200 },
201 },
202 {
203 .callback = set_bf_sort,
204 .ident = "HP ProLiant BL20p G4",
205 .matches = {
206 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
207 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL20p G4"),
208 },
209 },
210 {
211 .callback = set_bf_sort,
212 .ident = "HP ProLiant BL30p G1",
213 .matches = {
214 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
215 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL30p G1"),
216 },
217 },
218 {
219 .callback = set_bf_sort,
220 .ident = "HP ProLiant BL25p G1",
221 .matches = {
222 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
223 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL25p G1"),
224 },
225 },
226 {
227 .callback = set_bf_sort,
228 .ident = "HP ProLiant BL35p G1",
229 .matches = {
230 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
231 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL35p G1"),
232 },
233 },
234 {
235 .callback = set_bf_sort,
236 .ident = "HP ProLiant BL45p G1",
237 .matches = {
238 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
239 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL45p G1"),
240 },
241 },
242 {
243 .callback = set_bf_sort,
244 .ident = "HP ProLiant BL45p G2",
245 .matches = {
246 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
247 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL45p G2"),
248 },
249 },
250 {
251 .callback = set_bf_sort,
252 .ident = "HP ProLiant BL460c G1",
253 .matches = {
254 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
255 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL460c G1"),
256 },
257 },
258 {
259 .callback = set_bf_sort,
260 .ident = "HP ProLiant BL465c G1",
261 .matches = {
262 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
263 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL465c G1"),
264 },
265 },
266 {
267 .callback = set_bf_sort,
268 .ident = "HP ProLiant BL480c G1",
269 .matches = {
270 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
271 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL480c G1"),
272 },
273 },
274 {
275 .callback = set_bf_sort,
276 .ident = "HP ProLiant BL685c G1",
277 .matches = {
278 DMI_MATCH(DMI_SYS_VENDOR, "HP"),
279 DMI_MATCH(DMI_PRODUCT_NAME, "ProLiant BL685c G1"),
280 },
281 },
194 {} 282 {}
195}; 283};
196 284
diff --git a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
index 9197d7b361b3..3549c94467b8 100644
--- a/arch/ia64/kernel/acpi.c
+++ b/arch/ia64/kernel/acpi.c
@@ -651,7 +651,7 @@ int __init acpi_boot_init(void)
651 * information -- the successor to MPS tables. 651 * information -- the successor to MPS tables.
652 */ 652 */
653 653
654 if (acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt) < 1) { 654 if (acpi_table_parse(ACPI_SIG_MADT, acpi_parse_madt)) {
655 printk(KERN_ERR PREFIX "Can't find MADT\n"); 655 printk(KERN_ERR PREFIX "Can't find MADT\n");
656 goto skip_madt; 656 goto skip_madt;
657 } 657 }
@@ -702,7 +702,7 @@ int __init acpi_boot_init(void)
702 * gets interrupts such as power and sleep buttons. If it's not 702 * gets interrupts such as power and sleep buttons. If it's not
703 * on a Legacy interrupt, it needs to be setup. 703 * on a Legacy interrupt, it needs to be setup.
704 */ 704 */
705 if (acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt) < 1) 705 if (acpi_table_parse(ACPI_SIG_FADT, acpi_parse_fadt))
706 printk(KERN_ERR PREFIX "Can't find FADT\n"); 706 printk(KERN_ERR PREFIX "Can't find FADT\n");
707 707
708#ifdef CONFIG_SMP 708#ifdef CONFIG_SMP
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 340d9beab6d1..6dfbd52694ab 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -620,6 +620,15 @@ config RTAS_FLASH
620 tristate "Firmware flash interface" 620 tristate "Firmware flash interface"
621 depends on PPC64 && RTAS_PROC 621 depends on PPC64 && RTAS_PROC
622 622
623config PPC_PMI
624 tristate "Support for PMI"
625 depends PPC_IBM_CELL_BLADE
626 help
627 PMI (Platform Management Interrupt) is a way to
628 communicate with the BMC (Baseboard Mangement Controller).
629 It is used in some IBM Cell blades.
630 default m
631
623config MMIO_NVRAM 632config MMIO_NVRAM
624 bool 633 bool
625 default n 634 default n
diff --git a/arch/powerpc/boot/dts/kuroboxHD.dts b/arch/powerpc/boot/dts/kuroboxHD.dts
index 096e94ac415f..b89791802e86 100644
--- a/arch/powerpc/boot/dts/kuroboxHD.dts
+++ b/arch/powerpc/boot/dts/kuroboxHD.dts
@@ -35,7 +35,6 @@ build with: "dtc -f -I dts -O dtb -o kuroboxHD.dtb -V 16 kuroboxHD.dts"
35 35
36 PowerPC,603e { /* Really 8241 */ 36 PowerPC,603e { /* Really 8241 */
37 linux,phandle = <2100>; 37 linux,phandle = <2100>;
38 linux,boot-cpu;
39 device_type = "cpu"; 38 device_type = "cpu";
40 reg = <0>; 39 reg = <0>;
41 clock-frequency = <bebc200>; /* Fixed by bootwrapper */ 40 clock-frequency = <bebc200>; /* Fixed by bootwrapper */
diff --git a/arch/powerpc/boot/dts/kuroboxHG.dts b/arch/powerpc/boot/dts/kuroboxHG.dts
index d06b0b018899..753102752d8b 100644
--- a/arch/powerpc/boot/dts/kuroboxHG.dts
+++ b/arch/powerpc/boot/dts/kuroboxHG.dts
@@ -35,7 +35,6 @@ build with: "dtc -f -I dts -O dtb -o kuroboxHG.dtb -V 16 kuroboxHG.dts"
35 35
36 PowerPC,603e { /* Really 8241 */ 36 PowerPC,603e { /* Really 8241 */
37 linux,phandle = <2100>; 37 linux,phandle = <2100>;
38 linux,boot-cpu;
39 device_type = "cpu"; 38 device_type = "cpu";
40 reg = <0>; 39 reg = <0>;
41 clock-frequency = <fdad680>; /* Fixed by bootwrapper */ 40 clock-frequency = <fdad680>; /* Fixed by bootwrapper */
diff --git a/arch/powerpc/boot/dts/mpc7448hpc2.dts b/arch/powerpc/boot/dts/mpc7448hpc2.dts
index c4d9562cbaad..41d0720c5900 100644
--- a/arch/powerpc/boot/dts/mpc7448hpc2.dts
+++ b/arch/powerpc/boot/dts/mpc7448hpc2.dts
@@ -36,7 +36,6 @@
36 bus-frequency = <0>; // From U-Boot 36 bus-frequency = <0>; // From U-Boot
37 32-bit; 37 32-bit;
38 linux,phandle = <201>; 38 linux,phandle = <201>;
39 linux,boot-cpu;
40 }; 39 };
41 }; 40 };
42 41
diff --git a/arch/powerpc/boot/dts/mpc8272ads.dts b/arch/powerpc/boot/dts/mpc8272ads.dts
index 26b44f7513dc..260b2e447779 100644
--- a/arch/powerpc/boot/dts/mpc8272ads.dts
+++ b/arch/powerpc/boot/dts/mpc8272ads.dts
@@ -34,7 +34,6 @@
34 clock-frequency = <0>; 34 clock-frequency = <0>;
35 32-bit; 35 32-bit;
36 linux,phandle = <201>; 36 linux,phandle = <201>;
37 linux,boot-cpu;
38 }; 37 };
39 }; 38 };
40 39
diff --git a/arch/powerpc/boot/dts/mpc8313erdb.dts b/arch/powerpc/boot/dts/mpc8313erdb.dts
index 3d2f5a06df3f..6d721900d00e 100644
--- a/arch/powerpc/boot/dts/mpc8313erdb.dts
+++ b/arch/powerpc/boot/dts/mpc8313erdb.dts
@@ -11,7 +11,7 @@
11 11
12/ { 12/ {
13 model = "MPC8313ERDB"; 13 model = "MPC8313ERDB";
14 compatible = "MPC83xx"; 14 compatible = "MPC8313ERDB", "MPC831xRDB", "MPC83xxRDB";
15 #address-cells = <1>; 15 #address-cells = <1>;
16 #size-cells = <1>; 16 #size-cells = <1>;
17 17
@@ -59,7 +59,7 @@
59 compatible = "fsl-i2c"; 59 compatible = "fsl-i2c";
60 reg = <3000 100>; 60 reg = <3000 100>;
61 interrupts = <e 8>; 61 interrupts = <e 8>;
62 interrupt-parent = <700>; 62 interrupt-parent = < &ipic >;
63 dfsrr; 63 dfsrr;
64 }; 64 };
65 65
@@ -68,7 +68,7 @@
68 compatible = "fsl-i2c"; 68 compatible = "fsl-i2c";
69 reg = <3100 100>; 69 reg = <3100 100>;
70 interrupts = <f 8>; 70 interrupts = <f 8>;
71 interrupt-parent = <700>; 71 interrupt-parent = < &ipic >;
72 dfsrr; 72 dfsrr;
73 }; 73 };
74 74
@@ -77,7 +77,7 @@
77 compatible = "mpc83xx_spi"; 77 compatible = "mpc83xx_spi";
78 reg = <7000 1000>; 78 reg = <7000 1000>;
79 interrupts = <10 8>; 79 interrupts = <10 8>;
80 interrupt-parent = <700>; 80 interrupt-parent = < &ipic >;
81 mode = <0>; 81 mode = <0>;
82 }; 82 };
83 83
@@ -88,8 +88,8 @@
88 reg = <23000 1000>; 88 reg = <23000 1000>;
89 #address-cells = <1>; 89 #address-cells = <1>;
90 #size-cells = <0>; 90 #size-cells = <0>;
91 interrupt-parent = <700>; 91 interrupt-parent = < &ipic >;
92 interrupts = <26 2>; 92 interrupts = <26 8>;
93 phy_type = "utmi_wide"; 93 phy_type = "utmi_wide";
94 }; 94 };
95 95
@@ -99,18 +99,15 @@
99 reg = <24520 20>; 99 reg = <24520 20>;
100 #address-cells = <1>; 100 #address-cells = <1>;
101 #size-cells = <0>; 101 #size-cells = <0>;
102 linux,phandle = <24520>; 102 phy1: ethernet-phy@1 {
103 ethernet-phy@1 { 103 interrupt-parent = < &ipic >;
104 linux,phandle = <2452001>; 104 interrupts = <13 8>;
105 interrupt-parent = <700>;
106 interrupts = <13 2>;
107 reg = <1>; 105 reg = <1>;
108 device_type = "ethernet-phy"; 106 device_type = "ethernet-phy";
109 }; 107 };
110 ethernet-phy@4 { 108 phy4: ethernet-phy@4 {
111 linux,phandle = <2452004>; 109 interrupt-parent = < &ipic >;
112 interrupt-parent = <700>; 110 interrupts = <14 8>;
113 interrupts = <14 2>;
114 reg = <4>; 111 reg = <4>;
115 device_type = "ethernet-phy"; 112 device_type = "ethernet-phy";
116 }; 113 };
@@ -123,8 +120,8 @@
123 reg = <24000 1000>; 120 reg = <24000 1000>;
124 local-mac-address = [ 00 00 00 00 00 00 ]; 121 local-mac-address = [ 00 00 00 00 00 00 ];
125 interrupts = <25 8 24 8 23 8>; 122 interrupts = <25 8 24 8 23 8>;
126 interrupt-parent = <700>; 123 interrupt-parent = < &ipic >;
127 phy-handle = <2452001>; 124 phy-handle = < &phy1 >;
128 }; 125 };
129 126
130 ethernet@25000 { 127 ethernet@25000 {
@@ -134,8 +131,8 @@
134 reg = <25000 1000>; 131 reg = <25000 1000>;
135 local-mac-address = [ 00 00 00 00 00 00 ]; 132 local-mac-address = [ 00 00 00 00 00 00 ];
136 interrupts = <22 8 21 8 20 8>; 133 interrupts = <22 8 21 8 20 8>;
137 interrupt-parent = <700>; 134 interrupt-parent = < &ipic >;
138 phy-handle = <2452004>; 135 phy-handle = < &phy4 >;
139 }; 136 };
140 137
141 serial@4500 { 138 serial@4500 {
@@ -144,7 +141,7 @@
144 reg = <4500 100>; 141 reg = <4500 100>;
145 clock-frequency = <0>; 142 clock-frequency = <0>;
146 interrupts = <9 8>; 143 interrupts = <9 8>;
147 interrupt-parent = <700>; 144 interrupt-parent = < &ipic >;
148 }; 145 };
149 146
150 serial@4600 { 147 serial@4600 {
@@ -153,7 +150,7 @@
153 reg = <4600 100>; 150 reg = <4600 100>;
154 clock-frequency = <0>; 151 clock-frequency = <0>;
155 interrupts = <a 8>; 152 interrupts = <a 8>;
156 interrupt-parent = <700>; 153 interrupt-parent = < &ipic >;
157 }; 154 };
158 155
159 pci@8500 { 156 pci@8500 {
@@ -161,17 +158,17 @@
161 interrupt-map = < 158 interrupt-map = <
162 159
163 /* IDSEL 0x0E -mini PCI */ 160 /* IDSEL 0x0E -mini PCI */
164 7000 0 0 1 700 12 8 161 7000 0 0 1 &ipic 12 8
165 7000 0 0 2 700 12 8 162 7000 0 0 2 &ipic 12 8
166 7000 0 0 3 700 12 8 163 7000 0 0 3 &ipic 12 8
167 7000 0 0 4 700 12 8 164 7000 0 0 4 &ipic 12 8
168 165
169 /* IDSEL 0x0F - PCI slot */ 166 /* IDSEL 0x0F - PCI slot */
170 7800 0 0 1 700 11 8 167 7800 0 0 1 &ipic 11 8
171 7800 0 0 2 700 12 8 168 7800 0 0 2 &ipic 12 8
172 7800 0 0 3 700 11 8 169 7800 0 0 3 &ipic 11 8
173 7800 0 0 4 700 12 8>; 170 7800 0 0 4 &ipic 12 8>;
174 interrupt-parent = <700>; 171 interrupt-parent = < &ipic >;
175 interrupts = <42 8>; 172 interrupts = <42 8>;
176 bus-range = <0 0>; 173 bus-range = <0 0>;
177 ranges = <02000000 0 90000000 90000000 0 10000000 174 ranges = <02000000 0 90000000 90000000 0 10000000
@@ -192,7 +189,7 @@
192 compatible = "talitos"; 189 compatible = "talitos";
193 reg = <30000 7000>; 190 reg = <30000 7000>;
194 interrupts = <b 8>; 191 interrupts = <b 8>;
195 interrupt-parent = <700>; 192 interrupt-parent = < &ipic >;
196 /* Rev. 2.2 */ 193 /* Rev. 2.2 */
197 num-channels = <1>; 194 num-channels = <1>;
198 channel-fifo-len = <18>; 195 channel-fifo-len = <18>;
@@ -206,8 +203,7 @@
206 * sense == 8: Level, low assertion 203 * sense == 8: Level, low assertion
207 * sense == 2: Edge, high-to-low change 204 * sense == 2: Edge, high-to-low change
208 */ 205 */
209 pic@700 { 206 ipic: pic@700 {
210 linux,phandle = <700>;
211 interrupt-controller; 207 interrupt-controller;
212 #address-cells = <0>; 208 #address-cells = <0>;
213 #interrupt-cells = <2>; 209 #interrupt-cells = <2>;
diff --git a/arch/powerpc/boot/dts/mpc8323emds.dts b/arch/powerpc/boot/dts/mpc832x_mds.dts
index fa7ef24d205b..06b310698a02 100644
--- a/arch/powerpc/boot/dts/mpc8323emds.dts
+++ b/arch/powerpc/boot/dts/mpc832x_mds.dts
@@ -11,16 +11,14 @@
11 11
12/ { 12/ {
13 model = "MPC8323EMDS"; 13 model = "MPC8323EMDS";
14 compatible = "MPC83xx"; 14 compatible = "MPC8323EMDS", "MPC832xMDS", "MPC83xxMDS";
15 #address-cells = <1>; 15 #address-cells = <1>;
16 #size-cells = <1>; 16 #size-cells = <1>;
17 linux,phandle = <100>;
18 17
19 cpus { 18 cpus {
20 #cpus = <1>; 19 #cpus = <1>;
21 #address-cells = <1>; 20 #address-cells = <1>;
22 #size-cells = <0>; 21 #size-cells = <0>;
23 linux,phandle = <200>;
24 22
25 PowerPC,8323@0 { 23 PowerPC,8323@0 {
26 device_type = "cpu"; 24 device_type = "cpu";
@@ -33,14 +31,11 @@
33 bus-frequency = <0>; 31 bus-frequency = <0>;
34 clock-frequency = <0>; 32 clock-frequency = <0>;
35 32-bit; 33 32-bit;
36 linux,phandle = <201>;
37 linux,boot-cpu;
38 }; 34 };
39 }; 35 };
40 36
41 memory { 37 memory {
42 device_type = "memory"; 38 device_type = "memory";
43 linux,phandle = <300>;
44 reg = <00000000 08000000>; 39 reg = <00000000 08000000>;
45 }; 40 };
46 41
@@ -69,7 +64,7 @@
69 compatible = "fsl-i2c"; 64 compatible = "fsl-i2c";
70 reg = <3000 100>; 65 reg = <3000 100>;
71 interrupts = <e 8>; 66 interrupts = <e 8>;
72 interrupt-parent = <700>; 67 interrupt-parent = < &ipic >;
73 dfsrr; 68 dfsrr;
74 }; 69 };
75 70
@@ -79,7 +74,7 @@
79 reg = <4500 100>; 74 reg = <4500 100>;
80 clock-frequency = <0>; 75 clock-frequency = <0>;
81 interrupts = <9 8>; 76 interrupts = <9 8>;
82 interrupt-parent = <700>; 77 interrupt-parent = < &ipic >;
83 }; 78 };
84 79
85 serial@4600 { 80 serial@4600 {
@@ -88,7 +83,7 @@
88 reg = <4600 100>; 83 reg = <4600 100>;
89 clock-frequency = <0>; 84 clock-frequency = <0>;
90 interrupts = <a 8>; 85 interrupts = <a 8>;
91 interrupt-parent = <700>; 86 interrupt-parent = < &ipic >;
92 }; 87 };
93 88
94 crypto@30000 { 89 crypto@30000 {
@@ -97,7 +92,7 @@
97 compatible = "talitos"; 92 compatible = "talitos";
98 reg = <30000 7000>; 93 reg = <30000 7000>;
99 interrupts = <b 8>; 94 interrupts = <b 8>;
100 interrupt-parent = <700>; 95 interrupt-parent = < &ipic >;
101 /* Rev. 2.2 */ 96 /* Rev. 2.2 */
102 num-channels = <1>; 97 num-channels = <1>;
103 channel-fifo-len = <18>; 98 channel-fifo-len = <18>;
@@ -106,51 +101,50 @@
106 }; 101 };
107 102
108 pci@8500 { 103 pci@8500 {
109 linux,phandle = <8500>;
110 interrupt-map-mask = <f800 0 0 7>; 104 interrupt-map-mask = <f800 0 0 7>;
111 interrupt-map = < 105 interrupt-map = <
112 /* IDSEL 0x11 AD17 */ 106 /* IDSEL 0x11 AD17 */
113 8800 0 0 1 700 14 8 107 8800 0 0 1 &ipic 14 8
114 8800 0 0 2 700 15 8 108 8800 0 0 2 &ipic 15 8
115 8800 0 0 3 700 16 8 109 8800 0 0 3 &ipic 16 8
116 8800 0 0 4 700 17 8 110 8800 0 0 4 &ipic 17 8
117 111
118 /* IDSEL 0x12 AD18 */ 112 /* IDSEL 0x12 AD18 */
119 9000 0 0 1 700 16 8 113 9000 0 0 1 &ipic 16 8
120 9000 0 0 2 700 17 8 114 9000 0 0 2 &ipic 17 8
121 9000 0 0 3 700 14 8 115 9000 0 0 3 &ipic 14 8
122 9000 0 0 4 700 15 8 116 9000 0 0 4 &ipic 15 8
123 117
124 /* IDSEL 0x13 AD19 */ 118 /* IDSEL 0x13 AD19 */
125 9800 0 0 1 700 17 8 119 9800 0 0 1 &ipic 17 8
126 9800 0 0 2 700 14 8 120 9800 0 0 2 &ipic 14 8
127 9800 0 0 3 700 15 8 121 9800 0 0 3 &ipic 15 8
128 9800 0 0 4 700 16 8 122 9800 0 0 4 &ipic 16 8
129 123
130 /* IDSEL 0x15 AD21*/ 124 /* IDSEL 0x15 AD21*/
131 a800 0 0 1 700 14 8 125 a800 0 0 1 &ipic 14 8
132 a800 0 0 2 700 15 8 126 a800 0 0 2 &ipic 15 8
133 a800 0 0 3 700 16 8 127 a800 0 0 3 &ipic 16 8
134 a800 0 0 4 700 17 8 128 a800 0 0 4 &ipic 17 8
135 129
136 /* IDSEL 0x16 AD22*/ 130 /* IDSEL 0x16 AD22*/
137 b000 0 0 1 700 17 8 131 b000 0 0 1 &ipic 17 8
138 b000 0 0 2 700 14 8 132 b000 0 0 2 &ipic 14 8
139 b000 0 0 3 700 15 8 133 b000 0 0 3 &ipic 15 8
140 b000 0 0 4 700 16 8 134 b000 0 0 4 &ipic 16 8
141 135
142 /* IDSEL 0x17 AD23*/ 136 /* IDSEL 0x17 AD23*/
143 b800 0 0 1 700 16 8 137 b800 0 0 1 &ipic 16 8
144 b800 0 0 2 700 17 8 138 b800 0 0 2 &ipic 17 8
145 b800 0 0 3 700 14 8 139 b800 0 0 3 &ipic 14 8
146 b800 0 0 4 700 15 8 140 b800 0 0 4 &ipic 15 8
147 141
148 /* IDSEL 0x18 AD24*/ 142 /* IDSEL 0x18 AD24*/
149 c000 0 0 1 700 15 8 143 c000 0 0 1 &ipic 15 8
150 c000 0 0 2 700 16 8 144 c000 0 0 2 &ipic 16 8
151 c000 0 0 3 700 17 8 145 c000 0 0 3 &ipic 17 8
152 c000 0 0 4 700 14 8>; 146 c000 0 0 4 &ipic 14 8>;
153 interrupt-parent = <700>; 147 interrupt-parent = < &ipic >;
154 interrupts = <42 8>; 148 interrupts = <42 8>;
155 bus-range = <0 0>; 149 bus-range = <0 0>;
156 ranges = <02000000 0 a0000000 90000000 0 10000000 150 ranges = <02000000 0 a0000000 90000000 0 10000000
@@ -165,8 +159,7 @@
165 device_type = "pci"; 159 device_type = "pci";
166 }; 160 };
167 161
168 pic@700 { 162 ipic: pic@700 {
169 linux,phandle = <700>;
170 interrupt-controller; 163 interrupt-controller;
171 #address-cells = <0>; 164 #address-cells = <0>;
172 #interrupt-cells = <2>; 165 #interrupt-cells = <2>;
@@ -180,8 +173,7 @@
180 device_type = "par_io"; 173 device_type = "par_io";
181 num-ports = <7>; 174 num-ports = <7>;
182 175
183 ucc_pin@03 { 176 pio3: ucc_pin@03 {
184 linux,phandle = <140003>;
185 pio-map = < 177 pio-map = <
186 /* port pin dir open_drain assignment has_irq */ 178 /* port pin dir open_drain assignment has_irq */
187 3 4 3 0 2 0 /* MDIO */ 179 3 4 3 0 2 0 /* MDIO */
@@ -204,8 +196,7 @@
204 1 c 1 0 1 0 /* TX_EN */ 196 1 c 1 0 1 0 /* TX_EN */
205 1 d 2 0 1 0>;/* CRS */ 197 1 d 2 0 1 0>;/* CRS */
206 }; 198 };
207 ucc_pin@04 { 199 pio4: ucc_pin@04 {
208 linux,phandle = <140004>;
209 pio-map = < 200 pio-map = <
210 /* port pin dir open_drain assignment has_irq */ 201 /* port pin dir open_drain assignment has_irq */
211 3 1f 2 0 1 0 /* RX_CLK (CLK7) */ 202 3 1f 2 0 1 0 /* RX_CLK (CLK7) */
@@ -252,7 +243,7 @@
252 compatible = "fsl_spi"; 243 compatible = "fsl_spi";
253 reg = <4c0 40>; 244 reg = <4c0 40>;
254 interrupts = <2>; 245 interrupts = <2>;
255 interrupt-parent = <80>; 246 interrupt-parent = < &qeic >;
256 mode = "cpu"; 247 mode = "cpu";
257 }; 248 };
258 249
@@ -261,7 +252,7 @@
261 compatible = "fsl_spi"; 252 compatible = "fsl_spi";
262 reg = <500 40>; 253 reg = <500 40>;
263 interrupts = <1>; 254 interrupts = <1>;
264 interrupt-parent = <80>; 255 interrupt-parent = < &qeic >;
265 mode = "cpu"; 256 mode = "cpu";
266 }; 257 };
267 258
@@ -270,7 +261,7 @@
270 compatible = "qe_udc"; 261 compatible = "qe_udc";
271 reg = <6c0 40 8B00 100>; 262 reg = <6c0 40 8B00 100>;
272 interrupts = <b>; 263 interrupts = <b>;
273 interrupt-parent = <80>; 264 interrupt-parent = < &qeic >;
274 mode = "slave"; 265 mode = "slave";
275 }; 266 };
276 267
@@ -281,12 +272,12 @@
281 device-id = <3>; 272 device-id = <3>;
282 reg = <2200 200>; 273 reg = <2200 200>;
283 interrupts = <22>; 274 interrupts = <22>;
284 interrupt-parent = <80>; 275 interrupt-parent = < &qeic >;
285 mac-address = [ 00 04 9f 00 23 23 ]; 276 mac-address = [ 00 04 9f 00 23 23 ];
286 rx-clock = <19>; 277 rx-clock = <19>;
287 tx-clock = <1a>; 278 tx-clock = <1a>;
288 phy-handle = <212003>; 279 phy-handle = < &phy3 >;
289 pio-handle = <140003>; 280 pio-handle = < &pio3 >;
290 }; 281 };
291 282
292 ucc@3200 { 283 ucc@3200 {
@@ -296,12 +287,12 @@
296 device-id = <4>; 287 device-id = <4>;
297 reg = <3000 200>; 288 reg = <3000 200>;
298 interrupts = <23>; 289 interrupts = <23>;
299 interrupt-parent = <80>; 290 interrupt-parent = < &qeic >;
300 mac-address = [ 00 11 22 33 44 55 ]; 291 mac-address = [ 00 11 22 33 44 55 ];
301 rx-clock = <17>; 292 rx-clock = <17>;
302 tx-clock = <18>; 293 tx-clock = <18>;
303 phy-handle = <212004>; 294 phy-handle = < &phy4 >;
304 pio-handle = <140004>; 295 pio-handle = < &pio4 >;
305 }; 296 };
306 297
307 mdio@2320 { 298 mdio@2320 {
@@ -311,26 +302,23 @@
311 device_type = "mdio"; 302 device_type = "mdio";
312 compatible = "ucc_geth_phy"; 303 compatible = "ucc_geth_phy";
313 304
314 ethernet-phy@03 { 305 phy3: ethernet-phy@03 {
315 linux,phandle = <212003>; 306 interrupt-parent = < &ipic >;
316 interrupt-parent = <700>; 307 interrupts = <11 8>;
317 interrupts = <11 2>;
318 reg = <3>; 308 reg = <3>;
319 device_type = "ethernet-phy"; 309 device_type = "ethernet-phy";
320 interface = <3>; //ENET_100_MII 310 interface = <3>; //ENET_100_MII
321 }; 311 };
322 ethernet-phy@04 { 312 phy4: ethernet-phy@04 {
323 linux,phandle = <212004>; 313 interrupt-parent = < &ipic >;
324 interrupt-parent = <700>; 314 interrupts = <12 8>;
325 interrupts = <12 2>;
326 reg = <4>; 315 reg = <4>;
327 device_type = "ethernet-phy"; 316 device_type = "ethernet-phy";
328 interface = <3>; 317 interface = <3>;
329 }; 318 };
330 }; 319 };
331 320
332 qeic@80 { 321 qeic: qeic@80 {
333 linux,phandle = <80>;
334 interrupt-controller; 322 interrupt-controller;
335 device_type = "qeic"; 323 device_type = "qeic";
336 #address-cells = <0>; 324 #address-cells = <0>;
@@ -339,7 +327,7 @@
339 built-in; 327 built-in;
340 big-endian; 328 big-endian;
341 interrupts = <20 8 21 8>; //high:32 low:33 329 interrupts = <20 8 21 8>; //high:32 low:33
342 interrupt-parent = <700>; 330 interrupt-parent = < &ipic >;
343 }; 331 };
344 }; 332 };
345}; 333};
diff --git a/arch/powerpc/boot/dts/mpc8349emitx.dts b/arch/powerpc/boot/dts/mpc8349emitx.dts
index 27807fc45888..61b550bf1645 100644
--- a/arch/powerpc/boot/dts/mpc8349emitx.dts
+++ b/arch/powerpc/boot/dts/mpc8349emitx.dts
@@ -10,7 +10,7 @@
10 */ 10 */
11/ { 11/ {
12 model = "MPC8349EMITX"; 12 model = "MPC8349EMITX";
13 compatible = "MPC834xMITX"; 13 compatible = "MPC8349EMITX", "MPC834xMITX", "MPC83xxMITX";
14 #address-cells = <1>; 14 #address-cells = <1>;
15 #size-cells = <1>; 15 #size-cells = <1>;
16 16
@@ -58,7 +58,7 @@
58 compatible = "fsl-i2c"; 58 compatible = "fsl-i2c";
59 reg = <3000 100>; 59 reg = <3000 100>;
60 interrupts = <e 8>; 60 interrupts = <e 8>;
61 interrupt-parent = <700>; 61 interrupt-parent = < &ipic >;
62 dfsrr; 62 dfsrr;
63 }; 63 };
64 64
@@ -67,7 +67,7 @@
67 compatible = "fsl-i2c"; 67 compatible = "fsl-i2c";
68 reg = <3100 100>; 68 reg = <3100 100>;
69 interrupts = <f 8>; 69 interrupts = <f 8>;
70 interrupt-parent = <700>; 70 interrupt-parent = < &ipic >;
71 dfsrr; 71 dfsrr;
72 }; 72 };
73 73
@@ -76,7 +76,7 @@
76 compatible = "mpc83xx_spi"; 76 compatible = "mpc83xx_spi";
77 reg = <7000 1000>; 77 reg = <7000 1000>;
78 interrupts = <10 8>; 78 interrupts = <10 8>;
79 interrupt-parent = <700>; 79 interrupt-parent = < &ipic >;
80 mode = <0>; 80 mode = <0>;
81 }; 81 };
82 82
@@ -86,8 +86,8 @@
86 reg = <22000 1000>; 86 reg = <22000 1000>;
87 #address-cells = <1>; 87 #address-cells = <1>;
88 #size-cells = <0>; 88 #size-cells = <0>;
89 interrupt-parent = <700>; 89 interrupt-parent = < &ipic >;
90 interrupts = <27 2>; 90 interrupts = <27 8>;
91 phy_type = "ulpi"; 91 phy_type = "ulpi";
92 port1; 92 port1;
93 }; 93 };
@@ -98,8 +98,8 @@
98 reg = <23000 1000>; 98 reg = <23000 1000>;
99 #address-cells = <1>; 99 #address-cells = <1>;
100 #size-cells = <0>; 100 #size-cells = <0>;
101 interrupt-parent = <700>; 101 interrupt-parent = < &ipic >;
102 interrupts = <26 2>; 102 interrupts = <26 8>;
103 phy_type = "ulpi"; 103 phy_type = "ulpi";
104 }; 104 };
105 105
@@ -109,22 +109,19 @@
109 reg = <24520 20>; 109 reg = <24520 20>;
110 #address-cells = <1>; 110 #address-cells = <1>;
111 #size-cells = <0>; 111 #size-cells = <0>;
112 linux,phandle = <24520>;
113 112
114 /* Vitesse 8201 */ 113 /* Vitesse 8201 */
115 ethernet-phy@1c { 114 phy1c: ethernet-phy@1c {
116 linux,phandle = <245201c>; 115 interrupt-parent = < &ipic >;
117 interrupt-parent = <700>; 116 interrupts = <12 8>;
118 interrupts = <12 2>;
119 reg = <1c>; 117 reg = <1c>;
120 device_type = "ethernet-phy"; 118 device_type = "ethernet-phy";
121 }; 119 };
122 120
123 /* Vitesse 7385 */ 121 /* Vitesse 7385 */
124 ethernet-phy@1f { 122 phy1f: ethernet-phy@1f {
125 linux,phandle = <245201f>; 123 interrupt-parent = < &ipic >;
126 interrupt-parent = <700>; 124 interrupts = <12 8>;
127 interrupts = <12 2>;
128 reg = <1f>; 125 reg = <1f>;
129 device_type = "ethernet-phy"; 126 device_type = "ethernet-phy";
130 }; 127 };
@@ -138,8 +135,8 @@
138 address = [ 00 00 00 00 00 00 ]; 135 address = [ 00 00 00 00 00 00 ];
139 local-mac-address = [ 00 00 00 00 00 00 ]; 136 local-mac-address = [ 00 00 00 00 00 00 ];
140 interrupts = <20 8 21 8 22 8>; 137 interrupts = <20 8 21 8 22 8>;
141 interrupt-parent = <700>; 138 interrupt-parent = < &ipic >;
142 phy-handle = <245201c>; 139 phy-handle = < &phy1c >;
143 }; 140 };
144 141
145 ethernet@25000 { 142 ethernet@25000 {
@@ -152,8 +149,8 @@
152 address = [ 00 00 00 00 00 00 ]; 149 address = [ 00 00 00 00 00 00 ];
153 local-mac-address = [ 00 00 00 00 00 00 ]; 150 local-mac-address = [ 00 00 00 00 00 00 ];
154 interrupts = <23 8 24 8 25 8>; 151 interrupts = <23 8 24 8 25 8>;
155 interrupt-parent = <700>; 152 interrupt-parent = < &ipic >;
156 phy-handle = <245201f>; 153 phy-handle = < &phy1f >;
157 }; 154 };
158 155
159 serial@4500 { 156 serial@4500 {
@@ -162,7 +159,7 @@
162 reg = <4500 100>; 159 reg = <4500 100>;
163 clock-frequency = <0>; // from bootloader 160 clock-frequency = <0>; // from bootloader
164 interrupts = <9 8>; 161 interrupts = <9 8>;
165 interrupt-parent = <700>; 162 interrupt-parent = < &ipic >;
166 }; 163 };
167 164
168 serial@4600 { 165 serial@4600 {
@@ -171,16 +168,16 @@
171 reg = <4600 100>; 168 reg = <4600 100>;
172 clock-frequency = <0>; // from bootloader 169 clock-frequency = <0>; // from bootloader
173 interrupts = <a 8>; 170 interrupts = <a 8>;
174 interrupt-parent = <700>; 171 interrupt-parent = < &ipic >;
175 }; 172 };
176 173
177 pci@8500 { 174 pci@8500 {
178 interrupt-map-mask = <f800 0 0 7>; 175 interrupt-map-mask = <f800 0 0 7>;
179 interrupt-map = < 176 interrupt-map = <
180 /* IDSEL 0x10 - SATA */ 177 /* IDSEL 0x10 - SATA */
181 8000 0 0 1 700 16 8 /* SATA_INTA */ 178 8000 0 0 1 &ipic 16 8 /* SATA_INTA */
182 >; 179 >;
183 interrupt-parent = <700>; 180 interrupt-parent = < &ipic >;
184 interrupts = <42 8>; 181 interrupts = <42 8>;
185 bus-range = <0 0>; 182 bus-range = <0 0>;
186 ranges = <42000000 0 80000000 80000000 0 10000000 183 ranges = <42000000 0 80000000 80000000 0 10000000
@@ -199,13 +196,13 @@
199 interrupt-map-mask = <f800 0 0 7>; 196 interrupt-map-mask = <f800 0 0 7>;
200 interrupt-map = < 197 interrupt-map = <
201 /* IDSEL 0x0E - MiniPCI Slot */ 198 /* IDSEL 0x0E - MiniPCI Slot */
202 7000 0 0 1 700 15 8 /* PCI_INTA */ 199 7000 0 0 1 &ipic 15 8 /* PCI_INTA */
203 200
204 /* IDSEL 0x0F - PCI Slot */ 201 /* IDSEL 0x0F - PCI Slot */
205 7800 0 0 1 700 14 8 /* PCI_INTA */ 202 7800 0 0 1 &ipic 14 8 /* PCI_INTA */
206 7800 0 0 2 700 15 8 /* PCI_INTB */ 203 7800 0 0 2 &ipic 15 8 /* PCI_INTB */
207 >; 204 >;
208 interrupt-parent = <700>; 205 interrupt-parent = < &ipic >;
209 interrupts = <43 8>; 206 interrupts = <43 8>;
210 bus-range = <1 1>; 207 bus-range = <1 1>;
211 ranges = <42000000 0 a0000000 a0000000 0 10000000 208 ranges = <42000000 0 a0000000 a0000000 0 10000000
@@ -226,15 +223,14 @@
226 compatible = "talitos"; 223 compatible = "talitos";
227 reg = <30000 10000>; 224 reg = <30000 10000>;
228 interrupts = <b 8>; 225 interrupts = <b 8>;
229 interrupt-parent = <700>; 226 interrupt-parent = < &ipic >;
230 num-channels = <4>; 227 num-channels = <4>;
231 channel-fifo-len = <18>; 228 channel-fifo-len = <18>;
232 exec-units-mask = <0000007e>; 229 exec-units-mask = <0000007e>;
233 descriptor-types-mask = <01010ebf>; 230 descriptor-types-mask = <01010ebf>;
234 }; 231 };
235 232
236 pic@700 { 233 ipic: pic@700 {
237 linux,phandle = <700>;
238 interrupt-controller; 234 interrupt-controller;
239 #address-cells = <0>; 235 #address-cells = <0>;
240 #interrupt-cells = <2>; 236 #interrupt-cells = <2>;
diff --git a/arch/powerpc/boot/dts/mpc8349emitxgp.dts b/arch/powerpc/boot/dts/mpc8349emitxgp.dts
index 3190774de1d8..b2e1a5ec3779 100644
--- a/arch/powerpc/boot/dts/mpc8349emitxgp.dts
+++ b/arch/powerpc/boot/dts/mpc8349emitxgp.dts
@@ -10,7 +10,7 @@
10 */ 10 */
11/ { 11/ {
12 model = "MPC8349EMITXGP"; 12 model = "MPC8349EMITXGP";
13 compatible = "MPC834xMITXGP"; 13 compatible = "MPC8349EMITXGP", "MPC834xMITX", "MPC83xxMITX";
14 #address-cells = <1>; 14 #address-cells = <1>;
15 #size-cells = <1>; 15 #size-cells = <1>;
16 16
@@ -58,7 +58,7 @@
58 compatible = "fsl-i2c"; 58 compatible = "fsl-i2c";
59 reg = <3000 100>; 59 reg = <3000 100>;
60 interrupts = <e 8>; 60 interrupts = <e 8>;
61 interrupt-parent = <700>; 61 interrupt-parent = < &ipic >;
62 dfsrr; 62 dfsrr;
63 }; 63 };
64 64
@@ -67,7 +67,7 @@
67 compatible = "fsl-i2c"; 67 compatible = "fsl-i2c";
68 reg = <3100 100>; 68 reg = <3100 100>;
69 interrupts = <f 8>; 69 interrupts = <f 8>;
70 interrupt-parent = <700>; 70 interrupt-parent = < &ipic >;
71 dfsrr; 71 dfsrr;
72 }; 72 };
73 73
@@ -76,7 +76,7 @@
76 compatible = "mpc83xx_spi"; 76 compatible = "mpc83xx_spi";
77 reg = <7000 1000>; 77 reg = <7000 1000>;
78 interrupts = <10 8>; 78 interrupts = <10 8>;
79 interrupt-parent = <700>; 79 interrupt-parent = < &ipic >;
80 mode = <0>; 80 mode = <0>;
81 }; 81 };
82 82
@@ -86,8 +86,8 @@
86 reg = <23000 1000>; 86 reg = <23000 1000>;
87 #address-cells = <1>; 87 #address-cells = <1>;
88 #size-cells = <0>; 88 #size-cells = <0>;
89 interrupt-parent = <700>; 89 interrupt-parent = < &ipic >;
90 interrupts = <26 2>; 90 interrupts = <26 8>;
91 dr_mode = "otg"; 91 dr_mode = "otg";
92 phy_type = "ulpi"; 92 phy_type = "ulpi";
93 }; 93 };
@@ -98,13 +98,11 @@
98 reg = <24520 20>; 98 reg = <24520 20>;
99 #address-cells = <1>; 99 #address-cells = <1>;
100 #size-cells = <0>; 100 #size-cells = <0>;
101 linux,phandle = <24520>;
102 101
103 /* Vitesse 8201 */ 102 /* Vitesse 8201 */
104 ethernet-phy@1c { 103 phy1c: ethernet-phy@1c {
105 linux,phandle = <245201c>; 104 interrupt-parent = < &ipic >;
106 interrupt-parent = <700>; 105 interrupts = <12 8>;
107 interrupts = <12 2>;
108 reg = <1c>; 106 reg = <1c>;
109 device_type = "ethernet-phy"; 107 device_type = "ethernet-phy";
110 }; 108 };
@@ -117,8 +115,8 @@
117 reg = <24000 1000>; 115 reg = <24000 1000>;
118 local-mac-address = [ 00 00 00 00 00 00 ]; 116 local-mac-address = [ 00 00 00 00 00 00 ];
119 interrupts = <20 8 21 8 22 8>; 117 interrupts = <20 8 21 8 22 8>;
120 interrupt-parent = <700>; 118 interrupt-parent = < &ipic >;
121 phy-handle = <245201c>; 119 phy-handle = < &phy1c >;
122 }; 120 };
123 121
124 serial@4500 { 122 serial@4500 {
@@ -127,7 +125,7 @@
127 reg = <4500 100>; 125 reg = <4500 100>;
128 clock-frequency = <0>; // from bootloader 126 clock-frequency = <0>; // from bootloader
129 interrupts = <9 8>; 127 interrupts = <9 8>;
130 interrupt-parent = <700>; 128 interrupt-parent = < &ipic >;
131 }; 129 };
132 130
133 serial@4600 { 131 serial@4600 {
@@ -136,17 +134,17 @@
136 reg = <4600 100>; 134 reg = <4600 100>;
137 clock-frequency = <0>; // from bootloader 135 clock-frequency = <0>; // from bootloader
138 interrupts = <a 8>; 136 interrupts = <a 8>;
139 interrupt-parent = <700>; 137 interrupt-parent = < &ipic >;
140 }; 138 };
141 139
142 pci@8600 { 140 pci@8600 {
143 interrupt-map-mask = <f800 0 0 7>; 141 interrupt-map-mask = <f800 0 0 7>;
144 interrupt-map = < 142 interrupt-map = <
145 /* IDSEL 0x0F - PCI Slot */ 143 /* IDSEL 0x0F - PCI Slot */
146 7800 0 0 1 700 14 8 /* PCI_INTA */ 144 7800 0 0 1 &ipic 14 8 /* PCI_INTA */
147 7800 0 0 2 700 15 8 /* PCI_INTB */ 145 7800 0 0 2 &ipic 15 8 /* PCI_INTB */
148 >; 146 >;
149 interrupt-parent = <700>; 147 interrupt-parent = < &ipic >;
150 interrupts = <43 8>; 148 interrupts = <43 8>;
151 bus-range = <1 1>; 149 bus-range = <1 1>;
152 ranges = <42000000 0 a0000000 a0000000 0 10000000 150 ranges = <42000000 0 a0000000 a0000000 0 10000000
@@ -167,15 +165,14 @@
167 compatible = "talitos"; 165 compatible = "talitos";
168 reg = <30000 10000>; 166 reg = <30000 10000>;
169 interrupts = <b 8>; 167 interrupts = <b 8>;
170 interrupt-parent = <700>; 168 interrupt-parent = < &ipic >;
171 num-channels = <4>; 169 num-channels = <4>;
172 channel-fifo-len = <18>; 170 channel-fifo-len = <18>;
173 exec-units-mask = <0000007e>; 171 exec-units-mask = <0000007e>;
174 descriptor-types-mask = <01010ebf>; 172 descriptor-types-mask = <01010ebf>;
175 }; 173 };
176 174
177 pic@700 { 175 ipic: pic@700 {
178 linux,phandle = <700>;
179 interrupt-controller; 176 interrupt-controller;
180 #address-cells = <0>; 177 #address-cells = <0>;
181 #interrupt-cells = <2>; 178 #interrupt-cells = <2>;
diff --git a/arch/powerpc/boot/dts/mpc834x_mds.dts b/arch/powerpc/boot/dts/mpc834x_mds.dts
index dc121b3cb4a9..e4b43c24bc0b 100644
--- a/arch/powerpc/boot/dts/mpc834x_mds.dts
+++ b/arch/powerpc/boot/dts/mpc834x_mds.dts
@@ -11,7 +11,7 @@
11 11
12/ { 12/ {
13 model = "MPC8349EMDS"; 13 model = "MPC8349EMDS";
14 compatible = "MPC834xMDS"; 14 compatible = "MPC8349EMDS", "MPC834xMDS", "MPC83xxMDS";
15 #address-cells = <1>; 15 #address-cells = <1>;
16 #size-cells = <1>; 16 #size-cells = <1>;
17 17
@@ -64,7 +64,7 @@
64 compatible = "fsl-i2c"; 64 compatible = "fsl-i2c";
65 reg = <3000 100>; 65 reg = <3000 100>;
66 interrupts = <e 8>; 66 interrupts = <e 8>;
67 interrupt-parent = <700>; 67 interrupt-parent = < &ipic >;
68 dfsrr; 68 dfsrr;
69 }; 69 };
70 70
@@ -73,7 +73,7 @@
73 compatible = "fsl-i2c"; 73 compatible = "fsl-i2c";
74 reg = <3100 100>; 74 reg = <3100 100>;
75 interrupts = <f 8>; 75 interrupts = <f 8>;
76 interrupt-parent = <700>; 76 interrupt-parent = < &ipic >;
77 dfsrr; 77 dfsrr;
78 }; 78 };
79 79
@@ -82,7 +82,7 @@
82 compatible = "mpc83xx_spi"; 82 compatible = "mpc83xx_spi";
83 reg = <7000 1000>; 83 reg = <7000 1000>;
84 interrupts = <10 8>; 84 interrupts = <10 8>;
85 interrupt-parent = <700>; 85 interrupt-parent = < &ipic >;
86 mode = <0>; 86 mode = <0>;
87 }; 87 };
88 88
@@ -94,8 +94,8 @@
94 reg = <22000 1000>; 94 reg = <22000 1000>;
95 #address-cells = <1>; 95 #address-cells = <1>;
96 #size-cells = <0>; 96 #size-cells = <0>;
97 interrupt-parent = <700>; 97 interrupt-parent = < &ipic >;
98 interrupts = <27 2>; 98 interrupts = <27 8>;
99 phy_type = "ulpi"; 99 phy_type = "ulpi";
100 port1; 100 port1;
101 }; 101 };
@@ -106,8 +106,8 @@
106 reg = <23000 1000>; 106 reg = <23000 1000>;
107 #address-cells = <1>; 107 #address-cells = <1>;
108 #size-cells = <0>; 108 #size-cells = <0>;
109 interrupt-parent = <700>; 109 interrupt-parent = < &ipic >;
110 interrupts = <26 2>; 110 interrupts = <26 8>;
111 dr_mode = "otg"; 111 dr_mode = "otg";
112 phy_type = "ulpi"; 112 phy_type = "ulpi";
113 }; 113 };
@@ -118,18 +118,15 @@
118 reg = <24520 20>; 118 reg = <24520 20>;
119 #address-cells = <1>; 119 #address-cells = <1>;
120 #size-cells = <0>; 120 #size-cells = <0>;
121 linux,phandle = <24520>; 121 phy0: ethernet-phy@0 {
122 ethernet-phy@0 { 122 interrupt-parent = < &ipic >;
123 linux,phandle = <2452000>; 123 interrupts = <11 8>;
124 interrupt-parent = <700>;
125 interrupts = <11 2>;
126 reg = <0>; 124 reg = <0>;
127 device_type = "ethernet-phy"; 125 device_type = "ethernet-phy";
128 }; 126 };
129 ethernet-phy@1 { 127 phy1: ethernet-phy@1 {
130 linux,phandle = <2452001>; 128 interrupt-parent = < &ipic >;
131 interrupt-parent = <700>; 129 interrupts = <12 8>;
132 interrupts = <12 2>;
133 reg = <1>; 130 reg = <1>;
134 device_type = "ethernet-phy"; 131 device_type = "ethernet-phy";
135 }; 132 };
@@ -143,8 +140,8 @@
143 address = [ 00 00 00 00 00 00 ]; 140 address = [ 00 00 00 00 00 00 ];
144 local-mac-address = [ 00 00 00 00 00 00 ]; 141 local-mac-address = [ 00 00 00 00 00 00 ];
145 interrupts = <20 8 21 8 22 8>; 142 interrupts = <20 8 21 8 22 8>;
146 interrupt-parent = <700>; 143 interrupt-parent = < &ipic >;
147 phy-handle = <2452000>; 144 phy-handle = < &phy0 >;
148 }; 145 };
149 146
150 ethernet@25000 { 147 ethernet@25000 {
@@ -157,8 +154,8 @@
157 address = [ 00 00 00 00 00 00 ]; 154 address = [ 00 00 00 00 00 00 ];
158 local-mac-address = [ 00 00 00 00 00 00 ]; 155 local-mac-address = [ 00 00 00 00 00 00 ];
159 interrupts = <23 8 24 8 25 8>; 156 interrupts = <23 8 24 8 25 8>;
160 interrupt-parent = <700>; 157 interrupt-parent = < &ipic >;
161 phy-handle = <2452001>; 158 phy-handle = < &phy1 >;
162 }; 159 };
163 160
164 serial@4500 { 161 serial@4500 {
@@ -167,7 +164,7 @@
167 reg = <4500 100>; 164 reg = <4500 100>;
168 clock-frequency = <0>; 165 clock-frequency = <0>;
169 interrupts = <9 8>; 166 interrupts = <9 8>;
170 interrupt-parent = <700>; 167 interrupt-parent = < &ipic >;
171 }; 168 };
172 169
173 serial@4600 { 170 serial@4600 {
@@ -176,7 +173,7 @@
176 reg = <4600 100>; 173 reg = <4600 100>;
177 clock-frequency = <0>; 174 clock-frequency = <0>;
178 interrupts = <a 8>; 175 interrupts = <a 8>;
179 interrupt-parent = <700>; 176 interrupt-parent = < &ipic >;
180 }; 177 };
181 178
182 pci@8500 { 179 pci@8500 {
@@ -184,47 +181,47 @@
184 interrupt-map = < 181 interrupt-map = <
185 182
186 /* IDSEL 0x11 */ 183 /* IDSEL 0x11 */
187 8800 0 0 1 700 14 8 184 8800 0 0 1 &ipic 14 8
188 8800 0 0 2 700 15 8 185 8800 0 0 2 &ipic 15 8
189 8800 0 0 3 700 16 8 186 8800 0 0 3 &ipic 16 8
190 8800 0 0 4 700 17 8 187 8800 0 0 4 &ipic 17 8
191 188
192 /* IDSEL 0x12 */ 189 /* IDSEL 0x12 */
193 9000 0 0 1 700 16 8 190 9000 0 0 1 &ipic 16 8
194 9000 0 0 2 700 17 8 191 9000 0 0 2 &ipic 17 8
195 9000 0 0 3 700 14 8 192 9000 0 0 3 &ipic 14 8
196 9000 0 0 4 700 15 8 193 9000 0 0 4 &ipic 15 8
197 194
198 /* IDSEL 0x13 */ 195 /* IDSEL 0x13 */
199 9800 0 0 1 700 17 8 196 9800 0 0 1 &ipic 17 8
200 9800 0 0 2 700 14 8 197 9800 0 0 2 &ipic 14 8
201 9800 0 0 3 700 15 8 198 9800 0 0 3 &ipic 15 8
202 9800 0 0 4 700 16 8 199 9800 0 0 4 &ipic 16 8
203 200
204 /* IDSEL 0x15 */ 201 /* IDSEL 0x15 */
205 a800 0 0 1 700 14 8 202 a800 0 0 1 &ipic 14 8
206 a800 0 0 2 700 15 8 203 a800 0 0 2 &ipic 15 8
207 a800 0 0 3 700 16 8 204 a800 0 0 3 &ipic 16 8
208 a800 0 0 4 700 17 8 205 a800 0 0 4 &ipic 17 8
209 206
210 /* IDSEL 0x16 */ 207 /* IDSEL 0x16 */
211 b000 0 0 1 700 17 8 208 b000 0 0 1 &ipic 17 8
212 b000 0 0 2 700 14 8 209 b000 0 0 2 &ipic 14 8
213 b000 0 0 3 700 15 8 210 b000 0 0 3 &ipic 15 8
214 b000 0 0 4 700 16 8 211 b000 0 0 4 &ipic 16 8
215 212
216 /* IDSEL 0x17 */ 213 /* IDSEL 0x17 */
217 b800 0 0 1 700 16 8 214 b800 0 0 1 &ipic 16 8
218 b800 0 0 2 700 17 8 215 b800 0 0 2 &ipic 17 8
219 b800 0 0 3 700 14 8 216 b800 0 0 3 &ipic 14 8
220 b800 0 0 4 700 15 8 217 b800 0 0 4 &ipic 15 8
221 218
222 /* IDSEL 0x18 */ 219 /* IDSEL 0x18 */
223 c000 0 0 1 700 15 8 220 c000 0 0 1 &ipic 15 8
224 c000 0 0 2 700 16 8 221 c000 0 0 2 &ipic 16 8
225 c000 0 0 3 700 17 8 222 c000 0 0 3 &ipic 17 8
226 c000 0 0 4 700 14 8>; 223 c000 0 0 4 &ipic 14 8>;
227 interrupt-parent = <700>; 224 interrupt-parent = < &ipic >;
228 interrupts = <42 8>; 225 interrupts = <42 8>;
229 bus-range = <0 0>; 226 bus-range = <0 0>;
230 ranges = <02000000 0 a0000000 a0000000 0 10000000 227 ranges = <02000000 0 a0000000 a0000000 0 10000000
@@ -244,47 +241,47 @@
244 interrupt-map = < 241 interrupt-map = <
245 242
246 /* IDSEL 0x11 */ 243 /* IDSEL 0x11 */
247 8800 0 0 1 700 14 8 244 8800 0 0 1 &ipic 14 8
248 8800 0 0 2 700 15 8 245 8800 0 0 2 &ipic 15 8
249 8800 0 0 3 700 16 8 246 8800 0 0 3 &ipic 16 8
250 8800 0 0 4 700 17 8 247 8800 0 0 4 &ipic 17 8
251 248
252 /* IDSEL 0x12 */ 249 /* IDSEL 0x12 */
253 9000 0 0 1 700 16 8 250 9000 0 0 1 &ipic 16 8
254 9000 0 0 2 700 17 8 251 9000 0 0 2 &ipic 17 8
255 9000 0 0 3 700 14 8 252 9000 0 0 3 &ipic 14 8
256 9000 0 0 4 700 15 8 253 9000 0 0 4 &ipic 15 8
257 254
258 /* IDSEL 0x13 */ 255 /* IDSEL 0x13 */
259 9800 0 0 1 700 17 8 256 9800 0 0 1 &ipic 17 8
260 9800 0 0 2 700 14 8 257 9800 0 0 2 &ipic 14 8
261 9800 0 0 3 700 15 8 258 9800 0 0 3 &ipic 15 8
262 9800 0 0 4 700 16 8 259 9800 0 0 4 &ipic 16 8
263 260
264 /* IDSEL 0x15 */ 261 /* IDSEL 0x15 */
265 a800 0 0 1 700 14 8 262 a800 0 0 1 &ipic 14 8
266 a800 0 0 2 700 15 8 263 a800 0 0 2 &ipic 15 8
267 a800 0 0 3 700 16 8 264 a800 0 0 3 &ipic 16 8
268 a800 0 0 4 700 17 8 265 a800 0 0 4 &ipic 17 8
269 266
270 /* IDSEL 0x16 */ 267 /* IDSEL 0x16 */
271 b000 0 0 1 700 17 8 268 b000 0 0 1 &ipic 17 8
272 b000 0 0 2 700 14 8 269 b000 0 0 2 &ipic 14 8
273 b000 0 0 3 700 15 8 270 b000 0 0 3 &ipic 15 8
274 b000 0 0 4 700 16 8 271 b000 0 0 4 &ipic 16 8
275 272
276 /* IDSEL 0x17 */ 273 /* IDSEL 0x17 */
277 b800 0 0 1 700 16 8 274 b800 0 0 1 &ipic 16 8
278 b800 0 0 2 700 17 8 275 b800 0 0 2 &ipic 17 8
279 b800 0 0 3 700 14 8 276 b800 0 0 3 &ipic 14 8
280 b800 0 0 4 700 15 8 277 b800 0 0 4 &ipic 15 8
281 278
282 /* IDSEL 0x18 */ 279 /* IDSEL 0x18 */
283 c000 0 0 1 700 15 8 280 c000 0 0 1 &ipic 15 8
284 c000 0 0 2 700 16 8 281 c000 0 0 2 &ipic 16 8
285 c000 0 0 3 700 17 8 282 c000 0 0 3 &ipic 17 8
286 c000 0 0 4 700 14 8>; 283 c000 0 0 4 &ipic 14 8>;
287 interrupt-parent = <700>; 284 interrupt-parent = < &ipic >;
288 interrupts = <42 8>; 285 interrupts = <42 8>;
289 bus-range = <0 0>; 286 bus-range = <0 0>;
290 ranges = <02000000 0 b0000000 b0000000 0 10000000 287 ranges = <02000000 0 b0000000 b0000000 0 10000000
@@ -306,7 +303,7 @@
306 compatible = "talitos"; 303 compatible = "talitos";
307 reg = <30000 10000>; 304 reg = <30000 10000>;
308 interrupts = <b 8>; 305 interrupts = <b 8>;
309 interrupt-parent = <700>; 306 interrupt-parent = < &ipic >;
310 num-channels = <4>; 307 num-channels = <4>;
311 channel-fifo-len = <18>; 308 channel-fifo-len = <18>;
312 exec-units-mask = <0000007e>; 309 exec-units-mask = <0000007e>;
@@ -321,8 +318,7 @@
321 * sense == 8: Level, low assertion 318 * sense == 8: Level, low assertion
322 * sense == 2: Edge, high-to-low change 319 * sense == 2: Edge, high-to-low change
323 */ 320 */
324 pic@700 { 321 ipic: pic@700 {
325 linux,phandle = <700>;
326 interrupt-controller; 322 interrupt-controller;
327 #address-cells = <0>; 323 #address-cells = <0>;
328 #interrupt-cells = <2>; 324 #interrupt-cells = <2>;
diff --git a/arch/powerpc/boot/dts/mpc8360emds.dts b/arch/powerpc/boot/dts/mpc836x_mds.dts
index 9022192155b9..4fe45c021848 100644
--- a/arch/powerpc/boot/dts/mpc8360emds.dts
+++ b/arch/powerpc/boot/dts/mpc836x_mds.dts
@@ -15,17 +15,15 @@
15*/ 15*/
16 16
17/ { 17/ {
18 model = "MPC8360EPB"; 18 model = "MPC8360MDS";
19 compatible = "MPC83xx"; 19 compatible = "MPC8360EMDS", "MPC836xMDS", "MPC83xxMDS";
20 #address-cells = <1>; 20 #address-cells = <1>;
21 #size-cells = <1>; 21 #size-cells = <1>;
22 linux,phandle = <100>;
23 22
24 cpus { 23 cpus {
25 #cpus = <1>; 24 #cpus = <1>;
26 #address-cells = <1>; 25 #address-cells = <1>;
27 #size-cells = <0>; 26 #size-cells = <0>;
28 linux,phandle = <200>;
29 27
30 PowerPC,8360@0 { 28 PowerPC,8360@0 {
31 device_type = "cpu"; 29 device_type = "cpu";
@@ -38,14 +36,11 @@
38 bus-frequency = <FBC5200>; 36 bus-frequency = <FBC5200>;
39 clock-frequency = <1F78A400>; 37 clock-frequency = <1F78A400>;
40 32-bit; 38 32-bit;
41 linux,phandle = <201>;
42 linux,boot-cpu;
43 }; 39 };
44 }; 40 };
45 41
46 memory { 42 memory {
47 device_type = "memory"; 43 device_type = "memory";
48 linux,phandle = <300>;
49 reg = <00000000 10000000>; 44 reg = <00000000 10000000>;
50 }; 45 };
51 46
@@ -74,7 +69,7 @@
74 compatible = "fsl-i2c"; 69 compatible = "fsl-i2c";
75 reg = <3000 100>; 70 reg = <3000 100>;
76 interrupts = <e 8>; 71 interrupts = <e 8>;
77 interrupt-parent = <700>; 72 interrupt-parent = < &ipic >;
78 dfsrr; 73 dfsrr;
79 }; 74 };
80 75
@@ -83,7 +78,7 @@
83 compatible = "fsl-i2c"; 78 compatible = "fsl-i2c";
84 reg = <3100 100>; 79 reg = <3100 100>;
85 interrupts = <f 8>; 80 interrupts = <f 8>;
86 interrupt-parent = <700>; 81 interrupt-parent = < &ipic >;
87 dfsrr; 82 dfsrr;
88 }; 83 };
89 84
@@ -93,7 +88,7 @@
93 reg = <4500 100>; 88 reg = <4500 100>;
94 clock-frequency = <FBC5200>; 89 clock-frequency = <FBC5200>;
95 interrupts = <9 8>; 90 interrupts = <9 8>;
96 interrupt-parent = <700>; 91 interrupt-parent = < &ipic >;
97 }; 92 };
98 93
99 serial@4600 { 94 serial@4600 {
@@ -102,7 +97,7 @@
102 reg = <4600 100>; 97 reg = <4600 100>;
103 clock-frequency = <FBC5200>; 98 clock-frequency = <FBC5200>;
104 interrupts = <a 8>; 99 interrupts = <a 8>;
105 interrupt-parent = <700>; 100 interrupt-parent = < &ipic >;
106 }; 101 };
107 102
108 crypto@30000 { 103 crypto@30000 {
@@ -111,7 +106,7 @@
111 compatible = "talitos"; 106 compatible = "talitos";
112 reg = <30000 10000>; 107 reg = <30000 10000>;
113 interrupts = <b 8>; 108 interrupts = <b 8>;
114 interrupt-parent = <700>; 109 interrupt-parent = < &ipic >;
115 num-channels = <4>; 110 num-channels = <4>;
116 channel-fifo-len = <18>; 111 channel-fifo-len = <18>;
117 exec-units-mask = <0000007e>; 112 exec-units-mask = <0000007e>;
@@ -120,52 +115,51 @@
120 }; 115 };
121 116
122 pci@8500 { 117 pci@8500 {
123 linux,phandle = <8500>;
124 interrupt-map-mask = <f800 0 0 7>; 118 interrupt-map-mask = <f800 0 0 7>;
125 interrupt-map = < 119 interrupt-map = <
126 120
127 /* IDSEL 0x11 AD17 */ 121 /* IDSEL 0x11 AD17 */
128 8800 0 0 1 700 14 8 122 8800 0 0 1 &ipic 14 8
129 8800 0 0 2 700 15 8 123 8800 0 0 2 &ipic 15 8
130 8800 0 0 3 700 16 8 124 8800 0 0 3 &ipic 16 8
131 8800 0 0 4 700 17 8 125 8800 0 0 4 &ipic 17 8
132 126
133 /* IDSEL 0x12 AD18 */ 127 /* IDSEL 0x12 AD18 */
134 9000 0 0 1 700 16 8 128 9000 0 0 1 &ipic 16 8
135 9000 0 0 2 700 17 8 129 9000 0 0 2 &ipic 17 8
136 9000 0 0 3 700 14 8 130 9000 0 0 3 &ipic 14 8
137 9000 0 0 4 700 15 8 131 9000 0 0 4 &ipic 15 8
138 132
139 /* IDSEL 0x13 AD19 */ 133 /* IDSEL 0x13 AD19 */
140 9800 0 0 1 700 17 8 134 9800 0 0 1 &ipic 17 8
141 9800 0 0 2 700 14 8 135 9800 0 0 2 &ipic 14 8
142 9800 0 0 3 700 15 8 136 9800 0 0 3 &ipic 15 8
143 9800 0 0 4 700 16 8 137 9800 0 0 4 &ipic 16 8
144 138
145 /* IDSEL 0x15 AD21*/ 139 /* IDSEL 0x15 AD21*/
146 a800 0 0 1 700 14 8 140 a800 0 0 1 &ipic 14 8
147 a800 0 0 2 700 15 8 141 a800 0 0 2 &ipic 15 8
148 a800 0 0 3 700 16 8 142 a800 0 0 3 &ipic 16 8
149 a800 0 0 4 700 17 8 143 a800 0 0 4 &ipic 17 8
150 144
151 /* IDSEL 0x16 AD22*/ 145 /* IDSEL 0x16 AD22*/
152 b000 0 0 1 700 17 8 146 b000 0 0 1 &ipic 17 8
153 b000 0 0 2 700 14 8 147 b000 0 0 2 &ipic 14 8
154 b000 0 0 3 700 15 8 148 b000 0 0 3 &ipic 15 8
155 b000 0 0 4 700 16 8 149 b000 0 0 4 &ipic 16 8
156 150
157 /* IDSEL 0x17 AD23*/ 151 /* IDSEL 0x17 AD23*/
158 b800 0 0 1 700 16 8 152 b800 0 0 1 &ipic 16 8
159 b800 0 0 2 700 17 8 153 b800 0 0 2 &ipic 17 8
160 b800 0 0 3 700 14 8 154 b800 0 0 3 &ipic 14 8
161 b800 0 0 4 700 15 8 155 b800 0 0 4 &ipic 15 8
162 156
163 /* IDSEL 0x18 AD24*/ 157 /* IDSEL 0x18 AD24*/
164 c000 0 0 1 700 15 8 158 c000 0 0 1 &ipic 15 8
165 c000 0 0 2 700 16 8 159 c000 0 0 2 &ipic 16 8
166 c000 0 0 3 700 17 8 160 c000 0 0 3 &ipic 17 8
167 c000 0 0 4 700 14 8>; 161 c000 0 0 4 &ipic 14 8>;
168 interrupt-parent = <700>; 162 interrupt-parent = < &ipic >;
169 interrupts = <42 8>; 163 interrupts = <42 8>;
170 bus-range = <0 0>; 164 bus-range = <0 0>;
171 ranges = <02000000 0 a0000000 a0000000 0 10000000 165 ranges = <02000000 0 a0000000 a0000000 0 10000000
@@ -180,8 +174,7 @@
180 device_type = "pci"; 174 device_type = "pci";
181 }; 175 };
182 176
183 pic@700 { 177 ipic: pic@700 {
184 linux,phandle = <700>;
185 interrupt-controller; 178 interrupt-controller;
186 #address-cells = <0>; 179 #address-cells = <0>;
187 #interrupt-cells = <2>; 180 #interrupt-cells = <2>;
@@ -195,8 +188,7 @@
195 device_type = "par_io"; 188 device_type = "par_io";
196 num-ports = <7>; 189 num-ports = <7>;
197 190
198 ucc_pin@01 { 191 pio1: ucc_pin@01 {
199 linux,phandle = <140001>;
200 pio-map = < 192 pio-map = <
201 /* port pin dir open_drain assignment has_irq */ 193 /* port pin dir open_drain assignment has_irq */
202 0 3 1 0 1 0 /* TxD0 */ 194 0 3 1 0 1 0 /* TxD0 */
@@ -223,8 +215,7 @@
223 2 9 1 0 3 0 /* GTX_CLK - CLK10 */ 215 2 9 1 0 3 0 /* GTX_CLK - CLK10 */
224 2 8 2 0 1 0>; /* GTX125 - CLK9 */ 216 2 8 2 0 1 0>; /* GTX125 - CLK9 */
225 }; 217 };
226 ucc_pin@02 { 218 pio2: ucc_pin@02 {
227 linux,phandle = <140002>;
228 pio-map = < 219 pio-map = <
229 /* port pin dir open_drain assignment has_irq */ 220 /* port pin dir open_drain assignment has_irq */
230 0 11 1 0 1 0 /* TxD0 */ 221 0 11 1 0 1 0 /* TxD0 */
@@ -281,7 +272,7 @@
281 compatible = "fsl_spi"; 272 compatible = "fsl_spi";
282 reg = <4c0 40>; 273 reg = <4c0 40>;
283 interrupts = <2>; 274 interrupts = <2>;
284 interrupt-parent = <80>; 275 interrupt-parent = < &qeic >;
285 mode = "cpu"; 276 mode = "cpu";
286 }; 277 };
287 278
@@ -290,7 +281,7 @@
290 compatible = "fsl_spi"; 281 compatible = "fsl_spi";
291 reg = <500 40>; 282 reg = <500 40>;
292 interrupts = <1>; 283 interrupts = <1>;
293 interrupt-parent = <80>; 284 interrupt-parent = < &qeic >;
294 mode = "cpu"; 285 mode = "cpu";
295 }; 286 };
296 287
@@ -299,7 +290,7 @@
299 compatible = "qe_udc"; 290 compatible = "qe_udc";
300 reg = <6c0 40 8B00 100>; 291 reg = <6c0 40 8B00 100>;
301 interrupts = <b>; 292 interrupts = <b>;
302 interrupt-parent = <80>; 293 interrupt-parent = < &qeic >;
303 mode = "slave"; 294 mode = "slave";
304 }; 295 };
305 296
@@ -310,12 +301,12 @@
310 device-id = <1>; 301 device-id = <1>;
311 reg = <2000 200>; 302 reg = <2000 200>;
312 interrupts = <20>; 303 interrupts = <20>;
313 interrupt-parent = <80>; 304 interrupt-parent = < &qeic >;
314 mac-address = [ 00 04 9f 00 23 23 ]; 305 mac-address = [ 00 04 9f 00 23 23 ];
315 rx-clock = <0>; 306 rx-clock = <0>;
316 tx-clock = <19>; 307 tx-clock = <19>;
317 phy-handle = <212000>; 308 phy-handle = < &phy0 >;
318 pio-handle = <140001>; 309 pio-handle = < &pio1 >;
319 }; 310 };
320 311
321 ucc@3000 { 312 ucc@3000 {
@@ -325,12 +316,12 @@
325 device-id = <2>; 316 device-id = <2>;
326 reg = <3000 200>; 317 reg = <3000 200>;
327 interrupts = <21>; 318 interrupts = <21>;
328 interrupt-parent = <80>; 319 interrupt-parent = < &qeic >;
329 mac-address = [ 00 11 22 33 44 55 ]; 320 mac-address = [ 00 11 22 33 44 55 ];
330 rx-clock = <0>; 321 rx-clock = <0>;
331 tx-clock = <14>; 322 tx-clock = <14>;
332 phy-handle = <212001>; 323 phy-handle = < &phy1 >;
333 pio-handle = <140002>; 324 pio-handle = < &pio2 >;
334 }; 325 };
335 326
336 mdio@2120 { 327 mdio@2120 {
@@ -340,26 +331,23 @@
340 device_type = "mdio"; 331 device_type = "mdio";
341 compatible = "ucc_geth_phy"; 332 compatible = "ucc_geth_phy";
342 333
343 ethernet-phy@00 { 334 phy0: ethernet-phy@00 {
344 linux,phandle = <212000>; 335 interrupt-parent = < &ipic >;
345 interrupt-parent = <700>; 336 interrupts = <11 8>;
346 interrupts = <11 2>;
347 reg = <0>; 337 reg = <0>;
348 device_type = "ethernet-phy"; 338 device_type = "ethernet-phy";
349 interface = <6>; //ENET_1000_GMII 339 interface = <6>; //ENET_1000_GMII
350 }; 340 };
351 ethernet-phy@01 { 341 phy1: ethernet-phy@01 {
352 linux,phandle = <212001>; 342 interrupt-parent = < &ipic >;
353 interrupt-parent = <700>; 343 interrupts = <12 8>;
354 interrupts = <12 2>;
355 reg = <1>; 344 reg = <1>;
356 device_type = "ethernet-phy"; 345 device_type = "ethernet-phy";
357 interface = <6>; 346 interface = <6>;
358 }; 347 };
359 }; 348 };
360 349
361 qeic@80 { 350 qeic: qeic@80 {
362 linux,phandle = <80>;
363 interrupt-controller; 351 interrupt-controller;
364 device_type = "qeic"; 352 device_type = "qeic";
365 #address-cells = <0>; 353 #address-cells = <0>;
@@ -368,7 +356,7 @@
368 built-in; 356 built-in;
369 big-endian; 357 big-endian;
370 interrupts = <20 8 21 8>; //high:32 low:33 358 interrupts = <20 8 21 8>; //high:32 low:33
371 interrupt-parent = <700>; 359 interrupt-parent = < &ipic >;
372 }; 360 };
373 361
374 }; 362 };
diff --git a/arch/powerpc/boot/dts/mpc8540ads.dts b/arch/powerpc/boot/dts/mpc8540ads.dts
index 5f41c1f7a5f3..3c0917fa791c 100644
--- a/arch/powerpc/boot/dts/mpc8540ads.dts
+++ b/arch/powerpc/boot/dts/mpc8540ads.dts
@@ -12,16 +12,14 @@
12 12
13/ { 13/ {
14 model = "MPC8540ADS"; 14 model = "MPC8540ADS";
15 compatible = "MPC85xxADS"; 15 compatible = "MPC8540ADS", "MPC85xxADS";
16 #address-cells = <1>; 16 #address-cells = <1>;
17 #size-cells = <1>; 17 #size-cells = <1>;
18 linux,phandle = <100>;
19 18
20 cpus { 19 cpus {
21 #cpus = <1>; 20 #cpus = <1>;
22 #address-cells = <1>; 21 #address-cells = <1>;
23 #size-cells = <0>; 22 #size-cells = <0>;
24 linux,phandle = <200>;
25 23
26 PowerPC,8540@0 { 24 PowerPC,8540@0 {
27 device_type = "cpu"; 25 device_type = "cpu";
@@ -34,13 +32,11 @@
34 bus-frequency = <0>; // 166 MHz 32 bus-frequency = <0>; // 166 MHz
35 clock-frequency = <0>; // 825 MHz, from uboot 33 clock-frequency = <0>; // 825 MHz, from uboot
36 32-bit; 34 32-bit;
37 linux,phandle = <201>;
38 }; 35 };
39 }; 36 };
40 37
41 memory { 38 memory {
42 device_type = "memory"; 39 device_type = "memory";
43 linux,phandle = <300>;
44 reg = <00000000 08000000>; // 128M at 0x0 40 reg = <00000000 08000000>; // 128M at 0x0
45 }; 41 };
46 42
@@ -58,7 +54,7 @@
58 compatible = "fsl-i2c"; 54 compatible = "fsl-i2c";
59 reg = <3000 100>; 55 reg = <3000 100>;
60 interrupts = <1b 2>; 56 interrupts = <1b 2>;
61 interrupt-parent = <40000>; 57 interrupt-parent = <&mpic>;
62 dfsrr; 58 dfsrr;
63 }; 59 };
64 60
@@ -68,24 +64,20 @@
68 device_type = "mdio"; 64 device_type = "mdio";
69 compatible = "gianfar"; 65 compatible = "gianfar";
70 reg = <24520 20>; 66 reg = <24520 20>;
71 linux,phandle = <24520>; 67 phy0: ethernet-phy@0 {
72 ethernet-phy@0 { 68 interrupt-parent = <&mpic>;
73 linux,phandle = <2452000>;
74 interrupt-parent = <40000>;
75 interrupts = <35 1>; 69 interrupts = <35 1>;
76 reg = <0>; 70 reg = <0>;
77 device_type = "ethernet-phy"; 71 device_type = "ethernet-phy";
78 }; 72 };
79 ethernet-phy@1 { 73 phy1: ethernet-phy@1 {
80 linux,phandle = <2452001>; 74 interrupt-parent = <&mpic>;
81 interrupt-parent = <40000>;
82 interrupts = <35 1>; 75 interrupts = <35 1>;
83 reg = <1>; 76 reg = <1>;
84 device_type = "ethernet-phy"; 77 device_type = "ethernet-phy";
85 }; 78 };
86 ethernet-phy@3 { 79 phy3: ethernet-phy@3 {
87 linux,phandle = <2452003>; 80 interrupt-parent = <&mpic>;
88 interrupt-parent = <40000>;
89 interrupts = <37 1>; 81 interrupts = <37 1>;
90 reg = <3>; 82 reg = <3>;
91 device_type = "ethernet-phy"; 83 device_type = "ethernet-phy";
@@ -102,8 +94,8 @@
102 address = [ 00 E0 0C 00 73 00 ]; 94 address = [ 00 E0 0C 00 73 00 ];
103 local-mac-address = [ 00 E0 0C 00 73 00 ]; 95 local-mac-address = [ 00 E0 0C 00 73 00 ];
104 interrupts = <d 2 e 2 12 2>; 96 interrupts = <d 2 e 2 12 2>;
105 interrupt-parent = <40000>; 97 interrupt-parent = <&mpic>;
106 phy-handle = <2452000>; 98 phy-handle = <&phy0>;
107 }; 99 };
108 100
109 ethernet@25000 { 101 ethernet@25000 {
@@ -116,8 +108,8 @@
116 address = [ 00 E0 0C 00 73 01 ]; 108 address = [ 00 E0 0C 00 73 01 ];
117 local-mac-address = [ 00 E0 0C 00 73 01 ]; 109 local-mac-address = [ 00 E0 0C 00 73 01 ];
118 interrupts = <13 2 14 2 18 2>; 110 interrupts = <13 2 14 2 18 2>;
119 interrupt-parent = <40000>; 111 interrupt-parent = <&mpic>;
120 phy-handle = <2452001>; 112 phy-handle = <&phy1>;
121 }; 113 };
122 114
123 ethernet@26000 { 115 ethernet@26000 {
@@ -130,8 +122,8 @@
130 address = [ 00 E0 0C 00 73 02 ]; 122 address = [ 00 E0 0C 00 73 02 ];
131 local-mac-address = [ 00 E0 0C 00 73 02 ]; 123 local-mac-address = [ 00 E0 0C 00 73 02 ];
132 interrupts = <19 2>; 124 interrupts = <19 2>;
133 interrupt-parent = <40000>; 125 interrupt-parent = <&mpic>;
134 phy-handle = <2452003>; 126 phy-handle = <&phy3>;
135 }; 127 };
136 128
137 serial@4500 { 129 serial@4500 {
@@ -140,7 +132,7 @@
140 reg = <4500 100>; // reg base, size 132 reg = <4500 100>; // reg base, size
141 clock-frequency = <0>; // should we fill in in uboot? 133 clock-frequency = <0>; // should we fill in in uboot?
142 interrupts = <1a 2>; 134 interrupts = <1a 2>;
143 interrupt-parent = <40000>; 135 interrupt-parent = <&mpic>;
144 }; 136 };
145 137
146 serial@4600 { 138 serial@4600 {
@@ -149,85 +141,84 @@
149 reg = <4600 100>; // reg base, size 141 reg = <4600 100>; // reg base, size
150 clock-frequency = <0>; // should we fill in in uboot? 142 clock-frequency = <0>; // should we fill in in uboot?
151 interrupts = <1a 2>; 143 interrupts = <1a 2>;
152 interrupt-parent = <40000>; 144 interrupt-parent = <&mpic>;
153 }; 145 };
154 pci@8000 { 146 pci@8000 {
155 linux,phandle = <8000>;
156 interrupt-map-mask = <f800 0 0 7>; 147 interrupt-map-mask = <f800 0 0 7>;
157 interrupt-map = < 148 interrupt-map = <
158 149
159 /* IDSEL 0x02 */ 150 /* IDSEL 0x02 */
160 1000 0 0 1 40000 31 1 151 1000 0 0 1 &mpic 31 1
161 1000 0 0 2 40000 32 1 152 1000 0 0 2 &mpic 32 1
162 1000 0 0 3 40000 33 1 153 1000 0 0 3 &mpic 33 1
163 1000 0 0 4 40000 34 1 154 1000 0 0 4 &mpic 34 1
164 155
165 /* IDSEL 0x03 */ 156 /* IDSEL 0x03 */
166 1800 0 0 1 40000 34 1 157 1800 0 0 1 &mpic 34 1
167 1800 0 0 2 40000 31 1 158 1800 0 0 2 &mpic 31 1
168 1800 0 0 3 40000 32 1 159 1800 0 0 3 &mpic 32 1
169 1800 0 0 4 40000 33 1 160 1800 0 0 4 &mpic 33 1
170 161
171 /* IDSEL 0x04 */ 162 /* IDSEL 0x04 */
172 2000 0 0 1 40000 33 1 163 2000 0 0 1 &mpic 33 1
173 2000 0 0 2 40000 34 1 164 2000 0 0 2 &mpic 34 1
174 2000 0 0 3 40000 31 1 165 2000 0 0 3 &mpic 31 1
175 2000 0 0 4 40000 32 1 166 2000 0 0 4 &mpic 32 1
176 167
177 /* IDSEL 0x05 */ 168 /* IDSEL 0x05 */
178 2800 0 0 1 40000 32 1 169 2800 0 0 1 &mpic 32 1
179 2800 0 0 2 40000 33 1 170 2800 0 0 2 &mpic 33 1
180 2800 0 0 3 40000 34 1 171 2800 0 0 3 &mpic 34 1
181 2800 0 0 4 40000 31 1 172 2800 0 0 4 &mpic 31 1
182 173
183 /* IDSEL 0x0c */ 174 /* IDSEL 0x0c */
184 6000 0 0 1 40000 31 1 175 6000 0 0 1 &mpic 31 1
185 6000 0 0 2 40000 32 1 176 6000 0 0 2 &mpic 32 1
186 6000 0 0 3 40000 33 1 177 6000 0 0 3 &mpic 33 1
187 6000 0 0 4 40000 34 1 178 6000 0 0 4 &mpic 34 1
188 179
189 /* IDSEL 0x0d */ 180 /* IDSEL 0x0d */
190 6800 0 0 1 40000 34 1 181 6800 0 0 1 &mpic 34 1
191 6800 0 0 2 40000 31 1 182 6800 0 0 2 &mpic 31 1
192 6800 0 0 3 40000 32 1 183 6800 0 0 3 &mpic 32 1
193 6800 0 0 4 40000 33 1 184 6800 0 0 4 &mpic 33 1
194 185
195 /* IDSEL 0x0e */ 186 /* IDSEL 0x0e */
196 7000 0 0 1 40000 33 1 187 7000 0 0 1 &mpic 33 1
197 7000 0 0 2 40000 34 1 188 7000 0 0 2 &mpic 34 1
198 7000 0 0 3 40000 31 1 189 7000 0 0 3 &mpic 31 1
199 7000 0 0 4 40000 32 1 190 7000 0 0 4 &mpic 32 1
200 191
201 /* IDSEL 0x0f */ 192 /* IDSEL 0x0f */
202 7800 0 0 1 40000 32 1 193 7800 0 0 1 &mpic 32 1
203 7800 0 0 2 40000 33 1 194 7800 0 0 2 &mpic 33 1
204 7800 0 0 3 40000 34 1 195 7800 0 0 3 &mpic 34 1
205 7800 0 0 4 40000 31 1 196 7800 0 0 4 &mpic 31 1
206 197
207 /* IDSEL 0x12 */ 198 /* IDSEL 0x12 */
208 9000 0 0 1 40000 31 1 199 9000 0 0 1 &mpic 31 1
209 9000 0 0 2 40000 32 1 200 9000 0 0 2 &mpic 32 1
210 9000 0 0 3 40000 33 1 201 9000 0 0 3 &mpic 33 1
211 9000 0 0 4 40000 34 1 202 9000 0 0 4 &mpic 34 1
212 203
213 /* IDSEL 0x13 */ 204 /* IDSEL 0x13 */
214 9800 0 0 1 40000 34 1 205 9800 0 0 1 &mpic 34 1
215 9800 0 0 2 40000 31 1 206 9800 0 0 2 &mpic 31 1
216 9800 0 0 3 40000 32 1 207 9800 0 0 3 &mpic 32 1
217 9800 0 0 4 40000 33 1 208 9800 0 0 4 &mpic 33 1
218 209
219 /* IDSEL 0x14 */ 210 /* IDSEL 0x14 */
220 a000 0 0 1 40000 33 1 211 a000 0 0 1 &mpic 33 1
221 a000 0 0 2 40000 34 1 212 a000 0 0 2 &mpic 34 1
222 a000 0 0 3 40000 31 1 213 a000 0 0 3 &mpic 31 1
223 a000 0 0 4 40000 32 1 214 a000 0 0 4 &mpic 32 1
224 215
225 /* IDSEL 0x15 */ 216 /* IDSEL 0x15 */
226 a800 0 0 1 40000 32 1 217 a800 0 0 1 &mpic 32 1
227 a800 0 0 2 40000 33 1 218 a800 0 0 2 &mpic 33 1
228 a800 0 0 3 40000 34 1 219 a800 0 0 3 &mpic 34 1
229 a800 0 0 4 40000 31 1>; 220 a800 0 0 4 &mpic 31 1>;
230 interrupt-parent = <40000>; 221 interrupt-parent = <&mpic>;
231 interrupts = <08 2>; 222 interrupts = <08 2>;
232 bus-range = <0 0>; 223 bus-range = <0 0>;
233 ranges = <02000000 0 80000000 80000000 0 20000000 224 ranges = <02000000 0 80000000 80000000 0 20000000
@@ -241,8 +232,7 @@
241 device_type = "pci"; 232 device_type = "pci";
242 }; 233 };
243 234
244 pic@40000 { 235 mpic: pic@40000 {
245 linux,phandle = <40000>;
246 clock-frequency = <0>; 236 clock-frequency = <0>;
247 interrupt-controller; 237 interrupt-controller;
248 #address-cells = <0>; 238 #address-cells = <0>;
diff --git a/arch/powerpc/boot/dts/mpc8541cds.dts b/arch/powerpc/boot/dts/mpc8541cds.dts
index 7be0bc659e1c..2a1ae760ab3a 100644
--- a/arch/powerpc/boot/dts/mpc8541cds.dts
+++ b/arch/powerpc/boot/dts/mpc8541cds.dts
@@ -12,16 +12,14 @@
12 12
13/ { 13/ {
14 model = "MPC8541CDS"; 14 model = "MPC8541CDS";
15 compatible = "MPC85xxCDS"; 15 compatible = "MPC8541CDS", "MPC85xxCDS";
16 #address-cells = <1>; 16 #address-cells = <1>;
17 #size-cells = <1>; 17 #size-cells = <1>;
18 linux,phandle = <100>;
19 18
20 cpus { 19 cpus {
21 #cpus = <1>; 20 #cpus = <1>;
22 #address-cells = <1>; 21 #address-cells = <1>;
23 #size-cells = <0>; 22 #size-cells = <0>;
24 linux,phandle = <200>;
25 23
26 PowerPC,8541@0 { 24 PowerPC,8541@0 {
27 device_type = "cpu"; 25 device_type = "cpu";
@@ -34,13 +32,11 @@
34 bus-frequency = <0>; // 166 MHz 32 bus-frequency = <0>; // 166 MHz
35 clock-frequency = <0>; // 825 MHz, from uboot 33 clock-frequency = <0>; // 825 MHz, from uboot
36 32-bit; 34 32-bit;
37 linux,phandle = <201>;
38 }; 35 };
39 }; 36 };
40 37
41 memory { 38 memory {
42 device_type = "memory"; 39 device_type = "memory";
43 linux,phandle = <300>;
44 reg = <00000000 08000000>; // 128M at 0x0 40 reg = <00000000 08000000>; // 128M at 0x0
45 }; 41 };
46 42
@@ -58,7 +54,7 @@
58 compatible = "fsl-i2c"; 54 compatible = "fsl-i2c";
59 reg = <3000 100>; 55 reg = <3000 100>;
60 interrupts = <1b 2>; 56 interrupts = <1b 2>;
61 interrupt-parent = <40000>; 57 interrupt-parent = <&mpic>;
62 dfsrr; 58 dfsrr;
63 }; 59 };
64 60
@@ -68,17 +64,14 @@
68 device_type = "mdio"; 64 device_type = "mdio";
69 compatible = "gianfar"; 65 compatible = "gianfar";
70 reg = <24520 20>; 66 reg = <24520 20>;
71 linux,phandle = <24520>; 67 phy0: ethernet-phy@0 {
72 ethernet-phy@0 { 68 interrupt-parent = <&mpic>;
73 linux,phandle = <2452000>;
74 interrupt-parent = <40000>;
75 interrupts = <35 0>; 69 interrupts = <35 0>;
76 reg = <0>; 70 reg = <0>;
77 device_type = "ethernet-phy"; 71 device_type = "ethernet-phy";
78 }; 72 };
79 ethernet-phy@1 { 73 phy1: ethernet-phy@1 {
80 linux,phandle = <2452001>; 74 interrupt-parent = <&mpic>;
81 interrupt-parent = <40000>;
82 interrupts = <35 0>; 75 interrupts = <35 0>;
83 reg = <1>; 76 reg = <1>;
84 device_type = "ethernet-phy"; 77 device_type = "ethernet-phy";
@@ -94,8 +87,8 @@
94 reg = <24000 1000>; 87 reg = <24000 1000>;
95 local-mac-address = [ 00 E0 0C 00 73 00 ]; 88 local-mac-address = [ 00 E0 0C 00 73 00 ];
96 interrupts = <d 2 e 2 12 2>; 89 interrupts = <d 2 e 2 12 2>;
97 interrupt-parent = <40000>; 90 interrupt-parent = <&mpic>;
98 phy-handle = <2452000>; 91 phy-handle = <&phy0>;
99 }; 92 };
100 93
101 ethernet@25000 { 94 ethernet@25000 {
@@ -107,8 +100,8 @@
107 reg = <25000 1000>; 100 reg = <25000 1000>;
108 local-mac-address = [ 00 E0 0C 00 73 01 ]; 101 local-mac-address = [ 00 E0 0C 00 73 01 ];
109 interrupts = <13 2 14 2 18 2>; 102 interrupts = <13 2 14 2 18 2>;
110 interrupt-parent = <40000>; 103 interrupt-parent = <&mpic>;
111 phy-handle = <2452001>; 104 phy-handle = <&phy1>;
112 }; 105 };
113 106
114 serial@4500 { 107 serial@4500 {
@@ -117,7 +110,7 @@
117 reg = <4500 100>; // reg base, size 110 reg = <4500 100>; // reg base, size
118 clock-frequency = <0>; // should we fill in in uboot? 111 clock-frequency = <0>; // should we fill in in uboot?
119 interrupts = <1a 2>; 112 interrupts = <1a 2>;
120 interrupt-parent = <40000>; 113 interrupt-parent = <&mpic>;
121 }; 114 };
122 115
123 serial@4600 { 116 serial@4600 {
@@ -126,57 +119,56 @@
126 reg = <4600 100>; // reg base, size 119 reg = <4600 100>; // reg base, size
127 clock-frequency = <0>; // should we fill in in uboot? 120 clock-frequency = <0>; // should we fill in in uboot?
128 interrupts = <1a 2>; 121 interrupts = <1a 2>;
129 interrupt-parent = <40000>; 122 interrupt-parent = <&mpic>;
130 }; 123 };
131 124
132 pci@8000 { 125 pci1: pci@8000 {
133 linux,phandle = <8000>;
134 interrupt-map-mask = <1f800 0 0 7>; 126 interrupt-map-mask = <1f800 0 0 7>;
135 interrupt-map = < 127 interrupt-map = <
136 128
137 /* IDSEL 0x10 */ 129 /* IDSEL 0x10 */
138 08000 0 0 1 40000 30 1 130 08000 0 0 1 &mpic 30 1
139 08000 0 0 2 40000 31 1 131 08000 0 0 2 &mpic 31 1
140 08000 0 0 3 40000 32 1 132 08000 0 0 3 &mpic 32 1
141 08000 0 0 4 40000 33 1 133 08000 0 0 4 &mpic 33 1
142 134
143 /* IDSEL 0x11 */ 135 /* IDSEL 0x11 */
144 08800 0 0 1 40000 30 1 136 08800 0 0 1 &mpic 30 1
145 08800 0 0 2 40000 31 1 137 08800 0 0 2 &mpic 31 1
146 08800 0 0 3 40000 32 1 138 08800 0 0 3 &mpic 32 1
147 08800 0 0 4 40000 33 1 139 08800 0 0 4 &mpic 33 1
148 140
149 /* IDSEL 0x12 (Slot 1) */ 141 /* IDSEL 0x12 (Slot 1) */
150 09000 0 0 1 40000 30 1 142 09000 0 0 1 &mpic 30 1
151 09000 0 0 2 40000 31 1 143 09000 0 0 2 &mpic 31 1
152 09000 0 0 3 40000 32 1 144 09000 0 0 3 &mpic 32 1
153 09000 0 0 4 40000 33 1 145 09000 0 0 4 &mpic 33 1
154 146
155 /* IDSEL 0x13 (Slot 2) */ 147 /* IDSEL 0x13 (Slot 2) */
156 09800 0 0 1 40000 31 1 148 09800 0 0 1 &mpic 31 1
157 09800 0 0 2 40000 32 1 149 09800 0 0 2 &mpic 32 1
158 09800 0 0 3 40000 33 1 150 09800 0 0 3 &mpic 33 1
159 09800 0 0 4 40000 30 1 151 09800 0 0 4 &mpic 30 1
160 152
161 /* IDSEL 0x14 (Slot 3) */ 153 /* IDSEL 0x14 (Slot 3) */
162 0a000 0 0 1 40000 32 1 154 0a000 0 0 1 &mpic 32 1
163 0a000 0 0 2 40000 33 1 155 0a000 0 0 2 &mpic 33 1
164 0a000 0 0 3 40000 30 1 156 0a000 0 0 3 &mpic 30 1
165 0a000 0 0 4 40000 31 1 157 0a000 0 0 4 &mpic 31 1
166 158
167 /* IDSEL 0x15 (Slot 4) */ 159 /* IDSEL 0x15 (Slot 4) */
168 0a800 0 0 1 40000 33 1 160 0a800 0 0 1 &mpic 33 1
169 0a800 0 0 2 40000 30 1 161 0a800 0 0 2 &mpic 30 1
170 0a800 0 0 3 40000 31 1 162 0a800 0 0 3 &mpic 31 1
171 0a800 0 0 4 40000 32 1 163 0a800 0 0 4 &mpic 32 1
172 164
173 /* Bus 1 (Tundra Bridge) */ 165 /* Bus 1 (Tundra Bridge) */
174 /* IDSEL 0x12 (ISA bridge) */ 166 /* IDSEL 0x12 (ISA bridge) */
175 19000 0 0 1 40000 30 1 167 19000 0 0 1 &mpic 30 1
176 19000 0 0 2 40000 31 1 168 19000 0 0 2 &mpic 31 1
177 19000 0 0 3 40000 32 1 169 19000 0 0 3 &mpic 32 1
178 19000 0 0 4 40000 33 1>; 170 19000 0 0 4 &mpic 33 1>;
179 interrupt-parent = <40000>; 171 interrupt-parent = <&mpic>;
180 interrupts = <08 2>; 172 interrupts = <08 2>;
181 bus-range = <0 0>; 173 bus-range = <0 0>;
182 ranges = <02000000 0 80000000 80000000 0 20000000 174 ranges = <02000000 0 80000000 80000000 0 20000000
@@ -200,21 +192,20 @@
200 compatible = "chrp,iic"; 192 compatible = "chrp,iic";
201 big-endian; 193 big-endian;
202 interrupts = <1>; 194 interrupts = <1>;
203 interrupt-parent = <8000>; 195 interrupt-parent = <&pci1>;
204 }; 196 };
205 }; 197 };
206 198
207 pci@9000 { 199 pci@9000 {
208 linux,phandle = <9000>;
209 interrupt-map-mask = <f800 0 0 7>; 200 interrupt-map-mask = <f800 0 0 7>;
210 interrupt-map = < 201 interrupt-map = <
211 202
212 /* IDSEL 0x15 */ 203 /* IDSEL 0x15 */
213 a800 0 0 1 40000 3b 1 204 a800 0 0 1 &mpic 3b 1
214 a800 0 0 2 40000 3b 1 205 a800 0 0 2 &mpic 3b 1
215 a800 0 0 3 40000 3b 1 206 a800 0 0 3 &mpic 3b 1
216 a800 0 0 4 40000 3b 1>; 207 a800 0 0 4 &mpic 3b 1>;
217 interrupt-parent = <40000>; 208 interrupt-parent = <&mpic>;
218 interrupts = <09 2>; 209 interrupts = <09 2>;
219 bus-range = <0 0>; 210 bus-range = <0 0>;
220 ranges = <02000000 0 a0000000 a0000000 0 20000000 211 ranges = <02000000 0 a0000000 a0000000 0 20000000
@@ -228,8 +219,7 @@
228 device_type = "pci"; 219 device_type = "pci";
229 }; 220 };
230 221
231 pic@40000 { 222 mpic: pic@40000 {
232 linux,phandle = <40000>;
233 clock-frequency = <0>; 223 clock-frequency = <0>;
234 interrupt-controller; 224 interrupt-controller;
235 #address-cells = <0>; 225 #address-cells = <0>;
diff --git a/arch/powerpc/boot/dts/mpc8548cds.dts b/arch/powerpc/boot/dts/mpc8548cds.dts
index 893d7957c174..7eb5d81d5eec 100644
--- a/arch/powerpc/boot/dts/mpc8548cds.dts
+++ b/arch/powerpc/boot/dts/mpc8548cds.dts
@@ -12,16 +12,14 @@
12 12
13/ { 13/ {
14 model = "MPC8548CDS"; 14 model = "MPC8548CDS";
15 compatible = "MPC85xxCDS"; 15 compatible = "MPC8548CDS", "MPC85xxCDS";
16 #address-cells = <1>; 16 #address-cells = <1>;
17 #size-cells = <1>; 17 #size-cells = <1>;
18 linux,phandle = <100>;
19 18
20 cpus { 19 cpus {
21 #cpus = <1>; 20 #cpus = <1>;
22 #address-cells = <1>; 21 #address-cells = <1>;
23 #size-cells = <0>; 22 #size-cells = <0>;
24 linux,phandle = <200>;
25 23
26 PowerPC,8548@0 { 24 PowerPC,8548@0 {
27 device_type = "cpu"; 25 device_type = "cpu";
@@ -34,13 +32,11 @@
34 bus-frequency = <0>; // 166 MHz 32 bus-frequency = <0>; // 166 MHz
35 clock-frequency = <0>; // 825 MHz, from uboot 33 clock-frequency = <0>; // 825 MHz, from uboot
36 32-bit; 34 32-bit;
37 linux,phandle = <201>;
38 }; 35 };
39 }; 36 };
40 37
41 memory { 38 memory {
42 device_type = "memory"; 39 device_type = "memory";
43 linux,phandle = <300>;
44 reg = <00000000 08000000>; // 128M at 0x0 40 reg = <00000000 08000000>; // 128M at 0x0
45 }; 41 };
46 42
@@ -58,7 +54,7 @@
58 compatible = "fsl-i2c"; 54 compatible = "fsl-i2c";
59 reg = <3000 100>; 55 reg = <3000 100>;
60 interrupts = <1b 2>; 56 interrupts = <1b 2>;
61 interrupt-parent = <40000>; 57 interrupt-parent = <&mpic>;
62 dfsrr; 58 dfsrr;
63 }; 59 };
64 60
@@ -68,32 +64,26 @@
68 device_type = "mdio"; 64 device_type = "mdio";
69 compatible = "gianfar"; 65 compatible = "gianfar";
70 reg = <24520 20>; 66 reg = <24520 20>;
71 linux,phandle = <24520>; 67 phy0: ethernet-phy@0 {
72 ethernet-phy@0 { 68 interrupt-parent = <&mpic>;
73 linux,phandle = <2452000>;
74 interrupt-parent = <40000>;
75 interrupts = <35 0>; 69 interrupts = <35 0>;
76 reg = <0>; 70 reg = <0>;
77 device_type = "ethernet-phy"; 71 device_type = "ethernet-phy";
78 }; 72 };
79 ethernet-phy@1 { 73 phy1: ethernet-phy@1 {
80 linux,phandle = <2452001>; 74 interrupt-parent = <&mpic>;
81 interrupt-parent = <40000>;
82 interrupts = <35 0>; 75 interrupts = <35 0>;
83 reg = <1>; 76 reg = <1>;
84 device_type = "ethernet-phy"; 77 device_type = "ethernet-phy";
85 }; 78 };
86 79 phy2: ethernet-phy@2 {
87 ethernet-phy@2 { 80 interrupt-parent = <&mpic>;
88 linux,phandle = <2452002>;
89 interrupt-parent = <40000>;
90 interrupts = <35 0>; 81 interrupts = <35 0>;
91 reg = <2>; 82 reg = <2>;
92 device_type = "ethernet-phy"; 83 device_type = "ethernet-phy";
93 }; 84 };
94 ethernet-phy@3 { 85 phy3: ethernet-phy@3 {
95 linux,phandle = <2452003>; 86 interrupt-parent = <&mpic>;
96 interrupt-parent = <40000>;
97 interrupts = <35 0>; 87 interrupts = <35 0>;
98 reg = <3>; 88 reg = <3>;
99 device_type = "ethernet-phy"; 89 device_type = "ethernet-phy";
@@ -109,8 +99,8 @@
109 reg = <24000 1000>; 99 reg = <24000 1000>;
110 local-mac-address = [ 00 E0 0C 00 73 00 ]; 100 local-mac-address = [ 00 E0 0C 00 73 00 ];
111 interrupts = <d 2 e 2 12 2>; 101 interrupts = <d 2 e 2 12 2>;
112 interrupt-parent = <40000>; 102 interrupt-parent = <&mpic>;
113 phy-handle = <2452000>; 103 phy-handle = <&phy0>;
114 }; 104 };
115 105
116 ethernet@25000 { 106 ethernet@25000 {
@@ -122,10 +112,11 @@
122 reg = <25000 1000>; 112 reg = <25000 1000>;
123 local-mac-address = [ 00 E0 0C 00 73 01 ]; 113 local-mac-address = [ 00 E0 0C 00 73 01 ];
124 interrupts = <13 2 14 2 18 2>; 114 interrupts = <13 2 14 2 18 2>;
125 interrupt-parent = <40000>; 115 interrupt-parent = <&mpic>;
126 phy-handle = <2452001>; 116 phy-handle = <&phy1>;
127 }; 117 };
128 118
119/* eTSEC 3/4 are currently broken
129 ethernet@26000 { 120 ethernet@26000 {
130 #address-cells = <1>; 121 #address-cells = <1>;
131 #size-cells = <0>; 122 #size-cells = <0>;
@@ -135,11 +126,10 @@
135 reg = <26000 1000>; 126 reg = <26000 1000>;
136 local-mac-address = [ 00 E0 0C 00 73 02 ]; 127 local-mac-address = [ 00 E0 0C 00 73 02 ];
137 interrupts = <f 2 10 2 11 2>; 128 interrupts = <f 2 10 2 11 2>;
138 interrupt-parent = <40000>; 129 interrupt-parent = <&mpic>;
139 phy-handle = <2452001>; 130 phy-handle = <&phy2>;
140 }; 131 };
141 132
142/* eTSEC 4 is currently broken
143 ethernet@27000 { 133 ethernet@27000 {
144 #address-cells = <1>; 134 #address-cells = <1>;
145 #size-cells = <0>; 135 #size-cells = <0>;
@@ -149,8 +139,8 @@
149 reg = <27000 1000>; 139 reg = <27000 1000>;
150 local-mac-address = [ 00 E0 0C 00 73 03 ]; 140 local-mac-address = [ 00 E0 0C 00 73 03 ];
151 interrupts = <15 2 16 2 17 2>; 141 interrupts = <15 2 16 2 17 2>;
152 interrupt-parent = <40000>; 142 interrupt-parent = <&mpic>;
153 phy-handle = <2452001>; 143 phy-handle = <&phy3>;
154 }; 144 };
155 */ 145 */
156 146
@@ -160,7 +150,7 @@
160 reg = <4500 100>; // reg base, size 150 reg = <4500 100>; // reg base, size
161 clock-frequency = <0>; // should we fill in in uboot? 151 clock-frequency = <0>; // should we fill in in uboot?
162 interrupts = <1a 2>; 152 interrupts = <1a 2>;
163 interrupt-parent = <40000>; 153 interrupt-parent = <&mpic>;
164 }; 154 };
165 155
166 serial@4600 { 156 serial@4600 {
@@ -169,57 +159,56 @@
169 reg = <4600 100>; // reg base, size 159 reg = <4600 100>; // reg base, size
170 clock-frequency = <0>; // should we fill in in uboot? 160 clock-frequency = <0>; // should we fill in in uboot?
171 interrupts = <1a 2>; 161 interrupts = <1a 2>;
172 interrupt-parent = <40000>; 162 interrupt-parent = <&mpic>;
173 }; 163 };
174 164
175 pci@8000 { 165 pci1: pci@8000 {
176 linux,phandle = <8000>;
177 interrupt-map-mask = <1f800 0 0 7>; 166 interrupt-map-mask = <1f800 0 0 7>;
178 interrupt-map = < 167 interrupt-map = <
179 168
180 /* IDSEL 0x10 */ 169 /* IDSEL 0x10 */
181 08000 0 0 1 40000 30 1 170 08000 0 0 1 &mpic 30 1
182 08000 0 0 2 40000 31 1 171 08000 0 0 2 &mpic 31 1
183 08000 0 0 3 40000 32 1 172 08000 0 0 3 &mpic 32 1
184 08000 0 0 4 40000 33 1 173 08000 0 0 4 &mpic 33 1
185 174
186 /* IDSEL 0x11 */ 175 /* IDSEL 0x11 */
187 08800 0 0 1 40000 30 1 176 08800 0 0 1 &mpic 30 1
188 08800 0 0 2 40000 31 1 177 08800 0 0 2 &mpic 31 1
189 08800 0 0 3 40000 32 1 178 08800 0 0 3 &mpic 32 1
190 08800 0 0 4 40000 33 1 179 08800 0 0 4 &mpic 33 1
191 180
192 /* IDSEL 0x12 (Slot 1) */ 181 /* IDSEL 0x12 (Slot 1) */
193 09000 0 0 1 40000 30 1 182 09000 0 0 1 &mpic 30 1
194 09000 0 0 2 40000 31 1 183 09000 0 0 2 &mpic 31 1
195 09000 0 0 3 40000 32 1 184 09000 0 0 3 &mpic 32 1
196 09000 0 0 4 40000 33 1 185 09000 0 0 4 &mpic 33 1
197 186
198 /* IDSEL 0x13 (Slot 2) */ 187 /* IDSEL 0x13 (Slot 2) */
199 09800 0 0 1 40000 31 1 188 09800 0 0 1 &mpic 31 1
200 09800 0 0 2 40000 32 1 189 09800 0 0 2 &mpic 32 1
201 09800 0 0 3 40000 33 1 190 09800 0 0 3 &mpic 33 1
202 09800 0 0 4 40000 30 1 191 09800 0 0 4 &mpic 30 1
203 192
204 /* IDSEL 0x14 (Slot 3) */ 193 /* IDSEL 0x14 (Slot 3) */
205 0a000 0 0 1 40000 32 1 194 0a000 0 0 1 &mpic 32 1
206 0a000 0 0 2 40000 33 1 195 0a000 0 0 2 &mpic 33 1
207 0a000 0 0 3 40000 30 1 196 0a000 0 0 3 &mpic 30 1
208 0a000 0 0 4 40000 31 1 197 0a000 0 0 4 &mpic 31 1
209 198
210 /* IDSEL 0x15 (Slot 4) */ 199 /* IDSEL 0x15 (Slot 4) */
211 0a800 0 0 1 40000 33 1 200 0a800 0 0 1 &mpic 33 1
212 0a800 0 0 2 40000 30 1 201 0a800 0 0 2 &mpic 30 1
213 0a800 0 0 3 40000 31 1 202 0a800 0 0 3 &mpic 31 1
214 0a800 0 0 4 40000 32 1 203 0a800 0 0 4 &mpic 32 1
215 204
216 /* Bus 1 (Tundra Bridge) */ 205 /* Bus 1 (Tundra Bridge) */
217 /* IDSEL 0x12 (ISA bridge) */ 206 /* IDSEL 0x12 (ISA bridge) */
218 19000 0 0 1 40000 30 1 207 19000 0 0 1 &mpic 30 1
219 19000 0 0 2 40000 31 1 208 19000 0 0 2 &mpic 31 1
220 19000 0 0 3 40000 32 1 209 19000 0 0 3 &mpic 32 1
221 19000 0 0 4 40000 33 1>; 210 19000 0 0 4 &mpic 33 1>;
222 interrupt-parent = <40000>; 211 interrupt-parent = <&mpic>;
223 interrupts = <08 2>; 212 interrupts = <08 2>;
224 bus-range = <0 0>; 213 bus-range = <0 0>;
225 ranges = <02000000 0 80000000 80000000 0 20000000 214 ranges = <02000000 0 80000000 80000000 0 20000000
@@ -243,21 +232,20 @@
243 compatible = "chrp,iic"; 232 compatible = "chrp,iic";
244 big-endian; 233 big-endian;
245 interrupts = <1>; 234 interrupts = <1>;
246 interrupt-parent = <8000>; 235 interrupt-parent = <&pci1>;
247 }; 236 };
248 }; 237 };
249 238
250 pci@9000 { 239 pci@9000 {
251 linux,phandle = <9000>;
252 interrupt-map-mask = <f800 0 0 7>; 240 interrupt-map-mask = <f800 0 0 7>;
253 interrupt-map = < 241 interrupt-map = <
254 242
255 /* IDSEL 0x15 */ 243 /* IDSEL 0x15 */
256 a800 0 0 1 40000 3b 1 244 a800 0 0 1 &mpic 3b 1
257 a800 0 0 2 40000 3b 1 245 a800 0 0 2 &mpic 3b 1
258 a800 0 0 3 40000 3b 1 246 a800 0 0 3 &mpic 3b 1
259 a800 0 0 4 40000 3b 1>; 247 a800 0 0 4 &mpic 3b 1>;
260 interrupt-parent = <40000>; 248 interrupt-parent = <&mpic>;
261 interrupts = <09 2>; 249 interrupts = <09 2>;
262 bus-range = <0 0>; 250 bus-range = <0 0>;
263 ranges = <02000000 0 a0000000 a0000000 0 20000000 251 ranges = <02000000 0 a0000000 a0000000 0 20000000
@@ -271,8 +259,7 @@
271 device_type = "pci"; 259 device_type = "pci";
272 }; 260 };
273 261
274 pic@40000 { 262 mpic: pic@40000 {
275 linux,phandle = <40000>;
276 clock-frequency = <0>; 263 clock-frequency = <0>;
277 interrupt-controller; 264 interrupt-controller;
278 #address-cells = <0>; 265 #address-cells = <0>;
diff --git a/arch/powerpc/boot/dts/mpc8555cds.dts b/arch/powerpc/boot/dts/mpc8555cds.dts
index 118f5a887651..5f9c102a0ab4 100644
--- a/arch/powerpc/boot/dts/mpc8555cds.dts
+++ b/arch/powerpc/boot/dts/mpc8555cds.dts
@@ -12,16 +12,14 @@
12 12
13/ { 13/ {
14 model = "MPC8555CDS"; 14 model = "MPC8555CDS";
15 compatible = "MPC85xxCDS"; 15 compatible = "MPC8555CDS", "MPC85xxCDS";
16 #address-cells = <1>; 16 #address-cells = <1>;
17 #size-cells = <1>; 17 #size-cells = <1>;
18 linux,phandle = <100>;
19 18
20 cpus { 19 cpus {
21 #cpus = <1>; 20 #cpus = <1>;
22 #address-cells = <1>; 21 #address-cells = <1>;
23 #size-cells = <0>; 22 #size-cells = <0>;
24 linux,phandle = <200>;
25 23
26 PowerPC,8555@0 { 24 PowerPC,8555@0 {
27 device_type = "cpu"; 25 device_type = "cpu";
@@ -34,13 +32,11 @@
34 bus-frequency = <0>; // 166 MHz 32 bus-frequency = <0>; // 166 MHz
35 clock-frequency = <0>; // 825 MHz, from uboot 33 clock-frequency = <0>; // 825 MHz, from uboot
36 32-bit; 34 32-bit;
37 linux,phandle = <201>;
38 }; 35 };
39 }; 36 };
40 37
41 memory { 38 memory {
42 device_type = "memory"; 39 device_type = "memory";
43 linux,phandle = <300>;
44 reg = <00000000 08000000>; // 128M at 0x0 40 reg = <00000000 08000000>; // 128M at 0x0
45 }; 41 };
46 42
@@ -58,7 +54,7 @@
58 compatible = "fsl-i2c"; 54 compatible = "fsl-i2c";
59 reg = <3000 100>; 55 reg = <3000 100>;
60 interrupts = <1b 2>; 56 interrupts = <1b 2>;
61 interrupt-parent = <40000>; 57 interrupt-parent = <&mpic>;
62 dfsrr; 58 dfsrr;
63 }; 59 };
64 60
@@ -68,17 +64,14 @@
68 device_type = "mdio"; 64 device_type = "mdio";
69 compatible = "gianfar"; 65 compatible = "gianfar";
70 reg = <24520 20>; 66 reg = <24520 20>;
71 linux,phandle = <24520>; 67 phy0: ethernet-phy@0 {
72 ethernet-phy@0 { 68 interrupt-parent = <&mpic>;
73 linux,phandle = <2452000>;
74 interrupt-parent = <40000>;
75 interrupts = <35 0>; 69 interrupts = <35 0>;
76 reg = <0>; 70 reg = <0>;
77 device_type = "ethernet-phy"; 71 device_type = "ethernet-phy";
78 }; 72 };
79 ethernet-phy@1 { 73 phy1: ethernet-phy@1 {
80 linux,phandle = <2452001>; 74 interrupt-parent = <&mpic>;
81 interrupt-parent = <40000>;
82 interrupts = <35 0>; 75 interrupts = <35 0>;
83 reg = <1>; 76 reg = <1>;
84 device_type = "ethernet-phy"; 77 device_type = "ethernet-phy";
@@ -94,8 +87,8 @@
94 reg = <24000 1000>; 87 reg = <24000 1000>;
95 local-mac-address = [ 00 E0 0C 00 73 00 ]; 88 local-mac-address = [ 00 E0 0C 00 73 00 ];
96 interrupts = <0d 2 0e 2 12 2>; 89 interrupts = <0d 2 0e 2 12 2>;
97 interrupt-parent = <40000>; 90 interrupt-parent = <&mpic>;
98 phy-handle = <2452000>; 91 phy-handle = <&phy0>;
99 }; 92 };
100 93
101 ethernet@25000 { 94 ethernet@25000 {
@@ -107,8 +100,8 @@
107 reg = <25000 1000>; 100 reg = <25000 1000>;
108 local-mac-address = [ 00 E0 0C 00 73 01 ]; 101 local-mac-address = [ 00 E0 0C 00 73 01 ];
109 interrupts = <13 2 14 2 18 2>; 102 interrupts = <13 2 14 2 18 2>;
110 interrupt-parent = <40000>; 103 interrupt-parent = <&mpic>;
111 phy-handle = <2452001>; 104 phy-handle = <&phy1>;
112 }; 105 };
113 106
114 serial@4500 { 107 serial@4500 {
@@ -117,7 +110,7 @@
117 reg = <4500 100>; // reg base, size 110 reg = <4500 100>; // reg base, size
118 clock-frequency = <0>; // should we fill in in uboot? 111 clock-frequency = <0>; // should we fill in in uboot?
119 interrupts = <1a 2>; 112 interrupts = <1a 2>;
120 interrupt-parent = <40000>; 113 interrupt-parent = <&mpic>;
121 }; 114 };
122 115
123 serial@4600 { 116 serial@4600 {
@@ -126,57 +119,56 @@
126 reg = <4600 100>; // reg base, size 119 reg = <4600 100>; // reg base, size
127 clock-frequency = <0>; // should we fill in in uboot? 120 clock-frequency = <0>; // should we fill in in uboot?
128 interrupts = <1a 2>; 121 interrupts = <1a 2>;
129 interrupt-parent = <40000>; 122 interrupt-parent = <&mpic>;
130 }; 123 };
131 124
132 pci@8000 { 125 pci1: pci@8000 {
133 linux,phandle = <8000>;
134 interrupt-map-mask = <1f800 0 0 7>; 126 interrupt-map-mask = <1f800 0 0 7>;
135 interrupt-map = < 127 interrupt-map = <
136 128
137 /* IDSEL 0x10 */ 129 /* IDSEL 0x10 */
138 08000 0 0 1 40000 30 1 130 08000 0 0 1 &mpic 30 1
139 08000 0 0 2 40000 31 1 131 08000 0 0 2 &mpic 31 1
140 08000 0 0 3 40000 32 1 132 08000 0 0 3 &mpic 32 1
141 08000 0 0 4 40000 33 1 133 08000 0 0 4 &mpic 33 1
142 134
143 /* IDSEL 0x11 */ 135 /* IDSEL 0x11 */
144 08800 0 0 1 40000 30 1 136 08800 0 0 1 &mpic 30 1
145 08800 0 0 2 40000 31 1 137 08800 0 0 2 &mpic 31 1
146 08800 0 0 3 40000 32 1 138 08800 0 0 3 &mpic 32 1
147 08800 0 0 4 40000 33 1 139 08800 0 0 4 &mpic 33 1
148 140
149 /* IDSEL 0x12 (Slot 1) */ 141 /* IDSEL 0x12 (Slot 1) */
150 09000 0 0 1 40000 30 1 142 09000 0 0 1 &mpic 30 1
151 09000 0 0 2 40000 31 1 143 09000 0 0 2 &mpic 31 1
152 09000 0 0 3 40000 32 1 144 09000 0 0 3 &mpic 32 1
153 09000 0 0 4 40000 33 1 145 09000 0 0 4 &mpic 33 1
154 146
155 /* IDSEL 0x13 (Slot 2) */ 147 /* IDSEL 0x13 (Slot 2) */
156 09800 0 0 1 40000 31 1 148 09800 0 0 1 &mpic 31 1
157 09800 0 0 2 40000 32 1 149 09800 0 0 2 &mpic 32 1
158 09800 0 0 3 40000 33 1 150 09800 0 0 3 &mpic 33 1
159 09800 0 0 4 40000 30 1 151 09800 0 0 4 &mpic 30 1
160 152
161 /* IDSEL 0x14 (Slot 3) */ 153 /* IDSEL 0x14 (Slot 3) */
162 0a000 0 0 1 40000 32 1 154 0a000 0 0 1 &mpic 32 1
163 0a000 0 0 2 40000 33 1 155 0a000 0 0 2 &mpic 33 1
164 0a000 0 0 3 40000 30 1 156 0a000 0 0 3 &mpic 30 1
165 0a000 0 0 4 40000 31 1 157 0a000 0 0 4 &mpic 31 1
166 158
167 /* IDSEL 0x15 (Slot 4) */ 159 /* IDSEL 0x15 (Slot 4) */
168 0a800 0 0 1 40000 33 1 160 0a800 0 0 1 &mpic 33 1
169 0a800 0 0 2 40000 30 1 161 0a800 0 0 2 &mpic 30 1
170 0a800 0 0 3 40000 31 1 162 0a800 0 0 3 &mpic 31 1
171 0a800 0 0 4 40000 32 1 163 0a800 0 0 4 &mpic 32 1
172 164
173 /* Bus 1 (Tundra Bridge) */ 165 /* Bus 1 (Tundra Bridge) */
174 /* IDSEL 0x12 (ISA bridge) */ 166 /* IDSEL 0x12 (ISA bridge) */
175 19000 0 0 1 40000 30 1 167 19000 0 0 1 &mpic 30 1
176 19000 0 0 2 40000 31 1 168 19000 0 0 2 &mpic 31 1
177 19000 0 0 3 40000 32 1 169 19000 0 0 3 &mpic 32 1
178 19000 0 0 4 40000 33 1>; 170 19000 0 0 4 &mpic 33 1>;
179 interrupt-parent = <40000>; 171 interrupt-parent = <&mpic>;
180 interrupts = <08 2>; 172 interrupts = <08 2>;
181 bus-range = <0 0>; 173 bus-range = <0 0>;
182 ranges = <02000000 0 80000000 80000000 0 20000000 174 ranges = <02000000 0 80000000 80000000 0 20000000
@@ -200,21 +192,20 @@
200 compatible = "chrp,iic"; 192 compatible = "chrp,iic";
201 big-endian; 193 big-endian;
202 interrupts = <1>; 194 interrupts = <1>;
203 interrupt-parent = <8000>; 195 interrupt-parent = <&pci1>;
204 }; 196 };
205 }; 197 };
206 198
207 pci@9000 { 199 pci@9000 {
208 linux,phandle = <9000>;
209 interrupt-map-mask = <f800 0 0 7>; 200 interrupt-map-mask = <f800 0 0 7>;
210 interrupt-map = < 201 interrupt-map = <
211 202
212 /* IDSEL 0x15 */ 203 /* IDSEL 0x15 */
213 a800 0 0 1 40000 3b 1 204 a800 0 0 1 &mpic 3b 1
214 a800 0 0 2 40000 3b 1 205 a800 0 0 2 &mpic 3b 1
215 a800 0 0 3 40000 3b 1 206 a800 0 0 3 &mpic 3b 1
216 a800 0 0 4 40000 3b 1>; 207 a800 0 0 4 &mpic 3b 1>;
217 interrupt-parent = <40000>; 208 interrupt-parent = <&mpic>;
218 interrupts = <09 2>; 209 interrupts = <09 2>;
219 bus-range = <0 0>; 210 bus-range = <0 0>;
220 ranges = <02000000 0 a0000000 a0000000 0 20000000 211 ranges = <02000000 0 a0000000 a0000000 0 20000000
@@ -228,8 +219,7 @@
228 device_type = "pci"; 219 device_type = "pci";
229 }; 220 };
230 221
231 pic@40000 { 222 mpic: pic@40000 {
232 linux,phandle = <40000>;
233 clock-frequency = <0>; 223 clock-frequency = <0>;
234 interrupt-controller; 224 interrupt-controller;
235 #address-cells = <0>; 225 #address-cells = <0>;
diff --git a/arch/powerpc/boot/dts/mpc8560ads.dts b/arch/powerpc/boot/dts/mpc8560ads.dts
index 119bd5d3a834..10502638b0e9 100644
--- a/arch/powerpc/boot/dts/mpc8560ads.dts
+++ b/arch/powerpc/boot/dts/mpc8560ads.dts
@@ -12,16 +12,14 @@
12 12
13/ { 13/ {
14 model = "MPC8560ADS"; 14 model = "MPC8560ADS";
15 compatible = "MPC85xxADS"; 15 compatible = "MPC8560ADS", "MPC85xxADS";
16 #address-cells = <1>; 16 #address-cells = <1>;
17 #size-cells = <1>; 17 #size-cells = <1>;
18 linux,phandle = <100>;
19 18
20 cpus { 19 cpus {
21 #cpus = <1>; 20 #cpus = <1>;
22 #address-cells = <1>; 21 #address-cells = <1>;
23 #size-cells = <0>; 22 #size-cells = <0>;
24 linux,phandle = <200>;
25 23
26 PowerPC,8560@0 { 24 PowerPC,8560@0 {
27 device_type = "cpu"; 25 device_type = "cpu";
@@ -34,14 +32,11 @@
34 bus-frequency = <13ab6680>; 32 bus-frequency = <13ab6680>;
35 clock-frequency = <312c8040>; 33 clock-frequency = <312c8040>;
36 32-bit; 34 32-bit;
37 linux,phandle = <201>;
38 linux,boot-cpu;
39 }; 35 };
40 }; 36 };
41 37
42 memory { 38 memory {
43 device_type = "memory"; 39 device_type = "memory";
44 linux,phandle = <300>;
45 reg = <00000000 10000000>; 40 reg = <00000000 10000000>;
46 }; 41 };
47 42
@@ -58,33 +53,28 @@
58 device_type = "mdio"; 53 device_type = "mdio";
59 compatible = "gianfar"; 54 compatible = "gianfar";
60 reg = <24520 20>; 55 reg = <24520 20>;
61 linux,phandle = <24520>;
62 #address-cells = <1>; 56 #address-cells = <1>;
63 #size-cells = <0>; 57 #size-cells = <0>;
64 ethernet-phy@0 { 58 phy0: ethernet-phy@0 {
65 linux,phandle = <2452000>; 59 interrupt-parent = <&mpic>;
66 interrupt-parent = <40000>;
67 interrupts = <35 1>; 60 interrupts = <35 1>;
68 reg = <0>; 61 reg = <0>;
69 device_type = "ethernet-phy"; 62 device_type = "ethernet-phy";
70 }; 63 };
71 ethernet-phy@1 { 64 phy1: ethernet-phy@1 {
72 linux,phandle = <2452001>; 65 interrupt-parent = <&mpic>;
73 interrupt-parent = <40000>;
74 interrupts = <35 1>; 66 interrupts = <35 1>;
75 reg = <1>; 67 reg = <1>;
76 device_type = "ethernet-phy"; 68 device_type = "ethernet-phy";
77 }; 69 };
78 ethernet-phy@2 { 70 phy2: ethernet-phy@2 {
79 linux,phandle = <2452002>; 71 interrupt-parent = <&mpic>;
80 interrupt-parent = <40000>;
81 interrupts = <37 1>; 72 interrupts = <37 1>;
82 reg = <2>; 73 reg = <2>;
83 device_type = "ethernet-phy"; 74 device_type = "ethernet-phy";
84 }; 75 };
85 ethernet-phy@3 { 76 phy3: ethernet-phy@3 {
86 linux,phandle = <2452003>; 77 interrupt-parent = <&mpic>;
87 interrupt-parent = <40000>;
88 interrupts = <37 1>; 78 interrupts = <37 1>;
89 reg = <3>; 79 reg = <3>;
90 device_type = "ethernet-phy"; 80 device_type = "ethernet-phy";
@@ -98,8 +88,8 @@
98 reg = <24000 1000>; 88 reg = <24000 1000>;
99 address = [ 00 00 0C 00 00 FD ]; 89 address = [ 00 00 0C 00 00 FD ];
100 interrupts = <d 2 e 2 12 2>; 90 interrupts = <d 2 e 2 12 2>;
101 interrupt-parent = <40000>; 91 interrupt-parent = <&mpic>;
102 phy-handle = <2452000>; 92 phy-handle = <&phy0>;
103 }; 93 };
104 94
105 ethernet@25000 { 95 ethernet@25000 {
@@ -111,12 +101,11 @@
111 reg = <25000 1000>; 101 reg = <25000 1000>;
112 address = [ 00 00 0C 00 01 FD ]; 102 address = [ 00 00 0C 00 01 FD ];
113 interrupts = <13 2 14 2 18 2>; 103 interrupts = <13 2 14 2 18 2>;
114 interrupt-parent = <40000>; 104 interrupt-parent = <&mpic>;
115 phy-handle = <2452001>; 105 phy-handle = <&phy1>;
116 }; 106 };
117 107
118 pci@8000 { 108 pci@8000 {
119 linux,phandle = <8000>;
120 #interrupt-cells = <1>; 109 #interrupt-cells = <1>;
121 #size-cells = <2>; 110 #size-cells = <2>;
122 #address-cells = <3>; 111 #address-cells = <3>;
@@ -128,96 +117,94 @@
128 interrupt-map = < 117 interrupt-map = <
129 118
130 /* IDSEL 0x2 */ 119 /* IDSEL 0x2 */
131 1000 0 0 1 40000 31 1 120 1000 0 0 1 &mpic 31 1
132 1000 0 0 2 40000 32 1 121 1000 0 0 2 &mpic 32 1
133 1000 0 0 3 40000 33 1 122 1000 0 0 3 &mpic 33 1
134 1000 0 0 4 40000 34 1 123 1000 0 0 4 &mpic 34 1
135 124
136 /* IDSEL 0x3 */ 125 /* IDSEL 0x3 */
137 1800 0 0 1 40000 34 1 126 1800 0 0 1 &mpic 34 1
138 1800 0 0 2 40000 31 1 127 1800 0 0 2 &mpic 31 1
139 1800 0 0 3 40000 32 1 128 1800 0 0 3 &mpic 32 1
140 1800 0 0 4 40000 33 1 129 1800 0 0 4 &mpic 33 1
141 130
142 /* IDSEL 0x4 */ 131 /* IDSEL 0x4 */
143 2000 0 0 1 40000 33 1 132 2000 0 0 1 &mpic 33 1
144 2000 0 0 2 40000 34 1 133 2000 0 0 2 &mpic 34 1
145 2000 0 0 3 40000 31 1 134 2000 0 0 3 &mpic 31 1
146 2000 0 0 4 40000 32 1 135 2000 0 0 4 &mpic 32 1
147 136
148 /* IDSEL 0x5 */ 137 /* IDSEL 0x5 */
149 2800 0 0 1 40000 32 1 138 2800 0 0 1 &mpic 32 1
150 2800 0 0 2 40000 33 1 139 2800 0 0 2 &mpic 33 1
151 2800 0 0 3 40000 34 1 140 2800 0 0 3 &mpic 34 1
152 2800 0 0 4 40000 31 1 141 2800 0 0 4 &mpic 31 1
153 142
154 /* IDSEL 12 */ 143 /* IDSEL 12 */
155 6000 0 0 1 40000 31 1 144 6000 0 0 1 &mpic 31 1
156 6000 0 0 2 40000 32 1 145 6000 0 0 2 &mpic 32 1
157 6000 0 0 3 40000 33 1 146 6000 0 0 3 &mpic 33 1
158 6000 0 0 4 40000 34 1 147 6000 0 0 4 &mpic 34 1
159 148
160 /* IDSEL 13 */ 149 /* IDSEL 13 */
161 6800 0 0 1 40000 34 1 150 6800 0 0 1 &mpic 34 1
162 6800 0 0 2 40000 31 1 151 6800 0 0 2 &mpic 31 1
163 6800 0 0 3 40000 32 1 152 6800 0 0 3 &mpic 32 1
164 6800 0 0 4 40000 33 1 153 6800 0 0 4 &mpic 33 1
165 154
166 /* IDSEL 14*/ 155 /* IDSEL 14*/
167 7000 0 0 1 40000 33 1 156 7000 0 0 1 &mpic 33 1
168 7000 0 0 2 40000 34 1 157 7000 0 0 2 &mpic 34 1
169 7000 0 0 3 40000 31 1 158 7000 0 0 3 &mpic 31 1
170 7000 0 0 4 40000 32 1 159 7000 0 0 4 &mpic 32 1
171 160
172 /* IDSEL 15 */ 161 /* IDSEL 15 */
173 7800 0 0 1 40000 32 1 162 7800 0 0 1 &mpic 32 1
174 7800 0 0 2 40000 33 1 163 7800 0 0 2 &mpic 33 1
175 7800 0 0 3 40000 34 1 164 7800 0 0 3 &mpic 34 1
176 7800 0 0 4 40000 31 1 165 7800 0 0 4 &mpic 31 1
177 166
178 /* IDSEL 18 */ 167 /* IDSEL 18 */
179 9000 0 0 1 40000 31 1 168 9000 0 0 1 &mpic 31 1
180 9000 0 0 2 40000 32 1 169 9000 0 0 2 &mpic 32 1
181 9000 0 0 3 40000 33 1 170 9000 0 0 3 &mpic 33 1
182 9000 0 0 4 40000 34 1 171 9000 0 0 4 &mpic 34 1
183 172
184 /* IDSEL 19 */ 173 /* IDSEL 19 */
185 9800 0 0 1 40000 34 1 174 9800 0 0 1 &mpic 34 1
186 9800 0 0 2 40000 31 1 175 9800 0 0 2 &mpic 31 1
187 9800 0 0 3 40000 32 1 176 9800 0 0 3 &mpic 32 1
188 9800 0 0 4 40000 33 1 177 9800 0 0 4 &mpic 33 1
189 178
190 /* IDSEL 20 */ 179 /* IDSEL 20 */
191 a000 0 0 1 40000 33 1 180 a000 0 0 1 &mpic 33 1
192 a000 0 0 2 40000 34 1 181 a000 0 0 2 &mpic 34 1
193 a000 0 0 3 40000 31 1 182 a000 0 0 3 &mpic 31 1
194 a000 0 0 4 40000 32 1 183 a000 0 0 4 &mpic 32 1
195 184
196 /* IDSEL 21 */ 185 /* IDSEL 21 */
197 a800 0 0 1 40000 32 1 186 a800 0 0 1 &mpic 32 1
198 a800 0 0 2 40000 33 1 187 a800 0 0 2 &mpic 33 1
199 a800 0 0 3 40000 34 1 188 a800 0 0 3 &mpic 34 1
200 a800 0 0 4 40000 31 1>; 189 a800 0 0 4 &mpic 31 1>;
201 190
202 interrupt-parent = <40000>; 191 interrupt-parent = <&mpic>;
203 interrupts = <8 0>; 192 interrupts = <8 0>;
204 bus-range = <0 0>; 193 bus-range = <0 0>;
205 ranges = <02000000 0 80000000 80000000 0 20000000 194 ranges = <02000000 0 80000000 80000000 0 20000000
206 01000000 0 00000000 e2000000 0 01000000>; 195 01000000 0 00000000 e2000000 0 01000000>;
207 }; 196 };
208 197
209 pic@40000 { 198 mpic: pic@40000 {
210 linux,phandle = <40000>;
211 interrupt-controller; 199 interrupt-controller;
212 #address-cells = <0>; 200 #address-cells = <0>;
213 #interrupt-cells = <2>; 201 #interrupt-cells = <2>;
214 reg = <40000 20100>; 202 reg = <40000 40000>;
215 built-in; 203 built-in;
216 device_type = "open-pic"; 204 device_type = "open-pic";
217 }; 205 };
218 206
219 cpm@e0000000 { 207 cpm@e0000000 {
220 linux,phandle = <e0000000>;
221 #address-cells = <1>; 208 #address-cells = <1>;
222 #size-cells = <1>; 209 #size-cells = <1>;
223 #interrupt-cells = <2>; 210 #interrupt-cells = <2>;
@@ -228,13 +215,12 @@
228 command-proc = <919c0>; 215 command-proc = <919c0>;
229 brg-frequency = <9d5b340>; 216 brg-frequency = <9d5b340>;
230 217
231 pic@90c00 { 218 cpmpic: pic@90c00 {
232 linux,phandle = <90c00>;
233 interrupt-controller; 219 interrupt-controller;
234 #address-cells = <0>; 220 #address-cells = <0>;
235 #interrupt-cells = <2>; 221 #interrupt-cells = <2>;
236 interrupts = <1e 0>; 222 interrupts = <1e 0>;
237 interrupt-parent = <40000>; 223 interrupt-parent = <&mpic>;
238 reg = <90c00 80>; 224 reg = <90c00 80>;
239 built-in; 225 built-in;
240 device_type = "cpm-pic"; 226 device_type = "cpm-pic";
@@ -251,7 +237,7 @@
251 tx-clock = <1>; 237 tx-clock = <1>;
252 current-speed = <1c200>; 238 current-speed = <1c200>;
253 interrupts = <28 8>; 239 interrupts = <28 8>;
254 interrupt-parent = <90c00>; 240 interrupt-parent = <&cpmpic>;
255 }; 241 };
256 242
257 scc@91a20 { 243 scc@91a20 {
@@ -265,7 +251,7 @@
265 tx-clock = <2>; 251 tx-clock = <2>;
266 current-speed = <1c200>; 252 current-speed = <1c200>;
267 interrupts = <29 8>; 253 interrupts = <29 8>;
268 interrupt-parent = <90c00>; 254 interrupt-parent = <&cpmpic>;
269 }; 255 };
270 256
271 fcc@91320 { 257 fcc@91320 {
@@ -279,8 +265,8 @@
279 rx-clock = <15>; 265 rx-clock = <15>;
280 tx-clock = <16>; 266 tx-clock = <16>;
281 interrupts = <21 8>; 267 interrupts = <21 8>;
282 interrupt-parent = <90c00>; 268 interrupt-parent = <&cpmpic>;
283 phy-handle = <2452002>; 269 phy-handle = <&phy2>;
284 }; 270 };
285 271
286 fcc@91340 { 272 fcc@91340 {
@@ -294,8 +280,8 @@
294 rx-clock = <17>; 280 rx-clock = <17>;
295 tx-clock = <18>; 281 tx-clock = <18>;
296 interrupts = <22 8>; 282 interrupts = <22 8>;
297 interrupt-parent = <90c00>; 283 interrupt-parent = <&cpmpic>;
298 phy-handle = <2452003>; 284 phy-handle = <&phy3>;
299 }; 285 };
300 }; 286 };
301 }; 287 };
diff --git a/arch/powerpc/boot/dts/mpc8568mds.dts b/arch/powerpc/boot/dts/mpc8568mds.dts
index 06d24653e422..bf49d8c997b9 100644
--- a/arch/powerpc/boot/dts/mpc8568mds.dts
+++ b/arch/powerpc/boot/dts/mpc8568mds.dts
@@ -16,16 +16,14 @@
16 16
17/ { 17/ {
18 model = "MPC8568EMDS"; 18 model = "MPC8568EMDS";
19 compatible = "MPC85xxMDS"; 19 compatible = "MPC8568EMDS", "MPC85xxMDS";
20 #address-cells = <1>; 20 #address-cells = <1>;
21 #size-cells = <1>; 21 #size-cells = <1>;
22 linux,phandle = <100>;
23 22
24 cpus { 23 cpus {
25 #cpus = <1>; 24 #cpus = <1>;
26 #address-cells = <1>; 25 #address-cells = <1>;
27 #size-cells = <0>; 26 #size-cells = <0>;
28 linux,phandle = <200>;
29 27
30 PowerPC,8568@0 { 28 PowerPC,8568@0 {
31 device_type = "cpu"; 29 device_type = "cpu";
@@ -38,13 +36,11 @@
38 bus-frequency = <0>; 36 bus-frequency = <0>;
39 clock-frequency = <0>; 37 clock-frequency = <0>;
40 32-bit; 38 32-bit;
41 linux,phandle = <201>;
42 }; 39 };
43 }; 40 };
44 41
45 memory { 42 memory {
46 device_type = "memory"; 43 device_type = "memory";
47 linux,phandle = <300>;
48 reg = <00000000 10000000>; 44 reg = <00000000 10000000>;
49 }; 45 };
50 46
@@ -67,7 +63,7 @@
67 compatible = "fsl-i2c"; 63 compatible = "fsl-i2c";
68 reg = <3000 100>; 64 reg = <3000 100>;
69 interrupts = <1b 2>; 65 interrupts = <1b 2>;
70 interrupt-parent = <40000>; 66 interrupt-parent = <&mpic>;
71 dfsrr; 67 dfsrr;
72 }; 68 };
73 69
@@ -76,7 +72,7 @@
76 compatible = "fsl-i2c"; 72 compatible = "fsl-i2c";
77 reg = <3100 100>; 73 reg = <3100 100>;
78 interrupts = <1b 2>; 74 interrupts = <1b 2>;
79 interrupt-parent = <40000>; 75 interrupt-parent = <&mpic>;
80 dfsrr; 76 dfsrr;
81 }; 77 };
82 78
@@ -86,32 +82,26 @@
86 device_type = "mdio"; 82 device_type = "mdio";
87 compatible = "gianfar"; 83 compatible = "gianfar";
88 reg = <24520 20>; 84 reg = <24520 20>;
89 linux,phandle = <24520>; 85 phy0: ethernet-phy@0 {
90 ethernet-phy@0 { 86 interrupt-parent = <&mpic>;
91 linux,phandle = <2452000>;
92 interrupt-parent = <40000>;
93 interrupts = <31 1>; 87 interrupts = <31 1>;
94 reg = <0>; 88 reg = <0>;
95 device_type = "ethernet-phy"; 89 device_type = "ethernet-phy";
96 }; 90 };
97 ethernet-phy@1 { 91 phy1: ethernet-phy@1 {
98 linux,phandle = <2452001>; 92 interrupt-parent = <&mpic>;
99 interrupt-parent = <40000>;
100 interrupts = <32 1>; 93 interrupts = <32 1>;
101 reg = <1>; 94 reg = <1>;
102 device_type = "ethernet-phy"; 95 device_type = "ethernet-phy";
103 }; 96 };
104 97 phy2: ethernet-phy@2 {
105 ethernet-phy@2 { 98 interrupt-parent = <&mpic>;
106 linux,phandle = <2452002>;
107 interrupt-parent = <40000>;
108 interrupts = <31 1>; 99 interrupts = <31 1>;
109 reg = <2>; 100 reg = <2>;
110 device_type = "ethernet-phy"; 101 device_type = "ethernet-phy";
111 }; 102 };
112 ethernet-phy@3 { 103 phy3: ethernet-phy@3 {
113 linux,phandle = <2452003>; 104 interrupt-parent = <&mpic>;
114 interrupt-parent = <40000>;
115 interrupts = <32 1>; 105 interrupts = <32 1>;
116 reg = <3>; 106 reg = <3>;
117 device_type = "ethernet-phy"; 107 device_type = "ethernet-phy";
@@ -127,8 +117,8 @@
127 reg = <24000 1000>; 117 reg = <24000 1000>;
128 mac-address = [ 00 00 00 00 00 00 ]; 118 mac-address = [ 00 00 00 00 00 00 ];
129 interrupts = <d 2 e 2 12 2>; 119 interrupts = <d 2 e 2 12 2>;
130 interrupt-parent = <40000>; 120 interrupt-parent = <&mpic>;
131 phy-handle = <2452002>; 121 phy-handle = <&phy2>;
132 }; 122 };
133 123
134 ethernet@25000 { 124 ethernet@25000 {
@@ -140,8 +130,8 @@
140 reg = <25000 1000>; 130 reg = <25000 1000>;
141 mac-address = [ 00 00 00 00 00 00]; 131 mac-address = [ 00 00 00 00 00 00];
142 interrupts = <13 2 14 2 18 2>; 132 interrupts = <13 2 14 2 18 2>;
143 interrupt-parent = <40000>; 133 interrupt-parent = <&mpic>;
144 phy-handle = <2452003>; 134 phy-handle = <&phy3>;
145 }; 135 };
146 136
147 serial@4500 { 137 serial@4500 {
@@ -150,7 +140,7 @@
150 reg = <4500 100>; 140 reg = <4500 100>;
151 clock-frequency = <0>; 141 clock-frequency = <0>;
152 interrupts = <1a 2>; 142 interrupts = <1a 2>;
153 interrupt-parent = <40000>; 143 interrupt-parent = <&mpic>;
154 }; 144 };
155 145
156 serial@4600 { 146 serial@4600 {
@@ -159,7 +149,7 @@
159 reg = <4600 100>; 149 reg = <4600 100>;
160 clock-frequency = <0>; 150 clock-frequency = <0>;
161 interrupts = <1a 2>; 151 interrupts = <1a 2>;
162 interrupt-parent = <40000>; 152 interrupt-parent = <&mpic>;
163 }; 153 };
164 154
165 crypto@30000 { 155 crypto@30000 {
@@ -168,15 +158,14 @@
168 compatible = "talitos"; 158 compatible = "talitos";
169 reg = <30000 f000>; 159 reg = <30000 f000>;
170 interrupts = <1d 2>; 160 interrupts = <1d 2>;
171 interrupt-parent = <40000>; 161 interrupt-parent = <&mpic>;
172 num-channels = <4>; 162 num-channels = <4>;
173 channel-fifo-len = <18>; 163 channel-fifo-len = <18>;
174 exec-units-mask = <000000fe>; 164 exec-units-mask = <000000fe>;
175 descriptor-types-mask = <012b0ebf>; 165 descriptor-types-mask = <012b0ebf>;
176 }; 166 };
177 167
178 pic@40000 { 168 mpic: pic@40000 {
179 linux,phandle = <40000>;
180 clock-frequency = <0>; 169 clock-frequency = <0>;
181 interrupt-controller; 170 interrupt-controller;
182 #address-cells = <0>; 171 #address-cells = <0>;
@@ -192,8 +181,7 @@
192 device_type = "par_io"; 181 device_type = "par_io";
193 num-ports = <7>; 182 num-ports = <7>;
194 183
195 ucc_pin@01 { 184 pio1: ucc_pin@01 {
196 linux,phandle = <e010001>;
197 pio-map = < 185 pio-map = <
198 /* port pin dir open_drain assignment has_irq */ 186 /* port pin dir open_drain assignment has_irq */
199 4 0a 1 0 2 0 /* TxD0 */ 187 4 0a 1 0 2 0 /* TxD0 */
@@ -220,8 +208,7 @@
220 4 13 1 0 2 0 /* GTX_CLK */ 208 4 13 1 0 2 0 /* GTX_CLK */
221 1 1f 2 0 3 0>; /* GTX125 */ 209 1 1f 2 0 3 0>; /* GTX125 */
222 }; 210 };
223 ucc_pin@02 { 211 pio2: ucc_pin@02 {
224 linux,phandle = <e010002>;
225 pio-map = < 212 pio-map = <
226 /* port pin dir open_drain assignment has_irq */ 213 /* port pin dir open_drain assignment has_irq */
227 5 0a 1 0 2 0 /* TxD0 */ 214 5 0a 1 0 2 0 /* TxD0 */
@@ -277,7 +264,7 @@
277 compatible = "fsl_spi"; 264 compatible = "fsl_spi";
278 reg = <4c0 40>; 265 reg = <4c0 40>;
279 interrupts = <2>; 266 interrupts = <2>;
280 interrupt-parent = <80>; 267 interrupt-parent = <&qeic>;
281 mode = "cpu"; 268 mode = "cpu";
282 }; 269 };
283 270
@@ -286,7 +273,7 @@
286 compatible = "fsl_spi"; 273 compatible = "fsl_spi";
287 reg = <500 40>; 274 reg = <500 40>;
288 interrupts = <1>; 275 interrupts = <1>;
289 interrupt-parent = <80>; 276 interrupt-parent = <&qeic>;
290 mode = "cpu"; 277 mode = "cpu";
291 }; 278 };
292 279
@@ -297,12 +284,12 @@
297 device-id = <1>; 284 device-id = <1>;
298 reg = <2000 200>; 285 reg = <2000 200>;
299 interrupts = <20>; 286 interrupts = <20>;
300 interrupt-parent = <80>; 287 interrupt-parent = <&qeic>;
301 mac-address = [ 00 04 9f 00 23 23 ]; 288 mac-address = [ 00 04 9f 00 23 23 ];
302 rx-clock = <0>; 289 rx-clock = <0>;
303 tx-clock = <19>; 290 tx-clock = <19>;
304 phy-handle = <212000>; 291 phy-handle = <&qe_phy0>;
305 pio-handle = <e010001>; 292 pio-handle = <&pio1>;
306 }; 293 };
307 294
308 ucc@3000 { 295 ucc@3000 {
@@ -312,12 +299,12 @@
312 device-id = <2>; 299 device-id = <2>;
313 reg = <3000 200>; 300 reg = <3000 200>;
314 interrupts = <21>; 301 interrupts = <21>;
315 interrupt-parent = <80>; 302 interrupt-parent = <&qeic>;
316 mac-address = [ 00 11 22 33 44 55 ]; 303 mac-address = [ 00 11 22 33 44 55 ];
317 rx-clock = <0>; 304 rx-clock = <0>;
318 tx-clock = <14>; 305 tx-clock = <14>;
319 phy-handle = <212001>; 306 phy-handle = <&qe_phy1>;
320 pio-handle = <e010002>; 307 pio-handle = <&pio2>;
321 }; 308 };
322 309
323 mdio@2120 { 310 mdio@2120 {
@@ -329,33 +316,29 @@
329 316
330 /* These are the same PHYs as on 317 /* These are the same PHYs as on
331 * gianfar's MDIO bus */ 318 * gianfar's MDIO bus */
332 ethernet-phy@00 { 319 qe_phy0: ethernet-phy@00 {
333 linux,phandle = <212000>; 320 interrupt-parent = <&mpic>;
334 interrupt-parent = <40000>;
335 interrupts = <31 1>; 321 interrupts = <31 1>;
336 reg = <0>; 322 reg = <0>;
337 device_type = "ethernet-phy"; 323 device_type = "ethernet-phy";
338 interface = <6>; //ENET_1000_GMII 324 interface = <6>; //ENET_1000_GMII
339 }; 325 };
340 ethernet-phy@01 { 326 qe_phy1: ethernet-phy@01 {
341 linux,phandle = <212001>; 327 interrupt-parent = <&mpic>;
342 interrupt-parent = <40000>;
343 interrupts = <32 1>; 328 interrupts = <32 1>;
344 reg = <1>; 329 reg = <1>;
345 device_type = "ethernet-phy"; 330 device_type = "ethernet-phy";
346 interface = <6>; 331 interface = <6>;
347 }; 332 };
348 ethernet-phy@02 { 333 qe_phy2: ethernet-phy@02 {
349 linux,phandle = <212002>; 334 interrupt-parent = <&mpic>;
350 interrupt-parent = <40000>;
351 interrupts = <31 1>; 335 interrupts = <31 1>;
352 reg = <2>; 336 reg = <2>;
353 device_type = "ethernet-phy"; 337 device_type = "ethernet-phy";
354 interface = <6>; //ENET_1000_GMII 338 interface = <6>; //ENET_1000_GMII
355 }; 339 };
356 ethernet-phy@03 { 340 qe_phy3: ethernet-phy@03 {
357 linux,phandle = <212003>; 341 interrupt-parent = <&mpic>;
358 interrupt-parent = <40000>;
359 interrupts = <32 1>; 342 interrupts = <32 1>;
360 reg = <3>; 343 reg = <3>;
361 device_type = "ethernet-phy"; 344 device_type = "ethernet-phy";
@@ -363,8 +346,7 @@
363 }; 346 };
364 }; 347 };
365 348
366 qeic@80 { 349 qeic: qeic@80 {
367 linux,phandle = <80>;
368 interrupt-controller; 350 interrupt-controller;
369 device_type = "qeic"; 351 device_type = "qeic";
370 #address-cells = <0>; 352 #address-cells = <0>;
@@ -373,7 +355,7 @@
373 built-in; 355 built-in;
374 big-endian; 356 big-endian;
375 interrupts = <1e 2 1e 2>; //high:30 low:30 357 interrupts = <1e 2 1e 2>; //high:30 low:30
376 interrupt-parent = <40000>; 358 interrupt-parent = <&mpic>;
377 }; 359 };
378 360
379 }; 361 };
diff --git a/arch/powerpc/boot/dts/mpc8641_hpcn.dts b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
index f0c7731743ea..8a4995a85ba0 100644
--- a/arch/powerpc/boot/dts/mpc8641_hpcn.dts
+++ b/arch/powerpc/boot/dts/mpc8641_hpcn.dts
@@ -32,7 +32,6 @@
32 bus-frequency = <0>; // From uboot 32 bus-frequency = <0>; // From uboot
33 clock-frequency = <0>; // From uboot 33 clock-frequency = <0>; // From uboot
34 32-bit; 34 32-bit;
35 linux,boot-cpu;
36 }; 35 };
37 PowerPC,8641@1 { 36 PowerPC,8641@1 {
38 device_type = "cpu"; 37 device_type = "cpu";
@@ -67,7 +66,7 @@
67 compatible = "fsl-i2c"; 66 compatible = "fsl-i2c";
68 reg = <3000 100>; 67 reg = <3000 100>;
69 interrupts = <2b 2>; 68 interrupts = <2b 2>;
70 interrupt-parent = <40000>; 69 interrupt-parent = <&mpic>;
71 dfsrr; 70 dfsrr;
72 }; 71 };
73 72
@@ -76,7 +75,7 @@
76 compatible = "fsl-i2c"; 75 compatible = "fsl-i2c";
77 reg = <3100 100>; 76 reg = <3100 100>;
78 interrupts = <2b 2>; 77 interrupts = <2b 2>;
79 interrupt-parent = <40000>; 78 interrupt-parent = <&mpic>;
80 dfsrr; 79 dfsrr;
81 }; 80 };
82 81
@@ -86,31 +85,26 @@
86 device_type = "mdio"; 85 device_type = "mdio";
87 compatible = "gianfar"; 86 compatible = "gianfar";
88 reg = <24520 20>; 87 reg = <24520 20>;
89 linux,phandle = <24520>; 88 phy0: ethernet-phy@0 {
90 ethernet-phy@0 { 89 interrupt-parent = <&mpic>;
91 linux,phandle = <2452000>;
92 interrupt-parent = <40000>;
93 interrupts = <4a 1>; 90 interrupts = <4a 1>;
94 reg = <0>; 91 reg = <0>;
95 device_type = "ethernet-phy"; 92 device_type = "ethernet-phy";
96 }; 93 };
97 ethernet-phy@1 { 94 phy1: ethernet-phy@1 {
98 linux,phandle = <2452001>; 95 interrupt-parent = <&mpic>;
99 interrupt-parent = <40000>;
100 interrupts = <4a 1>; 96 interrupts = <4a 1>;
101 reg = <1>; 97 reg = <1>;
102 device_type = "ethernet-phy"; 98 device_type = "ethernet-phy";
103 }; 99 };
104 ethernet-phy@2 { 100 phy2: ethernet-phy@2 {
105 linux,phandle = <2452002>; 101 interrupt-parent = <&mpic>;
106 interrupt-parent = <40000>;
107 interrupts = <4a 1>; 102 interrupts = <4a 1>;
108 reg = <2>; 103 reg = <2>;
109 device_type = "ethernet-phy"; 104 device_type = "ethernet-phy";
110 }; 105 };
111 ethernet-phy@3 { 106 phy3: ethernet-phy@3 {
112 linux,phandle = <2452003>; 107 interrupt-parent = <&mpic>;
113 interrupt-parent = <40000>;
114 interrupts = <4a 1>; 108 interrupts = <4a 1>;
115 reg = <3>; 109 reg = <3>;
116 device_type = "ethernet-phy"; 110 device_type = "ethernet-phy";
@@ -126,8 +120,8 @@
126 reg = <24000 1000>; 120 reg = <24000 1000>;
127 mac-address = [ 00 E0 0C 00 73 00 ]; 121 mac-address = [ 00 E0 0C 00 73 00 ];
128 interrupts = <1d 2 1e 2 22 2>; 122 interrupts = <1d 2 1e 2 22 2>;
129 interrupt-parent = <40000>; 123 interrupt-parent = <&mpic>;
130 phy-handle = <2452000>; 124 phy-handle = <&phy0>;
131 }; 125 };
132 126
133 ethernet@25000 { 127 ethernet@25000 {
@@ -139,8 +133,8 @@
139 reg = <25000 1000>; 133 reg = <25000 1000>;
140 mac-address = [ 00 E0 0C 00 73 01 ]; 134 mac-address = [ 00 E0 0C 00 73 01 ];
141 interrupts = <23 2 24 2 28 2>; 135 interrupts = <23 2 24 2 28 2>;
142 interrupt-parent = <40000>; 136 interrupt-parent = <&mpic>;
143 phy-handle = <2452001>; 137 phy-handle = <&phy1>;
144 }; 138 };
145 139
146 ethernet@26000 { 140 ethernet@26000 {
@@ -152,8 +146,8 @@
152 reg = <26000 1000>; 146 reg = <26000 1000>;
153 mac-address = [ 00 E0 0C 00 02 FD ]; 147 mac-address = [ 00 E0 0C 00 02 FD ];
154 interrupts = <1F 2 20 2 21 2>; 148 interrupts = <1F 2 20 2 21 2>;
155 interrupt-parent = <40000>; 149 interrupt-parent = <&mpic>;
156 phy-handle = <2452002>; 150 phy-handle = <&phy2>;
157 }; 151 };
158 152
159 ethernet@27000 { 153 ethernet@27000 {
@@ -165,8 +159,8 @@
165 reg = <27000 1000>; 159 reg = <27000 1000>;
166 mac-address = [ 00 E0 0C 00 03 FD ]; 160 mac-address = [ 00 E0 0C 00 03 FD ];
167 interrupts = <25 2 26 2 27 2>; 161 interrupts = <25 2 26 2 27 2>;
168 interrupt-parent = <40000>; 162 interrupt-parent = <&mpic>;
169 phy-handle = <2452003>; 163 phy-handle = <&phy3>;
170 }; 164 };
171 serial@4500 { 165 serial@4500 {
172 device_type = "serial"; 166 device_type = "serial";
@@ -174,7 +168,7 @@
174 reg = <4500 100>; 168 reg = <4500 100>;
175 clock-frequency = <0>; 169 clock-frequency = <0>;
176 interrupts = <2a 2>; 170 interrupts = <2a 2>;
177 interrupt-parent = <40000>; 171 interrupt-parent = <&mpic>;
178 }; 172 };
179 173
180 serial@4600 { 174 serial@4600 {
@@ -183,7 +177,7 @@
183 reg = <4600 100>; 177 reg = <4600 100>;
184 clock-frequency = <0>; 178 clock-frequency = <0>;
185 interrupts = <1c 2>; 179 interrupts = <1c 2>;
186 interrupt-parent = <40000>; 180 interrupt-parent = <&mpic>;
187 }; 181 };
188 182
189 pci@8000 { 183 pci@8000 {
@@ -197,103 +191,102 @@
197 ranges = <02000000 0 80000000 80000000 0 20000000 191 ranges = <02000000 0 80000000 80000000 0 20000000
198 01000000 0 00000000 e2000000 0 00100000>; 192 01000000 0 00000000 e2000000 0 00100000>;
199 clock-frequency = <1fca055>; 193 clock-frequency = <1fca055>;
200 interrupt-parent = <40000>; 194 interrupt-parent = <&mpic>;
201 interrupts = <18 2>; 195 interrupts = <18 2>;
202 interrupt-map-mask = <f800 0 0 7>; 196 interrupt-map-mask = <f800 0 0 7>;
203 interrupt-map = < 197 interrupt-map = <
204 /* IDSEL 0x11 */ 198 /* IDSEL 0x11 */
205 8800 0 0 1 4d0 3 2 199 8800 0 0 1 &i8259 3 2
206 8800 0 0 2 4d0 4 2 200 8800 0 0 2 &i8259 4 2
207 8800 0 0 3 4d0 5 2 201 8800 0 0 3 &i8259 5 2
208 8800 0 0 4 4d0 6 2 202 8800 0 0 4 &i8259 6 2
209 203
210 /* IDSEL 0x12 */ 204 /* IDSEL 0x12 */
211 9000 0 0 1 4d0 4 2 205 9000 0 0 1 &i8259 4 2
212 9000 0 0 2 4d0 5 2 206 9000 0 0 2 &i8259 5 2
213 9000 0 0 3 4d0 6 2 207 9000 0 0 3 &i8259 6 2
214 9000 0 0 4 4d0 3 2 208 9000 0 0 4 &i8259 3 2
215 209
216 /* IDSEL 0x13 */ 210 /* IDSEL 0x13 */
217 9800 0 0 1 4d0 0 0 211 9800 0 0 1 &i8259 0 0
218 9800 0 0 2 4d0 0 0 212 9800 0 0 2 &i8259 0 0
219 9800 0 0 3 4d0 0 0 213 9800 0 0 3 &i8259 0 0
220 9800 0 0 4 4d0 0 0 214 9800 0 0 4 &i8259 0 0
221 215
222 /* IDSEL 0x14 */ 216 /* IDSEL 0x14 */
223 a000 0 0 1 4d0 0 0 217 a000 0 0 1 &i8259 0 0
224 a000 0 0 2 4d0 0 0 218 a000 0 0 2 &i8259 0 0
225 a000 0 0 3 4d0 0 0 219 a000 0 0 3 &i8259 0 0
226 a000 0 0 4 4d0 0 0 220 a000 0 0 4 &i8259 0 0
227 221
228 /* IDSEL 0x15 */ 222 /* IDSEL 0x15 */
229 a800 0 0 1 4d0 0 0 223 a800 0 0 1 &i8259 0 0
230 a800 0 0 2 4d0 0 0 224 a800 0 0 2 &i8259 0 0
231 a800 0 0 3 4d0 0 0 225 a800 0 0 3 &i8259 0 0
232 a800 0 0 4 4d0 0 0 226 a800 0 0 4 &i8259 0 0
233 227
234 /* IDSEL 0x16 */ 228 /* IDSEL 0x16 */
235 b000 0 0 1 4d0 0 0 229 b000 0 0 1 &i8259 0 0
236 b000 0 0 2 4d0 0 0 230 b000 0 0 2 &i8259 0 0
237 b000 0 0 3 4d0 0 0 231 b000 0 0 3 &i8259 0 0
238 b000 0 0 4 4d0 0 0 232 b000 0 0 4 &i8259 0 0
239 233
240 /* IDSEL 0x17 */ 234 /* IDSEL 0x17 */
241 b800 0 0 1 4d0 0 0 235 b800 0 0 1 &i8259 0 0
242 b800 0 0 2 4d0 0 0 236 b800 0 0 2 &i8259 0 0
243 b800 0 0 3 4d0 0 0 237 b800 0 0 3 &i8259 0 0
244 b800 0 0 4 4d0 0 0 238 b800 0 0 4 &i8259 0 0
245 239
246 /* IDSEL 0x18 */ 240 /* IDSEL 0x18 */
247 c000 0 0 1 4d0 0 0 241 c000 0 0 1 &i8259 0 0
248 c000 0 0 2 4d0 0 0 242 c000 0 0 2 &i8259 0 0
249 c000 0 0 3 4d0 0 0 243 c000 0 0 3 &i8259 0 0
250 c000 0 0 4 4d0 0 0 244 c000 0 0 4 &i8259 0 0
251 245
252 /* IDSEL 0x19 */ 246 /* IDSEL 0x19 */
253 c800 0 0 1 4d0 0 0 247 c800 0 0 1 &i8259 0 0
254 c800 0 0 2 4d0 0 0 248 c800 0 0 2 &i8259 0 0
255 c800 0 0 3 4d0 0 0 249 c800 0 0 3 &i8259 0 0
256 c800 0 0 4 4d0 0 0 250 c800 0 0 4 &i8259 0 0
257 251
258 /* IDSEL 0x1a */ 252 /* IDSEL 0x1a */
259 d000 0 0 1 4d0 6 2 253 d000 0 0 1 &i8259 6 2
260 d000 0 0 2 4d0 3 2 254 d000 0 0 2 &i8259 3 2
261 d000 0 0 3 4d0 4 2 255 d000 0 0 3 &i8259 4 2
262 d000 0 0 4 4d0 5 2 256 d000 0 0 4 &i8259 5 2
263 257
264 258
265 /* IDSEL 0x1b */ 259 /* IDSEL 0x1b */
266 d800 0 0 1 4d0 5 2 260 d800 0 0 1 &i8259 5 2
267 d800 0 0 2 4d0 0 0 261 d800 0 0 2 &i8259 0 0
268 d800 0 0 3 4d0 0 0 262 d800 0 0 3 &i8259 0 0
269 d800 0 0 4 4d0 0 0 263 d800 0 0 4 &i8259 0 0
270 264
271 /* IDSEL 0x1c */ 265 /* IDSEL 0x1c */
272 e000 0 0 1 4d0 9 2 266 e000 0 0 1 &i8259 9 2
273 e000 0 0 2 4d0 a 2 267 e000 0 0 2 &i8259 a 2
274 e000 0 0 3 4d0 c 2 268 e000 0 0 3 &i8259 c 2
275 e000 0 0 4 4d0 7 2 269 e000 0 0 4 &i8259 7 2
276 270
277 /* IDSEL 0x1d */ 271 /* IDSEL 0x1d */
278 e800 0 0 1 4d0 9 2 272 e800 0 0 1 &i8259 9 2
279 e800 0 0 2 4d0 a 2 273 e800 0 0 2 &i8259 a 2
280 e800 0 0 3 4d0 b 2 274 e800 0 0 3 &i8259 b 2
281 e800 0 0 4 4d0 0 0 275 e800 0 0 4 &i8259 0 0
282 276
283 /* IDSEL 0x1e */ 277 /* IDSEL 0x1e */
284 f000 0 0 1 4d0 c 2 278 f000 0 0 1 &i8259 c 2
285 f000 0 0 2 4d0 0 0 279 f000 0 0 2 &i8259 0 0
286 f000 0 0 3 4d0 0 0 280 f000 0 0 3 &i8259 0 0
287 f000 0 0 4 4d0 0 0 281 f000 0 0 4 &i8259 0 0
288 282
289 /* IDSEL 0x1f */ 283 /* IDSEL 0x1f */
290 f800 0 0 1 4d0 6 2 284 f800 0 0 1 &i8259 6 2
291 f800 0 0 2 4d0 0 0 285 f800 0 0 2 &i8259 0 0
292 f800 0 0 3 4d0 0 0 286 f800 0 0 3 &i8259 0 0
293 f800 0 0 4 4d0 0 0 287 f800 0 0 4 &i8259 0 0
294 >; 288 >;
295 i8259@4d0 { 289 i8259: i8259@4d0 {
296 linux,phandle = <4d0>;
297 clock-frequency = <0>; 290 clock-frequency = <0>;
298 interrupt-controller; 291 interrupt-controller;
299 device_type = "interrupt-controller"; 292 device_type = "interrupt-controller";
@@ -303,12 +296,11 @@
303 compatible = "chrp,iic"; 296 compatible = "chrp,iic";
304 big-endian; 297 big-endian;
305 interrupts = <49 2>; 298 interrupts = <49 2>;
306 interrupt-parent = <40000>; 299 interrupt-parent = <&mpic>;
307 }; 300 };
308 301
309 }; 302 };
310 pic@40000 { 303 mpic: pic@40000 {
311 linux,phandle = <40000>;
312 clock-frequency = <0>; 304 clock-frequency = <0>;
313 interrupt-controller; 305 interrupt-controller;
314 #address-cells = <0>; 306 #address-cells = <0>;
@@ -317,23 +309,7 @@
317 built-in; 309 built-in;
318 compatible = "chrp,open-pic"; 310 compatible = "chrp,open-pic";
319 device_type = "open-pic"; 311 device_type = "open-pic";
320 big-endian; 312 big-endian;
321 interrupts = <
322 10 2 11 2 12 2 13 2
323 14 2 15 2 16 2 17 2
324 18 2 19 2 1a 2 1b 2
325 1c 2 1d 2 1e 2 1f 2
326 20 2 21 2 22 2 23 2
327 24 2 25 2 26 2 27 2
328 28 2 29 2 2a 2 2b 2
329 2c 2 2d 2 2e 2 2f 2
330 30 2 31 2 32 2 33 2
331 34 2 35 2 36 2 37 2
332 38 2 39 2 2a 2 3b 2
333 3c 2 3d 2 3e 2 3f 2
334 48 1 49 2 4a 1
335 >;
336 interrupt-parent = <40000>;
337 }; 313 };
338 }; 314 };
339}; 315};
diff --git a/arch/powerpc/boot/dts/mpc866ads.dts b/arch/powerpc/boot/dts/mpc866ads.dts
index 5d4005239b83..2b56b5df451a 100644
--- a/arch/powerpc/boot/dts/mpc866ads.dts
+++ b/arch/powerpc/boot/dts/mpc866ads.dts
@@ -37,7 +37,6 @@
37 interrupts = <f 2>; // decrementer interrupt 37 interrupts = <f 2>; // decrementer interrupt
38 interrupt-parent = <ff000000>; 38 interrupt-parent = <ff000000>;
39 linux,phandle = <201>; 39 linux,phandle = <201>;
40 linux,boot-cpu;
41 }; 40 };
42 }; 41 };
43 42
diff --git a/arch/powerpc/boot/dts/mpc885ads.dts b/arch/powerpc/boot/dts/mpc885ads.dts
index cf1a19f962c5..faecd08c54da 100644
--- a/arch/powerpc/boot/dts/mpc885ads.dts
+++ b/arch/powerpc/boot/dts/mpc885ads.dts
@@ -37,7 +37,6 @@
37 interrupts = <f 2>; // decrementer interrupt 37 interrupts = <f 2>; // decrementer interrupt
38 interrupt-parent = <ff000000>; 38 interrupt-parent = <ff000000>;
39 linux,phandle = <201>; 39 linux,phandle = <201>;
40 linux,boot-cpu;
41 }; 40 };
42 }; 41 };
43 42
diff --git a/arch/powerpc/configs/cell_defconfig b/arch/powerpc/configs/cell_defconfig
index e956548da00c..24367319ce24 100644
--- a/arch/powerpc/configs/cell_defconfig
+++ b/arch/powerpc/configs/cell_defconfig
@@ -147,6 +147,7 @@ CONFIG_PPC_RTAS=y
147# CONFIG_RTAS_ERROR_LOGGING is not set 147# CONFIG_RTAS_ERROR_LOGGING is not set
148CONFIG_RTAS_PROC=y 148CONFIG_RTAS_PROC=y
149CONFIG_RTAS_FLASH=y 149CONFIG_RTAS_FLASH=y
150CONFIG_PPC_PMI=m
150CONFIG_MMIO_NVRAM=y 151CONFIG_MMIO_NVRAM=y
151# CONFIG_PPC_MPC106 is not set 152# CONFIG_PPC_MPC106 is not set
152# CONFIG_PPC_970_NAP is not set 153# CONFIG_PPC_970_NAP is not set
diff --git a/arch/powerpc/configs/mpc832xemds_defconfig b/arch/powerpc/configs/mpc832x_mds_defconfig
index e1b36de6b38c..e1b36de6b38c 100644
--- a/arch/powerpc/configs/mpc832xemds_defconfig
+++ b/arch/powerpc/configs/mpc832x_mds_defconfig
diff --git a/arch/powerpc/configs/mpc8360emds_defconfig b/arch/powerpc/configs/mpc836x_mds_defconfig
index bbe38ccc3d86..8eb475cd0df0 100644
--- a/arch/powerpc/configs/mpc8360emds_defconfig
+++ b/arch/powerpc/configs/mpc836x_mds_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.20-rc5 3# Linux kernel version: 2.6.20
4# Fri Jan 26 00:19:45 2007 4# Sat Feb 17 10:09:26 2007
5# 5#
6# CONFIG_PPC64 is not set 6# CONFIG_PPC64 is not set
7CONFIG_PPC32=y 7CONFIG_PPC32=y
@@ -34,9 +34,9 @@ CONFIG_DEFAULT_UIMAGE=y
34CONFIG_PPC_83xx=y 34CONFIG_PPC_83xx=y
35# CONFIG_PPC_85xx is not set 35# CONFIG_PPC_85xx is not set
36# CONFIG_PPC_86xx is not set 36# CONFIG_PPC_86xx is not set
37# CONFIG_PPC_8xx is not set
37# CONFIG_40x is not set 38# CONFIG_40x is not set
38# CONFIG_44x is not set 39# CONFIG_44x is not set
39# CONFIG_8xx is not set
40# CONFIG_E200 is not set 40# CONFIG_E200 is not set
41CONFIG_6xx=y 41CONFIG_6xx=y
42CONFIG_83xx=y 42CONFIG_83xx=y
@@ -63,6 +63,7 @@ CONFIG_LOCALVERSION_AUTO=y
63CONFIG_SWAP=y 63CONFIG_SWAP=y
64CONFIG_SYSVIPC=y 64CONFIG_SYSVIPC=y
65# CONFIG_IPC_NS is not set 65# CONFIG_IPC_NS is not set
66CONFIG_SYSVIPC_SYSCTL=y
66# CONFIG_POSIX_MQUEUE is not set 67# CONFIG_POSIX_MQUEUE is not set
67# CONFIG_BSD_PROCESS_ACCT is not set 68# CONFIG_BSD_PROCESS_ACCT is not set
68# CONFIG_TASKSTATS is not set 69# CONFIG_TASKSTATS is not set
@@ -129,10 +130,11 @@ CONFIG_PPC_GEN550=y
129# 130#
130# Platform support 131# Platform support
131# 132#
133# CONFIG_MPC8313_RDB is not set
132# CONFIG_MPC832x_MDS is not set 134# CONFIG_MPC832x_MDS is not set
133# CONFIG_MPC834x_SYS is not set 135# CONFIG_MPC834x_MDS is not set
134# CONFIG_MPC834x_ITX is not set 136# CONFIG_MPC834x_ITX is not set
135CONFIG_MPC8360E_PB=y 137CONFIG_MPC836x_MDS=y
136CONFIG_PPC_MPC836x=y 138CONFIG_PPC_MPC836x=y
137# CONFIG_MPIC is not set 139# CONFIG_MPIC is not set
138 140
@@ -162,6 +164,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y
162# CONFIG_SPARSEMEM_STATIC is not set 164# CONFIG_SPARSEMEM_STATIC is not set
163CONFIG_SPLIT_PTLOCK_CPUS=4 165CONFIG_SPLIT_PTLOCK_CPUS=4
164# CONFIG_RESOURCES_64BIT is not set 166# CONFIG_RESOURCES_64BIT is not set
167CONFIG_ZONE_DMA_FLAG=1
165CONFIG_PROC_DEVICETREE=y 168CONFIG_PROC_DEVICETREE=y
166# CONFIG_CMDLINE_BOOL is not set 169# CONFIG_CMDLINE_BOOL is not set
167# CONFIG_PM is not set 170# CONFIG_PM is not set
@@ -171,6 +174,7 @@ CONFIG_ISA_DMA_API=y
171# 174#
172# Bus options 175# Bus options
173# 176#
177CONFIG_ZONE_DMA=y
174CONFIG_GENERIC_ISA_DMA=y 178CONFIG_GENERIC_ISA_DMA=y
175# CONFIG_MPIC_WEIRD is not set 179# CONFIG_MPIC_WEIRD is not set
176# CONFIG_PPC_I8259 is not set 180# CONFIG_PPC_I8259 is not set
@@ -219,6 +223,7 @@ CONFIG_UNIX=y
219CONFIG_XFRM=y 223CONFIG_XFRM=y
220# CONFIG_XFRM_USER is not set 224# CONFIG_XFRM_USER is not set
221# CONFIG_XFRM_SUB_POLICY is not set 225# CONFIG_XFRM_SUB_POLICY is not set
226# CONFIG_XFRM_MIGRATE is not set
222# CONFIG_NET_KEY is not set 227# CONFIG_NET_KEY is not set
223CONFIG_INET=y 228CONFIG_INET=y
224CONFIG_IP_MULTICAST=y 229CONFIG_IP_MULTICAST=y
@@ -528,6 +533,7 @@ CONFIG_UCC_GETH=y
528# Ethernet (10000 Mbit) 533# Ethernet (10000 Mbit)
529# 534#
530# CONFIG_CHELSIO_T1 is not set 535# CONFIG_CHELSIO_T1 is not set
536# CONFIG_CHELSIO_T3 is not set
531# CONFIG_IXGB is not set 537# CONFIG_IXGB is not set
532# CONFIG_S2IO is not set 538# CONFIG_S2IO is not set
533# CONFIG_MYRI10GE is not set 539# CONFIG_MYRI10GE is not set
@@ -620,6 +626,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
620CONFIG_SERIAL_CORE=y 626CONFIG_SERIAL_CORE=y
621CONFIG_SERIAL_CORE_CONSOLE=y 627CONFIG_SERIAL_CORE_CONSOLE=y
622# CONFIG_SERIAL_JSM is not set 628# CONFIG_SERIAL_JSM is not set
629# CONFIG_SERIAL_OF_PLATFORM is not set
623CONFIG_UNIX98_PTYS=y 630CONFIG_UNIX98_PTYS=y
624CONFIG_LEGACY_PTYS=y 631CONFIG_LEGACY_PTYS=y
625CONFIG_LEGACY_PTY_COUNT=256 632CONFIG_LEGACY_PTY_COUNT=256
@@ -690,6 +697,7 @@ CONFIG_I2C_MPC=y
690# CONFIG_I2C_NFORCE2 is not set 697# CONFIG_I2C_NFORCE2 is not set
691# CONFIG_I2C_OCORES is not set 698# CONFIG_I2C_OCORES is not set
692# CONFIG_I2C_PARPORT_LIGHT is not set 699# CONFIG_I2C_PARPORT_LIGHT is not set
700# CONFIG_I2C_PASEMI is not set
693# CONFIG_I2C_PROSAVAGE is not set 701# CONFIG_I2C_PROSAVAGE is not set
694# CONFIG_I2C_SAVAGE4 is not set 702# CONFIG_I2C_SAVAGE4 is not set
695# CONFIG_I2C_SIS5595 is not set 703# CONFIG_I2C_SIS5595 is not set
@@ -804,6 +812,7 @@ CONFIG_FIRMWARE_EDID=y
804# HID Devices 812# HID Devices
805# 813#
806CONFIG_HID=y 814CONFIG_HID=y
815# CONFIG_HID_DEBUG is not set
807 816
808# 817#
809# USB support 818# USB support
@@ -868,6 +877,10 @@ CONFIG_USB_ARCH_HAS_EHCI=y
868# 877#
869 878
870# 879#
880# Auxiliary Display support
881#
882
883#
871# Virtualization 884# Virtualization
872# 885#
873 886
@@ -1011,7 +1024,8 @@ CONFIG_BITREVERSE=y
1011CONFIG_CRC32=y 1024CONFIG_CRC32=y
1012# CONFIG_LIBCRC32C is not set 1025# CONFIG_LIBCRC32C is not set
1013CONFIG_PLIST=y 1026CONFIG_PLIST=y
1014CONFIG_IOMAP_COPY=y 1027CONFIG_HAS_IOMEM=y
1028CONFIG_HAS_IOPORT=y
1015 1029
1016# 1030#
1017# Instrumentation Support 1031# Instrumentation Support
@@ -1060,8 +1074,10 @@ CONFIG_CRYPTO_MD5=y
1060# CONFIG_CRYPTO_GF128MUL is not set 1074# CONFIG_CRYPTO_GF128MUL is not set
1061CONFIG_CRYPTO_ECB=m 1075CONFIG_CRYPTO_ECB=m
1062CONFIG_CRYPTO_CBC=y 1076CONFIG_CRYPTO_CBC=y
1077CONFIG_CRYPTO_PCBC=m
1063# CONFIG_CRYPTO_LRW is not set 1078# CONFIG_CRYPTO_LRW is not set
1064CONFIG_CRYPTO_DES=y 1079CONFIG_CRYPTO_DES=y
1080# CONFIG_CRYPTO_FCRYPT is not set
1065# CONFIG_CRYPTO_BLOWFISH is not set 1081# CONFIG_CRYPTO_BLOWFISH is not set
1066# CONFIG_CRYPTO_TWOFISH is not set 1082# CONFIG_CRYPTO_TWOFISH is not set
1067# CONFIG_CRYPTO_SERPENT is not set 1083# CONFIG_CRYPTO_SERPENT is not set
@@ -1075,6 +1091,7 @@ CONFIG_CRYPTO_DES=y
1075# CONFIG_CRYPTO_DEFLATE is not set 1091# CONFIG_CRYPTO_DEFLATE is not set
1076# CONFIG_CRYPTO_MICHAEL_MIC is not set 1092# CONFIG_CRYPTO_MICHAEL_MIC is not set
1077# CONFIG_CRYPTO_CRC32C is not set 1093# CONFIG_CRYPTO_CRC32C is not set
1094# CONFIG_CRYPTO_CAMELLIA is not set
1078# CONFIG_CRYPTO_TEST is not set 1095# CONFIG_CRYPTO_TEST is not set
1079 1096
1080# 1097#
diff --git a/arch/powerpc/configs/mpc8568mds_defconfig b/arch/powerpc/configs/mpc8568mds_defconfig
index 058e06d88bc1..7b3800674cbf 100644
--- a/arch/powerpc/configs/mpc8568mds_defconfig
+++ b/arch/powerpc/configs/mpc8568mds_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.20-rc5 3# Linux kernel version: 2.6.20
4# Wed Feb 7 23:54:25 2007 4# Sat Feb 17 16:26:53 2007
5# 5#
6# CONFIG_PPC64 is not set 6# CONFIG_PPC64 is not set
7CONFIG_PPC32=y 7CONFIG_PPC32=y
@@ -34,9 +34,9 @@ CONFIG_DEFAULT_UIMAGE=y
34# CONFIG_PPC_83xx is not set 34# CONFIG_PPC_83xx is not set
35CONFIG_PPC_85xx=y 35CONFIG_PPC_85xx=y
36# CONFIG_PPC_86xx is not set 36# CONFIG_PPC_86xx is not set
37# CONFIG_PPC_8xx is not set
37# CONFIG_40x is not set 38# CONFIG_40x is not set
38# CONFIG_44x is not set 39# CONFIG_44x is not set
39# CONFIG_8xx is not set
40# CONFIG_E200 is not set 40# CONFIG_E200 is not set
41CONFIG_85xx=y 41CONFIG_85xx=y
42CONFIG_E500=y 42CONFIG_E500=y
@@ -63,6 +63,7 @@ CONFIG_LOCALVERSION_AUTO=y
63CONFIG_SWAP=y 63CONFIG_SWAP=y
64CONFIG_SYSVIPC=y 64CONFIG_SYSVIPC=y
65# CONFIG_IPC_NS is not set 65# CONFIG_IPC_NS is not set
66CONFIG_SYSVIPC_SYSCTL=y
66# CONFIG_POSIX_MQUEUE is not set 67# CONFIG_POSIX_MQUEUE is not set
67# CONFIG_BSD_PROCESS_ACCT is not set 68# CONFIG_BSD_PROCESS_ACCT is not set
68# CONFIG_TASKSTATS is not set 69# CONFIG_TASKSTATS is not set
@@ -130,7 +131,7 @@ CONFIG_DEFAULT_IOSCHED="anticipatory"
130# CONFIG_MPC8540_ADS is not set 131# CONFIG_MPC8540_ADS is not set
131# CONFIG_MPC8560_ADS is not set 132# CONFIG_MPC8560_ADS is not set
132# CONFIG_MPC85xx_CDS is not set 133# CONFIG_MPC85xx_CDS is not set
133CONFIG_MPC8568_MDS=y 134CONFIG_MPC85xx_MDS=y
134CONFIG_MPC85xx=y 135CONFIG_MPC85xx=y
135CONFIG_PPC_INDIRECT_PCI_BE=y 136CONFIG_PPC_INDIRECT_PCI_BE=y
136CONFIG_MPIC=y 137CONFIG_MPIC=y
@@ -162,6 +163,7 @@ CONFIG_FLAT_NODE_MEM_MAP=y
162# CONFIG_SPARSEMEM_STATIC is not set 163# CONFIG_SPARSEMEM_STATIC is not set
163CONFIG_SPLIT_PTLOCK_CPUS=4 164CONFIG_SPLIT_PTLOCK_CPUS=4
164# CONFIG_RESOURCES_64BIT is not set 165# CONFIG_RESOURCES_64BIT is not set
166CONFIG_ZONE_DMA_FLAG=1
165CONFIG_PROC_DEVICETREE=y 167CONFIG_PROC_DEVICETREE=y
166# CONFIG_CMDLINE_BOOL is not set 168# CONFIG_CMDLINE_BOOL is not set
167# CONFIG_PM is not set 169# CONFIG_PM is not set
@@ -171,6 +173,7 @@ CONFIG_ISA_DMA_API=y
171# 173#
172# Bus options 174# Bus options
173# 175#
176CONFIG_ZONE_DMA=y
174# CONFIG_MPIC_WEIRD is not set 177# CONFIG_MPIC_WEIRD is not set
175# CONFIG_PPC_I8259 is not set 178# CONFIG_PPC_I8259 is not set
176CONFIG_PPC_INDIRECT_PCI=y 179CONFIG_PPC_INDIRECT_PCI=y
@@ -216,6 +219,7 @@ CONFIG_UNIX=y
216CONFIG_XFRM=y 219CONFIG_XFRM=y
217# CONFIG_XFRM_USER is not set 220# CONFIG_XFRM_USER is not set
218# CONFIG_XFRM_SUB_POLICY is not set 221# CONFIG_XFRM_SUB_POLICY is not set
222# CONFIG_XFRM_MIGRATE is not set
219# CONFIG_NET_KEY is not set 223# CONFIG_NET_KEY is not set
220CONFIG_INET=y 224CONFIG_INET=y
221CONFIG_IP_MULTICAST=y 225CONFIG_IP_MULTICAST=y
@@ -301,6 +305,7 @@ CONFIG_STANDALONE=y
301CONFIG_PREVENT_FIRMWARE_BUILD=y 305CONFIG_PREVENT_FIRMWARE_BUILD=y
302# CONFIG_FW_LOADER is not set 306# CONFIG_FW_LOADER is not set
303# CONFIG_DEBUG_DRIVER is not set 307# CONFIG_DEBUG_DRIVER is not set
308# CONFIG_DEBUG_DEVRES is not set
304# CONFIG_SYS_HYPERVISOR is not set 309# CONFIG_SYS_HYPERVISOR is not set
305 310
306# 311#
@@ -341,7 +346,6 @@ CONFIG_BLK_DEV_INITRD=y
341# 346#
342# Misc devices 347# Misc devices
343# 348#
344# CONFIG_TIFM_CORE is not set
345 349
346# 350#
347# ATA/ATAPI/MFM/RLL support 351# ATA/ATAPI/MFM/RLL support
@@ -543,6 +547,7 @@ CONFIG_SERIAL_8250_RUNTIME_UARTS=4
543# CONFIG_SERIAL_UARTLITE is not set 547# CONFIG_SERIAL_UARTLITE is not set
544CONFIG_SERIAL_CORE=y 548CONFIG_SERIAL_CORE=y
545CONFIG_SERIAL_CORE_CONSOLE=y 549CONFIG_SERIAL_CORE_CONSOLE=y
550# CONFIG_SERIAL_OF_PLATFORM is not set
546CONFIG_UNIX98_PTYS=y 551CONFIG_UNIX98_PTYS=y
547CONFIG_LEGACY_PTYS=y 552CONFIG_LEGACY_PTYS=y
548CONFIG_LEGACY_PTY_COUNT=256 553CONFIG_LEGACY_PTY_COUNT=256
@@ -698,6 +703,7 @@ CONFIG_FIRMWARE_EDID=y
698# HID Devices 703# HID Devices
699# 704#
700CONFIG_HID=y 705CONFIG_HID=y
706# CONFIG_HID_DEBUG is not set
701 707
702# 708#
703# USB support 709# USB support
@@ -760,6 +766,10 @@ CONFIG_HID=y
760# 766#
761 767
762# 768#
769# Auxiliary Display support
770#
771
772#
763# Virtualization 773# Virtualization
764# 774#
765 775
@@ -896,7 +906,8 @@ CONFIG_BITREVERSE=y
896CONFIG_CRC32=y 906CONFIG_CRC32=y
897# CONFIG_LIBCRC32C is not set 907# CONFIG_LIBCRC32C is not set
898CONFIG_PLIST=y 908CONFIG_PLIST=y
899CONFIG_IOMAP_COPY=y 909CONFIG_HAS_IOMEM=y
910CONFIG_HAS_IOPORT=y
900 911
901# 912#
902# Instrumentation Support 913# Instrumentation Support
@@ -914,6 +925,7 @@ CONFIG_ENABLE_MUST_CHECK=y
914# CONFIG_DEBUG_FS is not set 925# CONFIG_DEBUG_FS is not set
915# CONFIG_HEADERS_CHECK is not set 926# CONFIG_HEADERS_CHECK is not set
916CONFIG_DEBUG_KERNEL=y 927CONFIG_DEBUG_KERNEL=y
928# CONFIG_DEBUG_SHIRQ is not set
917CONFIG_LOG_BUF_SHIFT=14 929CONFIG_LOG_BUF_SHIFT=14
918CONFIG_DETECT_SOFTLOCKUP=y 930CONFIG_DETECT_SOFTLOCKUP=y
919# CONFIG_SCHEDSTATS is not set 931# CONFIG_SCHEDSTATS is not set
@@ -922,7 +934,6 @@ CONFIG_DETECT_SOFTLOCKUP=y
922# CONFIG_RT_MUTEX_TESTER is not set 934# CONFIG_RT_MUTEX_TESTER is not set
923# CONFIG_DEBUG_SPINLOCK is not set 935# CONFIG_DEBUG_SPINLOCK is not set
924# CONFIG_DEBUG_MUTEXES is not set 936# CONFIG_DEBUG_MUTEXES is not set
925# CONFIG_DEBUG_RWSEMS is not set
926# CONFIG_DEBUG_SPINLOCK_SLEEP is not set 937# CONFIG_DEBUG_SPINLOCK_SLEEP is not set
927# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set 938# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set
928# CONFIG_DEBUG_KOBJECT is not set 939# CONFIG_DEBUG_KOBJECT is not set
@@ -932,6 +943,8 @@ CONFIG_DETECT_SOFTLOCKUP=y
932# CONFIG_DEBUG_LIST is not set 943# CONFIG_DEBUG_LIST is not set
933CONFIG_FORCED_INLINING=y 944CONFIG_FORCED_INLINING=y
934# CONFIG_RCU_TORTURE_TEST is not set 945# CONFIG_RCU_TORTURE_TEST is not set
946# CONFIG_DEBUG_STACKOVERFLOW is not set
947# CONFIG_DEBUG_STACK_USAGE is not set
935CONFIG_DEBUGGER=y 948CONFIG_DEBUGGER=y
936# CONFIG_XMON is not set 949# CONFIG_XMON is not set
937# CONFIG_BDI_SWITCH is not set 950# CONFIG_BDI_SWITCH is not set
@@ -943,6 +956,8 @@ CONFIG_PPC_EARLY_DEBUG=y
943# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set 956# CONFIG_PPC_EARLY_DEBUG_RTAS_CONSOLE is not set
944# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set 957# CONFIG_PPC_EARLY_DEBUG_MAPLE is not set
945# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set 958# CONFIG_PPC_EARLY_DEBUG_ISERIES is not set
959# CONFIG_PPC_EARLY_DEBUG_PAS_REALMODE is not set
960# CONFIG_PPC_EARLY_DEBUG_BEAT is not set
946 961
947# 962#
948# Security options 963# Security options
@@ -970,8 +985,10 @@ CONFIG_CRYPTO_MD5=y
970# CONFIG_CRYPTO_GF128MUL is not set 985# CONFIG_CRYPTO_GF128MUL is not set
971CONFIG_CRYPTO_ECB=m 986CONFIG_CRYPTO_ECB=m
972CONFIG_CRYPTO_CBC=y 987CONFIG_CRYPTO_CBC=y
988CONFIG_CRYPTO_PCBC=m
973# CONFIG_CRYPTO_LRW is not set 989# CONFIG_CRYPTO_LRW is not set
974CONFIG_CRYPTO_DES=y 990CONFIG_CRYPTO_DES=y
991# CONFIG_CRYPTO_FCRYPT is not set
975# CONFIG_CRYPTO_BLOWFISH is not set 992# CONFIG_CRYPTO_BLOWFISH is not set
976# CONFIG_CRYPTO_TWOFISH is not set 993# CONFIG_CRYPTO_TWOFISH is not set
977# CONFIG_CRYPTO_SERPENT is not set 994# CONFIG_CRYPTO_SERPENT is not set
@@ -985,6 +1002,7 @@ CONFIG_CRYPTO_DES=y
985# CONFIG_CRYPTO_DEFLATE is not set 1002# CONFIG_CRYPTO_DEFLATE is not set
986# CONFIG_CRYPTO_MICHAEL_MIC is not set 1003# CONFIG_CRYPTO_MICHAEL_MIC is not set
987# CONFIG_CRYPTO_CRC32C is not set 1004# CONFIG_CRYPTO_CRC32C is not set
1005# CONFIG_CRYPTO_CAMELLIA is not set
988# CONFIG_CRYPTO_TEST is not set 1006# CONFIG_CRYPTO_TEST is not set
989 1007
990# 1008#
diff --git a/arch/powerpc/configs/ppc64_defconfig b/arch/powerpc/configs/ppc64_defconfig
index debac66e8258..a8da0aea3b87 100644
--- a/arch/powerpc/configs/ppc64_defconfig
+++ b/arch/powerpc/configs/ppc64_defconfig
@@ -500,7 +500,7 @@ CONFIG_BLK_DEV_AMD74XX=y
500# CONFIG_BLK_DEV_PDC202XX_NEW is not set 500# CONFIG_BLK_DEV_PDC202XX_NEW is not set
501# CONFIG_BLK_DEV_SVWKS is not set 501# CONFIG_BLK_DEV_SVWKS is not set
502# CONFIG_BLK_DEV_SIIMAGE is not set 502# CONFIG_BLK_DEV_SIIMAGE is not set
503CONFIG_BLK_DEV_SL82C105=y 503# CONFIG_BLK_DEV_SL82C105 is not set
504# CONFIG_BLK_DEV_SLC90E66 is not set 504# CONFIG_BLK_DEV_SLC90E66 is not set
505# CONFIG_BLK_DEV_TRM290 is not set 505# CONFIG_BLK_DEV_TRM290 is not set
506# CONFIG_BLK_DEV_VIA82CXXX is not set 506# CONFIG_BLK_DEV_VIA82CXXX is not set
@@ -646,7 +646,7 @@ CONFIG_SATA_SVW=y
646# CONFIG_PATA_SIL680 is not set 646# CONFIG_PATA_SIL680 is not set
647# CONFIG_PATA_SIS is not set 647# CONFIG_PATA_SIS is not set
648# CONFIG_PATA_VIA is not set 648# CONFIG_PATA_VIA is not set
649# CONFIG_PATA_WINBOND is not set 649CONFIG_PATA_WINBOND=y
650 650
651# 651#
652# Multi-device support (RAID and LVM) 652# Multi-device support (RAID and LVM)
diff --git a/arch/powerpc/configs/pseries_defconfig b/arch/powerpc/configs/pseries_defconfig
index 1c794fe718fd..6e96e50c362d 100644
--- a/arch/powerpc/configs/pseries_defconfig
+++ b/arch/powerpc/configs/pseries_defconfig
@@ -483,7 +483,7 @@ CONFIG_BLK_DEV_AMD74XX=y
483# CONFIG_BLK_DEV_PDC202XX_NEW is not set 483# CONFIG_BLK_DEV_PDC202XX_NEW is not set
484# CONFIG_BLK_DEV_SVWKS is not set 484# CONFIG_BLK_DEV_SVWKS is not set
485# CONFIG_BLK_DEV_SIIMAGE is not set 485# CONFIG_BLK_DEV_SIIMAGE is not set
486CONFIG_BLK_DEV_SL82C105=y 486# CONFIG_BLK_DEV_SL82C105 is not set
487# CONFIG_BLK_DEV_SLC90E66 is not set 487# CONFIG_BLK_DEV_SLC90E66 is not set
488# CONFIG_BLK_DEV_TRM290 is not set 488# CONFIG_BLK_DEV_TRM290 is not set
489# CONFIG_BLK_DEV_VIA82CXXX is not set 489# CONFIG_BLK_DEV_VIA82CXXX is not set
@@ -628,7 +628,7 @@ CONFIG_ATA=y
628# CONFIG_PATA_SIL680 is not set 628# CONFIG_PATA_SIL680 is not set
629# CONFIG_PATA_SIS is not set 629# CONFIG_PATA_SIS is not set
630# CONFIG_PATA_VIA is not set 630# CONFIG_PATA_VIA is not set
631# CONFIG_PATA_WINBOND is not set 631CONFIG_PATA_WINBOND=y
632 632
633# 633#
634# Multi-device support (RAID and LVM) 634# Multi-device support (RAID and LVM)
diff --git a/arch/powerpc/kernel/prom.c b/arch/powerpc/kernel/prom.c
index 3e86e6e0f778..8d52b23348bd 100644
--- a/arch/powerpc/kernel/prom.c
+++ b/arch/powerpc/kernel/prom.c
@@ -1599,6 +1599,7 @@ struct property *of_find_property(const struct device_node *np,
1599 1599
1600 return pp; 1600 return pp;
1601} 1601}
1602EXPORT_SYMBOL(of_find_property);
1602 1603
1603/* 1604/*
1604 * Find a property with a given name for a given node 1605 * Find a property with a given name for a given node
diff --git a/arch/powerpc/kernel/prom_parse.c b/arch/powerpc/kernel/prom_parse.c
index 12c51e4ad2b4..ea6fd552c7ea 100644
--- a/arch/powerpc/kernel/prom_parse.c
+++ b/arch/powerpc/kernel/prom_parse.c
@@ -5,6 +5,7 @@
5#include <linux/pci_regs.h> 5#include <linux/pci_regs.h>
6#include <linux/module.h> 6#include <linux/module.h>
7#include <linux/ioport.h> 7#include <linux/ioport.h>
8#include <linux/etherdevice.h>
8#include <asm/prom.h> 9#include <asm/prom.h>
9#include <asm/pci-bridge.h> 10#include <asm/pci-bridge.h>
10 11
@@ -1003,3 +1004,42 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq
1003 return res; 1004 return res;
1004} 1005}
1005EXPORT_SYMBOL_GPL(of_irq_map_one); 1006EXPORT_SYMBOL_GPL(of_irq_map_one);
1007
1008/**
1009 * Search the device tree for the best MAC address to use. 'mac-address' is
1010 * checked first, because that is supposed to contain to "most recent" MAC
1011 * address. If that isn't set, then 'local-mac-address' is checked next,
1012 * because that is the default address. If that isn't set, then the obsolete
1013 * 'address' is checked, just in case we're using an old device tree.
1014 *
1015 * Note that the 'address' property is supposed to contain a virtual address of
1016 * the register set, but some DTS files have redefined that property to be the
1017 * MAC address.
1018 *
1019 * All-zero MAC addresses are rejected, because those could be properties that
1020 * exist in the device tree, but were not set by U-Boot. For example, the
1021 * DTS could define 'mac-address' and 'local-mac-address', with zero MAC
1022 * addresses. Some older U-Boots only initialized 'local-mac-address'. In
1023 * this case, the real MAC is in 'local-mac-address', and 'mac-address' exists
1024 * but is all zeros.
1025*/
1026const void *of_get_mac_address(struct device_node *np)
1027{
1028 struct property *pp;
1029
1030 pp = of_find_property(np, "mac-address", NULL);
1031 if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
1032 return pp->value;
1033
1034 pp = of_find_property(np, "local-mac-address", NULL);
1035 if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
1036 return pp->value;
1037
1038 pp = of_find_property(np, "address", NULL);
1039 if (pp && (pp->length == 6) && is_valid_ether_addr(pp->value))
1040 return pp->value;
1041
1042 return NULL;
1043}
1044EXPORT_SYMBOL(of_get_mac_address);
1045
diff --git a/arch/powerpc/mm/pgtable_64.c b/arch/powerpc/mm/pgtable_64.c
index 16e4ee1c2318..1d443407423c 100644
--- a/arch/powerpc/mm/pgtable_64.c
+++ b/arch/powerpc/mm/pgtable_64.c
@@ -103,7 +103,7 @@ static int map_io_page(unsigned long ea, unsigned long pa, int flags)
103 * 103 *
104 */ 104 */
105 if (htab_bolt_mapping(ea, ea + PAGE_SIZE, pa, flags, 105 if (htab_bolt_mapping(ea, ea + PAGE_SIZE, pa, flags,
106 mmu_virtual_psize)) { 106 mmu_io_psize)) {
107 printk(KERN_ERR "Failed to do bolted mapping IO " 107 printk(KERN_ERR "Failed to do bolted mapping IO "
108 "memory at %016lx !\n", pa); 108 "memory at %016lx !\n", pa);
109 return -ENOMEM; 109 return -ENOMEM;
diff --git a/arch/powerpc/platforms/83xx/Kconfig b/arch/powerpc/platforms/83xx/Kconfig
index 1aea1e69ff31..713b31a16ce9 100644
--- a/arch/powerpc/platforms/83xx/Kconfig
+++ b/arch/powerpc/platforms/83xx/Kconfig
@@ -38,12 +38,12 @@ config MPC834x_ITX
38 Be aware that PCI initialization is the bootloader's 38 Be aware that PCI initialization is the bootloader's
39 responsibility. 39 responsibility.
40 40
41config MPC8360E_PB 41config MPC836x_MDS
42 bool "Freescale MPC8360E PB" 42 bool "Freescale MPC836x MDS"
43 select DEFAULT_UIMAGE 43 select DEFAULT_UIMAGE
44 select QUICC_ENGINE 44 select QUICC_ENGINE
45 help 45 help
46 This option enables support for the MPC836x EMDS Processor Board. 46 This option enables support for the MPC836x MDS Processor Board.
47 47
48endchoice 48endchoice
49 49
@@ -69,6 +69,6 @@ config PPC_MPC836x
69 bool 69 bool
70 select PPC_UDBG_16550 70 select PPC_UDBG_16550
71 select PPC_INDIRECT_PCI 71 select PPC_INDIRECT_PCI
72 default y if MPC8360E_PB 72 default y if MPC836x_MDS
73 73
74endmenu 74endmenu
diff --git a/arch/powerpc/platforms/83xx/Makefile b/arch/powerpc/platforms/83xx/Makefile
index 6c8199c4c382..dfc970d0df10 100644
--- a/arch/powerpc/platforms/83xx/Makefile
+++ b/arch/powerpc/platforms/83xx/Makefile
@@ -6,5 +6,5 @@ obj-$(CONFIG_PCI) += pci.o
6obj-$(CONFIG_MPC8313_RDB) += mpc8313_rdb.o 6obj-$(CONFIG_MPC8313_RDB) += mpc8313_rdb.o
7obj-$(CONFIG_MPC834x_MDS) += mpc834x_mds.o 7obj-$(CONFIG_MPC834x_MDS) += mpc834x_mds.o
8obj-$(CONFIG_MPC834x_ITX) += mpc834x_itx.o 8obj-$(CONFIG_MPC834x_ITX) += mpc834x_itx.o
9obj-$(CONFIG_MPC8360E_PB) += mpc8360e_pb.o 9obj-$(CONFIG_MPC836x_MDS) += mpc836x_mds.o
10obj-$(CONFIG_MPC832x_MDS) += mpc832x_mds.o 10obj-$(CONFIG_MPC832x_MDS) += mpc832x_mds.o
diff --git a/arch/powerpc/platforms/83xx/mpc8313_rdb.c b/arch/powerpc/platforms/83xx/mpc8313_rdb.c
index c3b98c34eb6b..32e9e9492841 100644
--- a/arch/powerpc/platforms/83xx/mpc8313_rdb.c
+++ b/arch/powerpc/platforms/83xx/mpc8313_rdb.c
@@ -74,16 +74,9 @@ void __init mpc8313_rdb_init_IRQ(void)
74 */ 74 */
75static int __init mpc8313_rdb_probe(void) 75static int __init mpc8313_rdb_probe(void)
76{ 76{
77 char *model = of_get_flat_dt_prop(of_get_flat_dt_root(), 77 unsigned long root = of_get_flat_dt_root();
78 "model", NULL);
79 if (model == NULL)
80 return 0;
81 if (strcmp(model, "MPC8313ERDB"))
82 return 0;
83 78
84 DBG("MPC8313 RDB found\n"); 79 return of_flat_dt_is_compatible(root, "MPC8313ERDB");
85
86 return 1;
87} 80}
88 81
89define_machine(mpc8313_rdb) { 82define_machine(mpc8313_rdb) {
diff --git a/arch/powerpc/platforms/83xx/mpc832x_mds.c b/arch/powerpc/platforms/83xx/mpc832x_mds.c
index 3ecb55f8a6e2..17e3a3c6d8b4 100644
--- a/arch/powerpc/platforms/83xx/mpc832x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc832x_mds.c
@@ -57,11 +57,6 @@ unsigned long isa_mem_base = 0;
57 57
58static u8 *bcsr_regs = NULL; 58static u8 *bcsr_regs = NULL;
59 59
60u8 *get_bcsr(void)
61{
62 return bcsr_regs;
63}
64
65/* ************************************************************************ 60/* ************************************************************************
66 * 61 *
67 * Setup the architecture 62 * Setup the architecture
@@ -74,17 +69,6 @@ static void __init mpc832x_sys_setup_arch(void)
74 if (ppc_md.progress) 69 if (ppc_md.progress)
75 ppc_md.progress("mpc832x_sys_setup_arch()", 0); 70 ppc_md.progress("mpc832x_sys_setup_arch()", 0);
76 71
77 np = of_find_node_by_type(NULL, "cpu");
78 if (np != 0) {
79 unsigned int *fp =
80 (int *)get_property(np, "clock-frequency", NULL);
81 if (fp != 0)
82 loops_per_jiffy = *fp / HZ;
83 else
84 loops_per_jiffy = 50000000 / HZ;
85 of_node_put(np);
86 }
87
88 /* Map BCSR area */ 72 /* Map BCSR area */
89 np = of_find_node_by_name(NULL, "bcsr"); 73 np = of_find_node_by_name(NULL, "bcsr");
90 if (np != 0) { 74 if (np != 0) {
@@ -121,34 +105,23 @@ static void __init mpc832x_sys_setup_arch(void)
121 iounmap(bcsr_regs); 105 iounmap(bcsr_regs);
122 of_node_put(np); 106 of_node_put(np);
123 } 107 }
124
125#endif /* CONFIG_QUICC_ENGINE */ 108#endif /* CONFIG_QUICC_ENGINE */
126
127#ifdef CONFIG_BLK_DEV_INITRD
128 if (initrd_start)
129 ROOT_DEV = Root_RAM0;
130 else
131#endif
132#ifdef CONFIG_ROOT_NFS
133 ROOT_DEV = Root_NFS;
134#else
135 ROOT_DEV = Root_HDA1;
136#endif
137} 109}
138 110
111static struct of_device_id mpc832x_ids[] = {
112 { .type = "soc", },
113 { .compatible = "soc", },
114 { .type = "qe", },
115 {},
116};
117
139static int __init mpc832x_declare_of_platform_devices(void) 118static int __init mpc832x_declare_of_platform_devices(void)
140{ 119{
141 struct device_node *np; 120 if (!machine_is(mpc832x_mds))
142 121 return 0;
143 for (np = NULL; (np = of_find_compatible_node(np, "network",
144 "ucc_geth")) != NULL;) {
145 int ucc_num;
146 char bus_id[BUS_ID_SIZE];
147 122
148 ucc_num = *((uint *) get_property(np, "device-id", NULL)) - 1; 123 /* Publish the QE devices */
149 snprintf(bus_id, BUS_ID_SIZE, "ucc_geth.%u", ucc_num); 124 of_platform_bus_probe(NULL, mpc832x_ids, NULL);
150 of_platform_device_create(np, bus_id, NULL);
151 }
152 125
153 return 0; 126 return 0;
154} 127}
@@ -156,7 +129,6 @@ device_initcall(mpc832x_declare_of_platform_devices);
156 129
157static void __init mpc832x_sys_init_IRQ(void) 130static void __init mpc832x_sys_init_IRQ(void)
158{ 131{
159
160 struct device_node *np; 132 struct device_node *np;
161 133
162 np = of_find_node_by_type(NULL, "ipic"); 134 np = of_find_node_by_type(NULL, "ipic");
@@ -189,6 +161,9 @@ static int __init mpc832x_rtc_hookup(void)
189{ 161{
190 struct timespec tv; 162 struct timespec tv;
191 163
164 if (!machine_is(mpc832x_mds))
165 return 0;
166
192 ppc_md.get_rtc_time = ds1374_get_rtc_time; 167 ppc_md.get_rtc_time = ds1374_get_rtc_time;
193 ppc_md.set_rtc_time = ds1374_set_rtc_time; 168 ppc_md.set_rtc_time = ds1374_set_rtc_time;
194 169
@@ -207,17 +182,9 @@ late_initcall(mpc832x_rtc_hookup);
207 */ 182 */
208static int __init mpc832x_sys_probe(void) 183static int __init mpc832x_sys_probe(void)
209{ 184{
210 char *model = of_get_flat_dt_prop(of_get_flat_dt_root(), 185 unsigned long root = of_get_flat_dt_root();
211 "model", NULL);
212
213 if (model == NULL)
214 return 0;
215 if (strcmp(model, "MPC8323EMDS"))
216 return 0;
217
218 DBG("%s found\n", model);
219 186
220 return 1; 187 return of_flat_dt_is_compatible(root, "MPC832xMDS");
221} 188}
222 189
223define_machine(mpc832x_mds) { 190define_machine(mpc832x_mds) {
diff --git a/arch/powerpc/platforms/83xx/mpc834x_itx.c b/arch/powerpc/platforms/83xx/mpc834x_itx.c
index 443a3172f370..3c009f6d4a4f 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_itx.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_itx.c
@@ -55,28 +55,12 @@ static void __init mpc834x_itx_setup_arch(void)
55 if (ppc_md.progress) 55 if (ppc_md.progress)
56 ppc_md.progress("mpc834x_itx_setup_arch()", 0); 56 ppc_md.progress("mpc834x_itx_setup_arch()", 0);
57 57
58 np = of_find_node_by_type(NULL, "cpu");
59 if (np != 0) {
60 const unsigned int *fp =
61 get_property(np, "clock-frequency", NULL);
62 if (fp != 0)
63 loops_per_jiffy = *fp / HZ;
64 else
65 loops_per_jiffy = 50000000 / HZ;
66 of_node_put(np);
67 }
68#ifdef CONFIG_PCI 58#ifdef CONFIG_PCI
69 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 59 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
70 add_bridge(np); 60 add_bridge(np);
71 61
72 ppc_md.pci_exclude_device = mpc83xx_exclude_device; 62 ppc_md.pci_exclude_device = mpc83xx_exclude_device;
73#endif 63#endif
74
75#ifdef CONFIG_ROOT_NFS
76 ROOT_DEV = Root_NFS;
77#else
78 ROOT_DEV = Root_HDA1;
79#endif
80} 64}
81 65
82static void __init mpc834x_itx_init_IRQ(void) 66static void __init mpc834x_itx_init_IRQ(void)
@@ -100,10 +84,9 @@ static void __init mpc834x_itx_init_IRQ(void)
100 */ 84 */
101static int __init mpc834x_itx_probe(void) 85static int __init mpc834x_itx_probe(void)
102{ 86{
103 /* We always match for now, eventually we should look at the flat 87 unsigned long root = of_get_flat_dt_root();
104 dev tree to ensure this is the board we are suppose to run on 88
105 */ 89 return of_flat_dt_is_compatible(root, "MPC834xMITX");
106 return 1;
107} 90}
108 91
109define_machine(mpc834x_itx) { 92define_machine(mpc834x_itx) {
diff --git a/arch/powerpc/platforms/83xx/mpc834x_mds.c b/arch/powerpc/platforms/83xx/mpc834x_mds.c
index d2736da76c46..e5d819166874 100644
--- a/arch/powerpc/platforms/83xx/mpc834x_mds.c
+++ b/arch/powerpc/platforms/83xx/mpc834x_mds.c
@@ -125,17 +125,6 @@ static void __init mpc834x_mds_setup_arch(void)
125 if (ppc_md.progress) 125 if (ppc_md.progress)
126 ppc_md.progress("mpc834x_mds_setup_arch()", 0); 126 ppc_md.progress("mpc834x_mds_setup_arch()", 0);
127 127
128 np = of_find_node_by_type(NULL, "cpu");
129 if (np != 0) {
130 const unsigned int *fp =
131 get_property(np, "clock-frequency", NULL);
132 if (fp != 0)
133 loops_per_jiffy = *fp / HZ;
134 else
135 loops_per_jiffy = 50000000 / HZ;
136 of_node_put(np);
137 }
138
139#ifdef CONFIG_PCI 128#ifdef CONFIG_PCI
140 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) 129 for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;)
141 add_bridge(np); 130 add_bridge(np);
@@ -144,12 +133,6 @@ static void __init mpc834x_mds_setup_arch(void)
144#endif 133#endif
145 134
146 mpc834x_usb_cfg(); 135 mpc834x_usb_cfg();
147
148#ifdef CONFIG_ROOT_NFS
149 ROOT_DEV = Root_NFS;
150#else
151 ROOT_DEV = Root_HDA1;
152#endif
153} 136}
154 137
155static void __init mpc834x_mds_init_IRQ(void) 138static void __init mpc834x_mds_init_IRQ(void)
@@ -176,6 +159,9 @@ static int __init mpc834x_rtc_hookup(void)
176{ 159{
177 struct timespec tv; 160 struct timespec tv;
178 161
162 if (!machine_is(mpc834x_mds))
163 return 0;
164
179 ppc_md.get_rtc_time = ds1374_get_rtc_time; 165 ppc_md.get_rtc_time = ds1374_get_rtc_time;
180 ppc_md.set_rtc_time = ds1374_set_rtc_time; 166 ppc_md.set_rtc_time = ds1374_set_rtc_time;
181 167
@@ -194,10 +180,9 @@ late_initcall(mpc834x_rtc_hookup);
194 */ 180 */
195static int __init mpc834x_mds_probe(void) 181static int __init mpc834x_mds_probe(void)
196{ 182{
197 /* We always match for now, eventually we should look at the flat 183 unsigned long root = of_get_flat_dt_root();
198 dev tree to ensure this is the board we are suppose to run on 184
199 */ 185 return of_flat_dt_is_compatible(root, "MPC834xMDS");
200 return 1;
201} 186}
202 187
203define_machine(mpc834x_mds) { 188define_machine(mpc834x_mds) {
diff --git a/arch/powerpc/platforms/83xx/mpc8360e_pb.c b/arch/powerpc/platforms/83xx/mpc836x_mds.c
index ccce2f9f283d..526ed090a446 100644
--- a/arch/powerpc/platforms/83xx/mpc8360e_pb.c
+++ b/arch/powerpc/platforms/83xx/mpc836x_mds.c
@@ -5,12 +5,12 @@
5 * Yin Olivia <Hong-hua.Yin@freescale.com> 5 * Yin Olivia <Hong-hua.Yin@freescale.com>
6 * 6 *
7 * Description: 7 * Description:
8 * MPC8360E MDS PB board specific routines. 8 * MPC8360E MDS board specific routines.
9 * 9 *
10 * Changelog: 10 * Changelog:
11 * Jun 21, 2006 Initial version 11 * Jun 21, 2006 Initial version
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify it 13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the 14 * under the terms of the GNU General Public License as published by the
15 * Free Software Foundation; either version 2 of the License, or (at your 15 * Free Software Foundation; either version 2 of the License, or (at your
16 * option) any later version. 16 * option) any later version.
@@ -62,33 +62,17 @@ unsigned long isa_mem_base = 0;
62 62
63static u8 *bcsr_regs = NULL; 63static u8 *bcsr_regs = NULL;
64 64
65u8 *get_bcsr(void)
66{
67 return bcsr_regs;
68}
69
70/* ************************************************************************ 65/* ************************************************************************
71 * 66 *
72 * Setup the architecture 67 * Setup the architecture
73 * 68 *
74 */ 69 */
75static void __init mpc8360_sys_setup_arch(void) 70static void __init mpc836x_mds_setup_arch(void)
76{ 71{
77 struct device_node *np; 72 struct device_node *np;
78 73
79 if (ppc_md.progress) 74 if (ppc_md.progress)
80 ppc_md.progress("mpc8360_sys_setup_arch()", 0); 75 ppc_md.progress("mpc836x_mds_setup_arch()", 0);
81
82 np = of_find_node_by_type(NULL, "cpu");
83 if (np != 0) {
84 const unsigned int *fp =
85 get_property(np, "clock-frequency", NULL);
86 if (fp != 0)
87 loops_per_jiffy = *fp / HZ;
88 else
89 loops_per_jiffy = 50000000 / HZ;
90 of_node_put(np);
91 }
92 76
93 /* Map BCSR area */ 77 /* Map BCSR area */
94 np = of_find_node_by_name(NULL, "bcsr"); 78 np = of_find_node_by_name(NULL, "bcsr");
@@ -128,40 +112,29 @@ static void __init mpc8360_sys_setup_arch(void)
128 } 112 }
129 113
130#endif /* CONFIG_QUICC_ENGINE */ 114#endif /* CONFIG_QUICC_ENGINE */
131
132#ifdef CONFIG_BLK_DEV_INITRD
133 if (initrd_start)
134 ROOT_DEV = Root_RAM0;
135 else
136#endif
137#ifdef CONFIG_ROOT_NFS
138 ROOT_DEV = Root_NFS;
139#else
140 ROOT_DEV = Root_HDA1;
141#endif
142} 115}
143 116
144static int __init mpc8360_declare_of_platform_devices(void) 117static struct of_device_id mpc836x_ids[] = {
145{ 118 { .type = "soc", },
146 struct device_node *np; 119 { .compatible = "soc", },
120 { .type = "qe", },
121 {},
122};
147 123
148 for (np = NULL; (np = of_find_compatible_node(np, "network", 124static int __init mpc836x_declare_of_platform_devices(void)
149 "ucc_geth")) != NULL;) { 125{
150 int ucc_num; 126 if (!machine_is(mpc836x_mds))
151 char bus_id[BUS_ID_SIZE]; 127 return 0;
152 128
153 ucc_num = *((uint *) get_property(np, "device-id", NULL)) - 1; 129 /* Publish the QE devices */
154 snprintf(bus_id, BUS_ID_SIZE, "ucc_geth.%u", ucc_num); 130 of_platform_bus_probe(NULL, mpc836x_ids, NULL);
155 of_platform_device_create(np, bus_id, NULL);
156 }
157 131
158 return 0; 132 return 0;
159} 133}
160device_initcall(mpc8360_declare_of_platform_devices); 134device_initcall(mpc836x_declare_of_platform_devices);
161 135
162static void __init mpc8360_sys_init_IRQ(void) 136static void __init mpc836x_mds_init_IRQ(void)
163{ 137{
164
165 struct device_node *np; 138 struct device_node *np;
166 139
167 np = of_find_node_by_type(NULL, "ipic"); 140 np = of_find_node_by_type(NULL, "ipic");
@@ -194,6 +167,9 @@ static int __init mpc8360_rtc_hookup(void)
194{ 167{
195 struct timespec tv; 168 struct timespec tv;
196 169
170 if (!machine_is(mpc836x_mds))
171 return 0;
172
197 ppc_md.get_rtc_time = ds1374_get_rtc_time; 173 ppc_md.get_rtc_time = ds1374_get_rtc_time;
198 ppc_md.set_rtc_time = ds1374_set_rtc_time; 174 ppc_md.set_rtc_time = ds1374_set_rtc_time;
199 175
@@ -210,28 +186,21 @@ late_initcall(mpc8360_rtc_hookup);
210/* 186/*
211 * Called very early, MMU is off, device-tree isn't unflattened 187 * Called very early, MMU is off, device-tree isn't unflattened
212 */ 188 */
213static int __init mpc8360_sys_probe(void) 189static int __init mpc836x_mds_probe(void)
214{ 190{
215 char *model = of_get_flat_dt_prop(of_get_flat_dt_root(), 191 unsigned long root = of_get_flat_dt_root();
216 "model", NULL);
217 if (model == NULL)
218 return 0;
219 if (strcmp(model, "MPC8360EPB"))
220 return 0;
221
222 DBG("MPC8360EMDS-PB found\n");
223 192
224 return 1; 193 return of_flat_dt_is_compatible(root, "MPC836xMDS");
225} 194}
226 195
227define_machine(mpc8360_sys) { 196define_machine(mpc836x_mds) {
228 .name = "MPC8360E PB", 197 .name = "MPC836x MDS",
229 .probe = mpc8360_sys_probe, 198 .probe = mpc836x_mds_probe,
230 .setup_arch = mpc8360_sys_setup_arch, 199 .setup_arch = mpc836x_mds_setup_arch,
231 .init_IRQ = mpc8360_sys_init_IRQ, 200 .init_IRQ = mpc836x_mds_init_IRQ,
232 .get_irq = ipic_get_irq, 201 .get_irq = ipic_get_irq,
233 .restart = mpc83xx_restart, 202 .restart = mpc83xx_restart,
234 .time_init = mpc83xx_time_init, 203 .time_init = mpc83xx_time_init,
235 .calibrate_decr = generic_calibrate_decr, 204 .calibrate_decr = generic_calibrate_decr,
236 .progress = udbg_progress, 205 .progress = udbg_progress,
237}; 206};
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig
index 0efdd2f1babe..eb661ccf2dab 100644
--- a/arch/powerpc/platforms/85xx/Kconfig
+++ b/arch/powerpc/platforms/85xx/Kconfig
@@ -23,12 +23,12 @@ config MPC85xx_CDS
23 help 23 help
24 This option enables support for the MPC85xx CDS board 24 This option enables support for the MPC85xx CDS board
25 25
26config MPC8568_MDS 26config MPC85xx_MDS
27 bool "Freescale MPC8568 MDS" 27 bool "Freescale MPC85xx MDS"
28 select DEFAULT_UIMAGE 28 select DEFAULT_UIMAGE
29# select QUICC_ENGINE 29# select QUICC_ENGINE
30 help 30 help
31 This option enables support for the MPC8568 MDS board 31 This option enables support for the MPC85xx MDS board
32 32
33endchoice 33endchoice
34 34
@@ -47,7 +47,7 @@ config MPC85xx
47 bool 47 bool
48 select PPC_UDBG_16550 48 select PPC_UDBG_16550
49 select PPC_INDIRECT_PCI 49 select PPC_INDIRECT_PCI
50 default y if MPC8540_ADS || MPC85xx_CDS || MPC8560_ADS || MPC8568_MDS 50 default y if MPC8540_ADS || MPC85xx_CDS || MPC8560_ADS || MPC85xx_MDS
51 51
52config PPC_INDIRECT_PCI_BE 52config PPC_INDIRECT_PCI_BE
53 bool 53 bool
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile
index e40e521816b8..4e63917ada9d 100644
--- a/arch/powerpc/platforms/85xx/Makefile
+++ b/arch/powerpc/platforms/85xx/Makefile
@@ -5,4 +5,4 @@ obj-$(CONFIG_PPC_85xx) += misc.o pci.o
5obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o 5obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o
6obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o 6obj-$(CONFIG_MPC8560_ADS) += mpc85xx_ads.o
7obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o 7obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o
8obj-$(CONFIG_MPC8568_MDS) += mpc8568_mds.o 8obj-$(CONFIG_MPC85xx_MDS) += mpc85xx_mds.o
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_ads.c b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
index c56fce57621c..8ed034aeca5f 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_ads.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_ads.c
@@ -17,7 +17,6 @@
17#include <linux/kdev_t.h> 17#include <linux/kdev_t.h>
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/seq_file.h> 19#include <linux/seq_file.h>
20#include <linux/root_dev.h>
21 20
22#include <asm/system.h> 21#include <asm/system.h>
23#include <asm/time.h> 22#include <asm/time.h>
@@ -245,12 +244,6 @@ static void __init mpc85xx_ads_setup_arch(void)
245 add_bridge(np); 244 add_bridge(np);
246 ppc_md.pci_exclude_device = mpc85xx_exclude_device; 245 ppc_md.pci_exclude_device = mpc85xx_exclude_device;
247#endif 246#endif
248
249#ifdef CONFIG_ROOT_NFS
250 ROOT_DEV = Root_NFS;
251#else
252 ROOT_DEV = Root_HDA1;
253#endif
254} 247}
255 248
256static void mpc85xx_ads_show_cpuinfo(struct seq_file *m) 249static void mpc85xx_ads_show_cpuinfo(struct seq_file *m)
@@ -279,10 +272,9 @@ static void mpc85xx_ads_show_cpuinfo(struct seq_file *m)
279 */ 272 */
280static int __init mpc85xx_ads_probe(void) 273static int __init mpc85xx_ads_probe(void)
281{ 274{
282 /* We always match for now, eventually we should look at the flat 275 unsigned long root = of_get_flat_dt_root();
283 dev tree to ensure this is the board we are suppose to run on 276
284 */ 277 return of_flat_dt_is_compatible(root, "MPC85xxADS");
285 return 1;
286} 278}
287 279
288define_machine(mpc85xx_ads) { 280define_machine(mpc85xx_ads) {
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
index abc0aca6de40..4232686be441 100644
--- a/arch/powerpc/platforms/85xx/mpc85xx_cds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c
@@ -22,7 +22,6 @@
22#include <linux/console.h> 22#include <linux/console.h>
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/seq_file.h> 24#include <linux/seq_file.h>
25#include <linux/root_dev.h>
26#include <linux/initrd.h> 25#include <linux/initrd.h>
27#include <linux/module.h> 26#include <linux/module.h>
28#include <linux/fsl_devices.h> 27#include <linux/fsl_devices.h>
@@ -263,12 +262,6 @@ static void __init mpc85xx_cds_setup_arch(void)
263 ppc_md.pcibios_fixup = mpc85xx_cds_pcibios_fixup; 262 ppc_md.pcibios_fixup = mpc85xx_cds_pcibios_fixup;
264 ppc_md.pci_exclude_device = mpc85xx_exclude_device; 263 ppc_md.pci_exclude_device = mpc85xx_exclude_device;
265#endif 264#endif
266
267#ifdef CONFIG_ROOT_NFS
268 ROOT_DEV = Root_NFS;
269#else
270 ROOT_DEV = Root_HDA1;
271#endif
272} 265}
273 266
274static void mpc85xx_cds_show_cpuinfo(struct seq_file *m) 267static void mpc85xx_cds_show_cpuinfo(struct seq_file *m)
@@ -298,11 +291,9 @@ static void mpc85xx_cds_show_cpuinfo(struct seq_file *m)
298 */ 291 */
299static int __init mpc85xx_cds_probe(void) 292static int __init mpc85xx_cds_probe(void)
300{ 293{
301 /* We always match for now, eventually we should look at 294 unsigned long root = of_get_flat_dt_root();
302 * the flat dev tree to ensure this is the board we are 295
303 * supposed to run on 296 return of_flat_dt_is_compatible(root, "MPC85xxCDS");
304 */
305 return 1;
306} 297}
307 298
308define_machine(mpc85xx_cds) { 299define_machine(mpc85xx_cds) {
diff --git a/arch/powerpc/platforms/85xx/mpc8568_mds.c b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
index 0861d1107bc8..81144d2ae455 100644
--- a/arch/powerpc/platforms/85xx/mpc8568_mds.c
+++ b/arch/powerpc/platforms/85xx/mpc85xx_mds.c
@@ -8,7 +8,7 @@
8 * Yin Olivia <Hong-hua.Yin@freescale.com> 8 * Yin Olivia <Hong-hua.Yin@freescale.com>
9 * 9 *
10 * Description: 10 * Description:
11 * MPC8568E MDS PB board specific routines. 11 * MPC85xx MDS board specific routines.
12 * 12 *
13 * This program is free software; you can redistribute it and/or modify it 13 * This program is free software; you can redistribute it and/or modify it
14 * under the terms of the GNU General Public License as published by the 14 * under the terms of the GNU General Public License as published by the
@@ -27,7 +27,6 @@
27#include <linux/console.h> 27#include <linux/console.h>
28#include <linux/delay.h> 28#include <linux/delay.h>
29#include <linux/seq_file.h> 29#include <linux/seq_file.h>
30#include <linux/root_dev.h>
31#include <linux/initrd.h> 30#include <linux/initrd.h>
32#include <linux/module.h> 31#include <linux/module.h>
33#include <linux/fsl_devices.h> 32#include <linux/fsl_devices.h>
@@ -70,14 +69,13 @@ unsigned long isa_mem_base = 0;
70 * Setup the architecture 69 * Setup the architecture
71 * 70 *
72 */ 71 */
73static void __init mpc8568_mds_setup_arch(void) 72static void __init mpc85xx_mds_setup_arch(void)
74{ 73{
75 struct device_node *np; 74 struct device_node *np;
76 static u8 *bcsr_regs = NULL; 75 static u8 *bcsr_regs = NULL;
77 76
78
79 if (ppc_md.progress) 77 if (ppc_md.progress)
80 ppc_md.progress("mpc8568_mds_setup_arch()", 0); 78 ppc_md.progress("mpc85xx_mds_setup_arch()", 0);
81 79
82 np = of_find_node_by_type(NULL, "cpu"); 80 np = of_find_node_by_type(NULL, "cpu");
83 if (np != NULL) { 81 if (np != NULL) {
@@ -145,26 +143,26 @@ static void __init mpc8568_mds_setup_arch(void)
145#endif /* CONFIG_QUICC_ENGINE */ 143#endif /* CONFIG_QUICC_ENGINE */
146} 144}
147 145
148static struct of_device_id mpc8568_ids[] = { 146static struct of_device_id mpc85xx_ids[] = {
149 { .type = "soc", }, 147 { .type = "soc", },
150 { .compatible = "soc", }, 148 { .compatible = "soc", },
151 { .type = "qe", }, 149 { .type = "qe", },
152 {}, 150 {},
153}; 151};
154 152
155static int __init mpc8568_publish_devices(void) 153static int __init mpc85xx_publish_devices(void)
156{ 154{
157 if (!machine_is(mpc8568_mds)) 155 if (!machine_is(mpc85xx_mds))
158 return 0; 156 return 0;
159 157
160 /* Publish the QE devices */ 158 /* Publish the QE devices */
161 of_platform_bus_probe(NULL,mpc8568_ids,NULL); 159 of_platform_bus_probe(NULL,mpc85xx_ids,NULL);
162 160
163 return 0; 161 return 0;
164} 162}
165device_initcall(mpc8568_publish_devices); 163device_initcall(mpc85xx_publish_devices);
166 164
167static void __init mpc8568_mds_pic_init(void) 165static void __init mpc85xx_mds_pic_init(void)
168{ 166{
169 struct mpic *mpic; 167 struct mpic *mpic;
170 struct resource r; 168 struct resource r;
@@ -207,7 +205,6 @@ static void __init mpc8568_mds_pic_init(void)
207 205
208 mpic_init(mpic); 206 mpic_init(mpic);
209 207
210
211#ifdef CONFIG_QUICC_ENGINE 208#ifdef CONFIG_QUICC_ENGINE
212 np = of_find_node_by_type(NULL, "qeic"); 209 np = of_find_node_by_type(NULL, "qeic");
213 if (!np) 210 if (!np)
@@ -218,27 +215,18 @@ static void __init mpc8568_mds_pic_init(void)
218#endif /* CONFIG_QUICC_ENGINE */ 215#endif /* CONFIG_QUICC_ENGINE */
219} 216}
220 217
221 218static int __init mpc85xx_mds_probe(void)
222static int __init mpc8568_mds_probe(void)
223{ 219{
224 char *model = of_get_flat_dt_prop(of_get_flat_dt_root(), 220 unsigned long root = of_get_flat_dt_root();
225 "model", NULL);
226 if (model == NULL)
227 return 0;
228 if (strcmp(model, "MPC8568EMDS"))
229 return 0;
230
231 DBG("MPC8568EMDS found\n");
232 221
233 return 1; 222 return of_flat_dt_is_compatible(root, "MPC85xxMDS");
234} 223}
235 224
236 225define_machine(mpc85xx_mds) {
237define_machine(mpc8568_mds) { 226 .name = "MPC85xx MDS",
238 .name = "MPC8568E MDS", 227 .probe = mpc85xx_mds_probe,
239 .probe = mpc8568_mds_probe, 228 .setup_arch = mpc85xx_mds_setup_arch,
240 .setup_arch = mpc8568_mds_setup_arch, 229 .init_IRQ = mpc85xx_mds_pic_init,
241 .init_IRQ = mpc8568_mds_pic_init,
242 .get_irq = mpic_get_irq, 230 .get_irq = mpic_get_irq,
243 .restart = mpc85xx_restart, 231 .restart = mpc85xx_restart,
244 .calibrate_decr = generic_calibrate_decr, 232 .calibrate_decr = generic_calibrate_decr,
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
index f4dd5f2f8a28..f42f801cf84e 100644
--- a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
+++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c
@@ -18,7 +18,6 @@
18#include <linux/kdev_t.h> 18#include <linux/kdev_t.h>
19#include <linux/delay.h> 19#include <linux/delay.h>
20#include <linux/seq_file.h> 20#include <linux/seq_file.h>
21#include <linux/root_dev.h>
22 21
23#include <asm/system.h> 22#include <asm/system.h>
24#include <asm/time.h> 23#include <asm/time.h>
@@ -120,6 +119,8 @@ mpc86xx_hpcn_init_irq(void)
120 DBG("mpc86xxhpcn: cascade mapped to irq %d\n", cascade_irq); 119 DBG("mpc86xxhpcn: cascade mapped to irq %d\n", cascade_irq);
121 120
122 i8259_init(cascade_node, 0); 121 i8259_init(cascade_node, 0);
122 of_node_put(cascade_node);
123
123 set_irq_chained_handler(cascade_irq, mpc86xx_8259_cascade); 124 set_irq_chained_handler(cascade_irq, mpc86xx_8259_cascade);
124#endif 125#endif
125} 126}
@@ -365,12 +366,6 @@ mpc86xx_hpcn_setup_arch(void)
365 366
366 printk("MPC86xx HPCN board from Freescale Semiconductor\n"); 367 printk("MPC86xx HPCN board from Freescale Semiconductor\n");
367 368
368#ifdef CONFIG_ROOT_NFS
369 ROOT_DEV = Root_NFS;
370#else
371 ROOT_DEV = Root_HDA1;
372#endif
373
374#ifdef CONFIG_SMP 369#ifdef CONFIG_SMP
375 mpc86xx_smp_init(); 370 mpc86xx_smp_init();
376#endif 371#endif
diff --git a/arch/powerpc/platforms/celleb/Makefile b/arch/powerpc/platforms/celleb/Makefile
index 3baf658ac543..f4f82520dc4f 100644
--- a/arch/powerpc/platforms/celleb/Makefile
+++ b/arch/powerpc/platforms/celleb/Makefile
@@ -1,9 +1,8 @@
1obj-y += interrupt.o iommu.o setup.o \ 1obj-y += interrupt.o iommu.o setup.o \
2 htab.o beat.o pci.o \ 2 htab.o beat.o pci.o \
3 scc_epci.o hvCall.o 3 scc_epci.o scc_uhc.o hvCall.o
4 4
5obj-$(CONFIG_SMP) += smp.o 5obj-$(CONFIG_SMP) += smp.o
6obj-$(CONFIG_PPC_UDBG_BEAT) += udbg_beat.o 6obj-$(CONFIG_PPC_UDBG_BEAT) += udbg_beat.o
7obj-$(CONFIG_USB) += scc_uhc.o
8obj-$(CONFIG_HAS_TXX9_SERIAL) += scc_sio.o 7obj-$(CONFIG_HAS_TXX9_SERIAL) += scc_sio.o
9obj-$(CONFIG_SPU_BASE) += spu_priv1.o 8obj-$(CONFIG_SPU_BASE) += spu_priv1.o
diff --git a/arch/powerpc/platforms/celleb/setup.c b/arch/powerpc/platforms/celleb/setup.c
index 1de63acfda87..5f4d0d933238 100644
--- a/arch/powerpc/platforms/celleb/setup.c
+++ b/arch/powerpc/platforms/celleb/setup.c
@@ -137,10 +137,12 @@ static int celleb_check_legacy_ioport(unsigned int baseport)
137 return -ENODEV; 137 return -ENODEV;
138} 138}
139 139
140#ifdef CONFIG_KEXEC
140static void celleb_kexec_cpu_down(int crash, int secondary) 141static void celleb_kexec_cpu_down(int crash, int secondary)
141{ 142{
142 beatic_deinit_IRQ(); 143 beatic_deinit_IRQ();
143} 144}
145#endif
144 146
145static struct of_device_id celleb_bus_ids[] = { 147static struct of_device_id celleb_bus_ids[] = {
146 { .type = "scc", }, 148 { .type = "scc", },
diff --git a/arch/powerpc/platforms/ps3/Kconfig b/arch/powerpc/platforms/ps3/Kconfig
index 4be3943d1c0d..d270a1e374d5 100644
--- a/arch/powerpc/platforms/ps3/Kconfig
+++ b/arch/powerpc/platforms/ps3/Kconfig
@@ -62,4 +62,14 @@ config PS3_PS3AV
62 This support is required for graphics and sound. In 62 This support is required for graphics and sound. In
63 general, all users will say Y or M. 63 general, all users will say Y or M.
64 64
65config PS3_SYS_MANAGER
66 bool "PS3 System Manager driver"
67 select PS3_VUART
68 default y
69 help
70 Include support for the PS3 System Manager.
71
72 This support is required for system control. In
73 general, all users will say Y.
74
65endmenu 75endmenu
diff --git a/arch/powerpc/platforms/ps3/setup.c b/arch/powerpc/platforms/ps3/setup.c
index 13d669a8ecae..ac5df9688dcb 100644
--- a/arch/powerpc/platforms/ps3/setup.c
+++ b/arch/powerpc/platforms/ps3/setup.c
@@ -42,6 +42,10 @@
42#define DBG(fmt...) do{if(0)printk(fmt);}while(0) 42#define DBG(fmt...) do{if(0)printk(fmt);}while(0)
43#endif 43#endif
44 44
45#if !defined(CONFIG_SMP)
46static void smp_send_stop(void) {}
47#endif
48
45int ps3_get_firmware_version(union ps3_firmware_version *v) 49int ps3_get_firmware_version(union ps3_firmware_version *v)
46{ 50{
47 int result = lv1_get_version_info(&v->raw); 51 int result = lv1_get_version_info(&v->raw);
@@ -66,22 +70,35 @@ static void ps3_power_save(void)
66 lv1_pause(0); 70 lv1_pause(0);
67} 71}
68 72
73static void ps3_restart(char *cmd)
74{
75 DBG("%s:%d cmd '%s'\n", __func__, __LINE__, cmd);
76
77 smp_send_stop();
78 ps3_sys_manager_restart(); /* never returns */
79}
80
81static void ps3_power_off(void)
82{
83 DBG("%s:%d\n", __func__, __LINE__);
84
85 smp_send_stop();
86 ps3_sys_manager_power_off(); /* never returns */
87}
88
69static void ps3_panic(char *str) 89static void ps3_panic(char *str)
70{ 90{
71 DBG("%s:%d %s\n", __func__, __LINE__, str); 91 DBG("%s:%d %s\n", __func__, __LINE__, str);
72 92
73#ifdef CONFIG_SMP
74 smp_send_stop(); 93 smp_send_stop();
75#endif
76 printk("\n"); 94 printk("\n");
77 printk(" System does not reboot automatically.\n"); 95 printk(" System does not reboot automatically.\n");
78 printk(" Please press POWER button.\n"); 96 printk(" Please press POWER button.\n");
79 printk("\n"); 97 printk("\n");
80 98
81 for (;;) ; 99 while(1);
82} 100}
83 101
84
85static void prealloc(struct ps3_prealloc *p) 102static void prealloc(struct ps3_prealloc *p)
86{ 103{
87 if (!p->size) 104 if (!p->size)
@@ -219,6 +236,8 @@ define_machine(ps3) {
219 .get_rtc_time = ps3_get_rtc_time, 236 .get_rtc_time = ps3_get_rtc_time,
220 .calibrate_decr = ps3_calibrate_decr, 237 .calibrate_decr = ps3_calibrate_decr,
221 .progress = ps3_progress, 238 .progress = ps3_progress,
239 .restart = ps3_restart,
240 .power_off = ps3_power_off,
222#if defined(CONFIG_KEXEC) 241#if defined(CONFIG_KEXEC)
223 .kexec_cpu_down = ps3_kexec_cpu_down, 242 .kexec_cpu_down = ps3_kexec_cpu_down,
224 .machine_kexec = ps3_machine_kexec, 243 .machine_kexec = ps3_machine_kexec,
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile
index dc0583bdbc63..2dfd05095a25 100644
--- a/arch/powerpc/platforms/pseries/Makefile
+++ b/arch/powerpc/platforms/pseries/Makefile
@@ -4,7 +4,7 @@ endif
4 4
5obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \ 5obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \
6 setup.o iommu.o ras.o rtasd.o pci_dlpar.o \ 6 setup.o iommu.o ras.o rtasd.o pci_dlpar.o \
7 firmware.o 7 firmware.o power.o
8obj-$(CONFIG_SMP) += smp.o 8obj-$(CONFIG_SMP) += smp.o
9obj-$(CONFIG_XICS) += xics.o 9obj-$(CONFIG_XICS) += xics.o
10obj-$(CONFIG_SCANLOG) += scanlog.o 10obj-$(CONFIG_SCANLOG) += scanlog.o
diff --git a/arch/powerpc/platforms/pseries/power.c b/arch/powerpc/platforms/pseries/power.c
new file mode 100644
index 000000000000..2624b71df73d
--- /dev/null
+++ b/arch/powerpc/platforms/pseries/power.c
@@ -0,0 +1,87 @@
1/*
2 * Interface for power-management for ppc64 compliant platform
3 *
4 * Manish Ahuja <mahuja@us.ibm.com>
5 *
6 * Feb 2007
7 *
8 * Copyright (C) 2007 IBM Corporation.
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; version 2 of the License.
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#include <linux/kobject.h>
25#include <linux/string.h>
26#include <linux/errno.h>
27#include <linux/init.h>
28
29unsigned long rtas_poweron_auto; /* default and normal state is 0 */
30
31static ssize_t auto_poweron_show(struct subsystem *subsys, char *buf)
32{
33 return sprintf(buf, "%lu\n", rtas_poweron_auto);
34}
35
36static ssize_t
37auto_poweron_store(struct subsystem *subsys, const char *buf, size_t n)
38{
39 int ret;
40 unsigned long ups_restart;
41 ret = sscanf(buf, "%lu", &ups_restart);
42
43 if ((ret == 1) && ((ups_restart == 1) || (ups_restart == 0))){
44 rtas_poweron_auto = ups_restart;
45 return n;
46 }
47 return -EINVAL;
48}
49
50static struct subsys_attribute auto_poweron_attr = {
51 .attr = {
52 .name = __stringify(auto_poweron),
53 .mode = 0644,
54 },
55 .show = auto_poweron_show,
56 .store = auto_poweron_store,
57};
58
59#ifndef CONFIG_PM
60decl_subsys(power,NULL,NULL);
61
62static struct attribute *g[] = {
63 &auto_poweron_attr.attr,
64 NULL,
65};
66
67static struct attribute_group attr_group = {
68 .attrs = g,
69};
70
71static int __init pm_init(void)
72{
73 int error = subsystem_register(&power_subsys);
74 if (!error)
75 error = sysfs_create_group(&power_subsys.kset.kobj,&attr_group);
76 return error;
77}
78core_initcall(pm_init);
79#else
80extern struct subsystem power_subsys;
81
82static int __init apo_pm_init(void)
83{
84 return (subsys_create_file(&power_subsys, &auto_poweron_attr));
85}
86__initcall(apo_pm_init);
87#endif
diff --git a/arch/powerpc/platforms/pseries/pseries.h b/arch/powerpc/platforms/pseries/pseries.h
index b43f1397a5b6..22bc01989749 100644
--- a/arch/powerpc/platforms/pseries/pseries.h
+++ b/arch/powerpc/platforms/pseries/pseries.h
@@ -29,8 +29,11 @@ static inline smp_init_pseries_xics(void) { };
29extern void setup_kexec_cpu_down_xics(void); 29extern void setup_kexec_cpu_down_xics(void);
30extern void setup_kexec_cpu_down_mpic(void); 30extern void setup_kexec_cpu_down_mpic(void);
31#else 31#else
32static inline setup_kexec_cpu_down_xics(void) { }; 32static inline void setup_kexec_cpu_down_xics(void) { }
33static inline setup_kexec_cpu_down_mpic(void) { }; 33static inline void setup_kexec_cpu_down_mpic(void) { }
34#endif 34#endif
35 35
36/* Poweron flag used for enabling auto ups restart */
37extern unsigned long rtas_poweron_auto;
38
36#endif /* _PSERIES_PSERIES_H */ 39#endif /* _PSERIES_PSERIES_H */
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c
index 435a04596526..34aff47b1f55 100644
--- a/arch/powerpc/platforms/pseries/setup.c
+++ b/arch/powerpc/platforms/pseries/setup.c
@@ -486,6 +486,34 @@ static int pSeries_pci_probe_mode(struct pci_bus *bus)
486 return PCI_PROBE_NORMAL; 486 return PCI_PROBE_NORMAL;
487} 487}
488 488
489/**
490 * pSeries_power_off - tell firmware about how to power off the system.
491 *
492 * This function calls either the power-off rtas token in normal cases
493 * or the ibm,power-off-ups token (if present & requested) in case of
494 * a power failure. If power-off token is used, power on will only be
495 * possible with power button press. If ibm,power-off-ups token is used
496 * it will allow auto poweron after power is restored.
497 */
498void pSeries_power_off(void)
499{
500 int rc;
501 int rtas_poweroff_ups_token = rtas_token("ibm,power-off-ups");
502
503 if (rtas_flash_term_hook)
504 rtas_flash_term_hook(SYS_POWER_OFF);
505
506 if (rtas_poweron_auto == 0 ||
507 rtas_poweroff_ups_token == RTAS_UNKNOWN_SERVICE) {
508 rc = rtas_call(rtas_token("power-off"), 2, 1, NULL, -1, -1);
509 printk(KERN_INFO "RTAS power-off returned %d\n", rc);
510 } else {
511 rc = rtas_call(rtas_poweroff_ups_token, 0, 1, NULL);
512 printk(KERN_INFO "RTAS ibm,power-off-ups returned %d\n", rc);
513 }
514 for (;;);
515}
516
489define_machine(pseries) { 517define_machine(pseries) {
490 .name = "pSeries", 518 .name = "pSeries",
491 .probe = pSeries_probe, 519 .probe = pSeries_probe,
@@ -496,7 +524,7 @@ define_machine(pseries) {
496 .pcibios_fixup = pSeries_final_fixup, 524 .pcibios_fixup = pSeries_final_fixup,
497 .pci_probe_mode = pSeries_pci_probe_mode, 525 .pci_probe_mode = pSeries_pci_probe_mode,
498 .restart = rtas_restart, 526 .restart = rtas_restart,
499 .power_off = rtas_power_off, 527 .power_off = pSeries_power_off,
500 .halt = rtas_halt, 528 .halt = rtas_halt,
501 .panic = rtas_os_term, 529 .panic = rtas_os_term,
502 .get_boot_time = rtas_get_boot_time, 530 .get_boot_time = rtas_get_boot_time,
diff --git a/arch/powerpc/sysdev/Makefile b/arch/powerpc/sysdev/Makefile
index 85dcdf178415..26ca3ffbc1de 100644
--- a/arch/powerpc/sysdev/Makefile
+++ b/arch/powerpc/sysdev/Makefile
@@ -7,6 +7,7 @@ obj-$(CONFIG_PPC_INDIRECT_PCI) += indirect_pci.o
7obj-$(CONFIG_PPC_MPC106) += grackle.o 7obj-$(CONFIG_PPC_MPC106) += grackle.o
8obj-$(CONFIG_PPC_DCR) += dcr.o 8obj-$(CONFIG_PPC_DCR) += dcr.o
9obj-$(CONFIG_PPC_DCR_NATIVE) += dcr-low.o 9obj-$(CONFIG_PPC_DCR_NATIVE) += dcr-low.o
10obj-$(CONFIG_PPC_PMI) += pmi.o
10obj-$(CONFIG_U3_DART) += dart_iommu.o 11obj-$(CONFIG_U3_DART) += dart_iommu.o
11obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o 12obj-$(CONFIG_MMIO_NVRAM) += mmio_nvram.o
12obj-$(CONFIG_FSL_SOC) += fsl_soc.o 13obj-$(CONFIG_FSL_SOC) += fsl_soc.o
diff --git a/arch/powerpc/sysdev/fsl_soc.c b/arch/powerpc/sysdev/fsl_soc.c
index 34161bc5a02f..d20f02927f72 100644
--- a/arch/powerpc/sysdev/fsl_soc.c
+++ b/arch/powerpc/sysdev/fsl_soc.c
@@ -233,14 +233,7 @@ static int __init gfar_of_init(void)
233 goto err; 233 goto err;
234 } 234 }
235 235
236 mac_addr = get_property(np, "local-mac-address", NULL); 236 mac_addr = of_get_mac_address(np);
237 if (mac_addr == NULL)
238 mac_addr = get_property(np, "mac-address", NULL);
239 if (mac_addr == NULL) {
240 /* Obsolete */
241 mac_addr = get_property(np, "address", NULL);
242 }
243
244 if (mac_addr) 237 if (mac_addr)
245 memcpy(gfar_data.mac_addr, mac_addr, 6); 238 memcpy(gfar_data.mac_addr, mac_addr, 6);
246 239
@@ -646,8 +639,9 @@ static int __init fs_enet_of_init(void)
646 goto unreg; 639 goto unreg;
647 } 640 }
648 641
649 mac_addr = get_property(np, "mac-address", NULL); 642 mac_addr = of_get_mac_address(np);
650 memcpy(fs_enet_data.macaddr, mac_addr, 6); 643 if (mac_addr)
644 memcpy(fs_enet_data.macaddr, mac_addr, 6);
651 645
652 ph = get_property(np, "phy-handle", NULL); 646 ph = get_property(np, "phy-handle", NULL);
653 phy = of_find_node_by_phandle(*ph); 647 phy = of_find_node_by_phandle(*ph);
@@ -931,8 +925,9 @@ static int __init fs_enet_of_init(void)
931 goto err; 925 goto err;
932 r[0].name = enet_regs; 926 r[0].name = enet_regs;
933 927
934 mac_addr = (void *)get_property(np, "mac-address", NULL); 928 mac_addr = of_get_mac_address(np);
935 memcpy(fs_enet_data.macaddr, mac_addr, 6); 929 if (mac_addr)
930 memcpy(fs_enet_data.macaddr, mac_addr, 6);
936 931
937 ph = (phandle *) get_property(np, "phy-handle", NULL); 932 ph = (phandle *) get_property(np, "phy-handle", NULL);
938 if (ph != NULL) 933 if (ph != NULL)
diff --git a/arch/powerpc/sysdev/mpic.c b/arch/powerpc/sysdev/mpic.c
index 4e54a09dd33b..bcfb900481f8 100644
--- a/arch/powerpc/sysdev/mpic.c
+++ b/arch/powerpc/sysdev/mpic.c
@@ -1370,7 +1370,7 @@ void mpic_request_ipis(void)
1370 printk(KERN_ERR "Failed to map IPI %d\n", i); 1370 printk(KERN_ERR "Failed to map IPI %d\n", i);
1371 break; 1371 break;
1372 } 1372 }
1373 request_irq(vipi, mpic_ipi_action, IRQF_DISABLED, 1373 request_irq(vipi, mpic_ipi_action, IRQF_DISABLED|IRQF_PERCPU,
1374 ipi_names[i], mpic); 1374 ipi_names[i], mpic);
1375 } 1375 }
1376} 1376}
diff --git a/arch/powerpc/sysdev/pmi.c b/arch/powerpc/sysdev/pmi.c
new file mode 100644
index 000000000000..a5282011d39e
--- /dev/null
+++ b/arch/powerpc/sysdev/pmi.c
@@ -0,0 +1,305 @@
1/*
2 * pmi driver
3 *
4 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
5 *
6 * PMI (Platform Management Interrupt) is a way to communicate
7 * with the BMC (Baseboard Management Controller) via interrupts.
8 * Unlike IPMI it is bidirectional and has a low latency.
9 *
10 * Author: Christian Krafft <krafft@de.ibm.com>
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 as published by
14 * the Free Software Foundation; either version 2, or (at your option)
15 * any later version.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 */
26
27#include <linux/interrupt.h>
28#include <linux/completion.h>
29#include <linux/spinlock.h>
30#include <linux/workqueue.h>
31
32#include <asm/of_device.h>
33#include <asm/of_platform.h>
34#include <asm/io.h>
35#include <asm/pmi.h>
36
37
38struct pmi_data {
39 struct list_head handler;
40 spinlock_t handler_spinlock;
41 spinlock_t pmi_spinlock;
42 struct mutex msg_mutex;
43 pmi_message_t msg;
44 struct completion *completion;
45 struct of_device *dev;
46 int irq;
47 u8 __iomem *pmi_reg;
48 struct work_struct work;
49};
50
51
52
53static void __iomem *of_iomap(struct device_node *np)
54{
55 struct resource res;
56
57 if (of_address_to_resource(np, 0, &res))
58 return NULL;
59
60 pr_debug("Resource start: 0x%lx\n", res.start);
61 pr_debug("Resource end: 0x%lx\n", res.end);
62
63 return ioremap(res.start, 1 + res.end - res.start);
64}
65
66
67static int pmi_irq_handler(int irq, void *dev_id)
68{
69 struct pmi_data *data;
70 u8 type;
71 int rc;
72
73 data = dev_id;
74
75 spin_lock(&data->pmi_spinlock);
76
77 type = ioread8(data->pmi_reg + PMI_READ_TYPE);
78 pr_debug("pmi: got message of type %d\n", type);
79
80 if (type & PMI_ACK && !data->completion) {
81 printk(KERN_WARNING "pmi: got unexpected ACK message.\n");
82 rc = -EIO;
83 goto unlock;
84 }
85
86 if (data->completion && !(type & PMI_ACK)) {
87 printk(KERN_WARNING "pmi: expected ACK, but got %d\n", type);
88 rc = -EIO;
89 goto unlock;
90 }
91
92 data->msg.type = type;
93 data->msg.data0 = ioread8(data->pmi_reg + PMI_READ_DATA0);
94 data->msg.data1 = ioread8(data->pmi_reg + PMI_READ_DATA1);
95 data->msg.data2 = ioread8(data->pmi_reg + PMI_READ_DATA2);
96 rc = 0;
97unlock:
98 spin_unlock(&data->pmi_spinlock);
99
100 if (rc == -EIO) {
101 rc = IRQ_HANDLED;
102 goto out;
103 }
104
105 if (data->msg.type & PMI_ACK) {
106 complete(data->completion);
107 rc = IRQ_HANDLED;
108 goto out;
109 }
110
111 schedule_work(&data->work);
112
113 rc = IRQ_HANDLED;
114out:
115 return rc;
116}
117
118
119static struct of_device_id pmi_match[] = {
120 { .type = "ibm,pmi", .name = "ibm,pmi" },
121 {},
122};
123
124MODULE_DEVICE_TABLE(of, pmi_match);
125
126static void pmi_notify_handlers(struct work_struct *work)
127{
128 struct pmi_data *data;
129 struct pmi_handler *handler;
130
131 data = container_of(work, struct pmi_data, work);
132
133 spin_lock(&data->handler_spinlock);
134 list_for_each_entry(handler, &data->handler, node) {
135 pr_debug(KERN_INFO "pmi: notifying handler %p\n", handler);
136 if (handler->type == data->msg.type)
137 handler->handle_pmi_message(data->dev, data->msg);
138 }
139 spin_unlock(&data->handler_spinlock);
140}
141
142static int pmi_of_probe(struct of_device *dev,
143 const struct of_device_id *match)
144{
145 struct device_node *np = dev->node;
146 struct pmi_data *data;
147 int rc;
148
149 data = kzalloc(sizeof(struct pmi_data), GFP_KERNEL);
150 if (!data) {
151 printk(KERN_ERR "pmi: could not allocate memory.\n");
152 rc = -ENOMEM;
153 goto out;
154 }
155
156 data->pmi_reg = of_iomap(np);
157 if (!data->pmi_reg) {
158 printk(KERN_ERR "pmi: invalid register address.\n");
159 rc = -EFAULT;
160 goto error_cleanup_data;
161 }
162
163 INIT_LIST_HEAD(&data->handler);
164
165 mutex_init(&data->msg_mutex);
166 spin_lock_init(&data->pmi_spinlock);
167 spin_lock_init(&data->handler_spinlock);
168
169 INIT_WORK(&data->work, pmi_notify_handlers);
170
171 dev->dev.driver_data = data;
172 data->dev = dev;
173
174 data->irq = irq_of_parse_and_map(np, 0);
175 if (data->irq == NO_IRQ) {
176 printk(KERN_ERR "pmi: invalid interrupt.\n");
177 rc = -EFAULT;
178 goto error_cleanup_iomap;
179 }
180
181 rc = request_irq(data->irq, pmi_irq_handler, 0, "pmi", data);
182 if (rc) {
183 printk(KERN_ERR "pmi: can't request IRQ %d: returned %d\n",
184 data->irq, rc);
185 goto error_cleanup_iomap;
186 }
187
188 printk(KERN_INFO "pmi: found pmi device at addr %p.\n", data->pmi_reg);
189
190 goto out;
191
192error_cleanup_iomap:
193 iounmap(data->pmi_reg);
194
195error_cleanup_data:
196 kfree(data);
197
198out:
199 return rc;
200}
201
202static int pmi_of_remove(struct of_device *dev)
203{
204 struct pmi_data *data;
205 struct pmi_handler *handler, *tmp;
206
207 data = dev->dev.driver_data;
208
209 free_irq(data->irq, data);
210 iounmap(data->pmi_reg);
211
212 spin_lock(&data->handler_spinlock);
213
214 list_for_each_entry_safe(handler, tmp, &data->handler, node)
215 list_del(&handler->node);
216
217 spin_unlock(&data->handler_spinlock);
218
219 kfree(dev->dev.driver_data);
220
221 return 0;
222}
223
224static struct of_platform_driver pmi_of_platform_driver = {
225 .name = "pmi",
226 .match_table = pmi_match,
227 .probe = pmi_of_probe,
228 .remove = pmi_of_remove
229};
230
231static int __init pmi_module_init(void)
232{
233 return of_register_platform_driver(&pmi_of_platform_driver);
234}
235module_init(pmi_module_init);
236
237static void __exit pmi_module_exit(void)
238{
239 of_unregister_platform_driver(&pmi_of_platform_driver);
240}
241module_exit(pmi_module_exit);
242
243void pmi_send_message(struct of_device *device, pmi_message_t msg)
244{
245 struct pmi_data *data;
246 unsigned long flags;
247 DECLARE_COMPLETION_ONSTACK(completion);
248
249 data = device->dev.driver_data;
250
251 mutex_lock(&data->msg_mutex);
252
253 data->msg = msg;
254 pr_debug("pmi_send_message: msg is %08x\n", *(u32*)&msg);
255
256 data->completion = &completion;
257
258 spin_lock_irqsave(&data->pmi_spinlock, flags);
259 iowrite8(msg.data0, data->pmi_reg + PMI_WRITE_DATA0);
260 iowrite8(msg.data1, data->pmi_reg + PMI_WRITE_DATA1);
261 iowrite8(msg.data2, data->pmi_reg + PMI_WRITE_DATA2);
262 iowrite8(msg.type, data->pmi_reg + PMI_WRITE_TYPE);
263 spin_unlock_irqrestore(&data->pmi_spinlock, flags);
264
265 pr_debug("pmi_send_message: wait for completion\n");
266
267 wait_for_completion_interruptible_timeout(data->completion,
268 PMI_TIMEOUT);
269
270 data->completion = NULL;
271
272 mutex_unlock(&data->msg_mutex);
273}
274EXPORT_SYMBOL_GPL(pmi_send_message);
275
276void pmi_register_handler(struct of_device *device,
277 struct pmi_handler *handler)
278{
279 struct pmi_data *data;
280 data = device->dev.driver_data;
281
282 spin_lock(&data->handler_spinlock);
283 list_add_tail(&handler->node, &data->handler);
284 spin_unlock(&data->handler_spinlock);
285}
286EXPORT_SYMBOL_GPL(pmi_register_handler);
287
288void pmi_unregister_handler(struct of_device *device,
289 struct pmi_handler *handler)
290{
291 struct pmi_data *data;
292
293 pr_debug("pmi: unregistering handler %p\n", handler);
294
295 data = device->dev.driver_data;
296
297 spin_lock(&data->handler_spinlock);
298 list_del(&handler->node);
299 spin_unlock(&data->handler_spinlock);
300}
301EXPORT_SYMBOL_GPL(pmi_unregister_handler);
302
303MODULE_LICENSE("GPL");
304MODULE_AUTHOR("Christian Krafft <krafft@de.ibm.com>");
305MODULE_DESCRIPTION("IBM Platform Management Interrupt driver");
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_fast.c b/arch/powerpc/sysdev/qe_lib/ucc_fast.c
index e657559bea93..a457ac1c6639 100644
--- a/arch/powerpc/sysdev/qe_lib/ucc_fast.c
+++ b/arch/powerpc/sysdev/qe_lib/ucc_fast.c
@@ -1,13 +1,12 @@
1/* 1/*
2 * arch/powerpc/sysdev/qe_lib/ucc_fast.c
3 *
4 * QE UCC Fast API Set - UCC Fast specific routines implementations.
5 *
6 * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved. 2 * Copyright (C) 2006 Freescale Semicondutor, Inc. All rights reserved.
7 * 3 *
8 * Authors: Shlomi Gridish <gridish@freescale.com> 4 * Authors: Shlomi Gridish <gridish@freescale.com>
9 * Li Yang <leoli@freescale.com> 5 * Li Yang <leoli@freescale.com>
10 * 6 *
7 * Description:
8 * QE UCC Fast API Set - UCC Fast specific routines implementations.
9 *
11 * This program is free software; you can redistribute it and/or modify it 10 * This program is free software; you can redistribute it and/or modify it
12 * under the terms of the GNU General Public License as published by the 11 * under the terms of the GNU General Public License as published by the
13 * Free Software Foundation; either version 2 of the License, or (at your 12 * Free Software Foundation; either version 2 of the License, or (at your
@@ -27,79 +26,61 @@
27#include <asm/ucc.h> 26#include <asm/ucc.h>
28#include <asm/ucc_fast.h> 27#include <asm/ucc_fast.h>
29 28
30#define uccf_printk(level, format, arg...) \
31 printk(level format "\n", ## arg)
32
33#define uccf_dbg(format, arg...) \
34 uccf_printk(KERN_DEBUG , format , ## arg)
35#define uccf_err(format, arg...) \
36 uccf_printk(KERN_ERR , format , ## arg)
37#define uccf_info(format, arg...) \
38 uccf_printk(KERN_INFO , format , ## arg)
39#define uccf_warn(format, arg...) \
40 uccf_printk(KERN_WARNING , format , ## arg)
41
42#ifdef UCCF_VERBOSE_DEBUG
43#define uccf_vdbg uccf_dbg
44#else
45#define uccf_vdbg(fmt, args...) do { } while (0)
46#endif /* UCCF_VERBOSE_DEBUG */
47
48void ucc_fast_dump_regs(struct ucc_fast_private * uccf) 29void ucc_fast_dump_regs(struct ucc_fast_private * uccf)
49{ 30{
50 uccf_info("UCC%d Fast registers:", uccf->uf_info->ucc_num); 31 printk(KERN_INFO "UCC%d Fast registers:", uccf->uf_info->ucc_num);
51 uccf_info("Base address: 0x%08x", (u32) uccf->uf_regs); 32 printk(KERN_INFO "Base address: 0x%08x", (u32) uccf->uf_regs);
52 33
53 uccf_info("gumr : addr - 0x%08x, val - 0x%08x", 34 printk(KERN_INFO "gumr : addr - 0x%08x, val - 0x%08x",
54 (u32) & uccf->uf_regs->gumr, in_be32(&uccf->uf_regs->gumr)); 35 (u32) & uccf->uf_regs->gumr, in_be32(&uccf->uf_regs->gumr));
55 uccf_info("upsmr : addr - 0x%08x, val - 0x%08x", 36 printk(KERN_INFO "upsmr : addr - 0x%08x, val - 0x%08x",
56 (u32) & uccf->uf_regs->upsmr, in_be32(&uccf->uf_regs->upsmr)); 37 (u32) & uccf->uf_regs->upsmr, in_be32(&uccf->uf_regs->upsmr));
57 uccf_info("utodr : addr - 0x%08x, val - 0x%04x", 38 printk(KERN_INFO "utodr : addr - 0x%08x, val - 0x%04x",
58 (u32) & uccf->uf_regs->utodr, in_be16(&uccf->uf_regs->utodr)); 39 (u32) & uccf->uf_regs->utodr, in_be16(&uccf->uf_regs->utodr));
59 uccf_info("udsr : addr - 0x%08x, val - 0x%04x", 40 printk(KERN_INFO "udsr : addr - 0x%08x, val - 0x%04x",
60 (u32) & uccf->uf_regs->udsr, in_be16(&uccf->uf_regs->udsr)); 41 (u32) & uccf->uf_regs->udsr, in_be16(&uccf->uf_regs->udsr));
61 uccf_info("ucce : addr - 0x%08x, val - 0x%08x", 42 printk(KERN_INFO "ucce : addr - 0x%08x, val - 0x%08x",
62 (u32) & uccf->uf_regs->ucce, in_be32(&uccf->uf_regs->ucce)); 43 (u32) & uccf->uf_regs->ucce, in_be32(&uccf->uf_regs->ucce));
63 uccf_info("uccm : addr - 0x%08x, val - 0x%08x", 44 printk(KERN_INFO "uccm : addr - 0x%08x, val - 0x%08x",
64 (u32) & uccf->uf_regs->uccm, in_be32(&uccf->uf_regs->uccm)); 45 (u32) & uccf->uf_regs->uccm, in_be32(&uccf->uf_regs->uccm));
65 uccf_info("uccs : addr - 0x%08x, val - 0x%02x", 46 printk(KERN_INFO "uccs : addr - 0x%08x, val - 0x%02x",
66 (u32) & uccf->uf_regs->uccs, uccf->uf_regs->uccs); 47 (u32) & uccf->uf_regs->uccs, uccf->uf_regs->uccs);
67 uccf_info("urfb : addr - 0x%08x, val - 0x%08x", 48 printk(KERN_INFO "urfb : addr - 0x%08x, val - 0x%08x",
68 (u32) & uccf->uf_regs->urfb, in_be32(&uccf->uf_regs->urfb)); 49 (u32) & uccf->uf_regs->urfb, in_be32(&uccf->uf_regs->urfb));
69 uccf_info("urfs : addr - 0x%08x, val - 0x%04x", 50 printk(KERN_INFO "urfs : addr - 0x%08x, val - 0x%04x",
70 (u32) & uccf->uf_regs->urfs, in_be16(&uccf->uf_regs->urfs)); 51 (u32) & uccf->uf_regs->urfs, in_be16(&uccf->uf_regs->urfs));
71 uccf_info("urfet : addr - 0x%08x, val - 0x%04x", 52 printk(KERN_INFO "urfet : addr - 0x%08x, val - 0x%04x",
72 (u32) & uccf->uf_regs->urfet, in_be16(&uccf->uf_regs->urfet)); 53 (u32) & uccf->uf_regs->urfet, in_be16(&uccf->uf_regs->urfet));
73 uccf_info("urfset: addr - 0x%08x, val - 0x%04x", 54 printk(KERN_INFO "urfset: addr - 0x%08x, val - 0x%04x",
74 (u32) & uccf->uf_regs->urfset, 55 (u32) & uccf->uf_regs->urfset,
75 in_be16(&uccf->uf_regs->urfset)); 56 in_be16(&uccf->uf_regs->urfset));
76 uccf_info("utfb : addr - 0x%08x, val - 0x%08x", 57 printk(KERN_INFO "utfb : addr - 0x%08x, val - 0x%08x",
77 (u32) & uccf->uf_regs->utfb, in_be32(&uccf->uf_regs->utfb)); 58 (u32) & uccf->uf_regs->utfb, in_be32(&uccf->uf_regs->utfb));
78 uccf_info("utfs : addr - 0x%08x, val - 0x%04x", 59 printk(KERN_INFO "utfs : addr - 0x%08x, val - 0x%04x",
79 (u32) & uccf->uf_regs->utfs, in_be16(&uccf->uf_regs->utfs)); 60 (u32) & uccf->uf_regs->utfs, in_be16(&uccf->uf_regs->utfs));
80 uccf_info("utfet : addr - 0x%08x, val - 0x%04x", 61 printk(KERN_INFO "utfet : addr - 0x%08x, val - 0x%04x",
81 (u32) & uccf->uf_regs->utfet, in_be16(&uccf->uf_regs->utfet)); 62 (u32) & uccf->uf_regs->utfet, in_be16(&uccf->uf_regs->utfet));
82 uccf_info("utftt : addr - 0x%08x, val - 0x%04x", 63 printk(KERN_INFO "utftt : addr - 0x%08x, val - 0x%04x",
83 (u32) & uccf->uf_regs->utftt, in_be16(&uccf->uf_regs->utftt)); 64 (u32) & uccf->uf_regs->utftt, in_be16(&uccf->uf_regs->utftt));
84 uccf_info("utpt : addr - 0x%08x, val - 0x%04x", 65 printk(KERN_INFO "utpt : addr - 0x%08x, val - 0x%04x",
85 (u32) & uccf->uf_regs->utpt, in_be16(&uccf->uf_regs->utpt)); 66 (u32) & uccf->uf_regs->utpt, in_be16(&uccf->uf_regs->utpt));
86 uccf_info("urtry : addr - 0x%08x, val - 0x%08x", 67 printk(KERN_INFO "urtry : addr - 0x%08x, val - 0x%08x",
87 (u32) & uccf->uf_regs->urtry, in_be32(&uccf->uf_regs->urtry)); 68 (u32) & uccf->uf_regs->urtry, in_be32(&uccf->uf_regs->urtry));
88 uccf_info("guemr : addr - 0x%08x, val - 0x%02x", 69 printk(KERN_INFO "guemr : addr - 0x%08x, val - 0x%02x",
89 (u32) & uccf->uf_regs->guemr, uccf->uf_regs->guemr); 70 (u32) & uccf->uf_regs->guemr, uccf->uf_regs->guemr);
90} 71}
91 72
92u32 ucc_fast_get_qe_cr_subblock(int uccf_num) 73u32 ucc_fast_get_qe_cr_subblock(int uccf_num)
93{ 74{
94 switch (uccf_num) { 75 switch (uccf_num) {
95 case 0: return QE_CR_SUBBLOCK_UCCFAST1; 76 case 0: return QE_CR_SUBBLOCK_UCCFAST1;
96 case 1: return QE_CR_SUBBLOCK_UCCFAST2; 77 case 1: return QE_CR_SUBBLOCK_UCCFAST2;
97 case 2: return QE_CR_SUBBLOCK_UCCFAST3; 78 case 2: return QE_CR_SUBBLOCK_UCCFAST3;
98 case 3: return QE_CR_SUBBLOCK_UCCFAST4; 79 case 3: return QE_CR_SUBBLOCK_UCCFAST4;
99 case 4: return QE_CR_SUBBLOCK_UCCFAST5; 80 case 4: return QE_CR_SUBBLOCK_UCCFAST5;
100 case 5: return QE_CR_SUBBLOCK_UCCFAST6; 81 case 5: return QE_CR_SUBBLOCK_UCCFAST6;
101 case 6: return QE_CR_SUBBLOCK_UCCFAST7; 82 case 6: return QE_CR_SUBBLOCK_UCCFAST7;
102 case 7: return QE_CR_SUBBLOCK_UCCFAST8; 83 case 7: return QE_CR_SUBBLOCK_UCCFAST8;
103 default: return QE_CR_SUBBLOCK_INVALID; 84 default: return QE_CR_SUBBLOCK_INVALID;
104 } 85 }
105} 86}
@@ -153,84 +134,72 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
153{ 134{
154 struct ucc_fast_private *uccf; 135 struct ucc_fast_private *uccf;
155 struct ucc_fast *uf_regs; 136 struct ucc_fast *uf_regs;
156 u32 gumr = 0; 137 u32 gumr;
157 int ret; 138 int ret;
158 139
159 uccf_vdbg("%s: IN", __FUNCTION__);
160
161 if (!uf_info) 140 if (!uf_info)
162 return -EINVAL; 141 return -EINVAL;
163 142
164 /* check if the UCC port number is in range. */ 143 /* check if the UCC port number is in range. */
165 if ((uf_info->ucc_num < 0) || (uf_info->ucc_num > UCC_MAX_NUM - 1)) { 144 if ((uf_info->ucc_num < 0) || (uf_info->ucc_num > UCC_MAX_NUM - 1)) {
166 uccf_err("ucc_fast_init: Illegal UCC number!"); 145 printk(KERN_ERR "%s: illegal UCC number", __FUNCTION__);
167 return -EINVAL; 146 return -EINVAL;
168 } 147 }
169 148
170 /* Check that 'max_rx_buf_length' is properly aligned (4). */ 149 /* Check that 'max_rx_buf_length' is properly aligned (4). */
171 if (uf_info->max_rx_buf_length & (UCC_FAST_MRBLR_ALIGNMENT - 1)) { 150 if (uf_info->max_rx_buf_length & (UCC_FAST_MRBLR_ALIGNMENT - 1)) {
172 uccf_err("ucc_fast_init: max_rx_buf_length not aligned."); 151 printk(KERN_ERR "%s: max_rx_buf_length not aligned", __FUNCTION__);
173 return -EINVAL; 152 return -EINVAL;
174 } 153 }
175 154
176 /* Validate Virtual Fifo register values */ 155 /* Validate Virtual Fifo register values */
177 if (uf_info->urfs < UCC_FAST_URFS_MIN_VAL) { 156 if (uf_info->urfs < UCC_FAST_URFS_MIN_VAL) {
178 uccf_err 157 printk(KERN_ERR "%s: urfs is too small", __FUNCTION__);
179 ("ucc_fast_init: Virtual Fifo register urfs too small.");
180 return -EINVAL; 158 return -EINVAL;
181 } 159 }
182 160
183 if (uf_info->urfs & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) { 161 if (uf_info->urfs & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
184 uccf_err 162 printk(KERN_ERR "%s: urfs is not aligned", __FUNCTION__);
185 ("ucc_fast_init: Virtual Fifo register urfs not aligned.");
186 return -EINVAL; 163 return -EINVAL;
187 } 164 }
188 165
189 if (uf_info->urfet & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) { 166 if (uf_info->urfet & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
190 uccf_err 167 printk(KERN_ERR "%s: urfet is not aligned.", __FUNCTION__);
191 ("ucc_fast_init: Virtual Fifo register urfet not aligned.");
192 return -EINVAL; 168 return -EINVAL;
193 } 169 }
194 170
195 if (uf_info->urfset & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) { 171 if (uf_info->urfset & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
196 uccf_err 172 printk(KERN_ERR "%s: urfset is not aligned", __FUNCTION__);
197 ("ucc_fast_init: Virtual Fifo register urfset not aligned.");
198 return -EINVAL; 173 return -EINVAL;
199 } 174 }
200 175
201 if (uf_info->utfs & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) { 176 if (uf_info->utfs & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
202 uccf_err 177 printk(KERN_ERR "%s: utfs is not aligned", __FUNCTION__);
203 ("ucc_fast_init: Virtual Fifo register utfs not aligned.");
204 return -EINVAL; 178 return -EINVAL;
205 } 179 }
206 180
207 if (uf_info->utfet & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) { 181 if (uf_info->utfet & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
208 uccf_err 182 printk(KERN_ERR "%s: utfet is not aligned", __FUNCTION__);
209 ("ucc_fast_init: Virtual Fifo register utfet not aligned.");
210 return -EINVAL; 183 return -EINVAL;
211 } 184 }
212 185
213 if (uf_info->utftt & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) { 186 if (uf_info->utftt & (UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT - 1)) {
214 uccf_err 187 printk(KERN_ERR "%s: utftt is not aligned", __FUNCTION__);
215 ("ucc_fast_init: Virtual Fifo register utftt not aligned.");
216 return -EINVAL; 188 return -EINVAL;
217 } 189 }
218 190
219 uccf = kzalloc(sizeof(struct ucc_fast_private), GFP_KERNEL); 191 uccf = kzalloc(sizeof(struct ucc_fast_private), GFP_KERNEL);
220 if (!uccf) { 192 if (!uccf) {
221 uccf_err 193 printk(KERN_ERR "%s: Cannot allocate private data", __FUNCTION__);
222 ("ucc_fast_init: No memory for UCC slow data structure!");
223 return -ENOMEM; 194 return -ENOMEM;
224 } 195 }
225 196
226 /* Fill fast UCC structure */ 197 /* Fill fast UCC structure */
227 uccf->uf_info = uf_info; 198 uccf->uf_info = uf_info;
228 /* Set the PHY base address */ 199 /* Set the PHY base address */
229 uccf->uf_regs = 200 uccf->uf_regs = ioremap(uf_info->regs, sizeof(struct ucc_fast));
230 (struct ucc_fast *) ioremap(uf_info->regs, sizeof(struct ucc_fast));
231 if (uccf->uf_regs == NULL) { 201 if (uccf->uf_regs == NULL) {
232 uccf_err 202 printk(KERN_ERR "%s: Cannot map UCC registers", __FUNCTION__);
233 ("ucc_fast_init: No memory map for UCC slow controller!");
234 return -ENOMEM; 203 return -ENOMEM;
235 } 204 }
236 205
@@ -249,7 +218,7 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
249 218
250 /* Init Guemr register */ 219 /* Init Guemr register */
251 if ((ret = ucc_init_guemr((struct ucc_common *) (uf_regs)))) { 220 if ((ret = ucc_init_guemr((struct ucc_common *) (uf_regs)))) {
252 uccf_err("ucc_fast_init: Could not init the guemr register."); 221 printk(KERN_ERR "%s: cannot init GUEMR", __FUNCTION__);
253 ucc_fast_free(uccf); 222 ucc_fast_free(uccf);
254 return ret; 223 return ret;
255 } 224 }
@@ -258,7 +227,7 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
258 if ((ret = ucc_set_type(uf_info->ucc_num, 227 if ((ret = ucc_set_type(uf_info->ucc_num,
259 (struct ucc_common *) (uf_regs), 228 (struct ucc_common *) (uf_regs),
260 UCC_SPEED_TYPE_FAST))) { 229 UCC_SPEED_TYPE_FAST))) {
261 uccf_err("ucc_fast_init: Could not set type to fast."); 230 printk(KERN_ERR "%s: cannot set UCC type", __FUNCTION__);
262 ucc_fast_free(uccf); 231 ucc_fast_free(uccf);
263 return ret; 232 return ret;
264 } 233 }
@@ -267,10 +236,9 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
267 236
268 /* Set GUMR */ 237 /* Set GUMR */
269 /* For more details see the hardware spec. */ 238 /* For more details see the hardware spec. */
270 /* gumr starts as zero. */ 239 gumr = uf_info->ttx_trx;
271 if (uf_info->tci) 240 if (uf_info->tci)
272 gumr |= UCC_FAST_GUMR_TCI; 241 gumr |= UCC_FAST_GUMR_TCI;
273 gumr |= uf_info->ttx_trx;
274 if (uf_info->cdp) 242 if (uf_info->cdp)
275 gumr |= UCC_FAST_GUMR_CDP; 243 gumr |= UCC_FAST_GUMR_CDP;
276 if (uf_info->ctsp) 244 if (uf_info->ctsp)
@@ -298,9 +266,7 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
298 uccf->ucc_fast_tx_virtual_fifo_base_offset = 266 uccf->ucc_fast_tx_virtual_fifo_base_offset =
299 qe_muram_alloc(uf_info->utfs, UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT); 267 qe_muram_alloc(uf_info->utfs, UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
300 if (IS_MURAM_ERR(uccf->ucc_fast_tx_virtual_fifo_base_offset)) { 268 if (IS_MURAM_ERR(uccf->ucc_fast_tx_virtual_fifo_base_offset)) {
301 uccf_err 269 printk(KERN_ERR "%s: cannot allocate MURAM for TX FIFO", __FUNCTION__);
302 ("ucc_fast_init: Can not allocate MURAM memory for "
303 "struct ucc_fastx_virtual_fifo_base_offset.");
304 uccf->ucc_fast_tx_virtual_fifo_base_offset = 0; 270 uccf->ucc_fast_tx_virtual_fifo_base_offset = 0;
305 ucc_fast_free(uccf); 271 ucc_fast_free(uccf);
306 return -ENOMEM; 272 return -ENOMEM;
@@ -308,14 +274,11 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
308 274
309 /* Allocate memory for Rx Virtual Fifo */ 275 /* Allocate memory for Rx Virtual Fifo */
310 uccf->ucc_fast_rx_virtual_fifo_base_offset = 276 uccf->ucc_fast_rx_virtual_fifo_base_offset =
311 qe_muram_alloc(uf_info->urfs + 277 qe_muram_alloc(uf_info->urfs +
312 (u32)
313 UCC_FAST_RECEIVE_VIRTUAL_FIFO_SIZE_FUDGE_FACTOR, 278 UCC_FAST_RECEIVE_VIRTUAL_FIFO_SIZE_FUDGE_FACTOR,
314 UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT); 279 UCC_FAST_VIRT_FIFO_REGS_ALIGNMENT);
315 if (IS_MURAM_ERR(uccf->ucc_fast_rx_virtual_fifo_base_offset)) { 280 if (IS_MURAM_ERR(uccf->ucc_fast_rx_virtual_fifo_base_offset)) {
316 uccf_err 281 printk(KERN_ERR "%s: cannot allocate MURAM for RX FIFO", __FUNCTION__);
317 ("ucc_fast_init: Can not allocate MURAM memory for "
318 "ucc_fast_rx_virtual_fifo_base_offset.");
319 uccf->ucc_fast_rx_virtual_fifo_base_offset = 0; 282 uccf->ucc_fast_rx_virtual_fifo_base_offset = 0;
320 ucc_fast_free(uccf); 283 ucc_fast_free(uccf);
321 return -ENOMEM; 284 return -ENOMEM;
@@ -342,26 +305,22 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
342 /* If NMSI (not Tsa), set Tx and Rx clock. */ 305 /* If NMSI (not Tsa), set Tx and Rx clock. */
343 if (!uf_info->tsa) { 306 if (!uf_info->tsa) {
344 /* Rx clock routing */ 307 /* Rx clock routing */
345 if (uf_info->rx_clock != QE_CLK_NONE) { 308 if ((uf_info->rx_clock != QE_CLK_NONE) &&
346 if (ucc_set_qe_mux_rxtx 309 ucc_set_qe_mux_rxtx(uf_info->ucc_num, uf_info->rx_clock,
347 (uf_info->ucc_num, uf_info->rx_clock, 310 COMM_DIR_RX)) {
348 COMM_DIR_RX)) { 311 printk(KERN_ERR "%s: illegal value for RX clock",
349 uccf_err 312 __FUNCTION__);
350 ("ucc_fast_init: Illegal value for parameter 'RxClock'."); 313 ucc_fast_free(uccf);
351 ucc_fast_free(uccf); 314 return -EINVAL;
352 return -EINVAL;
353 }
354 } 315 }
355 /* Tx clock routing */ 316 /* Tx clock routing */
356 if (uf_info->tx_clock != QE_CLK_NONE) { 317 if ((uf_info->tx_clock != QE_CLK_NONE) &&
357 if (ucc_set_qe_mux_rxtx 318 ucc_set_qe_mux_rxtx(uf_info->ucc_num, uf_info->tx_clock,
358 (uf_info->ucc_num, uf_info->tx_clock, 319 COMM_DIR_TX)) {
359 COMM_DIR_TX)) { 320 printk(KERN_ERR "%s: illegal value for TX clock",
360 uccf_err 321 __FUNCTION__);
361 ("ucc_fast_init: Illegal value for parameter 'TxClock'."); 322 ucc_fast_free(uccf);
362 ucc_fast_free(uccf); 323 return -EINVAL;
363 return -EINVAL;
364 }
365 } 324 }
366 } 325 }
367 326
@@ -370,9 +329,9 @@ int ucc_fast_init(struct ucc_fast_info * uf_info, struct ucc_fast_private ** ucc
370 329
371 /* First, clear anything pending at UCC level, 330 /* First, clear anything pending at UCC level,
372 * otherwise, old garbage may come through 331 * otherwise, old garbage may come through
373 * as soon as the dam is opened 332 * as soon as the dam is opened. */
374 * Writing '1' clears 333
375 */ 334 /* Writing '1' clears */
376 out_be32(&uf_regs->ucce, 0xffffffff); 335 out_be32(&uf_regs->ucce, 0xffffffff);
377 336
378 *uccf_ret = uccf; 337 *uccf_ret = uccf;
diff --git a/arch/powerpc/sysdev/qe_lib/ucc_slow.c b/arch/powerpc/sysdev/qe_lib/ucc_slow.c
index 0e97e5c94f8a..817df73ecf56 100644
--- a/arch/powerpc/sysdev/qe_lib/ucc_slow.c
+++ b/arch/powerpc/sysdev/qe_lib/ucc_slow.c
@@ -19,7 +19,6 @@
19#include <linux/stddef.h> 19#include <linux/stddef.h>
20#include <linux/interrupt.h> 20#include <linux/interrupt.h>
21 21
22#include <asm/irq.h>
23#include <asm/io.h> 22#include <asm/io.h>
24#include <asm/immap_qe.h> 23#include <asm/immap_qe.h>
25#include <asm/qe.h> 24#include <asm/qe.h>
@@ -27,24 +26,6 @@
27#include <asm/ucc.h> 26#include <asm/ucc.h>
28#include <asm/ucc_slow.h> 27#include <asm/ucc_slow.h>
29 28
30#define uccs_printk(level, format, arg...) \
31 printk(level format "\n", ## arg)
32
33#define uccs_dbg(format, arg...) \
34 uccs_printk(KERN_DEBUG , format , ## arg)
35#define uccs_err(format, arg...) \
36 uccs_printk(KERN_ERR , format , ## arg)
37#define uccs_info(format, arg...) \
38 uccs_printk(KERN_INFO , format , ## arg)
39#define uccs_warn(format, arg...) \
40 uccs_printk(KERN_WARNING , format , ## arg)
41
42#ifdef UCCS_VERBOSE_DEBUG
43#define uccs_vdbg uccs_dbg
44#else
45#define uccs_vdbg(fmt, args...) do { } while (0)
46#endif /* UCCS_VERBOSE_DEBUG */
47
48u32 ucc_slow_get_qe_cr_subblock(int uccs_num) 29u32 ucc_slow_get_qe_cr_subblock(int uccs_num)
49{ 30{
50 switch (uccs_num) { 31 switch (uccs_num) {
@@ -135,51 +116,53 @@ void ucc_slow_disable(struct ucc_slow_private * uccs, enum comm_dir mode)
135 116
136int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** uccs_ret) 117int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** uccs_ret)
137{ 118{
119 struct ucc_slow_private *uccs;
138 u32 i; 120 u32 i;
139 struct ucc_slow *us_regs; 121 struct ucc_slow *us_regs;
140 u32 gumr; 122 u32 gumr;
141 u8 function_code = 0; 123 struct qe_bd *bd;
142 u8 *bd;
143 struct ucc_slow_private *uccs;
144 u32 id; 124 u32 id;
145 u32 command; 125 u32 command;
146 int ret; 126 int ret = 0;
147
148 uccs_vdbg("%s: IN", __FUNCTION__);
149 127
150 if (!us_info) 128 if (!us_info)
151 return -EINVAL; 129 return -EINVAL;
152 130
153 /* check if the UCC port number is in range. */ 131 /* check if the UCC port number is in range. */
154 if ((us_info->ucc_num < 0) || (us_info->ucc_num > UCC_MAX_NUM - 1)) { 132 if ((us_info->ucc_num < 0) || (us_info->ucc_num > UCC_MAX_NUM - 1)) {
155 uccs_err("ucc_slow_init: Illegal UCC number!"); 133 printk(KERN_ERR "%s: illegal UCC number", __FUNCTION__);
156 return -EINVAL; 134 return -EINVAL;
157 } 135 }
158 136
159 /* 137 /*
160 * Set mrblr 138 * Set mrblr
161 * Check that 'max_rx_buf_length' is properly aligned (4), unless 139 * Check that 'max_rx_buf_length' is properly aligned (4), unless
162 * rfw is 1, meaning that QE accepts one byte at a time, unlike normal 140 * rfw is 1, meaning that QE accepts one byte at a time, unlike normal
163 * case when QE accepts 32 bits at a time. 141 * case when QE accepts 32 bits at a time.
164 */ 142 */
165 if ((!us_info->rfw) && 143 if ((!us_info->rfw) &&
166 (us_info->max_rx_buf_length & (UCC_SLOW_MRBLR_ALIGNMENT - 1))) { 144 (us_info->max_rx_buf_length & (UCC_SLOW_MRBLR_ALIGNMENT - 1))) {
167 uccs_err("max_rx_buf_length not aligned."); 145 printk(KERN_ERR "max_rx_buf_length not aligned.");
168 return -EINVAL; 146 return -EINVAL;
169 } 147 }
170 148
171 uccs = kzalloc(sizeof(struct ucc_slow_private), GFP_KERNEL); 149 uccs = kzalloc(sizeof(struct ucc_slow_private), GFP_KERNEL);
172 if (!uccs) { 150 if (!uccs) {
173 uccs_err 151 printk(KERN_ERR "%s: Cannot allocate private data", __FUNCTION__);
174 ("ucc_slow_init: No memory for UCC slow data structure!");
175 return -ENOMEM; 152 return -ENOMEM;
176 } 153 }
177 154
178 /* Fill slow UCC structure */ 155 /* Fill slow UCC structure */
179 uccs->us_info = us_info; 156 uccs->us_info = us_info;
157 /* Set the PHY base address */
158 uccs->us_regs = ioremap(us_info->regs, sizeof(struct ucc_slow));
159 if (uccs->us_regs == NULL) {
160 printk(KERN_ERR "%s: Cannot map UCC registers", __FUNCTION__);
161 return -ENOMEM;
162 }
163
180 uccs->saved_uccm = 0; 164 uccs->saved_uccm = 0;
181 uccs->p_rx_frame = 0; 165 uccs->p_rx_frame = 0;
182 uccs->us_regs = us_info->regs;
183 us_regs = uccs->us_regs; 166 us_regs = uccs->us_regs;
184 uccs->p_ucce = (u16 *) & (us_regs->ucce); 167 uccs->p_ucce = (u16 *) & (us_regs->ucce);
185 uccs->p_uccm = (u16 *) & (us_regs->uccm); 168 uccs->p_uccm = (u16 *) & (us_regs->uccm);
@@ -190,24 +173,22 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
190#endif /* STATISTICS */ 173#endif /* STATISTICS */
191 174
192 /* Get PRAM base */ 175 /* Get PRAM base */
193 uccs->us_pram_offset = qe_muram_alloc(UCC_SLOW_PRAM_SIZE, 176 uccs->us_pram_offset =
194 ALIGNMENT_OF_UCC_SLOW_PRAM); 177 qe_muram_alloc(UCC_SLOW_PRAM_SIZE, ALIGNMENT_OF_UCC_SLOW_PRAM);
195 if (IS_MURAM_ERR(uccs->us_pram_offset)) { 178 if (IS_MURAM_ERR(uccs->us_pram_offset)) {
196 uccs_err 179 printk(KERN_ERR "%s: cannot allocate MURAM for PRAM", __FUNCTION__);
197 ("ucc_slow_init: Can not allocate MURAM memory "
198 "for Slow UCC.");
199 ucc_slow_free(uccs); 180 ucc_slow_free(uccs);
200 return -ENOMEM; 181 return -ENOMEM;
201 } 182 }
202 id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num); 183 id = ucc_slow_get_qe_cr_subblock(us_info->ucc_num);
203 qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, id, QE_CR_PROTOCOL_UNSPECIFIED, 184 qe_issue_cmd(QE_ASSIGN_PAGE_TO_DEVICE, id, QE_CR_PROTOCOL_UNSPECIFIED,
204 (u32) uccs->us_pram_offset); 185 uccs->us_pram_offset);
205 186
206 uccs->us_pram = qe_muram_addr(uccs->us_pram_offset); 187 uccs->us_pram = qe_muram_addr(uccs->us_pram_offset);
207 188
208 /* Init Guemr register */ 189 /* Init Guemr register */
209 if ((ret = ucc_init_guemr((struct ucc_common *) (us_info->regs)))) { 190 if ((ret = ucc_init_guemr((struct ucc_common *) (us_info->regs)))) {
210 uccs_err("ucc_slow_init: Could not init the guemr register."); 191 printk(KERN_ERR "%s: cannot init GUEMR", __FUNCTION__);
211 ucc_slow_free(uccs); 192 ucc_slow_free(uccs);
212 return ret; 193 return ret;
213 } 194 }
@@ -216,7 +197,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
216 if ((ret = ucc_set_type(us_info->ucc_num, 197 if ((ret = ucc_set_type(us_info->ucc_num,
217 (struct ucc_common *) (us_info->regs), 198 (struct ucc_common *) (us_info->regs),
218 UCC_SPEED_TYPE_SLOW))) { 199 UCC_SPEED_TYPE_SLOW))) {
219 uccs_err("ucc_slow_init: Could not init the guemr register."); 200 printk(KERN_ERR "%s: cannot set UCC type", __FUNCTION__);
220 ucc_slow_free(uccs); 201 ucc_slow_free(uccs);
221 return ret; 202 return ret;
222 } 203 }
@@ -230,7 +211,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
230 qe_muram_alloc(us_info->rx_bd_ring_len * sizeof(struct qe_bd), 211 qe_muram_alloc(us_info->rx_bd_ring_len * sizeof(struct qe_bd),
231 QE_ALIGNMENT_OF_BD); 212 QE_ALIGNMENT_OF_BD);
232 if (IS_MURAM_ERR(uccs->rx_base_offset)) { 213 if (IS_MURAM_ERR(uccs->rx_base_offset)) {
233 uccs_err("ucc_slow_init: No memory for Rx BD's."); 214 printk(KERN_ERR "%s: cannot allocate RX BDs", __FUNCTION__);
234 uccs->rx_base_offset = 0; 215 uccs->rx_base_offset = 0;
235 ucc_slow_free(uccs); 216 ucc_slow_free(uccs);
236 return -ENOMEM; 217 return -ENOMEM;
@@ -240,7 +221,7 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
240 qe_muram_alloc(us_info->tx_bd_ring_len * sizeof(struct qe_bd), 221 qe_muram_alloc(us_info->tx_bd_ring_len * sizeof(struct qe_bd),
241 QE_ALIGNMENT_OF_BD); 222 QE_ALIGNMENT_OF_BD);
242 if (IS_MURAM_ERR(uccs->tx_base_offset)) { 223 if (IS_MURAM_ERR(uccs->tx_base_offset)) {
243 uccs_err("ucc_slow_init: No memory for Tx BD's."); 224 printk(KERN_ERR "%s: cannot allocate TX BDs", __FUNCTION__);
244 uccs->tx_base_offset = 0; 225 uccs->tx_base_offset = 0;
245 ucc_slow_free(uccs); 226 ucc_slow_free(uccs);
246 return -ENOMEM; 227 return -ENOMEM;
@@ -248,34 +229,33 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
248 229
249 /* Init Tx bds */ 230 /* Init Tx bds */
250 bd = uccs->confBd = uccs->tx_bd = qe_muram_addr(uccs->tx_base_offset); 231 bd = uccs->confBd = uccs->tx_bd = qe_muram_addr(uccs->tx_base_offset);
251 for (i = 0; i < us_info->tx_bd_ring_len; i++) { 232 for (i = 0; i < us_info->tx_bd_ring_len - 1; i++) {
252 /* clear bd buffer */ 233 /* clear bd buffer */
253 out_be32(&(((struct qe_bd *)bd)->buf), 0); 234 out_be32(&bd->buf, 0);
254 /* set bd status and length */ 235 /* set bd status and length */
255 out_be32((u32*)bd, 0); 236 out_be32((u32 *) bd, 0);
256 bd += sizeof(struct qe_bd); 237 bd++;
257 } 238 }
258 bd -= sizeof(struct qe_bd); 239 /* for last BD set Wrap bit */
259 /* set bd status and length */ 240 out_be32(&bd->buf, 0);
260 out_be32((u32*)bd, T_W); /* for last BD set Wrap bit */ 241 out_be32((u32 *) bd, cpu_to_be32(T_W));
261 242
262 /* Init Rx bds */ 243 /* Init Rx bds */
263 bd = uccs->rx_bd = qe_muram_addr(uccs->rx_base_offset); 244 bd = uccs->rx_bd = qe_muram_addr(uccs->rx_base_offset);
264 for (i = 0; i < us_info->rx_bd_ring_len; i++) { 245 for (i = 0; i < us_info->rx_bd_ring_len - 1; i++) {
265 /* set bd status and length */ 246 /* set bd status and length */
266 out_be32((u32*)bd, 0); 247 out_be32((u32*)bd, 0);
267 /* clear bd buffer */ 248 /* clear bd buffer */
268 out_be32(&(((struct qe_bd *)bd)->buf), 0); 249 out_be32(&bd->buf, 0);
269 bd += sizeof(struct qe_bd); 250 bd++;
270 } 251 }
271 bd -= sizeof(struct qe_bd); 252 /* for last BD set Wrap bit */
272 /* set bd status and length */ 253 out_be32((u32*)bd, cpu_to_be32(R_W));
273 out_be32((u32*)bd, R_W); /* for last BD set Wrap bit */ 254 out_be32(&bd->buf, 0);
274 255
275 /* Set GUMR (For more details see the hardware spec.). */ 256 /* Set GUMR (For more details see the hardware spec.). */
276 /* gumr_h */ 257 /* gumr_h */
277 gumr = 0; 258 gumr = us_info->tcrc;
278 gumr |= us_info->tcrc;
279 if (us_info->cdp) 259 if (us_info->cdp)
280 gumr |= UCC_SLOW_GUMR_H_CDP; 260 gumr |= UCC_SLOW_GUMR_H_CDP;
281 if (us_info->ctsp) 261 if (us_info->ctsp)
@@ -295,7 +275,8 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
295 out_be32(&us_regs->gumr_h, gumr); 275 out_be32(&us_regs->gumr_h, gumr);
296 276
297 /* gumr_l */ 277 /* gumr_l */
298 gumr = 0; 278 gumr = us_info->tdcr | us_info->rdcr | us_info->tenc | us_info->renc |
279 us_info->diag | us_info->mode;
299 if (us_info->tci) 280 if (us_info->tci)
300 gumr |= UCC_SLOW_GUMR_L_TCI; 281 gumr |= UCC_SLOW_GUMR_L_TCI;
301 if (us_info->rinv) 282 if (us_info->rinv)
@@ -304,23 +285,14 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
304 gumr |= UCC_SLOW_GUMR_L_TINV; 285 gumr |= UCC_SLOW_GUMR_L_TINV;
305 if (us_info->tend) 286 if (us_info->tend)
306 gumr |= UCC_SLOW_GUMR_L_TEND; 287 gumr |= UCC_SLOW_GUMR_L_TEND;
307 gumr |= us_info->tdcr;
308 gumr |= us_info->rdcr;
309 gumr |= us_info->tenc;
310 gumr |= us_info->renc;
311 gumr |= us_info->diag;
312 gumr |= us_info->mode;
313 out_be32(&us_regs->gumr_l, gumr); 288 out_be32(&us_regs->gumr_l, gumr);
314 289
315 /* Function code registers */ 290 /* Function code registers */
316 /* function_code has initial value 0 */
317 291
318 /* if the data is in cachable memory, the 'global' */ 292 /* if the data is in cachable memory, the 'global' */
319 /* in the function code should be set. */ 293 /* in the function code should be set. */
320 function_code |= us_info->data_mem_part; 294 uccs->us_pram->tfcr = uccs->us_pram->rfcr =
321 function_code |= QE_BMR_BYTE_ORDER_BO_MOT; /* Required for QE */ 295 us_info->data_mem_part | QE_BMR_BYTE_ORDER_BO_MOT;
322 uccs->us_pram->tfcr = function_code;
323 uccs->us_pram->rfcr = function_code;
324 296
325 /* rbase, tbase are offsets from MURAM base */ 297 /* rbase, tbase are offsets from MURAM base */
326 out_be16(&uccs->us_pram->rbase, uccs->us_pram_offset); 298 out_be16(&uccs->us_pram->rbase, uccs->us_pram_offset);
@@ -336,34 +308,29 @@ int ucc_slow_init(struct ucc_slow_info * us_info, struct ucc_slow_private ** ucc
336 /* If NMSI (not Tsa), set Tx and Rx clock. */ 308 /* If NMSI (not Tsa), set Tx and Rx clock. */
337 if (!us_info->tsa) { 309 if (!us_info->tsa) {
338 /* Rx clock routing */ 310 /* Rx clock routing */
339 if (ucc_set_qe_mux_rxtx 311 if (ucc_set_qe_mux_rxtx(us_info->ucc_num, us_info->rx_clock,
340 (us_info->ucc_num, us_info->rx_clock, COMM_DIR_RX)) { 312 COMM_DIR_RX)) {
341 uccs_err 313 printk(KERN_ERR "%s: illegal value for RX clock",
342 ("ucc_slow_init: Illegal value for parameter" 314 __FUNCTION__);
343 " 'RxClock'.");
344 ucc_slow_free(uccs); 315 ucc_slow_free(uccs);
345 return -EINVAL; 316 return -EINVAL;
346 } 317 }
347 /* Tx clock routing */ 318 /* Tx clock routing */
348 if (ucc_set_qe_mux_rxtx(us_info->ucc_num, 319 if (ucc_set_qe_mux_rxtx(us_info->ucc_num, us_info->tx_clock,
349 us_info->tx_clock, COMM_DIR_TX)) { 320 COMM_DIR_TX)) {
350 uccs_err 321 printk(KERN_ERR "%s: illegal value for TX clock",
351 ("ucc_slow_init: Illegal value for parameter " 322 __FUNCTION__);
352 "'TxClock'.");
353 ucc_slow_free(uccs); 323 ucc_slow_free(uccs);
354 return -EINVAL; 324 return -EINVAL;
355 } 325 }
356 } 326 }
357 327
358 /*
359 * INTERRUPTS
360 */
361 /* Set interrupt mask register at UCC level. */ 328 /* Set interrupt mask register at UCC level. */
362 out_be16(&us_regs->uccm, us_info->uccm_mask); 329 out_be16(&us_regs->uccm, us_info->uccm_mask);
363 330
364 /* First, clear anything pending at UCC level, */ 331 /* First, clear anything pending at UCC level,
365 /* otherwise, old garbage may come through */ 332 * otherwise, old garbage may come through
366 /* as soon as the dam is opened. */ 333 * as soon as the dam is opened. */
367 334
368 /* Writing '1' clears */ 335 /* Writing '1' clears */
369 out_be16(&us_regs->ucce, 0xffff); 336 out_be16(&us_regs->ucce, 0xffff);
@@ -400,3 +367,5 @@ void ucc_slow_free(struct ucc_slow_private * uccs)
400 367
401 kfree(uccs); 368 kfree(uccs);
402} 369}
370
371
diff --git a/arch/x86_64/kernel/early-quirks.c b/arch/x86_64/kernel/early-quirks.c
index bd30d138113f..8047ea8c2ab2 100644
--- a/arch/x86_64/kernel/early-quirks.c
+++ b/arch/x86_64/kernel/early-quirks.c
@@ -53,7 +53,9 @@ static void nvidia_bugs(void)
53 return; 53 return;
54 54
55 nvidia_hpet_detected = 0; 55 nvidia_hpet_detected = 0;
56 acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check); 56 if (acpi_table_parse(ACPI_SIG_HPET, nvidia_hpet_check))
57 return;
58
57 if (nvidia_hpet_detected == 0) { 59 if (nvidia_hpet_detected == 0) {
58 acpi_skip_timer_override = 1; 60 acpi_skip_timer_override = 1;
59 printk(KERN_INFO "Nvidia board " 61 printk(KERN_INFO "Nvidia board "
diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig
index 20eacc2c9e0e..e942ffe8b57e 100644
--- a/drivers/acpi/Kconfig
+++ b/drivers/acpi/Kconfig
@@ -13,6 +13,7 @@ config ACPI
13 depends on IA64 || X86 13 depends on IA64 || X86
14 depends on PCI 14 depends on PCI
15 depends on PM 15 depends on PM
16 select PNP
16 default y 17 default y
17 ---help--- 18 ---help---
18 Advanced Configuration and Power Interface (ACPI) support for 19 Advanced Configuration and Power Interface (ACPI) support for
@@ -132,15 +133,6 @@ config ACPI_VIDEO
132 Note that this is an ref. implementation only. It may or may not work 133 Note that this is an ref. implementation only. It may or may not work
133 for your integrated video device. 134 for your integrated video device.
134 135
135config ACPI_HOTKEY
136 tristate "Generic Hotkey (EXPERIMENTAL)"
137 depends on EXPERIMENTAL
138 depends on X86
139 default n
140 help
141 Experimental consolidated hotkey driver.
142 If you are unsure, say N.
143
144config ACPI_FAN 136config ACPI_FAN
145 tristate "Fan" 137 tristate "Fan"
146 default y 138 default y
diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 856c32bccacb..5956e9f64a8b 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -46,7 +46,6 @@ obj-$(CONFIG_ACPI_FAN) += fan.o
46obj-$(CONFIG_ACPI_DOCK) += dock.o 46obj-$(CONFIG_ACPI_DOCK) += dock.o
47obj-$(CONFIG_ACPI_BAY) += bay.o 47obj-$(CONFIG_ACPI_BAY) += bay.o
48obj-$(CONFIG_ACPI_VIDEO) += video.o 48obj-$(CONFIG_ACPI_VIDEO) += video.o
49obj-$(CONFIG_ACPI_HOTKEY) += hotkey.o
50obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o 49obj-y += pci_root.o pci_link.o pci_irq.o pci_bind.o
51obj-$(CONFIG_ACPI_POWER) += power.o 50obj-$(CONFIG_ACPI_POWER) += power.o
52obj-$(CONFIG_ACPI_PROCESSOR) += processor.o 51obj-$(CONFIG_ACPI_PROCESSOR) += processor.o
diff --git a/drivers/acpi/ac.c b/drivers/acpi/ac.c
index 6daeace796a8..37c7dc4f9fe5 100644
--- a/drivers/acpi/ac.c
+++ b/drivers/acpi/ac.c
@@ -35,7 +35,6 @@
35#define ACPI_AC_COMPONENT 0x00020000 35#define ACPI_AC_COMPONENT 0x00020000
36#define ACPI_AC_CLASS "ac_adapter" 36#define ACPI_AC_CLASS "ac_adapter"
37#define ACPI_AC_HID "ACPI0003" 37#define ACPI_AC_HID "ACPI0003"
38#define ACPI_AC_DRIVER_NAME "ACPI AC Adapter Driver"
39#define ACPI_AC_DEVICE_NAME "AC Adapter" 38#define ACPI_AC_DEVICE_NAME "AC Adapter"
40#define ACPI_AC_FILE_STATE "state" 39#define ACPI_AC_FILE_STATE "state"
41#define ACPI_AC_NOTIFY_STATUS 0x80 40#define ACPI_AC_NOTIFY_STATUS 0x80
@@ -44,10 +43,10 @@
44#define ACPI_AC_STATUS_UNKNOWN 0xFF 43#define ACPI_AC_STATUS_UNKNOWN 0xFF
45 44
46#define _COMPONENT ACPI_AC_COMPONENT 45#define _COMPONENT ACPI_AC_COMPONENT
47ACPI_MODULE_NAME("acpi_ac") 46ACPI_MODULE_NAME("ac");
48 47
49 MODULE_AUTHOR("Paul Diefenbaugh"); 48MODULE_AUTHOR("Paul Diefenbaugh");
50MODULE_DESCRIPTION(ACPI_AC_DRIVER_NAME); 49MODULE_DESCRIPTION("ACPI AC Adapter Driver");
51MODULE_LICENSE("GPL"); 50MODULE_LICENSE("GPL");
52 51
53extern struct proc_dir_entry *acpi_lock_ac_dir(void); 52extern struct proc_dir_entry *acpi_lock_ac_dir(void);
@@ -58,7 +57,7 @@ static int acpi_ac_remove(struct acpi_device *device, int type);
58static int acpi_ac_open_fs(struct inode *inode, struct file *file); 57static int acpi_ac_open_fs(struct inode *inode, struct file *file);
59 58
60static struct acpi_driver acpi_ac_driver = { 59static struct acpi_driver acpi_ac_driver = {
61 .name = ACPI_AC_DRIVER_NAME, 60 .name = "ac",
62 .class = ACPI_AC_CLASS, 61 .class = ACPI_AC_CLASS,
63 .ids = ACPI_AC_HID, 62 .ids = ACPI_AC_HID,
64 .ops = { 63 .ops = {
diff --git a/drivers/acpi/acpi_memhotplug.c b/drivers/acpi/acpi_memhotplug.c
index cd946ed192d3..c26172671fd8 100644
--- a/drivers/acpi/acpi_memhotplug.c
+++ b/drivers/acpi/acpi_memhotplug.c
@@ -35,14 +35,13 @@
35#define ACPI_MEMORY_DEVICE_COMPONENT 0x08000000UL 35#define ACPI_MEMORY_DEVICE_COMPONENT 0x08000000UL
36#define ACPI_MEMORY_DEVICE_CLASS "memory" 36#define ACPI_MEMORY_DEVICE_CLASS "memory"
37#define ACPI_MEMORY_DEVICE_HID "PNP0C80" 37#define ACPI_MEMORY_DEVICE_HID "PNP0C80"
38#define ACPI_MEMORY_DEVICE_DRIVER_NAME "Hotplug Mem Driver"
39#define ACPI_MEMORY_DEVICE_NAME "Hotplug Mem Device" 38#define ACPI_MEMORY_DEVICE_NAME "Hotplug Mem Device"
40 39
41#define _COMPONENT ACPI_MEMORY_DEVICE_COMPONENT 40#define _COMPONENT ACPI_MEMORY_DEVICE_COMPONENT
42 41
43ACPI_MODULE_NAME("acpi_memory") 42ACPI_MODULE_NAME("acpi_memhotplug");
44 MODULE_AUTHOR("Naveen B S <naveen.b.s@intel.com>"); 43MODULE_AUTHOR("Naveen B S <naveen.b.s@intel.com>");
45MODULE_DESCRIPTION(ACPI_MEMORY_DEVICE_DRIVER_NAME); 44MODULE_DESCRIPTION("Hotplug Mem Driver");
46MODULE_LICENSE("GPL"); 45MODULE_LICENSE("GPL");
47 46
48/* ACPI _STA method values */ 47/* ACPI _STA method values */
@@ -60,7 +59,7 @@ static int acpi_memory_device_remove(struct acpi_device *device, int type);
60static int acpi_memory_device_start(struct acpi_device *device); 59static int acpi_memory_device_start(struct acpi_device *device);
61 60
62static struct acpi_driver acpi_memory_device_driver = { 61static struct acpi_driver acpi_memory_device_driver = {
63 .name = ACPI_MEMORY_DEVICE_DRIVER_NAME, 62 .name = "acpi_memhotplug",
64 .class = ACPI_MEMORY_DEVICE_CLASS, 63 .class = ACPI_MEMORY_DEVICE_CLASS,
65 .ids = ACPI_MEMORY_DEVICE_HID, 64 .ids = ACPI_MEMORY_DEVICE_HID,
66 .ops = { 65 .ops = {
diff --git a/drivers/acpi/asus_acpi.c b/drivers/acpi/asus_acpi.c
index 31ad70a6e22e..772299fb5f9d 100644
--- a/drivers/acpi/asus_acpi.c
+++ b/drivers/acpi/asus_acpi.c
@@ -141,6 +141,7 @@ struct asus_hotk {
141 W5A, //W5A 141 W5A, //W5A
142 W3V, //W3030V 142 W3V, //W3030V
143 xxN, //M2400N, M3700N, M5200N, M6800N, S1300N, S5200N 143 xxN, //M2400N, M3700N, M5200N, M6800N, S1300N, S5200N
144 A4S, //Z81sp
144 //(Centrino) 145 //(Centrino)
145 END_MODEL 146 END_MODEL
146 } model; //Models currently supported 147 } model; //Models currently supported
@@ -397,7 +398,16 @@ static struct model_data model_conf[END_MODEL] = {
397 .brightness_set = "SPLV", 398 .brightness_set = "SPLV",
398 .brightness_get = "GPLV", 399 .brightness_get = "GPLV",
399 .display_set = "SDSP", 400 .display_set = "SDSP",
400 .display_get = "\\ADVG"} 401 .display_get = "\\ADVG"},
402
403 {
404 .name = "A4S",
405 .brightness_set = "SPLV",
406 .brightness_get = "GPLV",
407 .mt_bt_switch = "BLED",
408 .mt_wled = "WLED"
409 }
410
401}; 411};
402 412
403/* procdir we use */ 413/* procdir we use */
@@ -421,7 +431,7 @@ static struct asus_hotk *hotk;
421static int asus_hotk_add(struct acpi_device *device); 431static int asus_hotk_add(struct acpi_device *device);
422static int asus_hotk_remove(struct acpi_device *device, int type); 432static int asus_hotk_remove(struct acpi_device *device, int type);
423static struct acpi_driver asus_hotk_driver = { 433static struct acpi_driver asus_hotk_driver = {
424 .name = ACPI_HOTK_NAME, 434 .name = "asus_acpi",
425 .class = ACPI_HOTK_CLASS, 435 .class = ACPI_HOTK_CLASS,
426 .ids = ACPI_HOTK_HID, 436 .ids = ACPI_HOTK_HID,
427 .ops = { 437 .ops = {
@@ -1117,6 +1127,8 @@ static int asus_model_match(char *model)
1117 return W3V; 1127 return W3V;
1118 else if (strncmp(model, "W5A", 3) == 0) 1128 else if (strncmp(model, "W5A", 3) == 0)
1119 return W5A; 1129 return W5A;
1130 else if (strncmp(model, "A4S", 3) == 0)
1131 return A4S;
1120 else 1132 else
1121 return END_MODEL; 1133 return END_MODEL;
1122} 1134}
@@ -1365,10 +1377,6 @@ static int __init asus_acpi_init(void)
1365 if (acpi_disabled) 1377 if (acpi_disabled)
1366 return -ENODEV; 1378 return -ENODEV;
1367 1379
1368 if (!acpi_specific_hotkey_enabled) {
1369 printk(KERN_ERR "Using generic hotkey driver\n");
1370 return -ENODEV;
1371 }
1372 asus_proc_dir = proc_mkdir(PROC_ASUS, acpi_root_dir); 1380 asus_proc_dir = proc_mkdir(PROC_ASUS, acpi_root_dir);
1373 if (!asus_proc_dir) { 1381 if (!asus_proc_dir) {
1374 printk(KERN_ERR "Asus ACPI: Unable to create /proc entry\n"); 1382 printk(KERN_ERR "Asus ACPI: Unable to create /proc entry\n");
diff --git a/drivers/acpi/battery.c b/drivers/acpi/battery.c
index 2f4521a48fe7..e64c76c8b726 100644
--- a/drivers/acpi/battery.c
+++ b/drivers/acpi/battery.c
@@ -42,7 +42,6 @@
42#define ACPI_BATTERY_COMPONENT 0x00040000 42#define ACPI_BATTERY_COMPONENT 0x00040000
43#define ACPI_BATTERY_CLASS "battery" 43#define ACPI_BATTERY_CLASS "battery"
44#define ACPI_BATTERY_HID "PNP0C0A" 44#define ACPI_BATTERY_HID "PNP0C0A"
45#define ACPI_BATTERY_DRIVER_NAME "ACPI Battery Driver"
46#define ACPI_BATTERY_DEVICE_NAME "Battery" 45#define ACPI_BATTERY_DEVICE_NAME "Battery"
47#define ACPI_BATTERY_FILE_INFO "info" 46#define ACPI_BATTERY_FILE_INFO "info"
48#define ACPI_BATTERY_FILE_STATUS "state" 47#define ACPI_BATTERY_FILE_STATUS "state"
@@ -53,10 +52,10 @@
53#define ACPI_BATTERY_UNITS_AMPS "mA" 52#define ACPI_BATTERY_UNITS_AMPS "mA"
54 53
55#define _COMPONENT ACPI_BATTERY_COMPONENT 54#define _COMPONENT ACPI_BATTERY_COMPONENT
56ACPI_MODULE_NAME("acpi_battery") 55ACPI_MODULE_NAME("battery");
57 56
58 MODULE_AUTHOR("Paul Diefenbaugh"); 57MODULE_AUTHOR("Paul Diefenbaugh");
59MODULE_DESCRIPTION(ACPI_BATTERY_DRIVER_NAME); 58MODULE_DESCRIPTION("ACPI Battery Driver");
60MODULE_LICENSE("GPL"); 59MODULE_LICENSE("GPL");
61 60
62extern struct proc_dir_entry *acpi_lock_battery_dir(void); 61extern struct proc_dir_entry *acpi_lock_battery_dir(void);
@@ -67,7 +66,7 @@ static int acpi_battery_remove(struct acpi_device *device, int type);
67static int acpi_battery_resume(struct acpi_device *device); 66static int acpi_battery_resume(struct acpi_device *device);
68 67
69static struct acpi_driver acpi_battery_driver = { 68static struct acpi_driver acpi_battery_driver = {
70 .name = ACPI_BATTERY_DRIVER_NAME, 69 .name = "battery",
71 .class = ACPI_BATTERY_CLASS, 70 .class = ACPI_BATTERY_CLASS,
72 .ids = ACPI_BATTERY_HID, 71 .ids = ACPI_BATTERY_HID,
73 .ops = { 72 .ops = {
@@ -324,6 +323,13 @@ static int acpi_battery_check(struct acpi_battery *battery)
324 return result; 323 return result;
325} 324}
326 325
326static void acpi_battery_check_present(struct acpi_battery *battery)
327{
328 if (!battery->flags.present) {
329 acpi_battery_check(battery);
330 }
331}
332
327/* -------------------------------------------------------------------------- 333/* --------------------------------------------------------------------------
328 FS Interface (/proc) 334 FS Interface (/proc)
329 -------------------------------------------------------------------------- */ 335 -------------------------------------------------------------------------- */
@@ -340,6 +346,8 @@ static int acpi_battery_read_info(struct seq_file *seq, void *offset)
340 if (!battery) 346 if (!battery)
341 goto end; 347 goto end;
342 348
349 acpi_battery_check_present(battery);
350
343 if (battery->flags.present) 351 if (battery->flags.present)
344 seq_printf(seq, "present: yes\n"); 352 seq_printf(seq, "present: yes\n");
345 else { 353 else {
@@ -424,6 +432,8 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
424 if (!battery) 432 if (!battery)
425 goto end; 433 goto end;
426 434
435 acpi_battery_check_present(battery);
436
427 if (battery->flags.present) 437 if (battery->flags.present)
428 seq_printf(seq, "present: yes\n"); 438 seq_printf(seq, "present: yes\n");
429 else { 439 else {
@@ -499,6 +509,8 @@ static int acpi_battery_read_alarm(struct seq_file *seq, void *offset)
499 if (!battery) 509 if (!battery)
500 goto end; 510 goto end;
501 511
512 acpi_battery_check_present(battery);
513
502 if (!battery->flags.present) { 514 if (!battery->flags.present) {
503 seq_printf(seq, "present: no\n"); 515 seq_printf(seq, "present: no\n");
504 goto end; 516 goto end;
@@ -536,6 +548,8 @@ acpi_battery_write_alarm(struct file *file,
536 if (!battery || (count > sizeof(alarm_string) - 1)) 548 if (!battery || (count > sizeof(alarm_string) - 1))
537 return -EINVAL; 549 return -EINVAL;
538 550
551 acpi_battery_check_present(battery);
552
539 if (!battery->flags.present) 553 if (!battery->flags.present)
540 return -ENODEV; 554 return -ENODEV;
541 555
diff --git a/drivers/acpi/bay.c b/drivers/acpi/bay.c
index 91082ce6f5d1..fb3f31b5e69f 100644
--- a/drivers/acpi/bay.c
+++ b/drivers/acpi/bay.c
@@ -32,11 +32,9 @@
32#include <asm/uaccess.h> 32#include <asm/uaccess.h>
33#include <linux/platform_device.h> 33#include <linux/platform_device.h>
34 34
35#define ACPI_BAY_DRIVER_NAME "ACPI Removable Drive Bay Driver" 35ACPI_MODULE_NAME("bay");
36
37ACPI_MODULE_NAME("bay")
38MODULE_AUTHOR("Kristen Carlson Accardi"); 36MODULE_AUTHOR("Kristen Carlson Accardi");
39MODULE_DESCRIPTION(ACPI_BAY_DRIVER_NAME); 37MODULE_DESCRIPTION("ACPI Removable Drive Bay Driver");
40MODULE_LICENSE("GPL"); 38MODULE_LICENSE("GPL");
41#define ACPI_BAY_CLASS "bay" 39#define ACPI_BAY_CLASS "bay"
42#define ACPI_BAY_COMPONENT 0x10000000 40#define ACPI_BAY_COMPONENT 0x10000000
@@ -47,18 +45,6 @@ MODULE_LICENSE("GPL");
47 acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer);\ 45 acpi_get_name(h, ACPI_FULL_PATHNAME, &buffer);\
48 printk(KERN_DEBUG PREFIX "%s: %s\n", prefix, s); } 46 printk(KERN_DEBUG PREFIX "%s: %s\n", prefix, s); }
49static void bay_notify(acpi_handle handle, u32 event, void *data); 47static void bay_notify(acpi_handle handle, u32 event, void *data);
50static int acpi_bay_add(struct acpi_device *device);
51static int acpi_bay_remove(struct acpi_device *device, int type);
52
53static struct acpi_driver acpi_bay_driver = {
54 .name = ACPI_BAY_DRIVER_NAME,
55 .class = ACPI_BAY_CLASS,
56 .ids = ACPI_BAY_HID,
57 .ops = {
58 .add = acpi_bay_add,
59 .remove = acpi_bay_remove,
60 },
61};
62 48
63struct bay { 49struct bay {
64 acpi_handle handle; 50 acpi_handle handle;
@@ -234,14 +220,6 @@ int eject_removable_drive(struct device *dev)
234} 220}
235EXPORT_SYMBOL_GPL(eject_removable_drive); 221EXPORT_SYMBOL_GPL(eject_removable_drive);
236 222
237static int acpi_bay_add(struct acpi_device *device)
238{
239 bay_dprintk(device->handle, "adding bay device");
240 strcpy(acpi_device_name(device), "Dockable Bay");
241 strcpy(acpi_device_class(device), "bay");
242 return 0;
243}
244
245static int acpi_bay_add_fs(struct bay *bay) 223static int acpi_bay_add_fs(struct bay *bay)
246{ 224{
247 int ret; 225 int ret;
@@ -303,7 +281,7 @@ static int bay_add(acpi_handle handle, int id)
303 281
304 /* initialize platform device stuff */ 282 /* initialize platform device stuff */
305 pdev = platform_device_register_simple(ACPI_BAY_CLASS, id, NULL, 0); 283 pdev = platform_device_register_simple(ACPI_BAY_CLASS, id, NULL, 0);
306 if (pdev == NULL) { 284 if (IS_ERR(pdev)) {
307 printk(KERN_ERR PREFIX "Error registering bay device\n"); 285 printk(KERN_ERR PREFIX "Error registering bay device\n");
308 goto bay_add_err; 286 goto bay_add_err;
309 } 287 }
@@ -339,52 +317,6 @@ bay_add_err:
339 return -ENODEV; 317 return -ENODEV;
340} 318}
341 319
342static int acpi_bay_remove(struct acpi_device *device, int type)
343{
344 /*** FIXME: do something here */
345 return 0;
346}
347
348/**
349 * bay_create_acpi_device - add new devices to acpi
350 * @handle - handle of the device to add
351 *
352 * This function will create a new acpi_device for the given
353 * handle if one does not exist already. This should cause
354 * acpi to scan for drivers for the given devices, and call
355 * matching driver's add routine.
356 *
357 * Returns a pointer to the acpi_device corresponding to the handle.
358 */
359static struct acpi_device * bay_create_acpi_device(acpi_handle handle)
360{
361 struct acpi_device *device = NULL;
362 struct acpi_device *parent_device;
363 acpi_handle parent;
364 int ret;
365
366 bay_dprintk(handle, "Trying to get device");
367 if (acpi_bus_get_device(handle, &device)) {
368 /*
369 * no device created for this object,
370 * so we should create one.
371 */
372 bay_dprintk(handle, "No device for handle");
373 acpi_get_parent(handle, &parent);
374 if (acpi_bus_get_device(parent, &parent_device))
375 parent_device = NULL;
376
377 ret = acpi_bus_add(&device, parent_device, handle,
378 ACPI_BUS_TYPE_DEVICE);
379 if (ret) {
380 pr_debug("error adding bus, %x\n",
381 -ret);
382 return NULL;
383 }
384 }
385 return device;
386}
387
388/** 320/**
389 * bay_notify - act upon an acpi bay notification 321 * bay_notify - act upon an acpi bay notification
390 * @handle: the bay handle 322 * @handle: the bay handle
@@ -394,38 +326,19 @@ static struct acpi_device * bay_create_acpi_device(acpi_handle handle)
394 */ 326 */
395static void bay_notify(acpi_handle handle, u32 event, void *data) 327static void bay_notify(acpi_handle handle, u32 event, void *data)
396{ 328{
397 struct acpi_device *dev; 329 struct bay *bay_dev = (struct bay *)data;
330 struct device *dev = &bay_dev->pdev->dev;
398 331
399 bay_dprintk(handle, "Bay event"); 332 bay_dprintk(handle, "Bay event");
400 333
401 switch(event) { 334 switch(event) {
402 case ACPI_NOTIFY_BUS_CHECK: 335 case ACPI_NOTIFY_BUS_CHECK:
403 printk("Bus Check\n");
404 case ACPI_NOTIFY_DEVICE_CHECK: 336 case ACPI_NOTIFY_DEVICE_CHECK:
405 printk("Device Check\n");
406 dev = bay_create_acpi_device(handle);
407 if (dev)
408 acpi_bus_generate_event(dev, event, 0);
409 else
410 printk("No device for generating event\n");
411 /* wouldn't it be a good idea to just rescan SATA
412 * right here?
413 */
414 break;
415 case ACPI_NOTIFY_EJECT_REQUEST: 337 case ACPI_NOTIFY_EJECT_REQUEST:
416 printk("Eject request\n"); 338 kobject_uevent(&dev->kobj, KOBJ_CHANGE);
417 dev = bay_create_acpi_device(handle);
418 if (dev)
419 acpi_bus_generate_event(dev, event, 0);
420 else
421 printk("No device for generating eventn");
422
423 /* wouldn't it be a good idea to just call the
424 * eject_device here if we were a SATA device?
425 */
426 break; 339 break;
427 default: 340 default:
428 printk("unknown event %d\n", event); 341 printk(KERN_ERR PREFIX "Bay: unknown event %d\n", event);
429 } 342 }
430} 343}
431 344
@@ -457,10 +370,6 @@ static int __init bay_init(void)
457 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT, 370 acpi_walk_namespace(ACPI_TYPE_DEVICE, ACPI_ROOT_OBJECT,
458 ACPI_UINT32_MAX, find_bay, &bays, NULL); 371 ACPI_UINT32_MAX, find_bay, &bays, NULL);
459 372
460 if (bays)
461 if ((acpi_bus_register_driver(&acpi_bay_driver) < 0))
462 printk(KERN_ERR "Unable to register bay driver\n");
463
464 if (!bays) 373 if (!bays)
465 return -ENODEV; 374 return -ENODEV;
466 375
@@ -481,8 +390,6 @@ static void __exit bay_exit(void)
481 kfree(bay->name); 390 kfree(bay->name);
482 kfree(bay); 391 kfree(bay);
483 } 392 }
484
485 acpi_bus_unregister_driver(&acpi_bay_driver);
486} 393}
487 394
488postcore_initcall(bay_init); 395postcore_initcall(bay_init);
diff --git a/drivers/acpi/bus.c b/drivers/acpi/bus.c
index c26468da4295..dd49ea0d0ed3 100644
--- a/drivers/acpi/bus.c
+++ b/drivers/acpi/bus.c
@@ -39,7 +39,7 @@
39#include <acpi/acpi_drivers.h> 39#include <acpi/acpi_drivers.h>
40 40
41#define _COMPONENT ACPI_BUS_COMPONENT 41#define _COMPONENT ACPI_BUS_COMPONENT
42ACPI_MODULE_NAME("acpi_bus") 42ACPI_MODULE_NAME("bus");
43#ifdef CONFIG_X86 43#ifdef CONFIG_X86
44extern void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger); 44extern void __init acpi_pic_sci_set_trigger(unsigned int irq, u16 trigger);
45#endif 45#endif
@@ -147,7 +147,7 @@ int acpi_bus_get_power(acpi_handle handle, int *state)
147 *state = ACPI_STATE_D0; 147 *state = ACPI_STATE_D0;
148 } else { 148 } else {
149 /* 149 /*
150 * Get the device's power state either directly (via _PSC) or 150 * Get the device's power state either directly (via _PSC) or
151 * indirectly (via power resources). 151 * indirectly (via power resources).
152 */ 152 */
153 if (device->power.flags.explicit_get) { 153 if (device->power.flags.explicit_get) {
@@ -199,15 +199,14 @@ int acpi_bus_set_power(acpi_handle handle, int state)
199 * Get device's current power state if it's unknown 199 * Get device's current power state if it's unknown
200 * This means device power state isn't initialized or previous setting failed 200 * This means device power state isn't initialized or previous setting failed
201 */ 201 */
202 if (!device->flags.force_power_state) { 202 if ((device->power.state == ACPI_STATE_UNKNOWN) || device->flags.force_power_state)
203 if (device->power.state == ACPI_STATE_UNKNOWN) 203 acpi_bus_get_power(device->handle, &device->power.state);
204 acpi_bus_get_power(device->handle, &device->power.state); 204 if ((state == device->power.state) && !device->flags.force_power_state) {
205 if (state == device->power.state) { 205 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n",
206 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device is already at D%d\n", 206 state));
207 state)); 207 return 0;
208 return 0;
209 }
210 } 208 }
209
211 if (!device->power.states[state].flags.valid) { 210 if (!device->power.states[state].flags.valid) {
212 printk(KERN_WARNING PREFIX "Device does not support D%d\n", state); 211 printk(KERN_WARNING PREFIX "Device does not support D%d\n", state);
213 return -ENODEV; 212 return -ENODEV;
@@ -462,7 +461,7 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
462 "Received BUS CHECK notification for device [%s]\n", 461 "Received BUS CHECK notification for device [%s]\n",
463 device->pnp.bus_id)); 462 device->pnp.bus_id));
464 result = acpi_bus_check_scope(device); 463 result = acpi_bus_check_scope(device);
465 /* 464 /*
466 * TBD: We'll need to outsource certain events to non-ACPI 465 * TBD: We'll need to outsource certain events to non-ACPI
467 * drivers via the device manager (device.c). 466 * drivers via the device manager (device.c).
468 */ 467 */
@@ -473,7 +472,7 @@ static void acpi_bus_notify(acpi_handle handle, u32 type, void *data)
473 "Received DEVICE CHECK notification for device [%s]\n", 472 "Received DEVICE CHECK notification for device [%s]\n",
474 device->pnp.bus_id)); 473 device->pnp.bus_id));
475 result = acpi_bus_check_device(device, NULL); 474 result = acpi_bus_check_device(device, NULL);
476 /* 475 /*
477 * TBD: We'll need to outsource certain events to non-ACPI 476 * TBD: We'll need to outsource certain events to non-ACPI
478 * drivers via the device manager (device.c). 477 * drivers via the device manager (device.c).
479 */ 478 */
@@ -543,7 +542,7 @@ static int __init acpi_bus_init_irq(void)
543 char *message = NULL; 542 char *message = NULL;
544 543
545 544
546 /* 545 /*
547 * Let the system know what interrupt model we are using by 546 * Let the system know what interrupt model we are using by
548 * evaluating the \_PIC object, if exists. 547 * evaluating the \_PIC object, if exists.
549 */ 548 */
@@ -684,7 +683,7 @@ static int __init acpi_bus_init(void)
684 * the EC device is found in the namespace (i.e. before acpi_initialize_objects() 683 * the EC device is found in the namespace (i.e. before acpi_initialize_objects()
685 * is called). 684 * is called).
686 * 685 *
687 * This is accomplished by looking for the ECDT table, and getting 686 * This is accomplished by looking for the ECDT table, and getting
688 * the EC parameters out of that. 687 * the EC parameters out of that.
689 */ 688 */
690 status = acpi_ec_ecdt_probe(); 689 status = acpi_ec_ecdt_probe();
@@ -699,6 +698,9 @@ static int __init acpi_bus_init(void)
699 698
700 printk(KERN_INFO PREFIX "Interpreter enabled\n"); 699 printk(KERN_INFO PREFIX "Interpreter enabled\n");
701 700
701 /* Initialize sleep structures */
702 acpi_sleep_init();
703
702 /* 704 /*
703 * Get the system interrupt model and evaluate \_PIC. 705 * Get the system interrupt model and evaluate \_PIC.
704 */ 706 */
diff --git a/drivers/acpi/button.c b/drivers/acpi/button.c
index c726612fafb6..cb4110b50cd0 100644
--- a/drivers/acpi/button.c
+++ b/drivers/acpi/button.c
@@ -34,7 +34,6 @@
34#include <acpi/acpi_drivers.h> 34#include <acpi/acpi_drivers.h>
35 35
36#define ACPI_BUTTON_COMPONENT 0x00080000 36#define ACPI_BUTTON_COMPONENT 0x00080000
37#define ACPI_BUTTON_DRIVER_NAME "ACPI Button Driver"
38#define ACPI_BUTTON_CLASS "button" 37#define ACPI_BUTTON_CLASS "button"
39#define ACPI_BUTTON_FILE_INFO "info" 38#define ACPI_BUTTON_FILE_INFO "info"
40#define ACPI_BUTTON_FILE_STATE "state" 39#define ACPI_BUTTON_FILE_STATE "state"
@@ -61,10 +60,10 @@
61#define ACPI_BUTTON_TYPE_LID 0x05 60#define ACPI_BUTTON_TYPE_LID 0x05
62 61
63#define _COMPONENT ACPI_BUTTON_COMPONENT 62#define _COMPONENT ACPI_BUTTON_COMPONENT
64ACPI_MODULE_NAME("acpi_button") 63ACPI_MODULE_NAME("button");
65 64
66MODULE_AUTHOR("Paul Diefenbaugh"); 65MODULE_AUTHOR("Paul Diefenbaugh");
67MODULE_DESCRIPTION(ACPI_BUTTON_DRIVER_NAME); 66MODULE_DESCRIPTION("ACPI Button Driver");
68MODULE_LICENSE("GPL"); 67MODULE_LICENSE("GPL");
69 68
70static int acpi_button_add(struct acpi_device *device); 69static int acpi_button_add(struct acpi_device *device);
@@ -73,7 +72,7 @@ static int acpi_button_info_open_fs(struct inode *inode, struct file *file);
73static int acpi_button_state_open_fs(struct inode *inode, struct file *file); 72static int acpi_button_state_open_fs(struct inode *inode, struct file *file);
74 73
75static struct acpi_driver acpi_button_driver = { 74static struct acpi_driver acpi_button_driver = {
76 .name = ACPI_BUTTON_DRIVER_NAME, 75 .name = "button",
77 .class = ACPI_BUTTON_CLASS, 76 .class = ACPI_BUTTON_CLASS,
78 .ids = "button_power,button_sleep,PNP0C0D,PNP0C0C,PNP0C0E", 77 .ids = "button_power,button_sleep,PNP0C0D,PNP0C0C,PNP0C0E",
79 .ops = { 78 .ops = {
diff --git a/drivers/acpi/cm_sbs.c b/drivers/acpi/cm_sbs.c
index 4a9b7bf6f44e..f9db4f444bd0 100644
--- a/drivers/acpi/cm_sbs.c
+++ b/drivers/acpi/cm_sbs.c
@@ -31,7 +31,7 @@
31#include <acpi/actypes.h> 31#include <acpi/actypes.h>
32#include <acpi/acutils.h> 32#include <acpi/acutils.h>
33 33
34ACPI_MODULE_NAME("cm_sbs") 34ACPI_MODULE_NAME("cm_sbs");
35#define ACPI_AC_CLASS "ac_adapter" 35#define ACPI_AC_CLASS "ac_adapter"
36#define ACPI_BATTERY_CLASS "battery" 36#define ACPI_BATTERY_CLASS "battery"
37#define ACPI_SBS_COMPONENT 0x00080000 37#define ACPI_SBS_COMPONENT 0x00080000
diff --git a/drivers/acpi/container.c b/drivers/acpi/container.c
index 69a68fd394cf..0930d9413dfa 100644
--- a/drivers/acpi/container.c
+++ b/drivers/acpi/container.c
@@ -35,7 +35,6 @@
35#include <acpi/acpi_drivers.h> 35#include <acpi/acpi_drivers.h>
36#include <acpi/container.h> 36#include <acpi/container.h>
37 37
38#define ACPI_CONTAINER_DRIVER_NAME "ACPI container driver"
39#define ACPI_CONTAINER_DEVICE_NAME "ACPI container device" 38#define ACPI_CONTAINER_DEVICE_NAME "ACPI container device"
40#define ACPI_CONTAINER_CLASS "container" 39#define ACPI_CONTAINER_CLASS "container"
41 40
@@ -44,10 +43,10 @@
44 43
45#define ACPI_CONTAINER_COMPONENT 0x01000000 44#define ACPI_CONTAINER_COMPONENT 0x01000000
46#define _COMPONENT ACPI_CONTAINER_COMPONENT 45#define _COMPONENT ACPI_CONTAINER_COMPONENT
47ACPI_MODULE_NAME("acpi_container") 46ACPI_MODULE_NAME("container");
48 47
49 MODULE_AUTHOR("Anil S Keshavamurthy"); 48MODULE_AUTHOR("Anil S Keshavamurthy");
50MODULE_DESCRIPTION(ACPI_CONTAINER_DRIVER_NAME); 49MODULE_DESCRIPTION("ACPI container driver");
51MODULE_LICENSE("GPL"); 50MODULE_LICENSE("GPL");
52 51
53#define ACPI_STA_PRESENT (0x00000001) 52#define ACPI_STA_PRESENT (0x00000001)
@@ -56,7 +55,7 @@ static int acpi_container_add(struct acpi_device *device);
56static int acpi_container_remove(struct acpi_device *device, int type); 55static int acpi_container_remove(struct acpi_device *device, int type);
57 56
58static struct acpi_driver acpi_container_driver = { 57static struct acpi_driver acpi_container_driver = {
59 .name = ACPI_CONTAINER_DRIVER_NAME, 58 .name = "container",
60 .class = ACPI_CONTAINER_CLASS, 59 .class = ACPI_CONTAINER_CLASS,
61 .ids = "ACPI0004,PNP0A05,PNP0A06", 60 .ids = "ACPI0004,PNP0A05,PNP0A06",
62 .ops = { 61 .ops = {
diff --git a/drivers/acpi/debug.c b/drivers/acpi/debug.c
index d48f65a8f658..bf513e07b773 100644
--- a/drivers/acpi/debug.c
+++ b/drivers/acpi/debug.c
@@ -12,7 +12,7 @@
12#include <acpi/acglobal.h> 12#include <acpi/acglobal.h>
13 13
14#define _COMPONENT ACPI_SYSTEM_COMPONENT 14#define _COMPONENT ACPI_SYSTEM_COMPONENT
15ACPI_MODULE_NAME("debug") 15ACPI_MODULE_NAME("debug");
16 16
17#ifdef MODULE_PARAM_PREFIX 17#ifdef MODULE_PARAM_PREFIX
18#undef MODULE_PARAM_PREFIX 18#undef MODULE_PARAM_PREFIX
diff --git a/drivers/acpi/dispatcher/dsmethod.c b/drivers/acpi/dispatcher/dsmethod.c
index 1cbe61905824..1683e5c5b94c 100644
--- a/drivers/acpi/dispatcher/dsmethod.c
+++ b/drivers/acpi/dispatcher/dsmethod.c
@@ -231,10 +231,8 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
231 * Obtain the method mutex if necessary. Do not acquire mutex for a 231 * Obtain the method mutex if necessary. Do not acquire mutex for a
232 * recursive call. 232 * recursive call.
233 */ 233 */
234 if (!walk_state || 234 if (acpi_os_get_thread_id() !=
235 !obj_desc->method.mutex->mutex.owner_thread || 235 obj_desc->method.mutex->mutex.owner_thread_id) {
236 (walk_state->thread !=
237 obj_desc->method.mutex->mutex.owner_thread)) {
238 /* 236 /*
239 * Acquire the method mutex. This releases the interpreter if we 237 * Acquire the method mutex. This releases the interpreter if we
240 * block (and reacquires it before it returns) 238 * block (and reacquires it before it returns)
@@ -248,14 +246,14 @@ acpi_ds_begin_method_execution(struct acpi_namespace_node *method_node,
248 } 246 }
249 247
250 /* Update the mutex and walk info and save the original sync_level */ 248 /* Update the mutex and walk info and save the original sync_level */
249 obj_desc->method.mutex->mutex.owner_thread_id =
250 acpi_os_get_thread_id();
251 251
252 if (walk_state) { 252 if (walk_state) {
253 obj_desc->method.mutex->mutex. 253 obj_desc->method.mutex->mutex.
254 original_sync_level = 254 original_sync_level =
255 walk_state->thread->current_sync_level; 255 walk_state->thread->current_sync_level;
256 256
257 obj_desc->method.mutex->mutex.owner_thread =
258 walk_state->thread;
259 walk_state->thread->current_sync_level = 257 walk_state->thread->current_sync_level =
260 obj_desc->method.sync_level; 258 obj_desc->method.sync_level;
261 } else { 259 } else {
@@ -569,7 +567,7 @@ acpi_ds_terminate_control_method(union acpi_operand_object *method_desc,
569 567
570 acpi_os_release_mutex(method_desc->method.mutex->mutex. 568 acpi_os_release_mutex(method_desc->method.mutex->mutex.
571 os_mutex); 569 os_mutex);
572 method_desc->method.mutex->mutex.owner_thread = NULL; 570 method_desc->method.mutex->mutex.owner_thread_id = ACPI_MUTEX_NOT_ACQUIRED;
573 } 571 }
574 } 572 }
575 573
diff --git a/drivers/acpi/dock.c b/drivers/acpi/dock.c
index 688e83a16906..54a697f9aa18 100644
--- a/drivers/acpi/dock.c
+++ b/drivers/acpi/dock.c
@@ -32,11 +32,11 @@
32#include <acpi/acpi_bus.h> 32#include <acpi/acpi_bus.h>
33#include <acpi/acpi_drivers.h> 33#include <acpi/acpi_drivers.h>
34 34
35#define ACPI_DOCK_DRIVER_NAME "ACPI Dock Station Driver" 35#define ACPI_DOCK_DRIVER_DESCRIPTION "ACPI Dock Station Driver"
36 36
37ACPI_MODULE_NAME("dock") 37ACPI_MODULE_NAME("dock");
38MODULE_AUTHOR("Kristen Carlson Accardi"); 38MODULE_AUTHOR("Kristen Carlson Accardi");
39MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_NAME); 39MODULE_DESCRIPTION(ACPI_DOCK_DRIVER_DESCRIPTION);
40MODULE_LICENSE("GPL"); 40MODULE_LICENSE("GPL");
41 41
42static struct atomic_notifier_head dock_notifier_list; 42static struct atomic_notifier_head dock_notifier_list;
@@ -741,7 +741,7 @@ static int dock_add(acpi_handle handle)
741 goto dock_add_err; 741 goto dock_add_err;
742 } 742 }
743 743
744 printk(KERN_INFO PREFIX "%s \n", ACPI_DOCK_DRIVER_NAME); 744 printk(KERN_INFO PREFIX "%s \n", ACPI_DOCK_DRIVER_DESCRIPTION);
745 745
746 return 0; 746 return 0;
747 747
diff --git a/drivers/acpi/ec.c b/drivers/acpi/ec.c
index 743ce27fa0bb..ab6888373795 100644
--- a/drivers/acpi/ec.c
+++ b/drivers/acpi/ec.c
@@ -38,11 +38,10 @@
38#include <acpi/actypes.h> 38#include <acpi/actypes.h>
39 39
40#define _COMPONENT ACPI_EC_COMPONENT 40#define _COMPONENT ACPI_EC_COMPONENT
41ACPI_MODULE_NAME("acpi_ec") 41ACPI_MODULE_NAME("ec");
42#define ACPI_EC_COMPONENT 0x00100000 42#define ACPI_EC_COMPONENT 0x00100000
43#define ACPI_EC_CLASS "embedded_controller" 43#define ACPI_EC_CLASS "embedded_controller"
44#define ACPI_EC_HID "PNP0C09" 44#define ACPI_EC_HID "PNP0C09"
45#define ACPI_EC_DRIVER_NAME "ACPI Embedded Controller Driver"
46#define ACPI_EC_DEVICE_NAME "Embedded Controller" 45#define ACPI_EC_DEVICE_NAME "Embedded Controller"
47#define ACPI_EC_FILE_INFO "info" 46#define ACPI_EC_FILE_INFO "info"
48#undef PREFIX 47#undef PREFIX
@@ -80,7 +79,7 @@ static int acpi_ec_stop(struct acpi_device *device, int type);
80static int acpi_ec_add(struct acpi_device *device); 79static int acpi_ec_add(struct acpi_device *device);
81 80
82static struct acpi_driver acpi_ec_driver = { 81static struct acpi_driver acpi_ec_driver = {
83 .name = ACPI_EC_DRIVER_NAME, 82 .name = "ec",
84 .class = ACPI_EC_CLASS, 83 .class = ACPI_EC_CLASS,
85 .ids = ACPI_EC_HID, 84 .ids = ACPI_EC_HID,
86 .ops = { 85 .ops = {
@@ -280,8 +279,10 @@ static int acpi_ec_transaction(struct acpi_ec *ec, u8 command,
280 mutex_lock(&ec->lock); 279 mutex_lock(&ec->lock);
281 if (ec->global_lock) { 280 if (ec->global_lock) {
282 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk); 281 status = acpi_acquire_global_lock(ACPI_EC_UDELAY_GLK, &glk);
283 if (ACPI_FAILURE(status)) 282 if (ACPI_FAILURE(status)) {
283 mutex_unlock(&ec->lock);
284 return -ENODEV; 284 return -ENODEV;
285 }
285 } 286 }
286 287
287 /* Make sure GPE is enabled before doing transaction */ 288 /* Make sure GPE is enabled before doing transaction */
diff --git a/drivers/acpi/event.c b/drivers/acpi/event.c
index 959a893c8d1f..3b23562e6f92 100644
--- a/drivers/acpi/event.c
+++ b/drivers/acpi/event.c
@@ -13,7 +13,7 @@
13#include <acpi/acpi_drivers.h> 13#include <acpi/acpi_drivers.h>
14 14
15#define _COMPONENT ACPI_SYSTEM_COMPONENT 15#define _COMPONENT ACPI_SYSTEM_COMPONENT
16ACPI_MODULE_NAME("event") 16ACPI_MODULE_NAME("event");
17 17
18/* Global vars for handling event proc entry */ 18/* Global vars for handling event proc entry */
19static DEFINE_SPINLOCK(acpi_system_event_lock); 19static DEFINE_SPINLOCK(acpi_system_event_lock);
diff --git a/drivers/acpi/events/evgpe.c b/drivers/acpi/events/evgpe.c
index dfac3ecc596e..635ba449ebc2 100644
--- a/drivers/acpi/events/evgpe.c
+++ b/drivers/acpi/events/evgpe.c
@@ -636,17 +636,6 @@ acpi_ev_gpe_dispatch(struct acpi_gpe_event_info *gpe_event_info, u32 gpe_number)
636 } 636 }
637 } 637 }
638 638
639 if (!acpi_gbl_system_awake_and_running) {
640 /*
641 * We just woke up because of a wake GPE. Disable any further GPEs
642 * until we are fully up and running (Only wake GPEs should be enabled
643 * at this time, but we just brute-force disable them all.)
644 * 1) We must disable this particular wake GPE so it won't fire again
645 * 2) We want to disable all wake GPEs, since we are now awake
646 */
647 (void)acpi_hw_disable_all_gpes();
648 }
649
650 /* 639 /*
651 * Dispatch the GPE to either an installed handler, or the control method 640 * Dispatch the GPE to either an installed handler, or the control method
652 * associated with this GPE (_Lxx or _Exx). If a handler exists, we invoke 641 * associated with this GPE (_Lxx or _Exx). If a handler exists, we invoke
diff --git a/drivers/acpi/events/evmisc.c b/drivers/acpi/events/evmisc.c
index 1b784ffe54c3..d572700197f3 100644
--- a/drivers/acpi/events/evmisc.c
+++ b/drivers/acpi/events/evmisc.c
@@ -196,12 +196,11 @@ acpi_ev_queue_notify_request(struct acpi_namespace_node * node,
196 notify_info->notify.value = (u16) notify_value; 196 notify_info->notify.value = (u16) notify_value;
197 notify_info->notify.handler_obj = handler_obj; 197 notify_info->notify.handler_obj = handler_obj;
198 198
199 status = 199 acpi_ex_relinquish_interpreter();
200 acpi_os_execute(OSL_NOTIFY_HANDLER, acpi_ev_notify_dispatch, 200
201 notify_info); 201 acpi_ev_notify_dispatch(notify_info);
202 if (ACPI_FAILURE(status)) { 202
203 acpi_ut_delete_generic_state(notify_info); 203 acpi_ex_reacquire_interpreter();
204 }
205 } 204 }
206 205
207 if (!handler_obj) { 206 if (!handler_obj) {
diff --git a/drivers/acpi/executer/exdump.c b/drivers/acpi/executer/exdump.c
index 68d283fd60e7..1a73c14df2c5 100644
--- a/drivers/acpi/executer/exdump.c
+++ b/drivers/acpi/executer/exdump.c
@@ -134,7 +134,7 @@ static struct acpi_exdump_info acpi_ex_dump_method[8] = {
134static struct acpi_exdump_info acpi_ex_dump_mutex[5] = { 134static struct acpi_exdump_info acpi_ex_dump_mutex[5] = {
135 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_mutex), NULL}, 135 {ACPI_EXD_INIT, ACPI_EXD_TABLE_SIZE(acpi_ex_dump_mutex), NULL},
136 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.sync_level), "Sync Level"}, 136 {ACPI_EXD_UINT8, ACPI_EXD_OFFSET(mutex.sync_level), "Sync Level"},
137 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread), "Owner Thread"}, 137 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.owner_thread_id), "Owner Thread"},
138 {ACPI_EXD_UINT16, ACPI_EXD_OFFSET(mutex.acquisition_depth), 138 {ACPI_EXD_UINT16, ACPI_EXD_OFFSET(mutex.acquisition_depth),
139 "Acquire Depth"}, 139 "Acquire Depth"},
140 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.os_mutex), "OsMutex"} 140 {ACPI_EXD_POINTER, ACPI_EXD_OFFSET(mutex.os_mutex), "OsMutex"}
diff --git a/drivers/acpi/executer/exmutex.c b/drivers/acpi/executer/exmutex.c
index 5101bad5baf8..4eb883bda6ae 100644
--- a/drivers/acpi/executer/exmutex.c
+++ b/drivers/acpi/executer/exmutex.c
@@ -66,10 +66,9 @@ acpi_ex_link_mutex(union acpi_operand_object *obj_desc,
66 * 66 *
67 ******************************************************************************/ 67 ******************************************************************************/
68 68
69void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc) 69void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc,
70 struct acpi_thread_state *thread)
70{ 71{
71 struct acpi_thread_state *thread = obj_desc->mutex.owner_thread;
72
73 if (!thread) { 72 if (!thread) {
74 return; 73 return;
75 } 74 }
@@ -174,16 +173,13 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
174 173
175 /* Support for multiple acquires by the owning thread */ 174 /* Support for multiple acquires by the owning thread */
176 175
177 if (obj_desc->mutex.owner_thread) { 176 if (obj_desc->mutex.owner_thread_id == acpi_os_get_thread_id()) {
178 if (obj_desc->mutex.owner_thread->thread_id == 177 /*
179 walk_state->thread->thread_id) { 178 * The mutex is already owned by this thread, just increment the
180 /* 179 * acquisition depth
181 * The mutex is already owned by this thread, just increment the 180 */
182 * acquisition depth 181 obj_desc->mutex.acquisition_depth++;
183 */ 182 return_ACPI_STATUS(AE_OK);
184 obj_desc->mutex.acquisition_depth++;
185 return_ACPI_STATUS(AE_OK);
186 }
187 } 183 }
188 184
189 /* Acquire the mutex, wait if necessary. Special case for Global Lock */ 185 /* Acquire the mutex, wait if necessary. Special case for Global Lock */
@@ -206,7 +202,7 @@ acpi_ex_acquire_mutex(union acpi_operand_object *time_desc,
206 202
207 /* Have the mutex: update mutex and walk info and save the sync_level */ 203 /* Have the mutex: update mutex and walk info and save the sync_level */
208 204
209 obj_desc->mutex.owner_thread = walk_state->thread; 205 obj_desc->mutex.owner_thread_id = acpi_os_get_thread_id();
210 obj_desc->mutex.acquisition_depth = 1; 206 obj_desc->mutex.acquisition_depth = 1;
211 obj_desc->mutex.original_sync_level = 207 obj_desc->mutex.original_sync_level =
212 walk_state->thread->current_sync_level; 208 walk_state->thread->current_sync_level;
@@ -246,7 +242,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
246 242
247 /* The mutex must have been previously acquired in order to release it */ 243 /* The mutex must have been previously acquired in order to release it */
248 244
249 if (!obj_desc->mutex.owner_thread) { 245 if (!obj_desc->mutex.owner_thread_id) {
250 ACPI_ERROR((AE_INFO, 246 ACPI_ERROR((AE_INFO,
251 "Cannot release Mutex [%4.4s], not acquired", 247 "Cannot release Mutex [%4.4s], not acquired",
252 acpi_ut_get_node_name(obj_desc->mutex.node))); 248 acpi_ut_get_node_name(obj_desc->mutex.node)));
@@ -266,14 +262,14 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
266 * The Mutex is owned, but this thread must be the owner. 262 * The Mutex is owned, but this thread must be the owner.
267 * Special case for Global Lock, any thread can release 263 * Special case for Global Lock, any thread can release
268 */ 264 */
269 if ((obj_desc->mutex.owner_thread->thread_id != 265 if ((obj_desc->mutex.owner_thread_id !=
270 walk_state->thread->thread_id) 266 walk_state->thread->thread_id)
271 && (obj_desc->mutex.os_mutex != acpi_gbl_global_lock_mutex)) { 267 && (obj_desc->mutex.os_mutex != acpi_gbl_global_lock_mutex)) {
272 ACPI_ERROR((AE_INFO, 268 ACPI_ERROR((AE_INFO,
273 "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX", 269 "Thread %lX cannot release Mutex [%4.4s] acquired by thread %lX",
274 (unsigned long)walk_state->thread->thread_id, 270 (unsigned long)walk_state->thread->thread_id,
275 acpi_ut_get_node_name(obj_desc->mutex.node), 271 acpi_ut_get_node_name(obj_desc->mutex.node),
276 (unsigned long)obj_desc->mutex.owner_thread->thread_id)); 272 (unsigned long)obj_desc->mutex.owner_thread_id));
277 return_ACPI_STATUS(AE_AML_NOT_OWNER); 273 return_ACPI_STATUS(AE_AML_NOT_OWNER);
278 } 274 }
279 275
@@ -300,7 +296,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
300 296
301 /* Unlink the mutex from the owner's list */ 297 /* Unlink the mutex from the owner's list */
302 298
303 acpi_ex_unlink_mutex(obj_desc); 299 acpi_ex_unlink_mutex(obj_desc, walk_state->thread);
304 300
305 /* Release the mutex, special case for Global Lock */ 301 /* Release the mutex, special case for Global Lock */
306 302
@@ -312,7 +308,7 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
312 308
313 /* Update the mutex and restore sync_level */ 309 /* Update the mutex and restore sync_level */
314 310
315 obj_desc->mutex.owner_thread = NULL; 311 obj_desc->mutex.owner_thread_id = ACPI_MUTEX_NOT_ACQUIRED;
316 walk_state->thread->current_sync_level = 312 walk_state->thread->current_sync_level =
317 obj_desc->mutex.original_sync_level; 313 obj_desc->mutex.original_sync_level;
318 314
@@ -367,7 +363,7 @@ void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread)
367 363
368 /* Mark mutex unowned */ 364 /* Mark mutex unowned */
369 365
370 obj_desc->mutex.owner_thread = NULL; 366 obj_desc->mutex.owner_thread_id = ACPI_MUTEX_NOT_ACQUIRED;
371 367
372 /* Update Thread sync_level (Last mutex is the important one) */ 368 /* Update Thread sync_level (Last mutex is the important one) */
373 369
diff --git a/drivers/acpi/fan.c b/drivers/acpi/fan.c
index af22fdf73413..ec655c539492 100644
--- a/drivers/acpi/fan.c
+++ b/drivers/acpi/fan.c
@@ -36,14 +36,13 @@
36 36
37#define ACPI_FAN_COMPONENT 0x00200000 37#define ACPI_FAN_COMPONENT 0x00200000
38#define ACPI_FAN_CLASS "fan" 38#define ACPI_FAN_CLASS "fan"
39#define ACPI_FAN_DRIVER_NAME "ACPI Fan Driver"
40#define ACPI_FAN_FILE_STATE "state" 39#define ACPI_FAN_FILE_STATE "state"
41 40
42#define _COMPONENT ACPI_FAN_COMPONENT 41#define _COMPONENT ACPI_FAN_COMPONENT
43ACPI_MODULE_NAME("acpi_fan") 42ACPI_MODULE_NAME("fan");
44 43
45 MODULE_AUTHOR("Paul Diefenbaugh"); 44MODULE_AUTHOR("Paul Diefenbaugh");
46MODULE_DESCRIPTION(ACPI_FAN_DRIVER_NAME); 45MODULE_DESCRIPTION("ACPI Fan Driver");
47MODULE_LICENSE("GPL"); 46MODULE_LICENSE("GPL");
48 47
49static int acpi_fan_add(struct acpi_device *device); 48static int acpi_fan_add(struct acpi_device *device);
@@ -52,7 +51,7 @@ static int acpi_fan_suspend(struct acpi_device *device, pm_message_t state);
52static int acpi_fan_resume(struct acpi_device *device); 51static int acpi_fan_resume(struct acpi_device *device);
53 52
54static struct acpi_driver acpi_fan_driver = { 53static struct acpi_driver acpi_fan_driver = {
55 .name = ACPI_FAN_DRIVER_NAME, 54 .name = "fan",
56 .class = ACPI_FAN_CLASS, 55 .class = ACPI_FAN_CLASS,
57 .ids = "PNP0C0B", 56 .ids = "PNP0C0B",
58 .ops = { 57 .ops = {
diff --git a/drivers/acpi/glue.c b/drivers/acpi/glue.c
index 7b6c9ff9bebe..4334c208841a 100644
--- a/drivers/acpi/glue.c
+++ b/drivers/acpi/glue.c
@@ -241,3 +241,65 @@ static int __init init_acpi_device_notify(void)
241} 241}
242 242
243arch_initcall(init_acpi_device_notify); 243arch_initcall(init_acpi_device_notify);
244
245
246#if defined(CONFIG_RTC_DRV_CMOS) || defined(CONFIG_RTC_DRV_CMOS_MODULE)
247
248/* Every ACPI platform has a mc146818 compatible "cmos rtc". Here we find
249 * its device node and pass extra config data. This helps its driver use
250 * capabilities that the now-obsolete mc146818 didn't have, and informs it
251 * that this board's RTC is wakeup-capable (per ACPI spec).
252 */
253#include <linux/mc146818rtc.h>
254
255static struct cmos_rtc_board_info rtc_info;
256
257
258/* PNP devices are registered in a subsys_initcall();
259 * ACPI specifies the PNP IDs to use.
260 */
261#include <linux/pnp.h>
262
263static int __init pnp_match(struct device *dev, void *data)
264{
265 static const char *ids[] = { "PNP0b00", "PNP0b01", "PNP0b02", };
266 struct pnp_dev *pnp = to_pnp_dev(dev);
267 int i;
268
269 for (i = 0; i < ARRAY_SIZE(ids); i++) {
270 if (compare_pnp_id(pnp->id, ids[i]) != 0)
271 return 1;
272 }
273 return 0;
274}
275
276static struct device *__init get_rtc_dev(void)
277{
278 return bus_find_device(&pnp_bus_type, NULL, NULL, pnp_match);
279}
280
281static int __init acpi_rtc_init(void)
282{
283 struct device *dev = get_rtc_dev();
284
285 if (dev) {
286 rtc_info.rtc_day_alarm = acpi_gbl_FADT.day_alarm;
287 rtc_info.rtc_mon_alarm = acpi_gbl_FADT.month_alarm;
288 rtc_info.rtc_century = acpi_gbl_FADT.century;
289
290 /* NOTE: acpi_gbl_FADT->rtcs4 is NOT currently useful */
291
292 dev->platform_data = &rtc_info;
293
294 /* RTC always wakes from S1/S2/S3, and often S4/STD */
295 device_init_wakeup(dev, 1);
296
297 put_device(dev);
298 } else
299 pr_debug("ACPI: RTC unavailable?\n");
300 return 0;
301}
302/* do this between RTC subsys_initcall() and rtc_cmos driver_initcall() */
303fs_initcall(acpi_rtc_init);
304
305#endif
diff --git a/drivers/acpi/hardware/hwsleep.c b/drivers/acpi/hardware/hwsleep.c
index 57901ca3ade9..8fa93125fd4c 100644
--- a/drivers/acpi/hardware/hwsleep.c
+++ b/drivers/acpi/hardware/hwsleep.c
@@ -235,6 +235,14 @@ acpi_status acpi_enter_sleep_state_prep(u8 sleep_state)
235 "While executing method _SST")); 235 "While executing method _SST"));
236 } 236 }
237 237
238 /*
239 * 1) Disable/Clear all GPEs
240 */
241 status = acpi_hw_disable_all_gpes();
242 if (ACPI_FAILURE(status)) {
243 return_ACPI_STATUS(status);
244 }
245
238 return_ACPI_STATUS(AE_OK); 246 return_ACPI_STATUS(AE_OK);
239} 247}
240 248
@@ -290,13 +298,8 @@ acpi_status asmlinkage acpi_enter_sleep_state(u8 sleep_state)
290 } 298 }
291 299
292 /* 300 /*
293 * 1) Disable/Clear all GPEs
294 * 2) Enable all wakeup GPEs 301 * 2) Enable all wakeup GPEs
295 */ 302 */
296 status = acpi_hw_disable_all_gpes();
297 if (ACPI_FAILURE(status)) {
298 return_ACPI_STATUS(status);
299 }
300 acpi_gbl_system_awake_and_running = FALSE; 303 acpi_gbl_system_awake_and_running = FALSE;
301 304
302 status = acpi_hw_enable_all_wakeup_gpes(); 305 status = acpi_hw_enable_all_wakeup_gpes();
diff --git a/drivers/acpi/hotkey.c b/drivers/acpi/hotkey.c
deleted file mode 100644
index 8edfb92f7ede..000000000000
--- a/drivers/acpi/hotkey.c
+++ /dev/null
@@ -1,1042 +0,0 @@
1/*
2 * hotkey.c - ACPI Hotkey Driver ($Revision: 0.2 $)
3 *
4 * Copyright (C) 2004 Luming Yu <luming.yu@intel.com>
5 *
6 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
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 of the License, or (at
11 * your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA.
21 *
22 * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
23 */
24#include <linux/kernel.h>
25#include <linux/module.h>
26#include <linux/init.h>
27#include <linux/types.h>
28#include <linux/proc_fs.h>
29#include <linux/sched.h>
30#include <linux/kmod.h>
31#include <linux/seq_file.h>
32#include <acpi/acpi_drivers.h>
33#include <acpi/acpi_bus.h>
34#include <asm/uaccess.h>
35
36#define HOTKEY_ACPI_VERSION "0.1"
37
38#define HOTKEY_PROC "hotkey"
39#define HOTKEY_EV_CONFIG "event_config"
40#define HOTKEY_PL_CONFIG "poll_config"
41#define HOTKEY_ACTION "action"
42#define HOTKEY_INFO "info"
43
44#define ACPI_HOTK_NAME "Generic Hotkey Driver"
45#define ACPI_HOTK_CLASS "Hotkey"
46#define ACPI_HOTK_DEVICE_NAME "Hotkey"
47#define ACPI_HOTK_HID "Unknown?"
48#define ACPI_HOTKEY_COMPONENT 0x20000000
49
50#define ACPI_HOTKEY_EVENT 0x1
51#define ACPI_HOTKEY_POLLING 0x2
52#define ACPI_UNDEFINED_EVENT 0xf
53
54#define RESULT_STR_LEN 80
55
56#define ACTION_METHOD 0
57#define POLL_METHOD 1
58
59#define IS_EVENT(e) ((e) <= 10000 && (e) >0)
60#define IS_POLL(e) ((e) > 10000)
61#define IS_OTHERS(e) ((e)<=0 || (e)>=20000)
62#define _COMPONENT ACPI_HOTKEY_COMPONENT
63ACPI_MODULE_NAME("acpi_hotkey")
64
65 MODULE_AUTHOR("luming.yu@intel.com");
66MODULE_DESCRIPTION(ACPI_HOTK_NAME);
67MODULE_LICENSE("GPL");
68
69/* standardized internal hotkey number/event */
70enum {
71 /* Video Extension event */
72 HK_EVENT_CYCLE_OUTPUT_DEVICE = 0x80,
73 HK_EVENT_OUTPUT_DEVICE_STATUS_CHANGE,
74 HK_EVENT_CYCLE_DISPLAY_OUTPUT,
75 HK_EVENT_NEXT_DISPLAY_OUTPUT,
76 HK_EVENT_PREVIOUS_DISPLAY_OUTPUT,
77 HK_EVENT_CYCLE_BRIGHTNESS,
78 HK_EVENT_INCREASE_BRIGHTNESS,
79 HK_EVENT_DECREASE_BRIGHTNESS,
80 HK_EVENT_ZERO_BRIGHTNESS,
81 HK_EVENT_DISPLAY_DEVICE_OFF,
82
83 /* Snd Card event */
84 HK_EVENT_VOLUME_MUTE,
85 HK_EVENT_VOLUME_INCLREASE,
86 HK_EVENT_VOLUME_DECREASE,
87
88 /* running state control */
89 HK_EVENT_ENTERRING_S3,
90 HK_EVENT_ENTERRING_S4,
91 HK_EVENT_ENTERRING_S5,
92};
93
94enum conf_entry_enum {
95 bus_handle = 0,
96 bus_method = 1,
97 action_handle = 2,
98 method = 3,
99 LAST_CONF_ENTRY
100};
101
102/* procdir we use */
103static struct proc_dir_entry *hotkey_proc_dir;
104static struct proc_dir_entry *hotkey_config;
105static struct proc_dir_entry *hotkey_poll_config;
106static struct proc_dir_entry *hotkey_action;
107static struct proc_dir_entry *hotkey_info;
108
109/* linkage for all type of hotkey */
110struct acpi_hotkey_link {
111 struct list_head entries;
112 int hotkey_type; /* event or polling based hotkey */
113 int hotkey_standard_num; /* standardized hotkey(event) number */
114};
115
116/* event based hotkey */
117struct acpi_event_hotkey {
118 struct acpi_hotkey_link hotkey_link;
119 int flag;
120 acpi_handle bus_handle; /* bus to install notify handler */
121 int external_hotkey_num; /* external hotkey/event number */
122 acpi_handle action_handle; /* acpi handle attached aml action method */
123 char *action_method; /* action method */
124};
125
126/*
127 * There are two ways to poll status
128 * 1. directy call read_xxx method, without any arguments passed in
129 * 2. call write_xxx method, with arguments passed in, you need
130 * the result is saved in acpi_polling_hotkey.poll_result.
131 * anthoer read command through polling interface.
132 *
133 */
134
135/* polling based hotkey */
136struct acpi_polling_hotkey {
137 struct acpi_hotkey_link hotkey_link;
138 int flag;
139 acpi_handle poll_handle; /* acpi handle attached polling method */
140 char *poll_method; /* poll method */
141 acpi_handle action_handle; /* acpi handle attached action method */
142 char *action_method; /* action method */
143 union acpi_object *poll_result; /* polling_result */
144 struct proc_dir_entry *proc;
145};
146
147/* hotkey object union */
148union acpi_hotkey {
149 struct list_head entries;
150 struct acpi_hotkey_link link;
151 struct acpi_event_hotkey event_hotkey;
152 struct acpi_polling_hotkey poll_hotkey;
153};
154
155/* hotkey object list */
156struct acpi_hotkey_list {
157 struct list_head *entries;
158 int count;
159};
160
161static int auto_hotkey_add(struct acpi_device *device);
162static int auto_hotkey_remove(struct acpi_device *device, int type);
163
164static struct acpi_driver hotkey_driver = {
165 .name = ACPI_HOTK_NAME,
166 .class = ACPI_HOTK_CLASS,
167 .ids = ACPI_HOTK_HID,
168 .ops = {
169 .add = auto_hotkey_add,
170 .remove = auto_hotkey_remove,
171 },
172};
173
174static void free_hotkey_device(union acpi_hotkey *key);
175static void free_hotkey_buffer(union acpi_hotkey *key);
176static void free_poll_hotkey_buffer(union acpi_hotkey *key);
177static int hotkey_open_config(struct inode *inode, struct file *file);
178static int hotkey_poll_open_config(struct inode *inode, struct file *file);
179static ssize_t hotkey_write_config(struct file *file,
180 const char __user * buffer,
181 size_t count, loff_t * data);
182static int hotkey_info_open_fs(struct inode *inode, struct file *file);
183static int hotkey_action_open_fs(struct inode *inode, struct file *file);
184static ssize_t hotkey_execute_aml_method(struct file *file,
185 const char __user * buffer,
186 size_t count, loff_t * data);
187static int hotkey_config_seq_show(struct seq_file *seq, void *offset);
188static int hotkey_poll_config_seq_show(struct seq_file *seq, void *offset);
189static int hotkey_polling_open_fs(struct inode *inode, struct file *file);
190static union acpi_hotkey *get_hotkey_by_event(struct
191 acpi_hotkey_list
192 *hotkey_list, int event);
193
194/* event based config */
195static const struct file_operations hotkey_config_fops = {
196 .open = hotkey_open_config,
197 .read = seq_read,
198 .write = hotkey_write_config,
199 .llseek = seq_lseek,
200 .release = single_release,
201};
202
203/* polling based config */
204static const struct file_operations hotkey_poll_config_fops = {
205 .open = hotkey_poll_open_config,
206 .read = seq_read,
207 .write = hotkey_write_config,
208 .llseek = seq_lseek,
209 .release = single_release,
210};
211
212/* hotkey driver info */
213static const struct file_operations hotkey_info_fops = {
214 .open = hotkey_info_open_fs,
215 .read = seq_read,
216 .llseek = seq_lseek,
217 .release = single_release,
218};
219
220/* action */
221static const struct file_operations hotkey_action_fops = {
222 .open = hotkey_action_open_fs,
223 .read = seq_read,
224 .write = hotkey_execute_aml_method,
225 .llseek = seq_lseek,
226 .release = single_release,
227};
228
229/* polling results */
230static const struct file_operations hotkey_polling_fops = {
231 .open = hotkey_polling_open_fs,
232 .read = seq_read,
233 .llseek = seq_lseek,
234 .release = single_release,
235};
236
237struct acpi_hotkey_list global_hotkey_list; /* link all ev or pl hotkey */
238struct list_head hotkey_entries; /* head of the list of hotkey_list */
239
240static int hotkey_info_seq_show(struct seq_file *seq, void *offset)
241{
242
243 seq_printf(seq, "Hotkey generic driver ver: %s\n", HOTKEY_ACPI_VERSION);
244
245 return 0;
246}
247
248static int hotkey_info_open_fs(struct inode *inode, struct file *file)
249{
250 return single_open(file, hotkey_info_seq_show, PDE(inode)->data);
251}
252
253static char *format_result(union acpi_object *object)
254{
255 char *buf;
256
257 buf = kzalloc(RESULT_STR_LEN, GFP_KERNEL);
258 if (!buf)
259 return NULL;
260 /* Now, just support integer type */
261 if (object->type == ACPI_TYPE_INTEGER)
262 sprintf(buf, "%d\n", (u32) object->integer.value);
263 return buf;
264}
265
266static int hotkey_polling_seq_show(struct seq_file *seq, void *offset)
267{
268 struct acpi_polling_hotkey *poll_hotkey = seq->private;
269 char *buf;
270
271
272 if (poll_hotkey->poll_result) {
273 buf = format_result(poll_hotkey->poll_result);
274 if (buf)
275 seq_printf(seq, "%s", buf);
276 kfree(buf);
277 }
278 return 0;
279}
280
281static int hotkey_polling_open_fs(struct inode *inode, struct file *file)
282{
283 return single_open(file, hotkey_polling_seq_show, PDE(inode)->data);
284}
285
286static int hotkey_action_open_fs(struct inode *inode, struct file *file)
287{
288 return single_open(file, hotkey_info_seq_show, PDE(inode)->data);
289}
290
291/* Mapping external hotkey number to standardized hotkey event num */
292static int hotkey_get_internal_event(int event, struct acpi_hotkey_list *list)
293{
294 struct list_head *entries;
295 int val = -1;
296
297
298 list_for_each(entries, list->entries) {
299 union acpi_hotkey *key =
300 container_of(entries, union acpi_hotkey, entries);
301 if (key->link.hotkey_type == ACPI_HOTKEY_EVENT
302 && key->event_hotkey.external_hotkey_num == event) {
303 val = key->link.hotkey_standard_num;
304 break;
305 }
306 }
307
308 return val;
309}
310
311static void
312acpi_hotkey_notify_handler(acpi_handle handle, u32 event, void *data)
313{
314 struct acpi_device *device = NULL;
315 u32 internal_event;
316
317
318 if (acpi_bus_get_device(handle, &device))
319 return;
320
321 internal_event = hotkey_get_internal_event(event, &global_hotkey_list);
322 acpi_bus_generate_event(device, internal_event, 0);
323
324 return;
325}
326
327/* Need to invent automatically hotkey add method */
328static int auto_hotkey_add(struct acpi_device *device)
329{
330 /* Implement me */
331 return 0;
332}
333
334/* Need to invent automatically hotkey remove method */
335static int auto_hotkey_remove(struct acpi_device *device, int type)
336{
337 /* Implement me */
338 return 0;
339}
340
341/* Create a proc file for each polling method */
342static int create_polling_proc(union acpi_hotkey *device)
343{
344 struct proc_dir_entry *proc;
345 char proc_name[80];
346 mode_t mode;
347
348 mode = S_IFREG | S_IRUGO | S_IWUGO;
349
350 sprintf(proc_name, "%d", device->link.hotkey_standard_num);
351 /*
352 strcat(proc_name, device->poll_hotkey.poll_method);
353 */
354 proc = create_proc_entry(proc_name, mode, hotkey_proc_dir);
355
356 if (!proc) {
357 return -ENODEV;
358 } else {
359 proc->proc_fops = &hotkey_polling_fops;
360 proc->owner = THIS_MODULE;
361 proc->data = device;
362 proc->uid = 0;
363 proc->gid = 0;
364 device->poll_hotkey.proc = proc;
365 }
366 return 0;
367}
368
369static int hotkey_add(union acpi_hotkey *device)
370{
371 int status = 0;
372 struct acpi_device *dev = NULL;
373
374
375 if (device->link.hotkey_type == ACPI_HOTKEY_EVENT) {
376 acpi_bus_get_device(device->event_hotkey.bus_handle, &dev);
377 status = acpi_install_notify_handler(dev->handle,
378 ACPI_DEVICE_NOTIFY,
379 acpi_hotkey_notify_handler,
380 dev);
381 } else /* Add polling hotkey */
382 create_polling_proc(device);
383
384 global_hotkey_list.count++;
385
386 list_add_tail(&device->link.entries, global_hotkey_list.entries);
387
388 return status;
389}
390
391static int hotkey_remove(union acpi_hotkey *device)
392{
393 struct list_head *entries, *next;
394
395
396 list_for_each_safe(entries, next, global_hotkey_list.entries) {
397 union acpi_hotkey *key =
398 container_of(entries, union acpi_hotkey, entries);
399 if (key->link.hotkey_standard_num ==
400 device->link.hotkey_standard_num) {
401 list_del(&key->link.entries);
402 free_hotkey_device(key);
403 global_hotkey_list.count--;
404 break;
405 }
406 }
407 kfree(device);
408 return 0;
409}
410
411static int hotkey_update(union acpi_hotkey *key)
412{
413 struct list_head *entries;
414
415
416 list_for_each(entries, global_hotkey_list.entries) {
417 union acpi_hotkey *tmp =
418 container_of(entries, union acpi_hotkey, entries);
419 if (tmp->link.hotkey_standard_num ==
420 key->link.hotkey_standard_num) {
421 if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
422 free_hotkey_buffer(tmp);
423 tmp->event_hotkey.bus_handle =
424 key->event_hotkey.bus_handle;
425 tmp->event_hotkey.external_hotkey_num =
426 key->event_hotkey.external_hotkey_num;
427 tmp->event_hotkey.action_handle =
428 key->event_hotkey.action_handle;
429 tmp->event_hotkey.action_method =
430 key->event_hotkey.action_method;
431 kfree(key);
432 } else {
433 /*
434 char proc_name[80];
435
436 sprintf(proc_name, "%d", tmp->link.hotkey_standard_num);
437 strcat(proc_name, tmp->poll_hotkey.poll_method);
438 remove_proc_entry(proc_name,hotkey_proc_dir);
439 */
440 free_poll_hotkey_buffer(tmp);
441 tmp->poll_hotkey.poll_handle =
442 key->poll_hotkey.poll_handle;
443 tmp->poll_hotkey.poll_method =
444 key->poll_hotkey.poll_method;
445 tmp->poll_hotkey.action_handle =
446 key->poll_hotkey.action_handle;
447 tmp->poll_hotkey.action_method =
448 key->poll_hotkey.action_method;
449 tmp->poll_hotkey.poll_result =
450 key->poll_hotkey.poll_result;
451 /*
452 create_polling_proc(tmp);
453 */
454 kfree(key);
455 }
456 return 0;
457 break;
458 }
459 }
460
461 return -ENODEV;
462}
463
464static void free_hotkey_device(union acpi_hotkey *key)
465{
466 struct acpi_device *dev;
467
468
469 if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
470 acpi_bus_get_device(key->event_hotkey.bus_handle, &dev);
471 if (dev->handle)
472 acpi_remove_notify_handler(dev->handle,
473 ACPI_DEVICE_NOTIFY,
474 acpi_hotkey_notify_handler);
475 free_hotkey_buffer(key);
476 } else {
477 char proc_name[80];
478
479 sprintf(proc_name, "%d", key->link.hotkey_standard_num);
480 /*
481 strcat(proc_name, key->poll_hotkey.poll_method);
482 */
483 remove_proc_entry(proc_name, hotkey_proc_dir);
484 free_poll_hotkey_buffer(key);
485 }
486 kfree(key);
487 return;
488}
489
490static void free_hotkey_buffer(union acpi_hotkey *key)
491{
492 /* key would never be null, action method could be */
493 kfree(key->event_hotkey.action_method);
494}
495
496static void free_poll_hotkey_buffer(union acpi_hotkey *key)
497{
498 /* key would never be null, others could be*/
499 kfree(key->poll_hotkey.action_method);
500 kfree(key->poll_hotkey.poll_method);
501 kfree(key->poll_hotkey.poll_result);
502}
503static int
504init_hotkey_device(union acpi_hotkey *key, char **config_entry,
505 int std_num, int external_num)
506{
507 acpi_handle tmp_handle;
508 acpi_status status = AE_OK;
509
510 if (std_num < 0 || IS_POLL(std_num) || !key)
511 goto do_fail;
512
513 if (!config_entry[bus_handle] || !config_entry[action_handle]
514 || !config_entry[method])
515 goto do_fail;
516
517 key->link.hotkey_type = ACPI_HOTKEY_EVENT;
518 key->link.hotkey_standard_num = std_num;
519 key->event_hotkey.flag = 0;
520 key->event_hotkey.action_method = config_entry[method];
521
522 status = acpi_get_handle(NULL, config_entry[bus_handle],
523 &(key->event_hotkey.bus_handle));
524 if (ACPI_FAILURE(status))
525 goto do_fail_zero;
526 key->event_hotkey.external_hotkey_num = external_num;
527 status = acpi_get_handle(NULL, config_entry[action_handle],
528 &(key->event_hotkey.action_handle));
529 if (ACPI_FAILURE(status))
530 goto do_fail_zero;
531 status = acpi_get_handle(key->event_hotkey.action_handle,
532 config_entry[method], &tmp_handle);
533 if (ACPI_FAILURE(status))
534 goto do_fail_zero;
535 return AE_OK;
536do_fail_zero:
537 key->event_hotkey.action_method = NULL;
538do_fail:
539 return -ENODEV;
540}
541
542static int
543init_poll_hotkey_device(union acpi_hotkey *key, char **config_entry,
544 int std_num)
545{
546 acpi_status status = AE_OK;
547 acpi_handle tmp_handle;
548
549 if (std_num < 0 || IS_EVENT(std_num) || !key)
550 goto do_fail;
551 if (!config_entry[bus_handle] ||!config_entry[bus_method] ||
552 !config_entry[action_handle] || !config_entry[method])
553 goto do_fail;
554
555 key->link.hotkey_type = ACPI_HOTKEY_POLLING;
556 key->link.hotkey_standard_num = std_num;
557 key->poll_hotkey.flag = 0;
558 key->poll_hotkey.poll_method = config_entry[bus_method];
559 key->poll_hotkey.action_method = config_entry[method];
560
561 status = acpi_get_handle(NULL, config_entry[bus_handle],
562 &(key->poll_hotkey.poll_handle));
563 if (ACPI_FAILURE(status))
564 goto do_fail_zero;
565 status = acpi_get_handle(key->poll_hotkey.poll_handle,
566 config_entry[bus_method], &tmp_handle);
567 if (ACPI_FAILURE(status))
568 goto do_fail_zero;
569 status =
570 acpi_get_handle(NULL, config_entry[action_handle],
571 &(key->poll_hotkey.action_handle));
572 if (ACPI_FAILURE(status))
573 goto do_fail_zero;
574 status = acpi_get_handle(key->poll_hotkey.action_handle,
575 config_entry[method], &tmp_handle);
576 if (ACPI_FAILURE(status))
577 goto do_fail_zero;
578 key->poll_hotkey.poll_result =
579 kmalloc(sizeof(union acpi_object), GFP_KERNEL);
580 if (!key->poll_hotkey.poll_result)
581 goto do_fail_zero;
582 return AE_OK;
583
584do_fail_zero:
585 key->poll_hotkey.poll_method = NULL;
586 key->poll_hotkey.action_method = NULL;
587do_fail:
588 return -ENODEV;
589}
590
591static int hotkey_open_config(struct inode *inode, struct file *file)
592{
593 return (single_open
594 (file, hotkey_config_seq_show, PDE(inode)->data));
595}
596
597static int hotkey_poll_open_config(struct inode *inode, struct file *file)
598{
599 return (single_open
600 (file, hotkey_poll_config_seq_show, PDE(inode)->data));
601}
602
603static int hotkey_config_seq_show(struct seq_file *seq, void *offset)
604{
605 struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
606 struct list_head *entries;
607 char bus_name[ACPI_PATHNAME_MAX] = { 0 };
608 char action_name[ACPI_PATHNAME_MAX] = { 0 };
609 struct acpi_buffer bus = { ACPI_PATHNAME_MAX, bus_name };
610 struct acpi_buffer act = { ACPI_PATHNAME_MAX, action_name };
611
612
613 list_for_each(entries, hotkey_list->entries) {
614 union acpi_hotkey *key =
615 container_of(entries, union acpi_hotkey, entries);
616 if (key->link.hotkey_type == ACPI_HOTKEY_EVENT) {
617 acpi_get_name(key->event_hotkey.bus_handle,
618 ACPI_NAME_TYPE_MAX, &bus);
619 acpi_get_name(key->event_hotkey.action_handle,
620 ACPI_NAME_TYPE_MAX, &act);
621 seq_printf(seq, "%s:%s:%s:%d:%d\n", bus_name,
622 action_name,
623 key->event_hotkey.action_method,
624 key->link.hotkey_standard_num,
625 key->event_hotkey.external_hotkey_num);
626 }
627 }
628 seq_puts(seq, "\n");
629 return 0;
630}
631
632static int hotkey_poll_config_seq_show(struct seq_file *seq, void *offset)
633{
634 struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
635 struct list_head *entries;
636 char bus_name[ACPI_PATHNAME_MAX] = { 0 };
637 char action_name[ACPI_PATHNAME_MAX] = { 0 };
638 struct acpi_buffer bus = { ACPI_PATHNAME_MAX, bus_name };
639 struct acpi_buffer act = { ACPI_PATHNAME_MAX, action_name };
640
641
642 list_for_each(entries, hotkey_list->entries) {
643 union acpi_hotkey *key =
644 container_of(entries, union acpi_hotkey, entries);
645 if (key->link.hotkey_type == ACPI_HOTKEY_POLLING) {
646 acpi_get_name(key->poll_hotkey.poll_handle,
647 ACPI_NAME_TYPE_MAX, &bus);
648 acpi_get_name(key->poll_hotkey.action_handle,
649 ACPI_NAME_TYPE_MAX, &act);
650 seq_printf(seq, "%s:%s:%s:%s:%d\n", bus_name,
651 key->poll_hotkey.poll_method,
652 action_name,
653 key->poll_hotkey.action_method,
654 key->link.hotkey_standard_num);
655 }
656 }
657 seq_puts(seq, "\n");
658 return 0;
659}
660
661static int
662get_parms(char *config_record, int *cmd, char **config_entry,
663 int *internal_event_num, int *external_event_num)
664{
665/* the format of *config_record =
666 * "1:\d+:*" : "cmd:internal_event_num"
667 * "\d+:\w+:\w+:\w+:\w+:\d+:\d+" :
668 * "cmd:bus_handle:bus_method:action_handle:method:internal_event_num:external_event_num"
669 */
670 char *tmp, *tmp1, count;
671 int i;
672
673 sscanf(config_record, "%d", cmd);
674 if (*cmd == 1) {
675 if (sscanf(config_record, "%d:%d", cmd, internal_event_num) !=
676 2)
677 goto do_fail;
678 else
679 return (6);
680 }
681 tmp = strchr(config_record, ':');
682 if (!tmp)
683 goto do_fail;
684 tmp++;
685 for (i = 0; i < LAST_CONF_ENTRY; i++) {
686 tmp1 = strchr(tmp, ':');
687 if (!tmp1) {
688 goto do_fail;
689 }
690 count = tmp1 - tmp;
691 config_entry[i] = kzalloc(count + 1, GFP_KERNEL);
692 if (!config_entry[i])
693 goto handle_failure;
694 strncpy(config_entry[i], tmp, count);
695 tmp = tmp1 + 1;
696 }
697 if (sscanf(tmp, "%d:%d", internal_event_num, external_event_num) <= 0)
698 goto handle_failure;
699 if (!IS_OTHERS(*internal_event_num)) {
700 return 6;
701 }
702handle_failure:
703 while (i-- > 0)
704 kfree(config_entry[i]);
705do_fail:
706 return -1;
707}
708
709/* count is length for one input record */
710static ssize_t hotkey_write_config(struct file *file,
711 const char __user * buffer,
712 size_t count, loff_t * data)
713{
714 char *config_record = NULL;
715 char *config_entry[LAST_CONF_ENTRY];
716 int cmd, internal_event_num, external_event_num;
717 int ret = 0;
718 union acpi_hotkey *key = kzalloc(sizeof(union acpi_hotkey), GFP_KERNEL);
719
720 if (!key)
721 return -ENOMEM;
722
723 config_record = kzalloc(count + 1, GFP_KERNEL);
724 if (!config_record) {
725 kfree(key);
726 return -ENOMEM;
727 }
728
729 if (copy_from_user(config_record, buffer, count)) {
730 kfree(config_record);
731 kfree(key);
732 printk(KERN_ERR PREFIX "Invalid data\n");
733 return -EINVAL;
734 }
735 ret = get_parms(config_record, &cmd, config_entry,
736 &internal_event_num, &external_event_num);
737 kfree(config_record);
738 if (ret != 6) {
739 printk(KERN_ERR PREFIX "Invalid data format ret=%d\n", ret);
740 return -EINVAL;
741 }
742
743 if (cmd == 1) {
744 union acpi_hotkey *tmp = NULL;
745 tmp = get_hotkey_by_event(&global_hotkey_list,
746 internal_event_num);
747 if (!tmp)
748 printk(KERN_ERR PREFIX "Invalid key\n");
749 else
750 memcpy(key, tmp, sizeof(union acpi_hotkey));
751 goto cont_cmd;
752 }
753 if (IS_EVENT(internal_event_num)) {
754 if (init_hotkey_device(key, config_entry,
755 internal_event_num, external_event_num))
756 goto init_hotkey_fail;
757 } else {
758 if (init_poll_hotkey_device(key, config_entry,
759 internal_event_num))
760 goto init_poll_hotkey_fail;
761 }
762cont_cmd:
763 switch (cmd) {
764 case 0:
765 if (get_hotkey_by_event(&global_hotkey_list,
766 key->link.hotkey_standard_num))
767 goto fail_out;
768 else
769 hotkey_add(key);
770 break;
771 case 1:
772 hotkey_remove(key);
773 break;
774 case 2:
775 /* key is kfree()ed if matched*/
776 if (hotkey_update(key))
777 goto fail_out;
778 break;
779 default:
780 goto fail_out;
781 break;
782 }
783 return count;
784
785init_poll_hotkey_fail: /* failed init_poll_hotkey_device */
786 kfree(config_entry[bus_method]);
787 config_entry[bus_method] = NULL;
788init_hotkey_fail: /* failed init_hotkey_device */
789 kfree(config_entry[method]);
790fail_out:
791 kfree(config_entry[bus_handle]);
792 kfree(config_entry[action_handle]);
793 /* No double free since elements =NULL for error cases */
794 if (IS_EVENT(internal_event_num)) {
795 if (config_entry[bus_method])
796 kfree(config_entry[bus_method]);
797 free_hotkey_buffer(key); /* frees [method] */
798 } else
799 free_poll_hotkey_buffer(key); /* frees [bus_method]+[method] */
800 kfree(key);
801 printk(KERN_ERR PREFIX "invalid key\n");
802 return -EINVAL;
803}
804
805/*
806 * This function evaluates an ACPI method, given an int as parameter, the
807 * method is searched within the scope of the handle, can be NULL. The output
808 * of the method is written is output, which can also be NULL
809 *
810 * returns 1 if write is successful, 0 else.
811 */
812static int write_acpi_int(acpi_handle handle, const char *method, int val,
813 struct acpi_buffer *output)
814{
815 struct acpi_object_list params; /* list of input parameters (an int here) */
816 union acpi_object in_obj; /* the only param we use */
817 acpi_status status;
818
819 params.count = 1;
820 params.pointer = &in_obj;
821 in_obj.type = ACPI_TYPE_INTEGER;
822 in_obj.integer.value = val;
823
824 status = acpi_evaluate_object(handle, (char *)method, &params, output);
825
826 return (status == AE_OK);
827}
828
829static int read_acpi_int(acpi_handle handle, const char *method,
830 union acpi_object *val)
831{
832 struct acpi_buffer output;
833 union acpi_object out_obj;
834 acpi_status status;
835
836 output.length = sizeof(out_obj);
837 output.pointer = &out_obj;
838
839 status = acpi_evaluate_object(handle, (char *)method, NULL, &output);
840 if (val) {
841 val->integer.value = out_obj.integer.value;
842 val->type = out_obj.type;
843 } else
844 printk(KERN_ERR PREFIX "null val pointer\n");
845 return ((status == AE_OK)
846 && (out_obj.type == ACPI_TYPE_INTEGER));
847}
848
849static union acpi_hotkey *get_hotkey_by_event(struct
850 acpi_hotkey_list
851 *hotkey_list, int event)
852{
853 struct list_head *entries;
854
855 list_for_each(entries, hotkey_list->entries) {
856 union acpi_hotkey *key =
857 container_of(entries, union acpi_hotkey, entries);
858 if (key->link.hotkey_standard_num == event) {
859 return (key);
860 }
861 }
862 return (NULL);
863}
864
865/*
866 * user call AML method interface:
867 * Call convention:
868 * echo "event_num: arg type : value"
869 * example: echo "1:1:30" > /proc/acpi/action
870 * Just support 1 integer arg passing to AML method
871 */
872
873static ssize_t hotkey_execute_aml_method(struct file *file,
874 const char __user * buffer,
875 size_t count, loff_t * data)
876{
877 struct acpi_hotkey_list *hotkey_list = &global_hotkey_list;
878 char *arg;
879 int event, method_type, type, value;
880 union acpi_hotkey *key;
881
882
883 arg = kzalloc(count + 1, GFP_KERNEL);
884 if (!arg)
885 return -ENOMEM;
886
887 if (copy_from_user(arg, buffer, count)) {
888 kfree(arg);
889 printk(KERN_ERR PREFIX "Invalid argument 2\n");
890 return -EINVAL;
891 }
892
893 if (sscanf(arg, "%d:%d:%d:%d", &event, &method_type, &type, &value) !=
894 4) {
895 kfree(arg);
896 printk(KERN_ERR PREFIX "Invalid argument 3\n");
897 return -EINVAL;
898 }
899 kfree(arg);
900 if (type == ACPI_TYPE_INTEGER) {
901 key = get_hotkey_by_event(hotkey_list, event);
902 if (!key)
903 goto do_fail;
904 if (IS_EVENT(event))
905 write_acpi_int(key->event_hotkey.action_handle,
906 key->event_hotkey.action_method, value,
907 NULL);
908 else if (IS_POLL(event)) {
909 if (method_type == POLL_METHOD)
910 read_acpi_int(key->poll_hotkey.poll_handle,
911 key->poll_hotkey.poll_method,
912 key->poll_hotkey.poll_result);
913 else if (method_type == ACTION_METHOD)
914 write_acpi_int(key->poll_hotkey.action_handle,
915 key->poll_hotkey.action_method,
916 value, NULL);
917 else
918 goto do_fail;
919
920 }
921 } else {
922 printk(KERN_WARNING "Not supported\n");
923 return -EINVAL;
924 }
925 return count;
926 do_fail:
927 return -EINVAL;
928
929}
930
931static int __init hotkey_init(void)
932{
933 int result;
934 mode_t mode = S_IFREG | S_IRUGO | S_IWUGO;
935
936
937 if (acpi_disabled)
938 return -ENODEV;
939
940 if (acpi_specific_hotkey_enabled) {
941 printk("Using specific hotkey driver\n");
942 return -ENODEV;
943 }
944
945 hotkey_proc_dir = proc_mkdir(HOTKEY_PROC, acpi_root_dir);
946 if (!hotkey_proc_dir) {
947 return (-ENODEV);
948 }
949 hotkey_proc_dir->owner = THIS_MODULE;
950
951 hotkey_config =
952 create_proc_entry(HOTKEY_EV_CONFIG, mode, hotkey_proc_dir);
953 if (!hotkey_config) {
954 goto do_fail1;
955 } else {
956 hotkey_config->proc_fops = &hotkey_config_fops;
957 hotkey_config->data = &global_hotkey_list;
958 hotkey_config->owner = THIS_MODULE;
959 hotkey_config->uid = 0;
960 hotkey_config->gid = 0;
961 }
962
963 hotkey_poll_config =
964 create_proc_entry(HOTKEY_PL_CONFIG, mode, hotkey_proc_dir);
965 if (!hotkey_poll_config) {
966 goto do_fail2;
967 } else {
968 hotkey_poll_config->proc_fops = &hotkey_poll_config_fops;
969 hotkey_poll_config->data = &global_hotkey_list;
970 hotkey_poll_config->owner = THIS_MODULE;
971 hotkey_poll_config->uid = 0;
972 hotkey_poll_config->gid = 0;
973 }
974
975 hotkey_action = create_proc_entry(HOTKEY_ACTION, mode, hotkey_proc_dir);
976 if (!hotkey_action) {
977 goto do_fail3;
978 } else {
979 hotkey_action->proc_fops = &hotkey_action_fops;
980 hotkey_action->owner = THIS_MODULE;
981 hotkey_action->uid = 0;
982 hotkey_action->gid = 0;
983 }
984
985 hotkey_info = create_proc_entry(HOTKEY_INFO, mode, hotkey_proc_dir);
986 if (!hotkey_info) {
987 goto do_fail4;
988 } else {
989 hotkey_info->proc_fops = &hotkey_info_fops;
990 hotkey_info->owner = THIS_MODULE;
991 hotkey_info->uid = 0;
992 hotkey_info->gid = 0;
993 }
994
995 result = acpi_bus_register_driver(&hotkey_driver);
996 if (result < 0)
997 goto do_fail5;
998 global_hotkey_list.count = 0;
999 global_hotkey_list.entries = &hotkey_entries;
1000
1001 INIT_LIST_HEAD(&hotkey_entries);
1002
1003 return (0);
1004
1005 do_fail5:
1006 remove_proc_entry(HOTKEY_INFO, hotkey_proc_dir);
1007 do_fail4:
1008 remove_proc_entry(HOTKEY_ACTION, hotkey_proc_dir);
1009 do_fail3:
1010 remove_proc_entry(HOTKEY_PL_CONFIG, hotkey_proc_dir);
1011 do_fail2:
1012 remove_proc_entry(HOTKEY_EV_CONFIG, hotkey_proc_dir);
1013 do_fail1:
1014 remove_proc_entry(HOTKEY_PROC, acpi_root_dir);
1015 return (-ENODEV);
1016}
1017
1018static void __exit hotkey_exit(void)
1019{
1020 struct list_head *entries, *next;
1021
1022
1023 list_for_each_safe(entries, next, global_hotkey_list.entries) {
1024 union acpi_hotkey *key =
1025 container_of(entries, union acpi_hotkey, entries);
1026
1027 acpi_os_wait_events_complete(NULL);
1028 list_del(&key->link.entries);
1029 global_hotkey_list.count--;
1030 free_hotkey_device(key);
1031 }
1032 acpi_bus_unregister_driver(&hotkey_driver);
1033 remove_proc_entry(HOTKEY_EV_CONFIG, hotkey_proc_dir);
1034 remove_proc_entry(HOTKEY_PL_CONFIG, hotkey_proc_dir);
1035 remove_proc_entry(HOTKEY_ACTION, hotkey_proc_dir);
1036 remove_proc_entry(HOTKEY_INFO, hotkey_proc_dir);
1037 remove_proc_entry(HOTKEY_PROC, acpi_root_dir);
1038 return;
1039}
1040
1041module_init(hotkey_init);
1042module_exit(hotkey_exit);
diff --git a/drivers/acpi/i2c_ec.c b/drivers/acpi/i2c_ec.c
index 76ec8b63e69f..acab4a481897 100644
--- a/drivers/acpi/i2c_ec.c
+++ b/drivers/acpi/i2c_ec.c
@@ -27,18 +27,17 @@
27#define ACPI_EC_HC_COMPONENT 0x00080000 27#define ACPI_EC_HC_COMPONENT 0x00080000
28#define ACPI_EC_HC_CLASS "ec_hc_smbus" 28#define ACPI_EC_HC_CLASS "ec_hc_smbus"
29#define ACPI_EC_HC_HID "ACPI0001" 29#define ACPI_EC_HC_HID "ACPI0001"
30#define ACPI_EC_HC_DRIVER_NAME "ACPI EC HC smbus driver"
31#define ACPI_EC_HC_DEVICE_NAME "EC HC smbus" 30#define ACPI_EC_HC_DEVICE_NAME "EC HC smbus"
32 31
33#define _COMPONENT ACPI_EC_HC_COMPONENT 32#define _COMPONENT ACPI_EC_HC_COMPONENT
34 33
35ACPI_MODULE_NAME("acpi_smbus") 34ACPI_MODULE_NAME("i2c_ec");
36 35
37static int acpi_ec_hc_add(struct acpi_device *device); 36static int acpi_ec_hc_add(struct acpi_device *device);
38static int acpi_ec_hc_remove(struct acpi_device *device, int type); 37static int acpi_ec_hc_remove(struct acpi_device *device, int type);
39 38
40static struct acpi_driver acpi_ec_hc_driver = { 39static struct acpi_driver acpi_ec_hc_driver = {
41 .name = ACPI_EC_HC_DRIVER_NAME, 40 .name = "i2c_ec",
42 .class = ACPI_EC_HC_CLASS, 41 .class = ACPI_EC_HC_CLASS,
43 .ids = ACPI_EC_HC_HID, 42 .ids = ACPI_EC_HC_HID,
44 .ops = { 43 .ops = {
diff --git a/drivers/acpi/ibm_acpi.c b/drivers/acpi/ibm_acpi.c
index c6144ca66638..1a0ed3dc409c 100644
--- a/drivers/acpi/ibm_acpi.c
+++ b/drivers/acpi/ibm_acpi.c
@@ -496,6 +496,10 @@ static int ibm_acpi_driver_init(void)
496 printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION); 496 printk(IBM_INFO "%s v%s\n", IBM_DESC, IBM_VERSION);
497 printk(IBM_INFO "%s\n", IBM_URL); 497 printk(IBM_INFO "%s\n", IBM_URL);
498 498
499 if (ibm_thinkpad_ec_found)
500 printk(IBM_INFO "ThinkPad EC firmware %s\n",
501 ibm_thinkpad_ec_found);
502
499 return 0; 503 return 0;
500} 504}
501 505
@@ -2617,7 +2621,7 @@ static void __init ibm_handle_init(char *name,
2617 ibm_handle_init(#object, &object##_handle, *object##_parent, \ 2621 ibm_handle_init(#object, &object##_handle, *object##_parent, \
2618 object##_paths, ARRAY_SIZE(object##_paths), &object##_path) 2622 object##_paths, ARRAY_SIZE(object##_paths), &object##_path)
2619 2623
2620static int set_ibm_param(const char *val, struct kernel_param *kp) 2624static int __init set_ibm_param(const char *val, struct kernel_param *kp)
2621{ 2625{
2622 unsigned int i; 2626 unsigned int i;
2623 2627
@@ -2659,7 +2663,8 @@ static void acpi_ibm_exit(void)
2659 for (i = ARRAY_SIZE(ibms) - 1; i >= 0; i--) 2663 for (i = ARRAY_SIZE(ibms) - 1; i >= 0; i--)
2660 ibm_exit(&ibms[i]); 2664 ibm_exit(&ibms[i]);
2661 2665
2662 remove_proc_entry(IBM_DIR, acpi_root_dir); 2666 if (proc_dir)
2667 remove_proc_entry(IBM_DIR, acpi_root_dir);
2663 2668
2664 if (ibm_thinkpad_ec_found) 2669 if (ibm_thinkpad_ec_found)
2665 kfree(ibm_thinkpad_ec_found); 2670 kfree(ibm_thinkpad_ec_found);
@@ -2696,11 +2701,6 @@ static int __init acpi_ibm_init(void)
2696 if (acpi_disabled) 2701 if (acpi_disabled)
2697 return -ENODEV; 2702 return -ENODEV;
2698 2703
2699 if (!acpi_specific_hotkey_enabled) {
2700 printk(IBM_ERR "using generic hotkey driver\n");
2701 return -ENODEV;
2702 }
2703
2704 /* ec is required because many other handles are relative to it */ 2704 /* ec is required because many other handles are relative to it */
2705 IBM_HANDLE_INIT(ec); 2705 IBM_HANDLE_INIT(ec);
2706 if (!ec_handle) { 2706 if (!ec_handle) {
@@ -2710,9 +2710,6 @@ static int __init acpi_ibm_init(void)
2710 2710
2711 /* Models with newer firmware report the EC in DMI */ 2711 /* Models with newer firmware report the EC in DMI */
2712 ibm_thinkpad_ec_found = check_dmi_for_ec(); 2712 ibm_thinkpad_ec_found = check_dmi_for_ec();
2713 if (ibm_thinkpad_ec_found)
2714 printk(IBM_INFO "ThinkPad EC firmware %s\n",
2715 ibm_thinkpad_ec_found);
2716 2713
2717 /* these handles are not required */ 2714 /* these handles are not required */
2718 IBM_HANDLE_INIT(vid); 2715 IBM_HANDLE_INIT(vid);
@@ -2742,6 +2739,7 @@ static int __init acpi_ibm_init(void)
2742 proc_dir = proc_mkdir(IBM_DIR, acpi_root_dir); 2739 proc_dir = proc_mkdir(IBM_DIR, acpi_root_dir);
2743 if (!proc_dir) { 2740 if (!proc_dir) {
2744 printk(IBM_ERR "unable to create proc dir %s", IBM_DIR); 2741 printk(IBM_ERR "unable to create proc dir %s", IBM_DIR);
2742 acpi_ibm_exit();
2745 return -ENODEV; 2743 return -ENODEV;
2746 } 2744 }
2747 proc_dir->owner = THIS_MODULE; 2745 proc_dir->owner = THIS_MODULE;
diff --git a/drivers/acpi/numa.c b/drivers/acpi/numa.c
index 4a9faff4c01d..8fcd6a15517f 100644
--- a/drivers/acpi/numa.c
+++ b/drivers/acpi/numa.c
@@ -33,7 +33,7 @@
33 33
34#define ACPI_NUMA 0x80000000 34#define ACPI_NUMA 0x80000000
35#define _COMPONENT ACPI_NUMA 35#define _COMPONENT ACPI_NUMA
36ACPI_MODULE_NAME("numa") 36ACPI_MODULE_NAME("numa");
37 37
38static nodemask_t nodes_found_map = NODE_MASK_NONE; 38static nodemask_t nodes_found_map = NODE_MASK_NONE;
39#define PXM_INVAL -1 39#define PXM_INVAL -1
@@ -45,12 +45,6 @@ int __cpuinitdata pxm_to_node_map[MAX_PXM_DOMAINS]
45int __cpuinitdata node_to_pxm_map[MAX_NUMNODES] 45int __cpuinitdata node_to_pxm_map[MAX_NUMNODES]
46 = { [0 ... MAX_NUMNODES - 1] = PXM_INVAL }; 46 = { [0 ... MAX_NUMNODES - 1] = PXM_INVAL };
47 47
48extern int __init acpi_table_parse_madt_family(char *id,
49 unsigned long madt_size,
50 int entry_id,
51 acpi_madt_entry_handler handler,
52 unsigned int max_entries);
53
54int __cpuinit pxm_to_node(int pxm) 48int __cpuinit pxm_to_node(int pxm)
55{ 49{
56 if (pxm < 0) 50 if (pxm < 0)
@@ -208,9 +202,9 @@ static int __init acpi_parse_srat(struct acpi_table_header *table)
208 202
209int __init 203int __init
210acpi_table_parse_srat(enum acpi_srat_type id, 204acpi_table_parse_srat(enum acpi_srat_type id,
211 acpi_madt_entry_handler handler, unsigned int max_entries) 205 acpi_table_entry_handler handler, unsigned int max_entries)
212{ 206{
213 return acpi_table_parse_madt_family(ACPI_SIG_SRAT, 207 return acpi_table_parse_entries(ACPI_SIG_SRAT,
214 sizeof(struct acpi_table_srat), id, 208 sizeof(struct acpi_table_srat), id,
215 handler, max_entries); 209 handler, max_entries);
216} 210}
@@ -220,9 +214,7 @@ int __init acpi_numa_init(void)
220 int result; 214 int result;
221 215
222 /* SRAT: Static Resource Affinity Table */ 216 /* SRAT: Static Resource Affinity Table */
223 result = acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat); 217 if (!acpi_table_parse(ACPI_SIG_SRAT, acpi_parse_srat)) {
224
225 if (result > 0) {
226 result = acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY, 218 result = acpi_table_parse_srat(ACPI_SRAT_TYPE_CPU_AFFINITY,
227 acpi_parse_processor_affinity, 219 acpi_parse_processor_affinity,
228 NR_CPUS); 220 NR_CPUS);
@@ -230,7 +222,7 @@ int __init acpi_numa_init(void)
230 } 222 }
231 223
232 /* SLIT: System Locality Information Table */ 224 /* SLIT: System Locality Information Table */
233 result = acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit); 225 acpi_table_parse(ACPI_SIG_SLIT, acpi_parse_slit);
234 226
235 acpi_numa_arch_fixup(); 227 acpi_numa_arch_fixup();
236 return 0; 228 return 0;
diff --git a/drivers/acpi/osl.c b/drivers/acpi/osl.c
index 0f6f3bcbc8eb..971eca4864fa 100644
--- a/drivers/acpi/osl.c
+++ b/drivers/acpi/osl.c
@@ -46,7 +46,7 @@
46#include <linux/efi.h> 46#include <linux/efi.h>
47 47
48#define _COMPONENT ACPI_OS_SERVICES 48#define _COMPONENT ACPI_OS_SERVICES
49ACPI_MODULE_NAME("osl") 49ACPI_MODULE_NAME("osl");
50#define PREFIX "ACPI: " 50#define PREFIX "ACPI: "
51struct acpi_os_dpc { 51struct acpi_os_dpc {
52 acpi_osd_exec_callback function; 52 acpi_osd_exec_callback function;
@@ -68,9 +68,6 @@ EXPORT_SYMBOL(acpi_in_debugger);
68extern char line_buf[80]; 68extern char line_buf[80];
69#endif /*ENABLE_DEBUGGER */ 69#endif /*ENABLE_DEBUGGER */
70 70
71int acpi_specific_hotkey_enabled = TRUE;
72EXPORT_SYMBOL(acpi_specific_hotkey_enabled);
73
74static unsigned int acpi_irq_irq; 71static unsigned int acpi_irq_irq;
75static acpi_osd_handler acpi_irq_handler; 72static acpi_osd_handler acpi_irq_handler;
76static void *acpi_irq_context; 73static void *acpi_irq_context;
@@ -205,7 +202,7 @@ void __iomem *acpi_os_map_memory(acpi_physical_address phys, acpi_size size)
205{ 202{
206 if (phys > ULONG_MAX) { 203 if (phys > ULONG_MAX) {
207 printk(KERN_ERR PREFIX "Cannot map memory that high\n"); 204 printk(KERN_ERR PREFIX "Cannot map memory that high\n");
208 return 0; 205 return NULL;
209 } 206 }
210 if (acpi_gbl_permanent_mmap) 207 if (acpi_gbl_permanent_mmap)
211 /* 208 /*
@@ -890,26 +887,6 @@ u32 acpi_os_get_line(char *buffer)
890} 887}
891#endif /* ACPI_FUTURE_USAGE */ 888#endif /* ACPI_FUTURE_USAGE */
892 889
893/* Assumes no unreadable holes inbetween */
894u8 acpi_os_readable(void *ptr, acpi_size len)
895{
896#if defined(__i386__) || defined(__x86_64__)
897 char tmp;
898 return !__get_user(tmp, (char __user *)ptr)
899 && !__get_user(tmp, (char __user *)ptr + len - 1);
900#endif
901 return 1;
902}
903
904#ifdef ACPI_FUTURE_USAGE
905u8 acpi_os_writable(void *ptr, acpi_size len)
906{
907 /* could do dummy write (racy) or a kernel page table lookup.
908 The later may be difficult at early boot when kmap doesn't work yet. */
909 return 1;
910}
911#endif
912
913acpi_status acpi_os_signal(u32 function, void *info) 890acpi_status acpi_os_signal(u32 function, void *info)
914{ 891{
915 switch (function) { 892 switch (function) {
@@ -1012,14 +989,6 @@ static int __init acpi_wake_gpes_always_on_setup(char *str)
1012 989
1013__setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup); 990__setup("acpi_wake_gpes_always_on", acpi_wake_gpes_always_on_setup);
1014 991
1015static int __init acpi_hotkey_setup(char *str)
1016{
1017 acpi_specific_hotkey_enabled = FALSE;
1018 return 1;
1019}
1020
1021__setup("acpi_generic_hotkey", acpi_hotkey_setup);
1022
1023/* 992/*
1024 * max_cstate is defined in the base kernel so modules can 993 * max_cstate is defined in the base kernel so modules can
1025 * change it w/o depending on the state of the processor module. 994 * change it w/o depending on the state of the processor module.
diff --git a/drivers/acpi/pci_bind.c b/drivers/acpi/pci_bind.c
index 55f57a61c55e..028969370bbf 100644
--- a/drivers/acpi/pci_bind.c
+++ b/drivers/acpi/pci_bind.c
@@ -36,7 +36,7 @@
36#include <acpi/acpi_drivers.h> 36#include <acpi/acpi_drivers.h>
37 37
38#define _COMPONENT ACPI_PCI_COMPONENT 38#define _COMPONENT ACPI_PCI_COMPONENT
39ACPI_MODULE_NAME("pci_bind") 39ACPI_MODULE_NAME("pci_bind");
40 40
41struct acpi_pci_data { 41struct acpi_pci_data {
42 struct acpi_pci_id id; 42 struct acpi_pci_id id;
diff --git a/drivers/acpi/pci_irq.c b/drivers/acpi/pci_irq.c
index fe7d007833ad..dd3186abe07a 100644
--- a/drivers/acpi/pci_irq.c
+++ b/drivers/acpi/pci_irq.c
@@ -38,7 +38,7 @@
38#include <acpi/acpi_drivers.h> 38#include <acpi/acpi_drivers.h>
39 39
40#define _COMPONENT ACPI_PCI_COMPONENT 40#define _COMPONENT ACPI_PCI_COMPONENT
41ACPI_MODULE_NAME("pci_irq") 41ACPI_MODULE_NAME("pci_irq");
42 42
43static struct acpi_prt_list acpi_prt; 43static struct acpi_prt_list acpi_prt;
44static DEFINE_SPINLOCK(acpi_prt_lock); 44static DEFINE_SPINLOCK(acpi_prt_lock);
diff --git a/drivers/acpi/pci_link.c b/drivers/acpi/pci_link.c
index 0f683c8c6fbc..acc594771379 100644
--- a/drivers/acpi/pci_link.c
+++ b/drivers/acpi/pci_link.c
@@ -44,10 +44,9 @@
44#include <acpi/acpi_drivers.h> 44#include <acpi/acpi_drivers.h>
45 45
46#define _COMPONENT ACPI_PCI_COMPONENT 46#define _COMPONENT ACPI_PCI_COMPONENT
47ACPI_MODULE_NAME("pci_link") 47ACPI_MODULE_NAME("pci_link");
48#define ACPI_PCI_LINK_CLASS "pci_irq_routing" 48#define ACPI_PCI_LINK_CLASS "pci_irq_routing"
49#define ACPI_PCI_LINK_HID "PNP0C0F" 49#define ACPI_PCI_LINK_HID "PNP0C0F"
50#define ACPI_PCI_LINK_DRIVER_NAME "ACPI PCI Interrupt Link Driver"
51#define ACPI_PCI_LINK_DEVICE_NAME "PCI Interrupt Link" 50#define ACPI_PCI_LINK_DEVICE_NAME "PCI Interrupt Link"
52#define ACPI_PCI_LINK_FILE_INFO "info" 51#define ACPI_PCI_LINK_FILE_INFO "info"
53#define ACPI_PCI_LINK_FILE_STATUS "state" 52#define ACPI_PCI_LINK_FILE_STATUS "state"
@@ -56,7 +55,7 @@ static int acpi_pci_link_add(struct acpi_device *device);
56static int acpi_pci_link_remove(struct acpi_device *device, int type); 55static int acpi_pci_link_remove(struct acpi_device *device, int type);
57 56
58static struct acpi_driver acpi_pci_link_driver = { 57static struct acpi_driver acpi_pci_link_driver = {
59 .name = ACPI_PCI_LINK_DRIVER_NAME, 58 .name = "pci_link",
60 .class = ACPI_PCI_LINK_CLASS, 59 .class = ACPI_PCI_LINK_CLASS,
61 .ids = ACPI_PCI_LINK_HID, 60 .ids = ACPI_PCI_LINK_HID,
62 .ops = { 61 .ops = {
diff --git a/drivers/acpi/pci_root.c b/drivers/acpi/pci_root.c
index 4ecf701687e8..ad4145a37786 100644
--- a/drivers/acpi/pci_root.c
+++ b/drivers/acpi/pci_root.c
@@ -36,17 +36,16 @@
36#include <acpi/acpi_drivers.h> 36#include <acpi/acpi_drivers.h>
37 37
38#define _COMPONENT ACPI_PCI_COMPONENT 38#define _COMPONENT ACPI_PCI_COMPONENT
39ACPI_MODULE_NAME("pci_root") 39ACPI_MODULE_NAME("pci_root");
40#define ACPI_PCI_ROOT_CLASS "pci_bridge" 40#define ACPI_PCI_ROOT_CLASS "pci_bridge"
41#define ACPI_PCI_ROOT_HID "PNP0A03" 41#define ACPI_PCI_ROOT_HID "PNP0A03"
42#define ACPI_PCI_ROOT_DRIVER_NAME "ACPI PCI Root Bridge Driver"
43#define ACPI_PCI_ROOT_DEVICE_NAME "PCI Root Bridge" 42#define ACPI_PCI_ROOT_DEVICE_NAME "PCI Root Bridge"
44static int acpi_pci_root_add(struct acpi_device *device); 43static int acpi_pci_root_add(struct acpi_device *device);
45static int acpi_pci_root_remove(struct acpi_device *device, int type); 44static int acpi_pci_root_remove(struct acpi_device *device, int type);
46static int acpi_pci_root_start(struct acpi_device *device); 45static int acpi_pci_root_start(struct acpi_device *device);
47 46
48static struct acpi_driver acpi_pci_root_driver = { 47static struct acpi_driver acpi_pci_root_driver = {
49 .name = ACPI_PCI_ROOT_DRIVER_NAME, 48 .name = "pci_root",
50 .class = ACPI_PCI_ROOT_CLASS, 49 .class = ACPI_PCI_ROOT_CLASS,
51 .ids = ACPI_PCI_ROOT_HID, 50 .ids = ACPI_PCI_ROOT_HID,
52 .ops = { 51 .ops = {
diff --git a/drivers/acpi/power.c b/drivers/acpi/power.c
index 0ba7dfbbb2ee..1ef338545dfe 100644
--- a/drivers/acpi/power.c
+++ b/drivers/acpi/power.c
@@ -45,10 +45,9 @@
45#include <acpi/acpi_drivers.h> 45#include <acpi/acpi_drivers.h>
46 46
47#define _COMPONENT ACPI_POWER_COMPONENT 47#define _COMPONENT ACPI_POWER_COMPONENT
48ACPI_MODULE_NAME("acpi_power") 48ACPI_MODULE_NAME("power");
49#define ACPI_POWER_COMPONENT 0x00800000 49#define ACPI_POWER_COMPONENT 0x00800000
50#define ACPI_POWER_CLASS "power_resource" 50#define ACPI_POWER_CLASS "power_resource"
51#define ACPI_POWER_DRIVER_NAME "ACPI Power Resource Driver"
52#define ACPI_POWER_DEVICE_NAME "Power Resource" 51#define ACPI_POWER_DEVICE_NAME "Power Resource"
53#define ACPI_POWER_FILE_INFO "info" 52#define ACPI_POWER_FILE_INFO "info"
54#define ACPI_POWER_FILE_STATUS "state" 53#define ACPI_POWER_FILE_STATUS "state"
@@ -57,25 +56,33 @@ ACPI_MODULE_NAME("acpi_power")
57#define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF 56#define ACPI_POWER_RESOURCE_STATE_UNKNOWN 0xFF
58static int acpi_power_add(struct acpi_device *device); 57static int acpi_power_add(struct acpi_device *device);
59static int acpi_power_remove(struct acpi_device *device, int type); 58static int acpi_power_remove(struct acpi_device *device, int type);
59static int acpi_power_resume(struct acpi_device *device);
60static int acpi_power_open_fs(struct inode *inode, struct file *file); 60static int acpi_power_open_fs(struct inode *inode, struct file *file);
61 61
62static struct acpi_driver acpi_power_driver = { 62static struct acpi_driver acpi_power_driver = {
63 .name = ACPI_POWER_DRIVER_NAME, 63 .name = "power",
64 .class = ACPI_POWER_CLASS, 64 .class = ACPI_POWER_CLASS,
65 .ids = ACPI_POWER_HID, 65 .ids = ACPI_POWER_HID,
66 .ops = { 66 .ops = {
67 .add = acpi_power_add, 67 .add = acpi_power_add,
68 .remove = acpi_power_remove, 68 .remove = acpi_power_remove,
69 .resume = acpi_power_resume,
69 }, 70 },
70}; 71};
71 72
73struct acpi_power_reference {
74 struct list_head node;
75 struct acpi_device *device;
76};
77
72struct acpi_power_resource { 78struct acpi_power_resource {
73 struct acpi_device * device; 79 struct acpi_device * device;
74 acpi_bus_id name; 80 acpi_bus_id name;
75 u32 system_level; 81 u32 system_level;
76 u32 order; 82 u32 order;
77 int state; 83 int state;
78 int references; 84 struct mutex resource_lock;
85 struct list_head reference;
79}; 86};
80 87
81static struct list_head acpi_power_resource_list; 88static struct list_head acpi_power_resource_list;
@@ -171,22 +178,47 @@ static int acpi_power_get_list_state(struct acpi_handle_list *list, int *state)
171 return result; 178 return result;
172} 179}
173 180
174static int acpi_power_on(acpi_handle handle) 181static int acpi_power_on(acpi_handle handle, struct acpi_device *dev)
175{ 182{
176 int result = 0; 183 int result = 0;
184 int found = 0;
177 acpi_status status = AE_OK; 185 acpi_status status = AE_OK;
178 struct acpi_device *device = NULL;
179 struct acpi_power_resource *resource = NULL; 186 struct acpi_power_resource *resource = NULL;
187 struct list_head *node, *next;
188 struct acpi_power_reference *ref;
180 189
181 190
182 result = acpi_power_get_context(handle, &resource); 191 result = acpi_power_get_context(handle, &resource);
183 if (result) 192 if (result)
184 return result; 193 return result;
185 194
186 resource->references++; 195 mutex_lock(&resource->resource_lock);
196 list_for_each_safe(node, next, &resource->reference) {
197 ref = container_of(node, struct acpi_power_reference, node);
198 if (dev->handle == ref->device->handle) {
199 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] already referenced by resource [%s]\n",
200 dev->pnp.bus_id, resource->name));
201 found = 1;
202 break;
203 }
204 }
205
206 if (!found) {
207 ref = kmalloc(sizeof (struct acpi_power_reference),
208 irqs_disabled() ? GFP_ATOMIC : GFP_KERNEL);
209 if (!ref) {
210 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "kmalloc() failed\n"));
211 mutex_unlock(&resource->resource_lock);
212 return -ENOMEM;
213 }
214 list_add_tail(&ref->node, &resource->reference);
215 ref->device = dev;
216 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] added to resource [%s] references\n",
217 dev->pnp.bus_id, resource->name));
218 }
219 mutex_unlock(&resource->resource_lock);
187 220
188 if ((resource->references > 1) 221 if (resource->state == ACPI_POWER_RESOURCE_STATE_ON) {
189 || (resource->state == ACPI_POWER_RESOURCE_STATE_ON)) {
190 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already on\n", 222 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already on\n",
191 resource->name)); 223 resource->name));
192 return 0; 224 return 0;
@@ -203,38 +235,49 @@ static int acpi_power_on(acpi_handle handle)
203 return -ENOEXEC; 235 return -ENOEXEC;
204 236
205 /* Update the power resource's _device_ power state */ 237 /* Update the power resource's _device_ power state */
206 device = resource->device;
207 resource->device->power.state = ACPI_STATE_D0; 238 resource->device->power.state = ACPI_STATE_D0;
208 239
209 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned on\n", 240 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] turned on\n",
210 resource->name)); 241 resource->name));
211
212 return 0; 242 return 0;
213} 243}
214 244
215static int acpi_power_off_device(acpi_handle handle) 245static int acpi_power_off_device(acpi_handle handle, struct acpi_device *dev)
216{ 246{
217 int result = 0; 247 int result = 0;
218 acpi_status status = AE_OK; 248 acpi_status status = AE_OK;
219 struct acpi_power_resource *resource = NULL; 249 struct acpi_power_resource *resource = NULL;
250 struct list_head *node, *next;
251 struct acpi_power_reference *ref;
252
220 253
221 result = acpi_power_get_context(handle, &resource); 254 result = acpi_power_get_context(handle, &resource);
222 if (result) 255 if (result)
223 return result; 256 return result;
224 257
225 if (resource->references) 258 mutex_lock(&resource->resource_lock);
226 resource->references--; 259 list_for_each_safe(node, next, &resource->reference) {
260 ref = container_of(node, struct acpi_power_reference, node);
261 if (dev->handle == ref->device->handle) {
262 list_del(&ref->node);
263 kfree(ref);
264 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Device [%s] removed from resource [%s] references\n",
265 dev->pnp.bus_id, resource->name));
266 break;
267 }
268 }
227 269
228 if (resource->references) { 270 if (!list_empty(&resource->reference)) {
229 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 271 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Cannot turn resource [%s] off - resource is in use\n",
230 "Resource [%s] is still in use, dereferencing\n", 272 resource->name));
231 resource->device->pnp.bus_id)); 273 mutex_unlock(&resource->resource_lock);
232 return 0; 274 return 0;
233 } 275 }
276 mutex_unlock(&resource->resource_lock);
234 277
235 if (resource->state == ACPI_POWER_RESOURCE_STATE_OFF) { 278 if (resource->state == ACPI_POWER_RESOURCE_STATE_OFF) {
236 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already off\n", 279 ACPI_DEBUG_PRINT((ACPI_DB_INFO, "Resource [%s] already off\n",
237 resource->device->pnp.bus_id)); 280 resource->name));
238 return 0; 281 return 0;
239 } 282 }
240 283
@@ -276,7 +319,7 @@ int acpi_enable_wakeup_device_power(struct acpi_device *dev)
276 arg.integer.value = 1; 319 arg.integer.value = 1;
277 /* Open power resource */ 320 /* Open power resource */
278 for (i = 0; i < dev->wakeup.resources.count; i++) { 321 for (i = 0; i < dev->wakeup.resources.count; i++) {
279 ret = acpi_power_on(dev->wakeup.resources.handles[i]); 322 ret = acpi_power_on(dev->wakeup.resources.handles[i], dev);
280 if (ret) { 323 if (ret) {
281 printk(KERN_ERR PREFIX "Transition power state\n"); 324 printk(KERN_ERR PREFIX "Transition power state\n");
282 dev->wakeup.flags.valid = 0; 325 dev->wakeup.flags.valid = 0;
@@ -323,7 +366,7 @@ int acpi_disable_wakeup_device_power(struct acpi_device *dev)
323 366
324 /* Close power resource */ 367 /* Close power resource */
325 for (i = 0; i < dev->wakeup.resources.count; i++) { 368 for (i = 0; i < dev->wakeup.resources.count; i++) {
326 ret = acpi_power_off_device(dev->wakeup.resources.handles[i]); 369 ret = acpi_power_off_device(dev->wakeup.resources.handles[i], dev);
327 if (ret) { 370 if (ret) {
328 printk(KERN_ERR PREFIX "Transition power state\n"); 371 printk(KERN_ERR PREFIX "Transition power state\n");
329 dev->wakeup.flags.valid = 0; 372 dev->wakeup.flags.valid = 0;
@@ -407,16 +450,20 @@ int acpi_power_transition(struct acpi_device *device, int state)
407 * (e.g. so the device doesn't lose power while transitioning). 450 * (e.g. so the device doesn't lose power while transitioning).
408 */ 451 */
409 for (i = 0; i < tl->count; i++) { 452 for (i = 0; i < tl->count; i++) {
410 result = acpi_power_on(tl->handles[i]); 453 result = acpi_power_on(tl->handles[i], device);
411 if (result) 454 if (result)
412 goto end; 455 goto end;
413 } 456 }
414 457
458 if (device->power.state == state) {
459 goto end;
460 }
461
415 /* 462 /*
416 * Then we dereference all power resources used in the current list. 463 * Then we dereference all power resources used in the current list.
417 */ 464 */
418 for (i = 0; i < cl->count; i++) { 465 for (i = 0; i < cl->count; i++) {
419 result = acpi_power_off_device(cl->handles[i]); 466 result = acpi_power_off_device(cl->handles[i], device);
420 if (result) 467 if (result)
421 goto end; 468 goto end;
422 } 469 }
@@ -439,7 +486,11 @@ static struct proc_dir_entry *acpi_power_dir;
439 486
440static int acpi_power_seq_show(struct seq_file *seq, void *offset) 487static int acpi_power_seq_show(struct seq_file *seq, void *offset)
441{ 488{
489 int count = 0;
490 int result = 0;
442 struct acpi_power_resource *resource = NULL; 491 struct acpi_power_resource *resource = NULL;
492 struct list_head *node, *next;
493 struct acpi_power_reference *ref;
443 494
444 495
445 resource = seq->private; 496 resource = seq->private;
@@ -447,6 +498,10 @@ static int acpi_power_seq_show(struct seq_file *seq, void *offset)
447 if (!resource) 498 if (!resource)
448 goto end; 499 goto end;
449 500
501 result = acpi_power_get_state(resource);
502 if (result)
503 goto end;
504
450 seq_puts(seq, "state: "); 505 seq_puts(seq, "state: ");
451 switch (resource->state) { 506 switch (resource->state) {
452 case ACPI_POWER_RESOURCE_STATE_ON: 507 case ACPI_POWER_RESOURCE_STATE_ON:
@@ -460,11 +515,18 @@ static int acpi_power_seq_show(struct seq_file *seq, void *offset)
460 break; 515 break;
461 } 516 }
462 517
518 mutex_lock(&resource->resource_lock);
519 list_for_each_safe(node, next, &resource->reference) {
520 ref = container_of(node, struct acpi_power_reference, node);
521 count++;
522 }
523 mutex_unlock(&resource->resource_lock);
524
463 seq_printf(seq, "system level: S%d\n" 525 seq_printf(seq, "system level: S%d\n"
464 "order: %d\n" 526 "order: %d\n"
465 "reference count: %d\n", 527 "reference count: %d\n",
466 resource->system_level, 528 resource->system_level,
467 resource->order, resource->references); 529 resource->order, count);
468 530
469 end: 531 end:
470 return 0; 532 return 0;
@@ -537,6 +599,8 @@ static int acpi_power_add(struct acpi_device *device)
537 return -ENOMEM; 599 return -ENOMEM;
538 600
539 resource->device = device; 601 resource->device = device;
602 mutex_init(&resource->resource_lock);
603 INIT_LIST_HEAD(&resource->reference);
540 strcpy(resource->name, device->pnp.bus_id); 604 strcpy(resource->name, device->pnp.bus_id);
541 strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME); 605 strcpy(acpi_device_name(device), ACPI_POWER_DEVICE_NAME);
542 strcpy(acpi_device_class(device), ACPI_POWER_CLASS); 606 strcpy(acpi_device_class(device), ACPI_POWER_CLASS);
@@ -584,6 +648,7 @@ static int acpi_power_add(struct acpi_device *device)
584static int acpi_power_remove(struct acpi_device *device, int type) 648static int acpi_power_remove(struct acpi_device *device, int type)
585{ 649{
586 struct acpi_power_resource *resource = NULL; 650 struct acpi_power_resource *resource = NULL;
651 struct list_head *node, *next;
587 652
588 653
589 if (!device || !acpi_driver_data(device)) 654 if (!device || !acpi_driver_data(device))
@@ -593,11 +658,54 @@ static int acpi_power_remove(struct acpi_device *device, int type)
593 658
594 acpi_power_remove_fs(device); 659 acpi_power_remove_fs(device);
595 660
661 mutex_lock(&resource->resource_lock);
662 list_for_each_safe(node, next, &resource->reference) {
663 struct acpi_power_reference *ref = container_of(node, struct acpi_power_reference, node);
664 list_del(&ref->node);
665 kfree(ref);
666 }
667 mutex_unlock(&resource->resource_lock);
668
596 kfree(resource); 669 kfree(resource);
597 670
598 return 0; 671 return 0;
599} 672}
600 673
674static int acpi_power_resume(struct acpi_device *device)
675{
676 int result = 0;
677 struct acpi_power_resource *resource = NULL;
678 struct acpi_power_reference *ref;
679
680 if (!device || !acpi_driver_data(device))
681 return -EINVAL;
682
683 resource = (struct acpi_power_resource *)acpi_driver_data(device);
684
685 result = acpi_power_get_state(resource);
686 if (result)
687 return result;
688
689 mutex_lock(&resource->resource_lock);
690 if ((resource->state == ACPI_POWER_RESOURCE_STATE_ON) &&
691 list_empty(&resource->reference)) {
692 mutex_unlock(&resource->resource_lock);
693 result = acpi_power_off_device(device->handle, NULL);
694 return result;
695 }
696
697 if ((resource->state == ACPI_POWER_RESOURCE_STATE_OFF) &&
698 !list_empty(&resource->reference)) {
699 ref = container_of(resource->reference.next, struct acpi_power_reference, node);
700 mutex_unlock(&resource->resource_lock);
701 result = acpi_power_on(device->handle, ref->device);
702 return result;
703 }
704
705 mutex_unlock(&resource->resource_lock);
706 return 0;
707}
708
601static int __init acpi_power_init(void) 709static int __init acpi_power_init(void)
602{ 710{
603 int result = 0; 711 int result = 0;
diff --git a/drivers/acpi/processor_core.c b/drivers/acpi/processor_core.c
index 0079bc51082c..99d1516d1e70 100644
--- a/drivers/acpi/processor_core.c
+++ b/drivers/acpi/processor_core.c
@@ -60,7 +60,6 @@
60 60
61#define ACPI_PROCESSOR_COMPONENT 0x01000000 61#define ACPI_PROCESSOR_COMPONENT 0x01000000
62#define ACPI_PROCESSOR_CLASS "processor" 62#define ACPI_PROCESSOR_CLASS "processor"
63#define ACPI_PROCESSOR_DRIVER_NAME "ACPI Processor Driver"
64#define ACPI_PROCESSOR_DEVICE_NAME "Processor" 63#define ACPI_PROCESSOR_DEVICE_NAME "Processor"
65#define ACPI_PROCESSOR_FILE_INFO "info" 64#define ACPI_PROCESSOR_FILE_INFO "info"
66#define ACPI_PROCESSOR_FILE_THROTTLING "throttling" 65#define ACPI_PROCESSOR_FILE_THROTTLING "throttling"
@@ -74,10 +73,10 @@
74#define ACPI_STA_PRESENT 0x00000001 73#define ACPI_STA_PRESENT 0x00000001
75 74
76#define _COMPONENT ACPI_PROCESSOR_COMPONENT 75#define _COMPONENT ACPI_PROCESSOR_COMPONENT
77ACPI_MODULE_NAME("acpi_processor") 76ACPI_MODULE_NAME("processor_core");
78 77
79 MODULE_AUTHOR("Paul Diefenbaugh"); 78MODULE_AUTHOR("Paul Diefenbaugh");
80MODULE_DESCRIPTION(ACPI_PROCESSOR_DRIVER_NAME); 79MODULE_DESCRIPTION("ACPI Processor Driver");
81MODULE_LICENSE("GPL"); 80MODULE_LICENSE("GPL");
82 81
83static int acpi_processor_add(struct acpi_device *device); 82static int acpi_processor_add(struct acpi_device *device);
@@ -89,7 +88,7 @@ static acpi_status acpi_processor_hotadd_init(acpi_handle handle, int *p_cpu);
89static int acpi_processor_handle_eject(struct acpi_processor *pr); 88static int acpi_processor_handle_eject(struct acpi_processor *pr);
90 89
91static struct acpi_driver acpi_processor_driver = { 90static struct acpi_driver acpi_processor_driver = {
92 .name = ACPI_PROCESSOR_DRIVER_NAME, 91 .name = "processor",
93 .class = ACPI_PROCESSOR_CLASS, 92 .class = ACPI_PROCESSOR_CLASS,
94 .ids = ACPI_PROCESSOR_HID, 93 .ids = ACPI_PROCESSOR_HID,
95 .ops = { 94 .ops = {
@@ -404,7 +403,7 @@ static int map_lsapic_id(struct acpi_subtable_header *entry,
404 if (lsapic->lapic_flags & ACPI_MADT_ENABLED) { 403 if (lsapic->lapic_flags & ACPI_MADT_ENABLED) {
405 /* First check against id */ 404 /* First check against id */
406 if (lsapic->processor_id == acpi_id) { 405 if (lsapic->processor_id == acpi_id) {
407 *apic_id = lsapic->id; 406 *apic_id = (lsapic->id << 8) | lsapic->eid;
408 return 1; 407 return 1;
409 /* Check against optional uid */ 408 /* Check against optional uid */
410 } else if (entry->length >= 16 && 409 } else if (entry->length >= 16 &&
@@ -1005,7 +1004,7 @@ static int __init acpi_processor_init(void)
1005#ifdef CONFIG_SMP 1004#ifdef CONFIG_SMP
1006 if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0, 1005 if (ACPI_FAILURE(acpi_get_table(ACPI_SIG_MADT, 0,
1007 (struct acpi_table_header **)&madt))) 1006 (struct acpi_table_header **)&madt)))
1008 madt = 0; 1007 madt = NULL;
1009#endif 1008#endif
1010 1009
1011 acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir); 1010 acpi_processor_dir = proc_mkdir(ACPI_PROCESSOR_CLASS, acpi_root_dir);
diff --git a/drivers/acpi/processor_idle.c b/drivers/acpi/processor_idle.c
index 8206fc1ecc58..60773005b8af 100644
--- a/drivers/acpi/processor_idle.c
+++ b/drivers/acpi/processor_idle.c
@@ -51,6 +51,14 @@
51#include <asm/apic.h> 51#include <asm/apic.h>
52#endif 52#endif
53 53
54/*
55 * Include the apic definitions for x86 to have the APIC timer related defines
56 * available also for UP (on SMP it gets magically included via linux/smp.h).
57 */
58#ifdef CONFIG_X86
59#include <asm/apic.h>
60#endif
61
54#include <asm/io.h> 62#include <asm/io.h>
55#include <asm/uaccess.h> 63#include <asm/uaccess.h>
56 64
@@ -59,9 +67,8 @@
59 67
60#define ACPI_PROCESSOR_COMPONENT 0x01000000 68#define ACPI_PROCESSOR_COMPONENT 0x01000000
61#define ACPI_PROCESSOR_CLASS "processor" 69#define ACPI_PROCESSOR_CLASS "processor"
62#define ACPI_PROCESSOR_DRIVER_NAME "ACPI Processor Driver"
63#define _COMPONENT ACPI_PROCESSOR_COMPONENT 70#define _COMPONENT ACPI_PROCESSOR_COMPONENT
64ACPI_MODULE_NAME("acpi_processor") 71ACPI_MODULE_NAME("processor_idle");
65#define ACPI_PROCESSOR_FILE_POWER "power" 72#define ACPI_PROCESSOR_FILE_POWER "power"
66#define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000) 73#define US_TO_PM_TIMER_TICKS(t) ((t * (PM_TIMER_FREQUENCY/1000)) / 1000)
67#define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */ 74#define C2_OVERHEAD 4 /* 1us (3.579 ticks per us) */
diff --git a/drivers/acpi/processor_perflib.c b/drivers/acpi/processor_perflib.c
index 058f13cf3b79..2f2e7964226d 100644
--- a/drivers/acpi/processor_perflib.c
+++ b/drivers/acpi/processor_perflib.c
@@ -44,10 +44,9 @@
44 44
45#define ACPI_PROCESSOR_COMPONENT 0x01000000 45#define ACPI_PROCESSOR_COMPONENT 0x01000000
46#define ACPI_PROCESSOR_CLASS "processor" 46#define ACPI_PROCESSOR_CLASS "processor"
47#define ACPI_PROCESSOR_DRIVER_NAME "ACPI Processor Driver"
48#define ACPI_PROCESSOR_FILE_PERFORMANCE "performance" 47#define ACPI_PROCESSOR_FILE_PERFORMANCE "performance"
49#define _COMPONENT ACPI_PROCESSOR_COMPONENT 48#define _COMPONENT ACPI_PROCESSOR_COMPONENT
50ACPI_MODULE_NAME("acpi_processor") 49ACPI_MODULE_NAME("processor_perflib");
51 50
52static DEFINE_MUTEX(performance_mutex); 51static DEFINE_MUTEX(performance_mutex);
53 52
diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c
index 40fecd67ad83..06e6f3fb8825 100644
--- a/drivers/acpi/processor_thermal.c
+++ b/drivers/acpi/processor_thermal.c
@@ -41,9 +41,8 @@
41 41
42#define ACPI_PROCESSOR_COMPONENT 0x01000000 42#define ACPI_PROCESSOR_COMPONENT 0x01000000
43#define ACPI_PROCESSOR_CLASS "processor" 43#define ACPI_PROCESSOR_CLASS "processor"
44#define ACPI_PROCESSOR_DRIVER_NAME "ACPI Processor Driver"
45#define _COMPONENT ACPI_PROCESSOR_COMPONENT 44#define _COMPONENT ACPI_PROCESSOR_COMPONENT
46ACPI_MODULE_NAME("acpi_processor") 45ACPI_MODULE_NAME("processor_thermal");
47 46
48/* -------------------------------------------------------------------------- 47/* --------------------------------------------------------------------------
49 Limit Interface 48 Limit Interface
diff --git a/drivers/acpi/processor_throttling.c b/drivers/acpi/processor_throttling.c
index 89dff3639abe..b33486009f41 100644
--- a/drivers/acpi/processor_throttling.c
+++ b/drivers/acpi/processor_throttling.c
@@ -41,9 +41,8 @@
41 41
42#define ACPI_PROCESSOR_COMPONENT 0x01000000 42#define ACPI_PROCESSOR_COMPONENT 0x01000000
43#define ACPI_PROCESSOR_CLASS "processor" 43#define ACPI_PROCESSOR_CLASS "processor"
44#define ACPI_PROCESSOR_DRIVER_NAME "ACPI Processor Driver"
45#define _COMPONENT ACPI_PROCESSOR_COMPONENT 44#define _COMPONENT ACPI_PROCESSOR_COMPONENT
46ACPI_MODULE_NAME("acpi_processor") 45ACPI_MODULE_NAME("processor_throttling");
47 46
48/* -------------------------------------------------------------------------- 47/* --------------------------------------------------------------------------
49 Throttling Control 48 Throttling Control
diff --git a/drivers/acpi/sbs.c b/drivers/acpi/sbs.c
index f58fc7447ab4..59640d9a0acc 100644
--- a/drivers/acpi/sbs.c
+++ b/drivers/acpi/sbs.c
@@ -59,7 +59,6 @@ extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
59#define ACPI_AC_CLASS "ac_adapter" 59#define ACPI_AC_CLASS "ac_adapter"
60#define ACPI_BATTERY_CLASS "battery" 60#define ACPI_BATTERY_CLASS "battery"
61#define ACPI_SBS_HID "ACPI0002" 61#define ACPI_SBS_HID "ACPI0002"
62#define ACPI_SBS_DRIVER_NAME "ACPI Smart Battery System Driver"
63#define ACPI_SBS_DEVICE_NAME "Smart Battery System" 62#define ACPI_SBS_DEVICE_NAME "Smart Battery System"
64#define ACPI_SBS_FILE_INFO "info" 63#define ACPI_SBS_FILE_INFO "info"
65#define ACPI_SBS_FILE_STATE "state" 64#define ACPI_SBS_FILE_STATE "state"
@@ -78,7 +77,7 @@ extern void acpi_unlock_battery_dir(struct proc_dir_entry *acpi_battery_dir);
78#define MAX_SBS_BAT 4 77#define MAX_SBS_BAT 4
79#define MAX_SMBUS_ERR 1 78#define MAX_SMBUS_ERR 1
80 79
81ACPI_MODULE_NAME("acpi_sbs"); 80ACPI_MODULE_NAME("sbs");
82 81
83MODULE_AUTHOR("Rich Townsend"); 82MODULE_AUTHOR("Rich Townsend");
84MODULE_DESCRIPTION("Smart Battery System ACPI interface driver"); 83MODULE_DESCRIPTION("Smart Battery System ACPI interface driver");
@@ -110,7 +109,7 @@ static void acpi_battery_smbus_err_handler(struct acpi_ec_smbus *smbus);
110static void acpi_sbs_update_queue(void *data); 109static void acpi_sbs_update_queue(void *data);
111 110
112static struct acpi_driver acpi_sbs_driver = { 111static struct acpi_driver acpi_sbs_driver = {
113 .name = ACPI_SBS_DRIVER_NAME, 112 .name = "sbs",
114 .class = ACPI_SBS_CLASS, 113 .class = ACPI_SBS_CLASS,
115 .ids = ACPI_SBS_HID, 114 .ids = ACPI_SBS_HID,
116 .ops = { 115 .ops = {
@@ -1034,21 +1033,19 @@ static int acpi_battery_read_state(struct seq_file *seq, void *offset)
1034 } else { 1033 } else {
1035 seq_printf(seq, "capacity state: ok\n"); 1034 seq_printf(seq, "capacity state: ok\n");
1036 } 1035 }
1036
1037 foo = (s16) battery->state.amperage * battery->info.ipscale;
1038 if (battery->info.capacity_mode) {
1039 foo = foo * battery->info.design_voltage / 1000;
1040 }
1037 if (battery->state.amperage < 0) { 1041 if (battery->state.amperage < 0) {
1038 seq_printf(seq, "charging state: discharging\n"); 1042 seq_printf(seq, "charging state: discharging\n");
1039 foo = battery->state.remaining_capacity * cscale * 60 / 1043 seq_printf(seq, "present rate: %d %s\n",
1040 (battery->state.average_time_to_empty == 0 ? 1 : 1044 -foo, battery->info.capacity_mode ? "mW" : "mA");
1041 battery->state.average_time_to_empty);
1042 seq_printf(seq, "present rate: %i%s\n",
1043 foo, battery->info.capacity_mode ? "0 mW" : " mA");
1044 } else if (battery->state.amperage > 0) { 1045 } else if (battery->state.amperage > 0) {
1045 seq_printf(seq, "charging state: charging\n"); 1046 seq_printf(seq, "charging state: charging\n");
1046 foo = (battery->info.full_charge_capacity - 1047 seq_printf(seq, "present rate: %d %s\n",
1047 battery->state.remaining_capacity) * cscale * 60 / 1048 foo, battery->info.capacity_mode ? "mW" : "mA");
1048 (battery->state.average_time_to_full == 0 ? 1 :
1049 battery->state.average_time_to_full);
1050 seq_printf(seq, "present rate: %i%s\n",
1051 foo, battery->info.capacity_mode ? "0 mW" : " mA");
1052 } else { 1049 } else {
1053 seq_printf(seq, "charging state: charged\n"); 1050 seq_printf(seq, "charging state: charged\n");
1054 seq_printf(seq, "present rate: 0 %s\n", 1051 seq_printf(seq, "present rate: 0 %s\n",
diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c
index 64f26db10c8e..bb0e0da39fb1 100644
--- a/drivers/acpi/scan.c
+++ b/drivers/acpi/scan.c
@@ -11,13 +11,12 @@
11#include <acpi/acinterp.h> /* for acpi_ex_eisa_id_to_string() */ 11#include <acpi/acinterp.h> /* for acpi_ex_eisa_id_to_string() */
12 12
13#define _COMPONENT ACPI_BUS_COMPONENT 13#define _COMPONENT ACPI_BUS_COMPONENT
14ACPI_MODULE_NAME("scan") 14ACPI_MODULE_NAME("scan");
15#define STRUCT_TO_INT(s) (*((int*)&s)) 15#define STRUCT_TO_INT(s) (*((int*)&s))
16extern struct acpi_device *acpi_root; 16extern struct acpi_device *acpi_root;
17 17
18#define ACPI_BUS_CLASS "system_bus" 18#define ACPI_BUS_CLASS "system_bus"
19#define ACPI_BUS_HID "ACPI_BUS" 19#define ACPI_BUS_HID "ACPI_BUS"
20#define ACPI_BUS_DRIVER_NAME "ACPI Bus Driver"
21#define ACPI_BUS_DEVICE_NAME "System Bus" 20#define ACPI_BUS_DEVICE_NAME "System Bus"
22 21
23static LIST_HEAD(acpi_device_list); 22static LIST_HEAD(acpi_device_list);
diff --git a/drivers/acpi/sleep/main.c b/drivers/acpi/sleep/main.c
index 62ce87d71651..37a0930fc0a6 100644
--- a/drivers/acpi/sleep/main.c
+++ b/drivers/acpi/sleep/main.c
@@ -200,7 +200,7 @@ static struct dmi_system_id __initdata acpisleep_dmi_table[] = {
200 {}, 200 {},
201}; 201};
202 202
203static int __init acpi_sleep_init(void) 203int __init acpi_sleep_init(void)
204{ 204{
205 int i = 0; 205 int i = 0;
206 206
@@ -229,4 +229,3 @@ static int __init acpi_sleep_init(void)
229 return 0; 229 return 0;
230} 230}
231 231
232late_initcall(acpi_sleep_init);
diff --git a/drivers/acpi/system.c b/drivers/acpi/system.c
index 7147b0bdab0a..83a8d3097904 100644
--- a/drivers/acpi/system.c
+++ b/drivers/acpi/system.c
@@ -31,14 +31,13 @@
31#include <acpi/acpi_drivers.h> 31#include <acpi/acpi_drivers.h>
32 32
33#define _COMPONENT ACPI_SYSTEM_COMPONENT 33#define _COMPONENT ACPI_SYSTEM_COMPONENT
34ACPI_MODULE_NAME("acpi_system") 34ACPI_MODULE_NAME("system");
35#ifdef MODULE_PARAM_PREFIX 35#ifdef MODULE_PARAM_PREFIX
36#undef MODULE_PARAM_PREFIX 36#undef MODULE_PARAM_PREFIX
37#endif 37#endif
38#define MODULE_PARAM_PREFIX "acpi." 38#define MODULE_PARAM_PREFIX "acpi."
39 39
40#define ACPI_SYSTEM_CLASS "system" 40#define ACPI_SYSTEM_CLASS "system"
41#define ACPI_SYSTEM_DRIVER_NAME "ACPI System Driver"
42#define ACPI_SYSTEM_DEVICE_NAME "System" 41#define ACPI_SYSTEM_DEVICE_NAME "System"
43#define ACPI_SYSTEM_FILE_INFO "info" 42#define ACPI_SYSTEM_FILE_INFO "info"
44#define ACPI_SYSTEM_FILE_EVENT "event" 43#define ACPI_SYSTEM_FILE_EVENT "event"
diff --git a/drivers/acpi/tables.c b/drivers/acpi/tables.c
index 45bd17313c4a..849e2c361804 100644
--- a/drivers/acpi/tables.c
+++ b/drivers/acpi/tables.c
@@ -169,40 +169,40 @@ void acpi_table_print_madt_entry(struct acpi_subtable_header * header)
169 169
170 170
171int __init 171int __init
172acpi_table_parse_madt_family(char *id, 172acpi_table_parse_entries(char *id,
173 unsigned long madt_size, 173 unsigned long table_size,
174 int entry_id, 174 int entry_id,
175 acpi_madt_entry_handler handler, 175 acpi_table_entry_handler handler,
176 unsigned int max_entries) 176 unsigned int max_entries)
177{ 177{
178 struct acpi_table_header *madt = NULL; 178 struct acpi_table_header *table_header = NULL;
179 struct acpi_subtable_header *entry; 179 struct acpi_subtable_header *entry;
180 unsigned int count = 0; 180 unsigned int count = 0;
181 unsigned long madt_end; 181 unsigned long table_end;
182 182
183 if (!handler) 183 if (!handler)
184 return -EINVAL; 184 return -EINVAL;
185 185
186 /* Locate the MADT (if exists). There should only be one. */ 186 /* Locate the table (if exists). There should only be one. */
187 acpi_get_table(id, 0, &madt); 187 acpi_get_table(id, 0, &table_header);
188 188
189 if (!madt) { 189 if (!table_header) {
190 printk(KERN_WARNING PREFIX "%4.4s not present\n", id); 190 printk(KERN_WARNING PREFIX "%4.4s not present\n", id);
191 return -ENODEV; 191 return -ENODEV;
192 } 192 }
193 193
194 madt_end = (unsigned long)madt + madt->length; 194 table_end = (unsigned long)table_header + table_header->length;
195 195
196 /* Parse all entries looking for a match. */ 196 /* Parse all entries looking for a match. */
197 197
198 entry = (struct acpi_subtable_header *) 198 entry = (struct acpi_subtable_header *)
199 ((unsigned long)madt + madt_size); 199 ((unsigned long)table_header + table_size);
200 200
201 while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) < 201 while (((unsigned long)entry) + sizeof(struct acpi_subtable_header) <
202 madt_end) { 202 table_end) {
203 if (entry->type == entry_id 203 if (entry->type == entry_id
204 && (!max_entries || count++ < max_entries)) 204 && (!max_entries || count++ < max_entries))
205 if (handler(entry, madt_end)) 205 if (handler(entry, table_end))
206 return -EINVAL; 206 return -EINVAL;
207 207
208 entry = (struct acpi_subtable_header *) 208 entry = (struct acpi_subtable_header *)
@@ -218,13 +218,22 @@ acpi_table_parse_madt_family(char *id,
218 218
219int __init 219int __init
220acpi_table_parse_madt(enum acpi_madt_type id, 220acpi_table_parse_madt(enum acpi_madt_type id,
221 acpi_madt_entry_handler handler, unsigned int max_entries) 221 acpi_table_entry_handler handler, unsigned int max_entries)
222{ 222{
223 return acpi_table_parse_madt_family(ACPI_SIG_MADT, 223 return acpi_table_parse_entries(ACPI_SIG_MADT,
224 sizeof(struct acpi_table_madt), id, 224 sizeof(struct acpi_table_madt), id,
225 handler, max_entries); 225 handler, max_entries);
226} 226}
227 227
228/**
229 * acpi_table_parse - find table with @id, run @handler on it
230 *
231 * @id: table id to find
232 * @handler: handler to run
233 *
234 * Scan the ACPI System Descriptor Table (STD) for a table matching @id,
235 * run @handler on it. Return 0 if table found, return on if not.
236 */
228int __init acpi_table_parse(char *id, acpi_table_handler handler) 237int __init acpi_table_parse(char *id, acpi_table_handler handler)
229{ 238{
230 struct acpi_table_header *table = NULL; 239 struct acpi_table_header *table = NULL;
@@ -234,9 +243,9 @@ int __init acpi_table_parse(char *id, acpi_table_handler handler)
234 acpi_get_table(id, 0, &table); 243 acpi_get_table(id, 0, &table);
235 if (table) { 244 if (table) {
236 handler(table); 245 handler(table);
237 return 1;
238 } else
239 return 0; 246 return 0;
247 } else
248 return 1;
240} 249}
241 250
242/* 251/*
diff --git a/drivers/acpi/tables/tbxface.c b/drivers/acpi/tables/tbxface.c
index 807978d5381a..417ef5fa7666 100644
--- a/drivers/acpi/tables/tbxface.c
+++ b/drivers/acpi/tables/tbxface.c
@@ -338,9 +338,9 @@ acpi_status acpi_unload_table_id(acpi_owner_id id)
338 int i; 338 int i;
339 acpi_status status = AE_NOT_EXIST; 339 acpi_status status = AE_NOT_EXIST;
340 340
341 ACPI_FUNCTION_TRACE(acpi_unload_table); 341 ACPI_FUNCTION_TRACE(acpi_unload_table_id);
342 342
343 /* Find table from the requested type list */ 343 /* Find table in the global table list */
344 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) { 344 for (i = 0; i < acpi_gbl_root_table_list.count; ++i) {
345 if (id != acpi_gbl_root_table_list.tables[i].owner_id) { 345 if (id != acpi_gbl_root_table_list.tables[i].owner_id) {
346 continue; 346 continue;
@@ -352,8 +352,9 @@ acpi_status acpi_unload_table_id(acpi_owner_id id)
352 * simply a position within the hierarchy 352 * simply a position within the hierarchy
353 */ 353 */
354 acpi_tb_delete_namespace_by_owner(i); 354 acpi_tb_delete_namespace_by_owner(i);
355 acpi_tb_release_owner_id(i); 355 status = acpi_tb_release_owner_id(i);
356 acpi_tb_set_table_loaded_flag(i, FALSE); 356 acpi_tb_set_table_loaded_flag(i, FALSE);
357 break;
357 } 358 }
358 return_ACPI_STATUS(status); 359 return_ACPI_STATUS(status);
359} 360}
@@ -408,7 +409,7 @@ acpi_get_table(char *signature,
408 } 409 }
409 410
410 if (!acpi_gbl_permanent_mmap) { 411 if (!acpi_gbl_permanent_mmap) {
411 acpi_gbl_root_table_list.tables[i].pointer = 0; 412 acpi_gbl_root_table_list.tables[i].pointer = NULL;
412 } 413 }
413 414
414 return (status); 415 return (status);
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 986afd470a14..0ae8b9310cbf 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -47,7 +47,6 @@
47 47
48#define ACPI_THERMAL_COMPONENT 0x04000000 48#define ACPI_THERMAL_COMPONENT 0x04000000
49#define ACPI_THERMAL_CLASS "thermal_zone" 49#define ACPI_THERMAL_CLASS "thermal_zone"
50#define ACPI_THERMAL_DRIVER_NAME "ACPI Thermal Zone Driver"
51#define ACPI_THERMAL_DEVICE_NAME "Thermal Zone" 50#define ACPI_THERMAL_DEVICE_NAME "Thermal Zone"
52#define ACPI_THERMAL_FILE_STATE "state" 51#define ACPI_THERMAL_FILE_STATE "state"
53#define ACPI_THERMAL_FILE_TEMPERATURE "temperature" 52#define ACPI_THERMAL_FILE_TEMPERATURE "temperature"
@@ -71,10 +70,10 @@
71#define CELSIUS_TO_KELVIN(t) ((t+273)*10) 70#define CELSIUS_TO_KELVIN(t) ((t+273)*10)
72 71
73#define _COMPONENT ACPI_THERMAL_COMPONENT 72#define _COMPONENT ACPI_THERMAL_COMPONENT
74ACPI_MODULE_NAME("acpi_thermal") 73ACPI_MODULE_NAME("thermal");
75 74
76MODULE_AUTHOR("Paul Diefenbaugh"); 75MODULE_AUTHOR("Paul Diefenbaugh");
77MODULE_DESCRIPTION(ACPI_THERMAL_DRIVER_NAME); 76MODULE_DESCRIPTION("ACPI Thermal Zone Driver");
78MODULE_LICENSE("GPL"); 77MODULE_LICENSE("GPL");
79 78
80static int tzp; 79static int tzp;
@@ -99,7 +98,7 @@ static ssize_t acpi_thermal_write_polling(struct file *, const char __user *,
99 size_t, loff_t *); 98 size_t, loff_t *);
100 99
101static struct acpi_driver acpi_thermal_driver = { 100static struct acpi_driver acpi_thermal_driver = {
102 .name = ACPI_THERMAL_DRIVER_NAME, 101 .name = "thermal",
103 .class = ACPI_THERMAL_CLASS, 102 .class = ACPI_THERMAL_CLASS,
104 .ids = ACPI_THERMAL_HID, 103 .ids = ACPI_THERMAL_HID,
105 .ops = { 104 .ops = {
@@ -270,7 +269,7 @@ static int acpi_thermal_set_polling(struct acpi_thermal *tz, int seconds)
270 269
271 ACPI_DEBUG_PRINT((ACPI_DB_INFO, 270 ACPI_DEBUG_PRINT((ACPI_DB_INFO,
272 "Polling frequency set to %lu seconds\n", 271 "Polling frequency set to %lu seconds\n",
273 tz->polling_frequency)); 272 tz->polling_frequency/10));
274 273
275 return 0; 274 return 0;
276} 275}
@@ -1357,28 +1356,32 @@ static int acpi_thermal_remove(struct acpi_device *device, int type)
1357static int acpi_thermal_resume(struct acpi_device *device) 1356static int acpi_thermal_resume(struct acpi_device *device)
1358{ 1357{
1359 struct acpi_thermal *tz = NULL; 1358 struct acpi_thermal *tz = NULL;
1360 int i; 1359 int i, j, power_state, result;
1360
1361 1361
1362 if (!device || !acpi_driver_data(device)) 1362 if (!device || !acpi_driver_data(device))
1363 return -EINVAL; 1363 return -EINVAL;
1364 1364
1365 tz = acpi_driver_data(device); 1365 tz = acpi_driver_data(device);
1366 1366
1367 acpi_thermal_get_temperature(tz);
1368
1369 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { 1367 for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) {
1370 if (tz->trips.active[i].flags.valid) { 1368 if (!(&tz->trips.active[i]))
1371 tz->temperature = tz->trips.active[i].temperature; 1369 break;
1372 tz->trips.active[i].flags.enabled = 0; 1370 if (!tz->trips.active[i].flags.valid)
1373 1371 break;
1374 acpi_thermal_active(tz); 1372 tz->trips.active[i].flags.enabled = 1;
1375 1373 for (j = 0; j < tz->trips.active[i].devices.count; j++) {
1376 tz->state.active |= tz->trips.active[i].flags.enabled; 1374 result = acpi_bus_get_power(tz->trips.active[i].devices.
1377 tz->state.active_index = i; 1375 handles[j], &power_state);
1376 if (result || (power_state != ACPI_STATE_D0)) {
1377 tz->trips.active[i].flags.enabled = 0;
1378 break;
1379 }
1378 } 1380 }
1381 tz->state.active |= tz->trips.active[i].flags.enabled;
1379 } 1382 }
1380 1383
1381 acpi_thermal_check(tz); 1384 acpi_thermal_check(tz);
1382 1385
1383 return AE_OK; 1386 return AE_OK;
1384} 1387}
diff --git a/drivers/acpi/toshiba_acpi.c b/drivers/acpi/toshiba_acpi.c
index d9b651ffcdc0..faf8a5232d8e 100644
--- a/drivers/acpi/toshiba_acpi.c
+++ b/drivers/acpi/toshiba_acpi.c
@@ -125,7 +125,7 @@ static int write_acpi_int(const char *methodName, int val)
125 union acpi_object in_objs[1]; 125 union acpi_object in_objs[1];
126 acpi_status status; 126 acpi_status status;
127 127
128 params.count = sizeof(in_objs) / sizeof(in_objs[0]); 128 params.count = ARRAY_SIZE(in_objs);
129 params.pointer = in_objs; 129 params.pointer = in_objs;
130 in_objs[0].type = ACPI_TYPE_INTEGER; 130 in_objs[0].type = ACPI_TYPE_INTEGER;
131 in_objs[0].integer.value = val; 131 in_objs[0].integer.value = val;
@@ -561,10 +561,6 @@ static int __init toshiba_acpi_init(void)
561 if (acpi_disabled) 561 if (acpi_disabled)
562 return -ENODEV; 562 return -ENODEV;
563 563
564 if (!acpi_specific_hotkey_enabled) {
565 printk(MY_INFO "Using generic hotkey driver\n");
566 return -ENODEV;
567 }
568 /* simple device detection: look for HCI method */ 564 /* simple device detection: look for HCI method */
569 if (is_valid_acpi_path(METHOD_HCI_1)) 565 if (is_valid_acpi_path(METHOD_HCI_1))
570 method_hci = METHOD_HCI_1; 566 method_hci = METHOD_HCI_1;
diff --git a/drivers/acpi/utilities/utdelete.c b/drivers/acpi/utilities/utdelete.c
index f777cebdc46d..673a0caa4073 100644
--- a/drivers/acpi/utilities/utdelete.c
+++ b/drivers/acpi/utilities/utdelete.c
@@ -170,7 +170,6 @@ static void acpi_ut_delete_internal_obj(union acpi_operand_object *object)
170 acpi_os_delete_mutex(object->mutex.os_mutex); 170 acpi_os_delete_mutex(object->mutex.os_mutex);
171 acpi_gbl_global_lock_mutex = NULL; 171 acpi_gbl_global_lock_mutex = NULL;
172 } else { 172 } else {
173 acpi_ex_unlink_mutex(object);
174 acpi_os_delete_mutex(object->mutex.os_mutex); 173 acpi_os_delete_mutex(object->mutex.os_mutex);
175 } 174 }
176 break; 175 break;
diff --git a/drivers/acpi/utils.c b/drivers/acpi/utils.c
index 68a809fa7b19..34f157571080 100644
--- a/drivers/acpi/utils.c
+++ b/drivers/acpi/utils.c
@@ -31,7 +31,7 @@
31#include <acpi/acpi_drivers.h> 31#include <acpi/acpi_drivers.h>
32 32
33#define _COMPONENT ACPI_BUS_COMPONENT 33#define _COMPONENT ACPI_BUS_COMPONENT
34ACPI_MODULE_NAME("acpi_utils") 34ACPI_MODULE_NAME("utils");
35 35
36/* -------------------------------------------------------------------------- 36/* --------------------------------------------------------------------------
37 Object Evaluation Helpers 37 Object Evaluation Helpers
diff --git a/drivers/acpi/video.c b/drivers/acpi/video.c
index e0b97add8c63..bf525cca3b63 100644
--- a/drivers/acpi/video.c
+++ b/drivers/acpi/video.c
@@ -40,7 +40,6 @@
40 40
41#define ACPI_VIDEO_COMPONENT 0x08000000 41#define ACPI_VIDEO_COMPONENT 0x08000000
42#define ACPI_VIDEO_CLASS "video" 42#define ACPI_VIDEO_CLASS "video"
43#define ACPI_VIDEO_DRIVER_NAME "ACPI Video Driver"
44#define ACPI_VIDEO_BUS_NAME "Video Bus" 43#define ACPI_VIDEO_BUS_NAME "Video Bus"
45#define ACPI_VIDEO_DEVICE_NAME "Video Device" 44#define ACPI_VIDEO_DEVICE_NAME "Video Device"
46#define ACPI_VIDEO_NOTIFY_SWITCH 0x80 45#define ACPI_VIDEO_NOTIFY_SWITCH 0x80
@@ -65,17 +64,17 @@
65#define ACPI_VIDEO_DISPLAY_LCD 4 64#define ACPI_VIDEO_DISPLAY_LCD 4
66 65
67#define _COMPONENT ACPI_VIDEO_COMPONENT 66#define _COMPONENT ACPI_VIDEO_COMPONENT
68ACPI_MODULE_NAME("acpi_video") 67ACPI_MODULE_NAME("video");
69 68
70 MODULE_AUTHOR("Bruno Ducrot"); 69MODULE_AUTHOR("Bruno Ducrot");
71MODULE_DESCRIPTION(ACPI_VIDEO_DRIVER_NAME); 70MODULE_DESCRIPTION("ACPI Video Driver");
72MODULE_LICENSE("GPL"); 71MODULE_LICENSE("GPL");
73 72
74static int acpi_video_bus_add(struct acpi_device *device); 73static int acpi_video_bus_add(struct acpi_device *device);
75static int acpi_video_bus_remove(struct acpi_device *device, int type); 74static int acpi_video_bus_remove(struct acpi_device *device, int type);
76 75
77static struct acpi_driver acpi_video_bus = { 76static struct acpi_driver acpi_video_bus = {
78 .name = ACPI_VIDEO_DRIVER_NAME, 77 .name = "video",
79 .class = ACPI_VIDEO_CLASS, 78 .class = ACPI_VIDEO_CLASS,
80 .ids = ACPI_VIDEO_HID, 79 .ids = ACPI_VIDEO_HID,
81 .ops = { 80 .ops = {
diff --git a/drivers/base/bus.c b/drivers/base/bus.c
index 472810f8e6e7..253868e03c70 100644
--- a/drivers/base/bus.c
+++ b/drivers/base/bus.c
@@ -324,27 +324,25 @@ int bus_for_each_drv(struct bus_type * bus, struct device_driver * start,
324 return error; 324 return error;
325} 325}
326 326
327static int device_add_attrs(struct bus_type * bus, struct device * dev) 327static int device_add_attrs(struct bus_type *bus, struct device *dev)
328{ 328{
329 int error = 0; 329 int error = 0;
330 int i; 330 int i;
331 331
332 if (bus->dev_attrs) { 332 if (!bus->dev_attrs)
333 for (i = 0; attr_name(bus->dev_attrs[i]); i++) { 333 return 0;
334 error = device_create_file(dev,&bus->dev_attrs[i]); 334
335 if (error) 335 for (i = 0; attr_name(bus->dev_attrs[i]); i++) {
336 goto Err; 336 error = device_create_file(dev,&bus->dev_attrs[i]);
337 if (error) {
338 while (--i >= 0)
339 device_remove_file(dev, &bus->dev_attrs[i]);
340 break;
337 } 341 }
338 } 342 }
339 Done:
340 return error; 343 return error;
341 Err:
342 while (--i >= 0)
343 device_remove_file(dev,&bus->dev_attrs[i]);
344 goto Done;
345} 344}
346 345
347
348static void device_remove_attrs(struct bus_type * bus, struct device * dev) 346static void device_remove_attrs(struct bus_type * bus, struct device * dev)
349{ 347{
350 int i; 348 int i;
diff --git a/drivers/base/class.c b/drivers/base/class.c
index 96def1ddba19..1417e5cd4c6f 100644
--- a/drivers/base/class.c
+++ b/drivers/base/class.c
@@ -163,8 +163,7 @@ int class_register(struct class * cls)
163void class_unregister(struct class * cls) 163void class_unregister(struct class * cls)
164{ 164{
165 pr_debug("device class '%s': unregistering\n", cls->name); 165 pr_debug("device class '%s': unregistering\n", cls->name);
166 if (cls->virtual_dir) 166 kobject_unregister(cls->virtual_dir);
167 kobject_unregister(cls->virtual_dir);
168 remove_class_attrs(cls); 167 remove_class_attrs(cls);
169 subsystem_unregister(&cls->subsys); 168 subsystem_unregister(&cls->subsys);
170} 169}
diff --git a/drivers/i2c/busses/i2c-iop3xx.c b/drivers/i2c/busses/i2c-iop3xx.c
index 20ee4f7c53a0..90e2d9350c1b 100644
--- a/drivers/i2c/busses/i2c-iop3xx.c
+++ b/drivers/i2c/busses/i2c-iop3xx.c
@@ -83,7 +83,7 @@ iop3xx_i2c_enable(struct i2c_algo_iop3xx_data *iop3xx_adap)
83 * Every time unit enable is asserted, GPOD needs to be cleared 83 * Every time unit enable is asserted, GPOD needs to be cleared
84 * on IOP3XX to avoid data corruption on the bus. 84 * on IOP3XX to avoid data corruption on the bus.
85 */ 85 */
86#ifdef CONFIG_PLAT_IOP 86#if defined(CONFIG_ARCH_IOP32X) || defined(CONFIG_ARCH_IOP33X)
87 if (iop3xx_adap->id == 0) { 87 if (iop3xx_adap->id == 0) {
88 gpio_line_set(IOP3XX_GPIO_LINE(7), GPIO_LOW); 88 gpio_line_set(IOP3XX_GPIO_LINE(7), GPIO_LOW);
89 gpio_line_set(IOP3XX_GPIO_LINE(6), GPIO_LOW); 89 gpio_line_set(IOP3XX_GPIO_LINE(6), GPIO_LOW);
diff --git a/drivers/i2c/busses/i2c-pxa.c b/drivers/i2c/busses/i2c-pxa.c
index c3b1567c852a..14e83d0aac8c 100644
--- a/drivers/i2c/busses/i2c-pxa.c
+++ b/drivers/i2c/busses/i2c-pxa.c
@@ -34,6 +34,7 @@
34 34
35#include <asm/hardware.h> 35#include <asm/hardware.h>
36#include <asm/irq.h> 36#include <asm/irq.h>
37#include <asm/io.h>
37#include <asm/arch/i2c.h> 38#include <asm/arch/i2c.h>
38#include <asm/arch/pxa-regs.h> 39#include <asm/arch/pxa-regs.h>
39 40
@@ -54,8 +55,21 @@ struct pxa_i2c {
54 unsigned int irqlogidx; 55 unsigned int irqlogidx;
55 u32 isrlog[32]; 56 u32 isrlog[32];
56 u32 icrlog[32]; 57 u32 icrlog[32];
58
59 void __iomem *reg_base;
60
61 unsigned long iobase;
62 unsigned long iosize;
63
64 int irq;
57}; 65};
58 66
67#define _IBMR(i2c) ((i2c)->reg_base + 0)
68#define _IDBR(i2c) ((i2c)->reg_base + 8)
69#define _ICR(i2c) ((i2c)->reg_base + 0x10)
70#define _ISR(i2c) ((i2c)->reg_base + 0x18)
71#define _ISAR(i2c) ((i2c)->reg_base + 0x20)
72
59/* 73/*
60 * I2C Slave mode address 74 * I2C Slave mode address
61 */ 75 */
@@ -130,7 +144,8 @@ static unsigned int i2c_debug = DEBUG;
130 144
131static void i2c_pxa_show_state(struct pxa_i2c *i2c, int lno, const char *fname) 145static void i2c_pxa_show_state(struct pxa_i2c *i2c, int lno, const char *fname)
132{ 146{
133 dev_dbg(&i2c->adap.dev, "state:%s:%d: ISR=%08x, ICR=%08x, IBMR=%02x\n", fname, lno, ISR, ICR, IBMR); 147 dev_dbg(&i2c->adap.dev, "state:%s:%d: ISR=%08x, ICR=%08x, IBMR=%02x\n", fname, lno,
148 readl(_ISR(i2c)), readl(_ICR(i2c)), readl(_IBMR(i2c)));
134} 149}
135 150
136#define show_state(i2c) i2c_pxa_show_state(i2c, __LINE__, __FUNCTION__) 151#define show_state(i2c) i2c_pxa_show_state(i2c, __LINE__, __FUNCTION__)
@@ -153,7 +168,7 @@ static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why)
153 printk("i2c: msg_num: %d msg_idx: %d msg_ptr: %d\n", 168 printk("i2c: msg_num: %d msg_idx: %d msg_ptr: %d\n",
154 i2c->msg_num, i2c->msg_idx, i2c->msg_ptr); 169 i2c->msg_num, i2c->msg_idx, i2c->msg_ptr);
155 printk("i2c: ICR: %08x ISR: %08x\n" 170 printk("i2c: ICR: %08x ISR: %08x\n"
156 "i2c: log: ", ICR, ISR); 171 "i2c: log: ", readl(_ICR(i2c)), readl(_ISR(i2c)));
157 for (i = 0; i < i2c->irqlogidx; i++) 172 for (i = 0; i < i2c->irqlogidx; i++)
158 printk("[%08x:%08x] ", i2c->isrlog[i], i2c->icrlog[i]); 173 printk("[%08x:%08x] ", i2c->isrlog[i], i2c->icrlog[i]);
159 printk("\n"); 174 printk("\n");
@@ -161,7 +176,7 @@ static void i2c_pxa_scream_blue_murder(struct pxa_i2c *i2c, const char *why)
161 176
162static inline int i2c_pxa_is_slavemode(struct pxa_i2c *i2c) 177static inline int i2c_pxa_is_slavemode(struct pxa_i2c *i2c)
163{ 178{
164 return !(ICR & ICR_SCLE); 179 return !(readl(_ICR(i2c)) & ICR_SCLE);
165} 180}
166 181
167static void i2c_pxa_abort(struct pxa_i2c *i2c) 182static void i2c_pxa_abort(struct pxa_i2c *i2c)
@@ -173,28 +188,29 @@ static void i2c_pxa_abort(struct pxa_i2c *i2c)
173 return; 188 return;
174 } 189 }
175 190
176 while (time_before(jiffies, timeout) && (IBMR & 0x1) == 0) { 191 while (time_before(jiffies, timeout) && (readl(_IBMR(i2c)) & 0x1) == 0) {
177 unsigned long icr = ICR; 192 unsigned long icr = readl(_ICR(i2c));
178 193
179 icr &= ~ICR_START; 194 icr &= ~ICR_START;
180 icr |= ICR_ACKNAK | ICR_STOP | ICR_TB; 195 icr |= ICR_ACKNAK | ICR_STOP | ICR_TB;
181 196
182 ICR = icr; 197 writel(icr, _ICR(i2c));
183 198
184 show_state(i2c); 199 show_state(i2c);
185 200
186 msleep(1); 201 msleep(1);
187 } 202 }
188 203
189 ICR &= ~(ICR_MA | ICR_START | ICR_STOP); 204 writel(readl(_ICR(i2c)) & ~(ICR_MA | ICR_START | ICR_STOP),
205 _ICR(i2c));
190} 206}
191 207
192static int i2c_pxa_wait_bus_not_busy(struct pxa_i2c *i2c) 208static int i2c_pxa_wait_bus_not_busy(struct pxa_i2c *i2c)
193{ 209{
194 int timeout = DEF_TIMEOUT; 210 int timeout = DEF_TIMEOUT;
195 211
196 while (timeout-- && ISR & (ISR_IBB | ISR_UB)) { 212 while (timeout-- && readl(_ISR(i2c)) & (ISR_IBB | ISR_UB)) {
197 if ((ISR & ISR_SAD) != 0) 213 if ((readl(_ISR(i2c)) & ISR_SAD) != 0)
198 timeout += 4; 214 timeout += 4;
199 215
200 msleep(2); 216 msleep(2);
@@ -214,9 +230,9 @@ static int i2c_pxa_wait_master(struct pxa_i2c *i2c)
214 while (time_before(jiffies, timeout)) { 230 while (time_before(jiffies, timeout)) {
215 if (i2c_debug > 1) 231 if (i2c_debug > 1)
216 dev_dbg(&i2c->adap.dev, "%s: %ld: ISR=%08x, ICR=%08x, IBMR=%02x\n", 232 dev_dbg(&i2c->adap.dev, "%s: %ld: ISR=%08x, ICR=%08x, IBMR=%02x\n",
217 __func__, (long)jiffies, ISR, ICR, IBMR); 233 __func__, (long)jiffies, readl(_ISR(i2c)), readl(_ICR(i2c)), readl(_IBMR(i2c)));
218 234
219 if (ISR & ISR_SAD) { 235 if (readl(_ISR(i2c)) & ISR_SAD) {
220 if (i2c_debug > 0) 236 if (i2c_debug > 0)
221 dev_dbg(&i2c->adap.dev, "%s: Slave detected\n", __func__); 237 dev_dbg(&i2c->adap.dev, "%s: Slave detected\n", __func__);
222 goto out; 238 goto out;
@@ -226,7 +242,7 @@ static int i2c_pxa_wait_master(struct pxa_i2c *i2c)
226 * quick check of the i2c lines themselves to ensure they've 242 * quick check of the i2c lines themselves to ensure they've
227 * gone high... 243 * gone high...
228 */ 244 */
229 if ((ISR & (ISR_UB | ISR_IBB)) == 0 && IBMR == 3) { 245 if ((readl(_ISR(i2c)) & (ISR_UB | ISR_IBB)) == 0 && readl(_IBMR(i2c)) == 3) {
230 if (i2c_debug > 0) 246 if (i2c_debug > 0)
231 dev_dbg(&i2c->adap.dev, "%s: done\n", __func__); 247 dev_dbg(&i2c->adap.dev, "%s: done\n", __func__);
232 return 1; 248 return 1;
@@ -246,7 +262,7 @@ static int i2c_pxa_set_master(struct pxa_i2c *i2c)
246 if (i2c_debug) 262 if (i2c_debug)
247 dev_dbg(&i2c->adap.dev, "setting to bus master\n"); 263 dev_dbg(&i2c->adap.dev, "setting to bus master\n");
248 264
249 if ((ISR & (ISR_UB | ISR_IBB)) != 0) { 265 if ((readl(_ISR(i2c)) & (ISR_UB | ISR_IBB)) != 0) {
250 dev_dbg(&i2c->adap.dev, "%s: unit is busy\n", __func__); 266 dev_dbg(&i2c->adap.dev, "%s: unit is busy\n", __func__);
251 if (!i2c_pxa_wait_master(i2c)) { 267 if (!i2c_pxa_wait_master(i2c)) {
252 dev_dbg(&i2c->adap.dev, "%s: error: unit busy\n", __func__); 268 dev_dbg(&i2c->adap.dev, "%s: error: unit busy\n", __func__);
@@ -254,7 +270,7 @@ static int i2c_pxa_set_master(struct pxa_i2c *i2c)
254 } 270 }
255 } 271 }
256 272
257 ICR |= ICR_SCLE; 273 writel(readl(_ICR(i2c)) | ICR_SCLE, _ICR(i2c));
258 return 0; 274 return 0;
259} 275}
260 276
@@ -270,11 +286,11 @@ static int i2c_pxa_wait_slave(struct pxa_i2c *i2c)
270 while (time_before(jiffies, timeout)) { 286 while (time_before(jiffies, timeout)) {
271 if (i2c_debug > 1) 287 if (i2c_debug > 1)
272 dev_dbg(&i2c->adap.dev, "%s: %ld: ISR=%08x, ICR=%08x, IBMR=%02x\n", 288 dev_dbg(&i2c->adap.dev, "%s: %ld: ISR=%08x, ICR=%08x, IBMR=%02x\n",
273 __func__, (long)jiffies, ISR, ICR, IBMR); 289 __func__, (long)jiffies, readl(_ISR(i2c)), readl(_ICR(i2c)), readl(_IBMR(i2c)));
274 290
275 if ((ISR & (ISR_UB|ISR_IBB)) == 0 || 291 if ((readl(_ISR(i2c)) & (ISR_UB|ISR_IBB)) == 0 ||
276 (ISR & ISR_SAD) != 0 || 292 (readl(_ISR(i2c)) & ISR_SAD) != 0 ||
277 (ICR & ICR_SCLE) == 0) { 293 (readl(_ICR(i2c)) & ICR_SCLE) == 0) {
278 if (i2c_debug > 1) 294 if (i2c_debug > 1)
279 dev_dbg(&i2c->adap.dev, "%s: done\n", __func__); 295 dev_dbg(&i2c->adap.dev, "%s: done\n", __func__);
280 return 1; 296 return 1;
@@ -302,9 +318,9 @@ static void i2c_pxa_set_slave(struct pxa_i2c *i2c, int errcode)
302 /* we need to wait for the stop condition to end */ 318 /* we need to wait for the stop condition to end */
303 319
304 /* if we where in stop, then clear... */ 320 /* if we where in stop, then clear... */
305 if (ICR & ICR_STOP) { 321 if (readl(_ICR(i2c)) & ICR_STOP) {
306 udelay(100); 322 udelay(100);
307 ICR &= ~ICR_STOP; 323 writel(readl(_ICR(i2c)) & ~ICR_STOP, _ICR(i2c));
308 } 324 }
309 325
310 if (!i2c_pxa_wait_slave(i2c)) { 326 if (!i2c_pxa_wait_slave(i2c)) {
@@ -314,12 +330,12 @@ static void i2c_pxa_set_slave(struct pxa_i2c *i2c, int errcode)
314 } 330 }
315 } 331 }
316 332
317 ICR &= ~(ICR_STOP|ICR_ACKNAK|ICR_MA); 333 writel(readl(_ICR(i2c)) & ~(ICR_STOP|ICR_ACKNAK|ICR_MA), _ICR(i2c));
318 ICR &= ~ICR_SCLE; 334 writel(readl(_ICR(i2c)) & ~ICR_SCLE, _ICR(i2c));
319 335
320 if (i2c_debug) { 336 if (i2c_debug) {
321 dev_dbg(&i2c->adap.dev, "ICR now %08x, ISR %08x\n", ICR, ISR); 337 dev_dbg(&i2c->adap.dev, "ICR now %08x, ISR %08x\n", readl(_ICR(i2c)), readl(_ISR(i2c)));
322 decode_ICR(ICR); 338 decode_ICR(readl(_ICR(i2c)));
323 } 339 }
324} 340}
325#else 341#else
@@ -334,24 +350,24 @@ static void i2c_pxa_reset(struct pxa_i2c *i2c)
334 i2c_pxa_abort(i2c); 350 i2c_pxa_abort(i2c);
335 351
336 /* reset according to 9.8 */ 352 /* reset according to 9.8 */
337 ICR = ICR_UR; 353 writel(ICR_UR, _ICR(i2c));
338 ISR = I2C_ISR_INIT; 354 writel(I2C_ISR_INIT, _ISR(i2c));
339 ICR &= ~ICR_UR; 355 writel(readl(_ICR(i2c)) & ~ICR_UR, _ICR(i2c));
340 356
341 ISAR = i2c->slave_addr; 357 writel(i2c->slave_addr, _ISAR(i2c));
342 358
343 /* set control register values */ 359 /* set control register values */
344 ICR = I2C_ICR_INIT; 360 writel(I2C_ICR_INIT, _ICR(i2c));
345 361
346#ifdef CONFIG_I2C_PXA_SLAVE 362#ifdef CONFIG_I2C_PXA_SLAVE
347 dev_info(&i2c->adap.dev, "Enabling slave mode\n"); 363 dev_info(&i2c->adap.dev, "Enabling slave mode\n");
348 ICR |= ICR_SADIE | ICR_ALDIE | ICR_SSDIE; 364 writel(readl(_ICR(i2c)) | ICR_SADIE | ICR_ALDIE | ICR_SSDIE, _ICR(i2c));
349#endif 365#endif
350 366
351 i2c_pxa_set_slave(i2c, 0); 367 i2c_pxa_set_slave(i2c, 0);
352 368
353 /* enable unit */ 369 /* enable unit */
354 ICR |= ICR_IUE; 370 writel(readl(_ICR(i2c)) | ICR_IUE, _ICR(i2c));
355 udelay(100); 371 udelay(100);
356} 372}
357 373
@@ -371,19 +387,19 @@ static void i2c_pxa_slave_txempty(struct pxa_i2c *i2c, u32 isr)
371 if (i2c->slave != NULL) 387 if (i2c->slave != NULL)
372 ret = i2c->slave->read(i2c->slave->data); 388 ret = i2c->slave->read(i2c->slave->data);
373 389
374 IDBR = ret; 390 writel(ret, _IDBR(i2c));
375 ICR |= ICR_TB; /* allow next byte */ 391 writel(readl(_ICR(i2c)) | ICR_TB, _ICR(i2c)); /* allow next byte */
376 } 392 }
377} 393}
378 394
379static void i2c_pxa_slave_rxfull(struct pxa_i2c *i2c, u32 isr) 395static void i2c_pxa_slave_rxfull(struct pxa_i2c *i2c, u32 isr)
380{ 396{
381 unsigned int byte = IDBR; 397 unsigned int byte = readl(_IDBR(i2c));
382 398
383 if (i2c->slave != NULL) 399 if (i2c->slave != NULL)
384 i2c->slave->write(i2c->slave->data, byte); 400 i2c->slave->write(i2c->slave->data, byte);
385 401
386 ICR |= ICR_TB; 402 writel(readl(_ICR(i2c)) | ICR_TB, _ICR(i2c));
387} 403}
388 404
389static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr) 405static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
@@ -403,13 +419,13 @@ static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
403 * start condition... if this happens, we'd better back off 419 * start condition... if this happens, we'd better back off
404 * and stop holding the poor thing up 420 * and stop holding the poor thing up
405 */ 421 */
406 ICR &= ~(ICR_START|ICR_STOP); 422 writel(readl(_ICR(i2c)) & ~(ICR_START|ICR_STOP), _ICR(i2c));
407 ICR |= ICR_TB; 423 writel(readl(_ICR(i2c)) | ICR_TB, _ICR(i2c));
408 424
409 timeout = 0x10000; 425 timeout = 0x10000;
410 426
411 while (1) { 427 while (1) {
412 if ((IBMR & 2) == 2) 428 if ((readl(_IBMR(i2c)) & 2) == 2)
413 break; 429 break;
414 430
415 timeout--; 431 timeout--;
@@ -420,7 +436,7 @@ static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
420 } 436 }
421 } 437 }
422 438
423 ICR &= ~ICR_SCLE; 439 writel(readl(_ICR(i2c)) & ~ICR_SCLE, _ICR(i2c));
424} 440}
425 441
426static void i2c_pxa_slave_stop(struct pxa_i2c *i2c) 442static void i2c_pxa_slave_stop(struct pxa_i2c *i2c)
@@ -447,14 +463,14 @@ static void i2c_pxa_slave_txempty(struct pxa_i2c *i2c, u32 isr)
447 if (isr & ISR_BED) { 463 if (isr & ISR_BED) {
448 /* what should we do here? */ 464 /* what should we do here? */
449 } else { 465 } else {
450 IDBR = 0; 466 writel(0, _IDBR(i2c));
451 ICR |= ICR_TB; 467 writel(readl(_ICR(i2c)) | ICR_TB, _ICR(i2c));
452 } 468 }
453} 469}
454 470
455static void i2c_pxa_slave_rxfull(struct pxa_i2c *i2c, u32 isr) 471static void i2c_pxa_slave_rxfull(struct pxa_i2c *i2c, u32 isr)
456{ 472{
457 ICR |= ICR_TB | ICR_ACKNAK; 473 writel(readl(_ICR(i2c)) | ICR_TB | ICR_ACKNAK, _ICR(i2c));
458} 474}
459 475
460static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr) 476static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
@@ -466,13 +482,13 @@ static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
466 * start condition... if this happens, we'd better back off 482 * start condition... if this happens, we'd better back off
467 * and stop holding the poor thing up 483 * and stop holding the poor thing up
468 */ 484 */
469 ICR &= ~(ICR_START|ICR_STOP); 485 writel(readl(_ICR(i2c)) & ~(ICR_START|ICR_STOP), _ICR(i2c));
470 ICR |= ICR_TB | ICR_ACKNAK; 486 writel(readl(_ICR(i2c)) | ICR_TB | ICR_ACKNAK, _ICR(i2c));
471 487
472 timeout = 0x10000; 488 timeout = 0x10000;
473 489
474 while (1) { 490 while (1) {
475 if ((IBMR & 2) == 2) 491 if ((readl(_IBMR(i2c)) & 2) == 2)
476 break; 492 break;
477 493
478 timeout--; 494 timeout--;
@@ -483,7 +499,7 @@ static void i2c_pxa_slave_start(struct pxa_i2c *i2c, u32 isr)
483 } 499 }
484 } 500 }
485 501
486 ICR &= ~ICR_SCLE; 502 writel(readl(_ICR(i2c)) & ~ICR_SCLE, _ICR(i2c));
487} 503}
488 504
489static void i2c_pxa_slave_stop(struct pxa_i2c *i2c) 505static void i2c_pxa_slave_stop(struct pxa_i2c *i2c)
@@ -514,13 +530,13 @@ static inline void i2c_pxa_start_message(struct pxa_i2c *i2c)
514 /* 530 /*
515 * Step 1: target slave address into IDBR 531 * Step 1: target slave address into IDBR
516 */ 532 */
517 IDBR = i2c_pxa_addr_byte(i2c->msg); 533 writel(i2c_pxa_addr_byte(i2c->msg), _IDBR(i2c));
518 534
519 /* 535 /*
520 * Step 2: initiate the write. 536 * Step 2: initiate the write.
521 */ 537 */
522 icr = ICR & ~(ICR_STOP | ICR_ALDIE); 538 icr = readl(_ICR(i2c)) & ~(ICR_STOP | ICR_ALDIE);
523 ICR = icr | ICR_START | ICR_TB; 539 writel(icr | ICR_START | ICR_TB, _ICR(i2c));
524} 540}
525 541
526/* 542/*
@@ -594,7 +610,7 @@ static void i2c_pxa_master_complete(struct pxa_i2c *i2c, int ret)
594 610
595static void i2c_pxa_irq_txempty(struct pxa_i2c *i2c, u32 isr) 611static void i2c_pxa_irq_txempty(struct pxa_i2c *i2c, u32 isr)
596{ 612{
597 u32 icr = ICR & ~(ICR_START|ICR_STOP|ICR_ACKNAK|ICR_TB); 613 u32 icr = readl(_ICR(i2c)) & ~(ICR_START|ICR_STOP|ICR_ACKNAK|ICR_TB);
598 614
599 again: 615 again:
600 /* 616 /*
@@ -645,7 +661,7 @@ static void i2c_pxa_irq_txempty(struct pxa_i2c *i2c, u32 isr)
645 /* 661 /*
646 * Write mode. Write the next data byte. 662 * Write mode. Write the next data byte.
647 */ 663 */
648 IDBR = i2c->msg->buf[i2c->msg_ptr++]; 664 writel(i2c->msg->buf[i2c->msg_ptr++], _IDBR(i2c));
649 665
650 icr |= ICR_ALDIE | ICR_TB; 666 icr |= ICR_ALDIE | ICR_TB;
651 667
@@ -675,7 +691,7 @@ static void i2c_pxa_irq_txempty(struct pxa_i2c *i2c, u32 isr)
675 /* 691 /*
676 * Write the next address. 692 * Write the next address.
677 */ 693 */
678 IDBR = i2c_pxa_addr_byte(i2c->msg); 694 writel(i2c_pxa_addr_byte(i2c->msg), _IDBR(i2c));
679 695
680 /* 696 /*
681 * And trigger a repeated start, and send the byte. 697 * And trigger a repeated start, and send the byte.
@@ -696,18 +712,18 @@ static void i2c_pxa_irq_txempty(struct pxa_i2c *i2c, u32 isr)
696 712
697 i2c->icrlog[i2c->irqlogidx-1] = icr; 713 i2c->icrlog[i2c->irqlogidx-1] = icr;
698 714
699 ICR = icr; 715 writel(icr, _ICR(i2c));
700 show_state(i2c); 716 show_state(i2c);
701} 717}
702 718
703static void i2c_pxa_irq_rxfull(struct pxa_i2c *i2c, u32 isr) 719static void i2c_pxa_irq_rxfull(struct pxa_i2c *i2c, u32 isr)
704{ 720{
705 u32 icr = ICR & ~(ICR_START|ICR_STOP|ICR_ACKNAK|ICR_TB); 721 u32 icr = readl(_ICR(i2c)) & ~(ICR_START|ICR_STOP|ICR_ACKNAK|ICR_TB);
706 722
707 /* 723 /*
708 * Read the byte. 724 * Read the byte.
709 */ 725 */
710 i2c->msg->buf[i2c->msg_ptr++] = IDBR; 726 i2c->msg->buf[i2c->msg_ptr++] = readl(_IDBR(i2c));
711 727
712 if (i2c->msg_ptr < i2c->msg->len) { 728 if (i2c->msg_ptr < i2c->msg->len) {
713 /* 729 /*
@@ -724,17 +740,17 @@ static void i2c_pxa_irq_rxfull(struct pxa_i2c *i2c, u32 isr)
724 740
725 i2c->icrlog[i2c->irqlogidx-1] = icr; 741 i2c->icrlog[i2c->irqlogidx-1] = icr;
726 742
727 ICR = icr; 743 writel(icr, _ICR(i2c));
728} 744}
729 745
730static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id) 746static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id)
731{ 747{
732 struct pxa_i2c *i2c = dev_id; 748 struct pxa_i2c *i2c = dev_id;
733 u32 isr = ISR; 749 u32 isr = readl(_ISR(i2c));
734 750
735 if (i2c_debug > 2 && 0) { 751 if (i2c_debug > 2 && 0) {
736 dev_dbg(&i2c->adap.dev, "%s: ISR=%08x, ICR=%08x, IBMR=%02x\n", 752 dev_dbg(&i2c->adap.dev, "%s: ISR=%08x, ICR=%08x, IBMR=%02x\n",
737 __func__, isr, ICR, IBMR); 753 __func__, isr, readl(_ICR(i2c)), readl(_IBMR(i2c)));
738 decode_ISR(isr); 754 decode_ISR(isr);
739 } 755 }
740 756
@@ -746,7 +762,7 @@ static irqreturn_t i2c_pxa_handler(int this_irq, void *dev_id)
746 /* 762 /*
747 * Always clear all pending IRQs. 763 * Always clear all pending IRQs.
748 */ 764 */
749 ISR = isr & (ISR_SSD|ISR_ALD|ISR_ITE|ISR_IRF|ISR_SAD|ISR_BED); 765 writel(isr & (ISR_SSD|ISR_ALD|ISR_ITE|ISR_IRF|ISR_SAD|ISR_BED), _ISR(i2c));
750 766
751 if (isr & ISR_SAD) 767 if (isr & ISR_SAD)
752 i2c_pxa_slave_start(i2c, isr); 768 i2c_pxa_slave_start(i2c, isr);
@@ -779,7 +795,7 @@ static int i2c_pxa_xfer(struct i2c_adapter *adap, struct i2c_msg msgs[], int num
779 /* If the I2C controller is disabled we need to reset it (probably due 795 /* If the I2C controller is disabled we need to reset it (probably due
780 to a suspend/resume destroying state). We do this here as we can then 796 to a suspend/resume destroying state). We do this here as we can then
781 avoid worrying about resuming the controller before its users. */ 797 avoid worrying about resuming the controller before its users. */
782 if (!(ICR & ICR_IUE)) 798 if (!(readl(_ICR(i2c)) & ICR_IUE))
783 i2c_pxa_reset(i2c); 799 i2c_pxa_reset(i2c);
784 800
785 for (i = adap->retries; i >= 0; i--) { 801 for (i = adap->retries; i >= 0; i--) {
@@ -810,28 +826,53 @@ static const struct i2c_algorithm i2c_pxa_algorithm = {
810 826
811static struct pxa_i2c i2c_pxa = { 827static struct pxa_i2c i2c_pxa = {
812 .lock = SPIN_LOCK_UNLOCKED, 828 .lock = SPIN_LOCK_UNLOCKED,
813 .wait = __WAIT_QUEUE_HEAD_INITIALIZER(i2c_pxa.wait),
814 .adap = { 829 .adap = {
815 .owner = THIS_MODULE, 830 .owner = THIS_MODULE,
816 .algo = &i2c_pxa_algorithm, 831 .algo = &i2c_pxa_algorithm,
817 .name = "pxa2xx-i2c", 832 .name = "pxa2xx-i2c.0",
818 .retries = 5, 833 .retries = 5,
819 }, 834 },
820}; 835};
821 836
837#define res_len(r) ((r)->end - (r)->start + 1)
822static int i2c_pxa_probe(struct platform_device *dev) 838static int i2c_pxa_probe(struct platform_device *dev)
823{ 839{
824 struct pxa_i2c *i2c = &i2c_pxa; 840 struct pxa_i2c *i2c = &i2c_pxa;
841 struct resource *res;
825#ifdef CONFIG_I2C_PXA_SLAVE 842#ifdef CONFIG_I2C_PXA_SLAVE
826 struct i2c_pxa_platform_data *plat = dev->dev.platform_data; 843 struct i2c_pxa_platform_data *plat = dev->dev.platform_data;
827#endif 844#endif
828 int ret; 845 int ret;
846 int irq;
829 847
830#ifdef CONFIG_PXA27x 848 res = platform_get_resource(dev, IORESOURCE_MEM, 0);
831 pxa_gpio_mode(GPIO117_I2CSCL_MD); 849 irq = platform_get_irq(dev, 0);
832 pxa_gpio_mode(GPIO118_I2CSDA_MD); 850 if (res == NULL || irq < 0)
833 udelay(100); 851 return -ENODEV;
834#endif 852
853 if (!request_mem_region(res->start, res_len(res), res->name))
854 return -ENOMEM;
855
856 i2c = kmalloc(sizeof(struct pxa_i2c), GFP_KERNEL);
857 if (!i2c) {
858 ret = -ENOMEM;
859 goto emalloc;
860 }
861
862 memcpy(i2c, &i2c_pxa, sizeof(struct pxa_i2c));
863 init_waitqueue_head(&i2c->wait);
864 i2c->adap.name[strlen(i2c->adap.name) - 1] = '0' + dev->id % 10;
865
866 i2c->reg_base = ioremap(res->start, res_len(res));
867 if (!i2c->reg_base) {
868 ret = -EIO;
869 goto eremap;
870 }
871
872 i2c->iobase = res->start;
873 i2c->iosize = res_len(res);
874
875 i2c->irq = irq;
835 876
836 i2c->slave_addr = I2C_PXA_SLAVE_ADDR; 877 i2c->slave_addr = I2C_PXA_SLAVE_ADDR;
837 878
@@ -842,11 +883,28 @@ static int i2c_pxa_probe(struct platform_device *dev)
842 } 883 }
843#endif 884#endif
844 885
845 pxa_set_cken(CKEN14_I2C, 1); 886 switch (dev->id) {
846 ret = request_irq(IRQ_I2C, i2c_pxa_handler, IRQF_DISABLED, 887 case 0:
847 "pxa2xx-i2c", i2c); 888#ifdef CONFIG_PXA27x
889 pxa_gpio_mode(GPIO117_I2CSCL_MD);
890 pxa_gpio_mode(GPIO118_I2CSDA_MD);
891#endif
892 pxa_set_cken(CKEN14_I2C, 1);
893 break;
894#ifdef CONFIG_PXA27x
895 case 1:
896 local_irq_disable();
897 PCFR |= PCFR_PI2CEN;
898 local_irq_enable();
899 pxa_set_cken(CKEN15_PWRI2C, 1);
900#endif
901 }
902
903 ret = request_irq(irq, i2c_pxa_handler, IRQF_DISABLED,
904 i2c->adap.name, i2c);
848 if (ret) 905 if (ret)
849 goto out; 906 goto ereqirq;
907
850 908
851 i2c_pxa_reset(i2c); 909 i2c_pxa_reset(i2c);
852 910
@@ -856,7 +914,7 @@ static int i2c_pxa_probe(struct platform_device *dev)
856 ret = i2c_add_adapter(&i2c->adap); 914 ret = i2c_add_adapter(&i2c->adap);
857 if (ret < 0) { 915 if (ret < 0) {
858 printk(KERN_INFO "I2C: Failed to add bus\n"); 916 printk(KERN_INFO "I2C: Failed to add bus\n");
859 goto err_irq; 917 goto eadapt;
860 } 918 }
861 919
862 platform_set_drvdata(dev, i2c); 920 platform_set_drvdata(dev, i2c);
@@ -870,9 +928,25 @@ static int i2c_pxa_probe(struct platform_device *dev)
870#endif 928#endif
871 return 0; 929 return 0;
872 930
873 err_irq: 931eadapt:
874 free_irq(IRQ_I2C, i2c); 932 free_irq(irq, i2c);
875 out: 933ereqirq:
934 switch (dev->id) {
935 case 0:
936 pxa_set_cken(CKEN14_I2C, 0);
937 break;
938#ifdef CONFIG_PXA27x
939 case 1:
940 pxa_set_cken(CKEN15_PWRI2C, 0);
941 local_irq_disable();
942 PCFR &= ~PCFR_PI2CEN;
943 local_irq_enable();
944#endif
945 }
946eremap:
947 kfree(i2c);
948emalloc:
949 release_mem_region(res->start, res_len(res));
876 return ret; 950 return ret;
877} 951}
878 952
@@ -883,8 +957,21 @@ static int i2c_pxa_remove(struct platform_device *dev)
883 platform_set_drvdata(dev, NULL); 957 platform_set_drvdata(dev, NULL);
884 958
885 i2c_del_adapter(&i2c->adap); 959 i2c_del_adapter(&i2c->adap);
886 free_irq(IRQ_I2C, i2c); 960 free_irq(i2c->irq, i2c);
887 pxa_set_cken(CKEN14_I2C, 0); 961 switch (dev->id) {
962 case 0:
963 pxa_set_cken(CKEN14_I2C, 0);
964 break;
965#ifdef CONFIG_PXA27x
966 case 1:
967 pxa_set_cken(CKEN15_PWRI2C, 0);
968 local_irq_disable();
969 PCFR &= ~PCFR_PI2CEN;
970 local_irq_enable();
971#endif
972 }
973 release_mem_region(i2c->iobase, i2c->iosize);
974 kfree(i2c);
888 975
889 return 0; 976 return 0;
890} 977}
diff --git a/drivers/ide/Kconfig b/drivers/ide/Kconfig
index ec03341d2bd8..350764ece7fe 100644
--- a/drivers/ide/Kconfig
+++ b/drivers/ide/Kconfig
@@ -797,6 +797,14 @@ config BLK_DEV_IDEDMA_PMAC
797 to transfer data to and from memory. Saying Y is safe and improves 797 to transfer data to and from memory. Saying Y is safe and improves
798 performance. 798 performance.
799 799
800config BLK_DEV_IDE_CELLEB
801 bool "Toshiba's Cell Reference Set IDE support"
802 depends on PPC_CELLEB
803 help
804 This driver provides support for the built-in IDE controller on
805 Toshiba Cell Reference Board.
806 If unsure, say Y.
807
800config BLK_DEV_IDE_SWARM 808config BLK_DEV_IDE_SWARM
801 tristate "IDE for Sibyte evaluation boards" 809 tristate "IDE for Sibyte evaluation boards"
802 depends on SIBYTE_SB1xxx_SOC 810 depends on SIBYTE_SB1xxx_SOC
diff --git a/drivers/ide/Makefile b/drivers/ide/Makefile
index d9f029e8ff74..28feedfbd21d 100644
--- a/drivers/ide/Makefile
+++ b/drivers/ide/Makefile
@@ -37,6 +37,7 @@ ide-core-$(CONFIG_BLK_DEV_Q40IDE) += legacy/q40ide.o
37# built-in only drivers from ppc/ 37# built-in only drivers from ppc/
38ide-core-$(CONFIG_BLK_DEV_MPC8xx_IDE) += ppc/mpc8xx.o 38ide-core-$(CONFIG_BLK_DEV_MPC8xx_IDE) += ppc/mpc8xx.o
39ide-core-$(CONFIG_BLK_DEV_IDE_PMAC) += ppc/pmac.o 39ide-core-$(CONFIG_BLK_DEV_IDE_PMAC) += ppc/pmac.o
40ide-core-$(CONFIG_BLK_DEV_IDE_CELLEB) += ppc/scc_pata.o
40 41
41# built-in only drivers from h8300/ 42# built-in only drivers from h8300/
42ide-core-$(CONFIG_H8300) += h8300/ide-h8300.o 43ide-core-$(CONFIG_H8300) += h8300/ide-h8300.o
diff --git a/drivers/ide/arm/icside.c b/drivers/ide/arm/icside.c
index 8a1c27f28692..40e5c66b81ce 100644
--- a/drivers/ide/arm/icside.c
+++ b/drivers/ide/arm/icside.c
@@ -307,26 +307,24 @@ static int icside_set_speed(ide_drive_t *drive, u8 xfer_mode)
307 return on; 307 return on;
308} 308}
309 309
310static int icside_dma_host_off(ide_drive_t *drive) 310static void icside_dma_host_off(ide_drive_t *drive)
311{ 311{
312 return 0;
313} 312}
314 313
315static int icside_dma_off_quietly(ide_drive_t *drive) 314static void icside_dma_off_quietly(ide_drive_t *drive)
316{ 315{
317 drive->using_dma = 0; 316 drive->using_dma = 0;
318 return icside_dma_host_off(drive);
319} 317}
320 318
321static int icside_dma_host_on(ide_drive_t *drive) 319static void icside_dma_host_on(ide_drive_t *drive)
322{ 320{
323 return 0;
324} 321}
325 322
326static int icside_dma_on(ide_drive_t *drive) 323static int icside_dma_on(ide_drive_t *drive)
327{ 324{
328 drive->using_dma = 1; 325 drive->using_dma = 1;
329 return icside_dma_host_on(drive); 326
327 return 0;
330} 328}
331 329
332static int icside_dma_check(ide_drive_t *drive) 330static int icside_dma_check(ide_drive_t *drive)
@@ -365,10 +363,7 @@ static int icside_dma_check(ide_drive_t *drive)
365out: 363out:
366 on = icside_set_speed(drive, xfer_mode); 364 on = icside_set_speed(drive, xfer_mode);
367 365
368 if (on) 366 return on ? 0 : -1;
369 return icside_dma_on(drive);
370 else
371 return icside_dma_off_quietly(drive);
372} 367}
373 368
374static int icside_dma_end(ide_drive_t *drive) 369static int icside_dma_end(ide_drive_t *drive)
@@ -497,9 +492,9 @@ static void icside_dma_init(ide_hwif_t *hwif)
497 hwif->autodma = autodma; 492 hwif->autodma = autodma;
498 493
499 hwif->ide_dma_check = icside_dma_check; 494 hwif->ide_dma_check = icside_dma_check;
500 hwif->ide_dma_host_off = icside_dma_host_off; 495 hwif->dma_host_off = icside_dma_host_off;
501 hwif->ide_dma_off_quietly = icside_dma_off_quietly; 496 hwif->dma_off_quietly = icside_dma_off_quietly;
502 hwif->ide_dma_host_on = icside_dma_host_on; 497 hwif->dma_host_on = icside_dma_host_on;
503 hwif->ide_dma_on = icside_dma_on; 498 hwif->ide_dma_on = icside_dma_on;
504 hwif->dma_setup = icside_dma_setup; 499 hwif->dma_setup = icside_dma_setup;
505 hwif->dma_exec_cmd = icside_dma_exec_cmd; 500 hwif->dma_exec_cmd = icside_dma_exec_cmd;
@@ -556,7 +551,7 @@ icside_setup(void __iomem *base, struct cardinfo *info, struct expansion_card *e
556 * Ensure we're using MMIO 551 * Ensure we're using MMIO
557 */ 552 */
558 default_hwif_mmiops(hwif); 553 default_hwif_mmiops(hwif);
559 hwif->mmio = 2; 554 hwif->mmio = 1;
560 555
561 for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { 556 for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) {
562 hwif->hw.io_ports[i] = port; 557 hwif->hw.io_ports[i] = port;
diff --git a/drivers/ide/arm/rapide.c b/drivers/ide/arm/rapide.c
index 3058217767d6..9c6c49fdd2b1 100644
--- a/drivers/ide/arm/rapide.c
+++ b/drivers/ide/arm/rapide.c
@@ -46,7 +46,7 @@ rapide_locate_hwif(void __iomem *base, void __iomem *ctrl, unsigned int sz, int
46 hwif->hw.io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl; 46 hwif->hw.io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
47 hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl; 47 hwif->io_ports[IDE_CONTROL_OFFSET] = (unsigned long)ctrl;
48 hwif->hw.irq = hwif->irq = irq; 48 hwif->hw.irq = hwif->irq = irq;
49 hwif->mmio = 2; 49 hwif->mmio = 1;
50 default_hwif_mmiops(hwif); 50 default_hwif_mmiops(hwif);
51 51
52 return hwif; 52 return hwif;
diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c
index 5797e0b5a132..6b2d152351b3 100644
--- a/drivers/ide/cris/ide-cris.c
+++ b/drivers/ide/cris/ide-cris.c
@@ -682,9 +682,12 @@ static void cris_ide_input_data (ide_drive_t *drive, void *, unsigned int);
682static void cris_ide_output_data (ide_drive_t *drive, void *, unsigned int); 682static void cris_ide_output_data (ide_drive_t *drive, void *, unsigned int);
683static void cris_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int); 683static void cris_atapi_input_bytes(ide_drive_t *drive, void *, unsigned int);
684static void cris_atapi_output_bytes(ide_drive_t *drive, void *, unsigned int); 684static void cris_atapi_output_bytes(ide_drive_t *drive, void *, unsigned int);
685static int cris_dma_off (ide_drive_t *drive);
686static int cris_dma_on (ide_drive_t *drive); 685static int cris_dma_on (ide_drive_t *drive);
687 686
687static void cris_dma_off(ide_drive_t *drive)
688{
689}
690
688static void tune_cris_ide(ide_drive_t *drive, u8 pio) 691static void tune_cris_ide(ide_drive_t *drive, u8 pio)
689{ 692{
690 int setup, strobe, hold; 693 int setup, strobe, hold;
@@ -795,7 +798,7 @@ init_e100_ide (void)
795 0, 0, cris_ide_ack_intr, 798 0, 0, cris_ide_ack_intr,
796 ide_default_irq(0)); 799 ide_default_irq(0));
797 ide_register_hw(&hw, &hwif); 800 ide_register_hw(&hw, &hwif);
798 hwif->mmio = 2; 801 hwif->mmio = 1;
799 hwif->chipset = ide_etrax100; 802 hwif->chipset = ide_etrax100;
800 hwif->tuneproc = &tune_cris_ide; 803 hwif->tuneproc = &tune_cris_ide;
801 hwif->speedproc = &speed_cris_ide; 804 hwif->speedproc = &speed_cris_ide;
@@ -814,13 +817,16 @@ init_e100_ide (void)
814 hwif->OUTBSYNC = &cris_ide_outbsync; 817 hwif->OUTBSYNC = &cris_ide_outbsync;
815 hwif->INB = &cris_ide_inb; 818 hwif->INB = &cris_ide_inb;
816 hwif->INW = &cris_ide_inw; 819 hwif->INW = &cris_ide_inw;
817 hwif->ide_dma_host_off = &cris_dma_off; 820 hwif->dma_host_off = &cris_dma_off;
818 hwif->ide_dma_host_on = &cris_dma_on; 821 hwif->dma_host_on = &cris_dma_on;
819 hwif->ide_dma_off_quietly = &cris_dma_off; 822 hwif->dma_off_quietly = &cris_dma_off;
820 hwif->udma_four = 0; 823 hwif->udma_four = 0;
821 hwif->ultra_mask = cris_ultra_mask; 824 hwif->ultra_mask = cris_ultra_mask;
822 hwif->mwdma_mask = 0x07; /* Multiword DMA 0-2 */ 825 hwif->mwdma_mask = 0x07; /* Multiword DMA 0-2 */
823 hwif->swdma_mask = 0x07; /* Singleword DMA 0-2 */ 826 hwif->swdma_mask = 0x07; /* Singleword DMA 0-2 */
827 hwif->autodma = 1;
828 hwif->drives[0].autodma = 1;
829 hwif->drives[1].autodma = 1;
824 } 830 }
825 831
826 /* Reset pulse */ 832 /* Reset pulse */
@@ -835,11 +841,6 @@ init_e100_ide (void)
835 cris_ide_set_speed(TYPE_UDMA, ATA_UDMA2_CYC, ATA_UDMA2_DVS, 0); 841 cris_ide_set_speed(TYPE_UDMA, ATA_UDMA2_CYC, ATA_UDMA2_DVS, 0);
836} 842}
837 843
838static int cris_dma_off (ide_drive_t *drive)
839{
840 return 0;
841}
842
843static int cris_dma_on (ide_drive_t *drive) 844static int cris_dma_on (ide_drive_t *drive)
844{ 845{
845 return 0; 846 return 0;
@@ -1045,17 +1046,10 @@ static ide_startstop_t cris_dma_intr (ide_drive_t *drive)
1045 1046
1046static int cris_dma_check(ide_drive_t *drive) 1047static int cris_dma_check(ide_drive_t *drive)
1047{ 1048{
1048 ide_hwif_t *hwif = drive->hwif; 1049 if (ide_use_dma(drive) && cris_config_drive_for_dma(drive))
1049 struct hd_driveid* id = drive->id; 1050 return 0;
1050
1051 if (id && (id->capability & 1)) {
1052 if (ide_use_dma(drive)) {
1053 if (cris_config_drive_for_dma(drive))
1054 return hwif->ide_dma_on(drive);
1055 }
1056 }
1057 1051
1058 return hwif->ide_dma_off_quietly(drive); 1052 return -1;
1059} 1053}
1060 1054
1061static int cris_dma_end(ide_drive_t *drive) 1055static int cris_dma_end(ide_drive_t *drive)
diff --git a/drivers/ide/h8300/ide-h8300.c b/drivers/ide/h8300/ide-h8300.c
index 608ca871744b..88750a300337 100644
--- a/drivers/ide/h8300/ide-h8300.c
+++ b/drivers/ide/h8300/ide-h8300.c
@@ -76,13 +76,11 @@ static inline void hwif_setup(ide_hwif_t *hwif)
76{ 76{
77 default_hwif_iops(hwif); 77 default_hwif_iops(hwif);
78 78
79 hwif->mmio = 2; 79 hwif->mmio = 1;
80 hwif->OUTW = mm_outw; 80 hwif->OUTW = mm_outw;
81 hwif->OUTSW = mm_outsw; 81 hwif->OUTSW = mm_outsw;
82 hwif->INW = mm_inw; 82 hwif->INW = mm_inw;
83 hwif->INSW = mm_insw; 83 hwif->INSW = mm_insw;
84 hwif->OUTL = NULL;
85 hwif->INL = NULL;
86 hwif->OUTSL = NULL; 84 hwif->OUTSL = NULL;
87 hwif->INSL = NULL; 85 hwif->INSL = NULL;
88} 86}
diff --git a/drivers/ide/ide-cd.c b/drivers/ide/ide-cd.c
index 5969cec58dc1..45a928c058cf 100644
--- a/drivers/ide/ide-cd.c
+++ b/drivers/ide/ide-cd.c
@@ -687,15 +687,8 @@ static void ide_dump_status_no_sense(ide_drive_t *drive, const char *msg, u8 sta
687static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret) 687static int cdrom_decode_status(ide_drive_t *drive, int good_stat, int *stat_ret)
688{ 688{
689 struct request *rq = HWGROUP(drive)->rq; 689 struct request *rq = HWGROUP(drive)->rq;
690 ide_hwif_t *hwif = HWIF(drive);
691 int stat, err, sense_key; 690 int stat, err, sense_key;
692 691
693 /* We may have bogus DMA interrupts in PIO state here */
694 if (HWIF(drive)->dma_status && hwif->atapi_irq_bogon) {
695 stat = hwif->INB(hwif->dma_status);
696 /* Should we force the bit as well ? */
697 hwif->OUTB(stat, hwif->dma_status);
698 }
699 /* Check for errors. */ 692 /* Check for errors. */
700 stat = HWIF(drive)->INB(IDE_STATUS_REG); 693 stat = HWIF(drive)->INB(IDE_STATUS_REG);
701 if (stat_ret) 694 if (stat_ret)
@@ -930,6 +923,10 @@ static ide_startstop_t cdrom_start_packet_command(ide_drive_t *drive,
930 HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG); 923 HWIF(drive)->OUTB(drive->ctl, IDE_CONTROL_REG);
931 924
932 if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) { 925 if (CDROM_CONFIG_FLAGS (drive)->drq_interrupt) {
926 /* waiting for CDB interrupt, not DMA yet. */
927 if (info->dma)
928 drive->waiting_for_dma = 0;
929
933 /* packet command */ 930 /* packet command */
934 ide_execute_command(drive, WIN_PACKETCMD, handler, ATAPI_WAIT_PC, cdrom_timer_expiry); 931 ide_execute_command(drive, WIN_PACKETCMD, handler, ATAPI_WAIT_PC, cdrom_timer_expiry);
935 return ide_started; 932 return ide_started;
@@ -972,6 +969,10 @@ static ide_startstop_t cdrom_transfer_packet_command (ide_drive_t *drive,
972 /* Check for errors. */ 969 /* Check for errors. */
973 if (cdrom_decode_status(drive, DRQ_STAT, NULL)) 970 if (cdrom_decode_status(drive, DRQ_STAT, NULL))
974 return ide_stopped; 971 return ide_stopped;
972
973 /* Ok, next interrupt will be DMA interrupt. */
974 if (info->dma)
975 drive->waiting_for_dma = 1;
975 } else { 976 } else {
976 /* Otherwise, we must wait for DRQ to get set. */ 977 /* Otherwise, we must wait for DRQ to get set. */
977 if (ide_wait_stat(&startstop, drive, DRQ_STAT, 978 if (ide_wait_stat(&startstop, drive, DRQ_STAT,
@@ -1103,7 +1104,7 @@ static ide_startstop_t cdrom_read_intr (ide_drive_t *drive)
1103 if (dma) { 1104 if (dma) {
1104 info->dma = 0; 1105 info->dma = 0;
1105 if ((dma_error = HWIF(drive)->ide_dma_end(drive))) 1106 if ((dma_error = HWIF(drive)->ide_dma_end(drive)))
1106 __ide_dma_off(drive); 1107 ide_dma_off(drive);
1107 } 1108 }
1108 1109
1109 if (cdrom_decode_status(drive, 0, &stat)) 1110 if (cdrom_decode_status(drive, 0, &stat))
@@ -1699,7 +1700,7 @@ static ide_startstop_t cdrom_newpc_intr(ide_drive_t *drive)
1699 if (dma) { 1700 if (dma) {
1700 if (dma_error) { 1701 if (dma_error) {
1701 printk(KERN_ERR "ide-cd: dma error\n"); 1702 printk(KERN_ERR "ide-cd: dma error\n");
1702 __ide_dma_off(drive); 1703 ide_dma_off(drive);
1703 return ide_error(drive, "dma error", stat); 1704 return ide_error(drive, "dma error", stat);
1704 } 1705 }
1705 1706
@@ -1825,7 +1826,7 @@ static ide_startstop_t cdrom_write_intr(ide_drive_t *drive)
1825 info->dma = 0; 1826 info->dma = 0;
1826 if ((dma_error = HWIF(drive)->ide_dma_end(drive))) { 1827 if ((dma_error = HWIF(drive)->ide_dma_end(drive))) {
1827 printk(KERN_ERR "ide-cd: write dma error\n"); 1828 printk(KERN_ERR "ide-cd: write dma error\n");
1828 __ide_dma_off(drive); 1829 ide_dma_off(drive);
1829 } 1830 }
1830 } 1831 }
1831 1832
@@ -3254,14 +3255,6 @@ int ide_cdrom_setup (ide_drive_t *drive)
3254 if (drive->autotune == IDE_TUNE_DEFAULT || 3255 if (drive->autotune == IDE_TUNE_DEFAULT ||
3255 drive->autotune == IDE_TUNE_AUTO) 3256 drive->autotune == IDE_TUNE_AUTO)
3256 drive->dsc_overlap = (drive->next != drive); 3257 drive->dsc_overlap = (drive->next != drive);
3257#if 0
3258 drive->dsc_overlap = (HWIF(drive)->no_dsc) ? 0 : 1;
3259 if (HWIF(drive)->no_dsc) {
3260 printk(KERN_INFO "ide-cd: %s: disabling DSC overlap\n",
3261 drive->name);
3262 drive->dsc_overlap = 0;
3263 }
3264#endif
3265 3258
3266 if (ide_cdrom_register(drive, nslots)) { 3259 if (ide_cdrom_register(drive, nslots)) {
3267 printk (KERN_ERR "%s: ide_cdrom_setup failed to register device with the cdrom driver.\n", drive->name); 3260 printk (KERN_ERR "%s: ide_cdrom_setup failed to register device with the cdrom driver.\n", drive->name);
@@ -3360,21 +3353,16 @@ static int idecd_open(struct inode * inode, struct file * file)
3360{ 3353{
3361 struct gendisk *disk = inode->i_bdev->bd_disk; 3354 struct gendisk *disk = inode->i_bdev->bd_disk;
3362 struct cdrom_info *info; 3355 struct cdrom_info *info;
3363 ide_drive_t *drive;
3364 int rc = -ENOMEM; 3356 int rc = -ENOMEM;
3365 3357
3366 if (!(info = ide_cd_get(disk))) 3358 if (!(info = ide_cd_get(disk)))
3367 return -ENXIO; 3359 return -ENXIO;
3368 3360
3369 drive = info->drive;
3370
3371 drive->usage++;
3372
3373 if (!info->buffer) 3361 if (!info->buffer)
3374 info->buffer = kmalloc(SECTOR_BUFFER_SIZE, 3362 info->buffer = kmalloc(SECTOR_BUFFER_SIZE, GFP_KERNEL|__GFP_REPEAT);
3375 GFP_KERNEL|__GFP_REPEAT); 3363
3376 if (!info->buffer || (rc = cdrom_open(&info->devinfo, inode, file))) 3364 if (info->buffer)
3377 drive->usage--; 3365 rc = cdrom_open(&info->devinfo, inode, file);
3378 3366
3379 if (rc < 0) 3367 if (rc < 0)
3380 ide_cd_put(info); 3368 ide_cd_put(info);
@@ -3386,10 +3374,8 @@ static int idecd_release(struct inode * inode, struct file * file)
3386{ 3374{
3387 struct gendisk *disk = inode->i_bdev->bd_disk; 3375 struct gendisk *disk = inode->i_bdev->bd_disk;
3388 struct cdrom_info *info = ide_cd_g(disk); 3376 struct cdrom_info *info = ide_cd_g(disk);
3389 ide_drive_t *drive = info->drive;
3390 3377
3391 cdrom_release (&info->devinfo, file); 3378 cdrom_release (&info->devinfo, file);
3392 drive->usage--;
3393 3379
3394 ide_cd_put(info); 3380 ide_cd_put(info);
3395 3381
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 0a05a377d66a..e2cea1889c4d 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -77,6 +77,7 @@ struct ide_disk_obj {
77 ide_driver_t *driver; 77 ide_driver_t *driver;
78 struct gendisk *disk; 78 struct gendisk *disk;
79 struct kref kref; 79 struct kref kref;
80 unsigned int openers; /* protected by BKL for now */
80}; 81};
81 82
82static DEFINE_MUTEX(idedisk_ref_mutex); 83static DEFINE_MUTEX(idedisk_ref_mutex);
@@ -1081,8 +1082,9 @@ static int idedisk_open(struct inode *inode, struct file *filp)
1081 1082
1082 drive = idkp->drive; 1083 drive = idkp->drive;
1083 1084
1084 drive->usage++; 1085 idkp->openers++;
1085 if (drive->removable && drive->usage == 1) { 1086
1087 if (drive->removable && idkp->openers == 1) {
1086 ide_task_t args; 1088 ide_task_t args;
1087 memset(&args, 0, sizeof(ide_task_t)); 1089 memset(&args, 0, sizeof(ide_task_t));
1088 args.tfRegister[IDE_COMMAND_OFFSET] = WIN_DOORLOCK; 1090 args.tfRegister[IDE_COMMAND_OFFSET] = WIN_DOORLOCK;
@@ -1106,9 +1108,10 @@ static int idedisk_release(struct inode *inode, struct file *filp)
1106 struct ide_disk_obj *idkp = ide_disk_g(disk); 1108 struct ide_disk_obj *idkp = ide_disk_g(disk);
1107 ide_drive_t *drive = idkp->drive; 1109 ide_drive_t *drive = idkp->drive;
1108 1110
1109 if (drive->usage == 1) 1111 if (idkp->openers == 1)
1110 ide_cacheflush_p(drive); 1112 ide_cacheflush_p(drive);
1111 if (drive->removable && drive->usage == 1) { 1113
1114 if (drive->removable && idkp->openers == 1) {
1112 ide_task_t args; 1115 ide_task_t args;
1113 memset(&args, 0, sizeof(ide_task_t)); 1116 memset(&args, 0, sizeof(ide_task_t));
1114 args.tfRegister[IDE_COMMAND_OFFSET] = WIN_DOORUNLOCK; 1117 args.tfRegister[IDE_COMMAND_OFFSET] = WIN_DOORUNLOCK;
@@ -1117,7 +1120,8 @@ static int idedisk_release(struct inode *inode, struct file *filp)
1117 if (drive->doorlocking && ide_raw_taskfile(drive, &args, NULL)) 1120 if (drive->doorlocking && ide_raw_taskfile(drive, &args, NULL))
1118 drive->doorlocking = 0; 1121 drive->doorlocking = 0;
1119 } 1122 }
1120 drive->usage--; 1123
1124 idkp->openers--;
1121 1125
1122 ide_disk_put(idkp); 1126 ide_disk_put(idkp);
1123 1127
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index 56efed6742d4..08e7cd043bcc 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -348,15 +348,14 @@ EXPORT_SYMBOL_GPL(ide_destroy_dmatable);
348static int config_drive_for_dma (ide_drive_t *drive) 348static int config_drive_for_dma (ide_drive_t *drive)
349{ 349{
350 struct hd_driveid *id = drive->id; 350 struct hd_driveid *id = drive->id;
351 ide_hwif_t *hwif = HWIF(drive);
352 351
353 if ((id->capability & 1) && hwif->autodma) { 352 if ((id->capability & 1) && drive->hwif->autodma) {
354 /* 353 /*
355 * Enable DMA on any drive that has 354 * Enable DMA on any drive that has
356 * UltraDMA (mode 0/1/2/3/4/5/6) enabled 355 * UltraDMA (mode 0/1/2/3/4/5/6) enabled
357 */ 356 */
358 if ((id->field_valid & 4) && ((id->dma_ultra >> 8) & 0x7f)) 357 if ((id->field_valid & 4) && ((id->dma_ultra >> 8) & 0x7f))
359 return hwif->ide_dma_on(drive); 358 return 0;
360 /* 359 /*
361 * Enable DMA on any drive that has mode2 DMA 360 * Enable DMA on any drive that has mode2 DMA
362 * (multi or single) enabled 361 * (multi or single) enabled
@@ -364,14 +363,14 @@ static int config_drive_for_dma (ide_drive_t *drive)
364 if (id->field_valid & 2) /* regular DMA */ 363 if (id->field_valid & 2) /* regular DMA */
365 if ((id->dma_mword & 0x404) == 0x404 || 364 if ((id->dma_mword & 0x404) == 0x404 ||
366 (id->dma_1word & 0x404) == 0x404) 365 (id->dma_1word & 0x404) == 0x404)
367 return hwif->ide_dma_on(drive); 366 return 0;
368 367
369 /* Consult the list of known "good" drives */ 368 /* Consult the list of known "good" drives */
370 if (__ide_dma_good_drive(drive)) 369 if (__ide_dma_good_drive(drive))
371 return hwif->ide_dma_on(drive); 370 return 0;
372 } 371 }
373// if (hwif->tuneproc != NULL) hwif->tuneproc(drive, 255); 372
374 return hwif->ide_dma_off_quietly(drive); 373 return -1;
375} 374}
376 375
377/** 376/**
@@ -415,72 +414,68 @@ static int dma_timer_expiry (ide_drive_t *drive)
415} 414}
416 415
417/** 416/**
418 * __ide_dma_host_off - Generic DMA kill 417 * ide_dma_host_off - Generic DMA kill
419 * @drive: drive to control 418 * @drive: drive to control
420 * 419 *
421 * Perform the generic IDE controller DMA off operation. This 420 * Perform the generic IDE controller DMA off operation. This
422 * works for most IDE bus mastering controllers 421 * works for most IDE bus mastering controllers
423 */ 422 */
424 423
425int __ide_dma_host_off (ide_drive_t *drive) 424void ide_dma_host_off(ide_drive_t *drive)
426{ 425{
427 ide_hwif_t *hwif = HWIF(drive); 426 ide_hwif_t *hwif = HWIF(drive);
428 u8 unit = (drive->select.b.unit & 0x01); 427 u8 unit = (drive->select.b.unit & 0x01);
429 u8 dma_stat = hwif->INB(hwif->dma_status); 428 u8 dma_stat = hwif->INB(hwif->dma_status);
430 429
431 hwif->OUTB((dma_stat & ~(1<<(5+unit))), hwif->dma_status); 430 hwif->OUTB((dma_stat & ~(1<<(5+unit))), hwif->dma_status);
432 return 0;
433} 431}
434 432
435EXPORT_SYMBOL(__ide_dma_host_off); 433EXPORT_SYMBOL(ide_dma_host_off);
436 434
437/** 435/**
438 * __ide_dma_host_off_quietly - Generic DMA kill 436 * ide_dma_off_quietly - Generic DMA kill
439 * @drive: drive to control 437 * @drive: drive to control
440 * 438 *
441 * Turn off the current DMA on this IDE controller. 439 * Turn off the current DMA on this IDE controller.
442 */ 440 */
443 441
444int __ide_dma_off_quietly (ide_drive_t *drive) 442void ide_dma_off_quietly(ide_drive_t *drive)
445{ 443{
446 drive->using_dma = 0; 444 drive->using_dma = 0;
447 ide_toggle_bounce(drive, 0); 445 ide_toggle_bounce(drive, 0);
448 446
449 if (HWIF(drive)->ide_dma_host_off(drive)) 447 drive->hwif->dma_host_off(drive);
450 return 1;
451
452 return 0;
453} 448}
454 449
455EXPORT_SYMBOL(__ide_dma_off_quietly); 450EXPORT_SYMBOL(ide_dma_off_quietly);
456#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */ 451#endif /* CONFIG_BLK_DEV_IDEDMA_PCI */
457 452
458/** 453/**
459 * __ide_dma_off - disable DMA on a device 454 * ide_dma_off - disable DMA on a device
460 * @drive: drive to disable DMA on 455 * @drive: drive to disable DMA on
461 * 456 *
462 * Disable IDE DMA for a device on this IDE controller. 457 * Disable IDE DMA for a device on this IDE controller.
463 * Inform the user that DMA has been disabled. 458 * Inform the user that DMA has been disabled.
464 */ 459 */
465 460
466int __ide_dma_off (ide_drive_t *drive) 461void ide_dma_off(ide_drive_t *drive)
467{ 462{
468 printk(KERN_INFO "%s: DMA disabled\n", drive->name); 463 printk(KERN_INFO "%s: DMA disabled\n", drive->name);
469 return HWIF(drive)->ide_dma_off_quietly(drive); 464 drive->hwif->dma_off_quietly(drive);
470} 465}
471 466
472EXPORT_SYMBOL(__ide_dma_off); 467EXPORT_SYMBOL(ide_dma_off);
473 468
474#ifdef CONFIG_BLK_DEV_IDEDMA_PCI 469#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
475/** 470/**
476 * __ide_dma_host_on - Enable DMA on a host 471 * ide_dma_host_on - Enable DMA on a host
477 * @drive: drive to enable for DMA 472 * @drive: drive to enable for DMA
478 * 473 *
479 * Enable DMA on an IDE controller following generic bus mastering 474 * Enable DMA on an IDE controller following generic bus mastering
480 * IDE controller behaviour 475 * IDE controller behaviour
481 */ 476 */
482 477
483int __ide_dma_host_on (ide_drive_t *drive) 478void ide_dma_host_on(ide_drive_t *drive)
484{ 479{
485 if (drive->using_dma) { 480 if (drive->using_dma) {
486 ide_hwif_t *hwif = HWIF(drive); 481 ide_hwif_t *hwif = HWIF(drive);
@@ -488,12 +483,10 @@ int __ide_dma_host_on (ide_drive_t *drive)
488 u8 dma_stat = hwif->INB(hwif->dma_status); 483 u8 dma_stat = hwif->INB(hwif->dma_status);
489 484
490 hwif->OUTB((dma_stat|(1<<(5+unit))), hwif->dma_status); 485 hwif->OUTB((dma_stat|(1<<(5+unit))), hwif->dma_status);
491 return 0;
492 } 486 }
493 return 1;
494} 487}
495 488
496EXPORT_SYMBOL(__ide_dma_host_on); 489EXPORT_SYMBOL(ide_dma_host_on);
497 490
498/** 491/**
499 * __ide_dma_on - Enable DMA on a device 492 * __ide_dma_on - Enable DMA on a device
@@ -511,8 +504,7 @@ int __ide_dma_on (ide_drive_t *drive)
511 drive->using_dma = 1; 504 drive->using_dma = 1;
512 ide_toggle_bounce(drive, 1); 505 ide_toggle_bounce(drive, 1);
513 506
514 if (HWIF(drive)->ide_dma_host_on(drive)) 507 drive->hwif->dma_host_on(drive);
515 return 1;
516 508
517 return 0; 509 return 0;
518} 510}
@@ -565,7 +557,10 @@ int ide_dma_setup(ide_drive_t *drive)
565 } 557 }
566 558
567 /* PRD table */ 559 /* PRD table */
568 hwif->OUTL(hwif->dmatable_dma, hwif->dma_prdtable); 560 if (hwif->mmio)
561 writel(hwif->dmatable_dma, (void __iomem *)hwif->dma_prdtable);
562 else
563 outl(hwif->dmatable_dma, hwif->dma_prdtable);
569 564
570 /* specify r/w */ 565 /* specify r/w */
571 hwif->OUTB(reading, hwif->dma_command); 566 hwif->OUTB(reading, hwif->dma_command);
@@ -680,6 +675,9 @@ int ide_use_dma(ide_drive_t *drive)
680 struct hd_driveid *id = drive->id; 675 struct hd_driveid *id = drive->id;
681 ide_hwif_t *hwif = drive->hwif; 676 ide_hwif_t *hwif = drive->hwif;
682 677
678 if ((id->capability & 1) == 0 || drive->autodma == 0)
679 return 0;
680
683 /* consult the list of known "bad" drives */ 681 /* consult the list of known "bad" drives */
684 if (__ide_dma_bad_drive(drive)) 682 if (__ide_dma_bad_drive(drive))
685 return 0; 683 return 0;
@@ -753,12 +751,37 @@ void ide_dma_verbose(ide_drive_t *drive)
753 return; 751 return;
754bug_dma_off: 752bug_dma_off:
755 printk(", BUG DMA OFF"); 753 printk(", BUG DMA OFF");
756 hwif->ide_dma_off_quietly(drive); 754 hwif->dma_off_quietly(drive);
757 return; 755 return;
758} 756}
759 757
760EXPORT_SYMBOL(ide_dma_verbose); 758EXPORT_SYMBOL(ide_dma_verbose);
761 759
760int ide_set_dma(ide_drive_t *drive)
761{
762 ide_hwif_t *hwif = drive->hwif;
763 int rc;
764
765 rc = hwif->ide_dma_check(drive);
766
767 switch(rc) {
768 case -1: /* DMA needs to be disabled */
769 hwif->dma_off_quietly(drive);
770 return 0;
771 case 0: /* DMA needs to be enabled */
772 return hwif->ide_dma_on(drive);
773 case 1: /* DMA setting cannot be changed */
774 break;
775 default:
776 BUG();
777 break;
778 }
779
780 return rc;
781}
782
783EXPORT_SYMBOL_GPL(ide_set_dma);
784
762#ifdef CONFIG_BLK_DEV_IDEDMA_PCI 785#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
763int __ide_dma_lostirq (ide_drive_t *drive) 786int __ide_dma_lostirq (ide_drive_t *drive)
764{ 787{
@@ -809,7 +832,7 @@ int ide_release_dma(ide_hwif_t *hwif)
809{ 832{
810 ide_release_dma_engine(hwif); 833 ide_release_dma_engine(hwif);
811 834
812 if (hwif->mmio == 2) 835 if (hwif->mmio)
813 return 1; 836 return 1;
814 else 837 else
815 return ide_release_iomio_dma(hwif); 838 return ide_release_iomio_dma(hwif);
@@ -878,9 +901,9 @@ static int ide_iomio_dma(ide_hwif_t *hwif, unsigned long base, unsigned int port
878 901
879static int ide_dma_iobase(ide_hwif_t *hwif, unsigned long base, unsigned int ports) 902static int ide_dma_iobase(ide_hwif_t *hwif, unsigned long base, unsigned int ports)
880{ 903{
881 if (hwif->mmio == 2) 904 if (hwif->mmio)
882 return ide_mapped_mmio_dma(hwif, base,ports); 905 return ide_mapped_mmio_dma(hwif, base,ports);
883 BUG_ON(hwif->mmio == 1); 906
884 return ide_iomio_dma(hwif, base, ports); 907 return ide_iomio_dma(hwif, base, ports);
885} 908}
886 909
@@ -908,14 +931,14 @@ void ide_setup_dma (ide_hwif_t *hwif, unsigned long dma_base, unsigned int num_p
908 if (!(hwif->dma_prdtable)) 931 if (!(hwif->dma_prdtable))
909 hwif->dma_prdtable = (hwif->dma_base + 4); 932 hwif->dma_prdtable = (hwif->dma_base + 4);
910 933
911 if (!hwif->ide_dma_off_quietly) 934 if (!hwif->dma_off_quietly)
912 hwif->ide_dma_off_quietly = &__ide_dma_off_quietly; 935 hwif->dma_off_quietly = &ide_dma_off_quietly;
913 if (!hwif->ide_dma_host_off) 936 if (!hwif->dma_host_off)
914 hwif->ide_dma_host_off = &__ide_dma_host_off; 937 hwif->dma_host_off = &ide_dma_host_off;
915 if (!hwif->ide_dma_on) 938 if (!hwif->ide_dma_on)
916 hwif->ide_dma_on = &__ide_dma_on; 939 hwif->ide_dma_on = &__ide_dma_on;
917 if (!hwif->ide_dma_host_on) 940 if (!hwif->dma_host_on)
918 hwif->ide_dma_host_on = &__ide_dma_host_on; 941 hwif->dma_host_on = &ide_dma_host_on;
919 if (!hwif->ide_dma_check) 942 if (!hwif->ide_dma_check)
920 hwif->ide_dma_check = &__ide_dma_check; 943 hwif->ide_dma_check = &__ide_dma_check;
921 if (!hwif->dma_setup) 944 if (!hwif->dma_setup)
diff --git a/drivers/ide/ide-floppy.c b/drivers/ide/ide-floppy.c
index d33717c8afd4..57cd21c5b2c1 100644
--- a/drivers/ide/ide-floppy.c
+++ b/drivers/ide/ide-floppy.c
@@ -279,6 +279,7 @@ typedef struct ide_floppy_obj {
279 ide_driver_t *driver; 279 ide_driver_t *driver;
280 struct gendisk *disk; 280 struct gendisk *disk;
281 struct kref kref; 281 struct kref kref;
282 unsigned int openers; /* protected by BKL for now */
282 283
283 /* Current packet command */ 284 /* Current packet command */
284 idefloppy_pc_t *pc; 285 idefloppy_pc_t *pc;
@@ -866,7 +867,7 @@ static ide_startstop_t idefloppy_pc_intr (ide_drive_t *drive)
866 if (test_and_clear_bit(PC_DMA_IN_PROGRESS, &pc->flags)) { 867 if (test_and_clear_bit(PC_DMA_IN_PROGRESS, &pc->flags)) {
867 printk(KERN_ERR "ide-floppy: The floppy wants to issue " 868 printk(KERN_ERR "ide-floppy: The floppy wants to issue "
868 "more interrupts in DMA mode\n"); 869 "more interrupts in DMA mode\n");
869 (void)__ide_dma_off(drive); 870 ide_dma_off(drive);
870 return ide_do_reset(drive); 871 return ide_do_reset(drive);
871 } 872 }
872 873
@@ -1096,9 +1097,9 @@ static ide_startstop_t idefloppy_issue_pc (ide_drive_t *drive, idefloppy_pc_t *p
1096 pc->current_position = pc->buffer; 1097 pc->current_position = pc->buffer;
1097 bcount.all = min(pc->request_transfer, 63 * 1024); 1098 bcount.all = min(pc->request_transfer, 63 * 1024);
1098 1099
1099 if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) { 1100 if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags))
1100 (void)__ide_dma_off(drive); 1101 ide_dma_off(drive);
1101 } 1102
1102 feature.all = 0; 1103 feature.all = 0;
1103 1104
1104 if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) 1105 if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
@@ -1433,7 +1434,8 @@ static int idefloppy_get_capacity (ide_drive_t *drive)
1433 1434
1434 drive->bios_cyl = 0; 1435 drive->bios_cyl = 0;
1435 drive->bios_head = drive->bios_sect = 0; 1436 drive->bios_head = drive->bios_sect = 0;
1436 floppy->blocks = floppy->bs_factor = 0; 1437 floppy->blocks = 0;
1438 floppy->bs_factor = 1;
1437 set_capacity(floppy->disk, 0); 1439 set_capacity(floppy->disk, 0);
1438 1440
1439 idefloppy_create_read_capacity_cmd(&pc); 1441 idefloppy_create_read_capacity_cmd(&pc);
@@ -1949,9 +1951,9 @@ static int idefloppy_open(struct inode *inode, struct file *filp)
1949 1951
1950 drive = floppy->drive; 1952 drive = floppy->drive;
1951 1953
1952 drive->usage++; 1954 floppy->openers++;
1953 1955
1954 if (drive->usage == 1) { 1956 if (floppy->openers == 1) {
1955 clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags); 1957 clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
1956 /* Just in case */ 1958 /* Just in case */
1957 1959
@@ -1969,13 +1971,11 @@ static int idefloppy_open(struct inode *inode, struct file *filp)
1969 ** capacity of the drive or begin the format - Sam 1971 ** capacity of the drive or begin the format - Sam
1970 */ 1972 */
1971 ) { 1973 ) {
1972 drive->usage--;
1973 ret = -EIO; 1974 ret = -EIO;
1974 goto out_put_floppy; 1975 goto out_put_floppy;
1975 } 1976 }
1976 1977
1977 if (floppy->wp && (filp->f_mode & 2)) { 1978 if (floppy->wp && (filp->f_mode & 2)) {
1978 drive->usage--;
1979 ret = -EROFS; 1979 ret = -EROFS;
1980 goto out_put_floppy; 1980 goto out_put_floppy;
1981 } 1981 }
@@ -1987,13 +1987,13 @@ static int idefloppy_open(struct inode *inode, struct file *filp)
1987 } 1987 }
1988 check_disk_change(inode->i_bdev); 1988 check_disk_change(inode->i_bdev);
1989 } else if (test_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags)) { 1989 } else if (test_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags)) {
1990 drive->usage--;
1991 ret = -EBUSY; 1990 ret = -EBUSY;
1992 goto out_put_floppy; 1991 goto out_put_floppy;
1993 } 1992 }
1994 return 0; 1993 return 0;
1995 1994
1996out_put_floppy: 1995out_put_floppy:
1996 floppy->openers--;
1997 ide_floppy_put(floppy); 1997 ide_floppy_put(floppy);
1998 return ret; 1998 return ret;
1999} 1999}
@@ -2007,7 +2007,7 @@ static int idefloppy_release(struct inode *inode, struct file *filp)
2007 2007
2008 debug_log(KERN_INFO "Reached idefloppy_release\n"); 2008 debug_log(KERN_INFO "Reached idefloppy_release\n");
2009 2009
2010 if (drive->usage == 1) { 2010 if (floppy->openers == 1) {
2011 /* IOMEGA Clik! drives do not support lock/unlock commands */ 2011 /* IOMEGA Clik! drives do not support lock/unlock commands */
2012 if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) { 2012 if (!test_bit(IDEFLOPPY_CLIK_DRIVE, &floppy->flags)) {
2013 idefloppy_create_prevent_cmd(&pc, 0); 2013 idefloppy_create_prevent_cmd(&pc, 0);
@@ -2016,7 +2016,8 @@ static int idefloppy_release(struct inode *inode, struct file *filp)
2016 2016
2017 clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags); 2017 clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, &floppy->flags);
2018 } 2018 }
2019 drive->usage--; 2019
2020 floppy->openers--;
2020 2021
2021 ide_floppy_put(floppy); 2022 ide_floppy_put(floppy);
2022 2023
@@ -2050,7 +2051,7 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file,
2050 prevent = 0; 2051 prevent = 0;
2051 /* fall through */ 2052 /* fall through */
2052 case CDROM_LOCKDOOR: 2053 case CDROM_LOCKDOOR:
2053 if (drive->usage > 1) 2054 if (floppy->openers > 1)
2054 return -EBUSY; 2055 return -EBUSY;
2055 2056
2056 /* The IOMEGA Clik! Drive doesn't support this command - no room for an eject mechanism */ 2057 /* The IOMEGA Clik! Drive doesn't support this command - no room for an eject mechanism */
@@ -2072,7 +2073,7 @@ static int idefloppy_ioctl(struct inode *inode, struct file *file,
2072 if (!(file->f_mode & 2)) 2073 if (!(file->f_mode & 2))
2073 return -EPERM; 2074 return -EPERM;
2074 2075
2075 if (drive->usage > 1) { 2076 if (floppy->openers > 1) {
2076 /* Don't format if someone is using the disk */ 2077 /* Don't format if someone is using the disk */
2077 2078
2078 clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS, 2079 clear_bit(IDEFLOPPY_FORMAT_IN_PROGRESS,
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 2614f41b5074..c193553f6fe7 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -226,7 +226,7 @@ static ide_startstop_t ide_start_power_step(ide_drive_t *drive, struct request *
226 break; 226 break;
227 if (drive->hwif->ide_dma_check == NULL) 227 if (drive->hwif->ide_dma_check == NULL)
228 break; 228 break;
229 drive->hwif->ide_dma_check(drive); 229 ide_set_dma(drive);
230 break; 230 break;
231 } 231 }
232 pm->pm_step = ide_pm_state_completed; 232 pm->pm_step = ide_pm_state_completed;
@@ -1351,7 +1351,7 @@ static ide_startstop_t ide_dma_timeout_retry(ide_drive_t *drive, int error)
1351 */ 1351 */
1352 drive->retry_pio++; 1352 drive->retry_pio++;
1353 drive->state = DMA_PIO_RETRY; 1353 drive->state = DMA_PIO_RETRY;
1354 (void) hwif->ide_dma_off_quietly(drive); 1354 hwif->dma_off_quietly(drive);
1355 1355
1356 /* 1356 /*
1357 * un-busy drive etc (hwgroup->busy is cleared on return) and 1357 * un-busy drive etc (hwgroup->busy is cleared on return) and
@@ -1646,6 +1646,17 @@ irqreturn_t ide_intr (int irq, void *dev_id)
1646 del_timer(&hwgroup->timer); 1646 del_timer(&hwgroup->timer);
1647 spin_unlock(&ide_lock); 1647 spin_unlock(&ide_lock);
1648 1648
1649 /* Some controllers might set DMA INTR no matter DMA or PIO;
1650 * bmdma status might need to be cleared even for
1651 * PIO interrupts to prevent spurious/lost irq.
1652 */
1653 if (hwif->ide_dma_clear_irq && !(drive->waiting_for_dma))
1654 /* ide_dma_end() needs bmdma status for error checking.
1655 * So, skip clearing bmdma status here and leave it
1656 * to ide_dma_end() if this is dma interrupt.
1657 */
1658 hwif->ide_dma_clear_irq(drive);
1659
1649 if (drive->unmask) 1660 if (drive->unmask)
1650 local_irq_enable_in_hardirq(); 1661 local_irq_enable_in_hardirq();
1651 /* service this interrupt, may set handler for next interrupt */ 1662 /* service this interrupt, may set handler for next interrupt */
diff --git a/drivers/ide/ide-iops.c b/drivers/ide/ide-iops.c
index badde6331775..c67b3b1e6f4c 100644
--- a/drivers/ide/ide-iops.c
+++ b/drivers/ide/ide-iops.c
@@ -49,11 +49,6 @@ static void ide_insw (unsigned long port, void *addr, u32 count)
49 insw(port, addr, count); 49 insw(port, addr, count);
50} 50}
51 51
52static u32 ide_inl (unsigned long port)
53{
54 return (u32) inl(port);
55}
56
57static void ide_insl (unsigned long port, void *addr, u32 count) 52static void ide_insl (unsigned long port, void *addr, u32 count)
58{ 53{
59 insl(port, addr, count); 54 insl(port, addr, count);
@@ -79,11 +74,6 @@ static void ide_outsw (unsigned long port, void *addr, u32 count)
79 outsw(port, addr, count); 74 outsw(port, addr, count);
80} 75}
81 76
82static void ide_outl (u32 val, unsigned long port)
83{
84 outl(val, port);
85}
86
87static void ide_outsl (unsigned long port, void *addr, u32 count) 77static void ide_outsl (unsigned long port, void *addr, u32 count)
88{ 78{
89 outsl(port, addr, count); 79 outsl(port, addr, count);
@@ -94,12 +84,10 @@ void default_hwif_iops (ide_hwif_t *hwif)
94 hwif->OUTB = ide_outb; 84 hwif->OUTB = ide_outb;
95 hwif->OUTBSYNC = ide_outbsync; 85 hwif->OUTBSYNC = ide_outbsync;
96 hwif->OUTW = ide_outw; 86 hwif->OUTW = ide_outw;
97 hwif->OUTL = ide_outl;
98 hwif->OUTSW = ide_outsw; 87 hwif->OUTSW = ide_outsw;
99 hwif->OUTSL = ide_outsl; 88 hwif->OUTSL = ide_outsl;
100 hwif->INB = ide_inb; 89 hwif->INB = ide_inb;
101 hwif->INW = ide_inw; 90 hwif->INW = ide_inw;
102 hwif->INL = ide_inl;
103 hwif->INSW = ide_insw; 91 hwif->INSW = ide_insw;
104 hwif->INSL = ide_insl; 92 hwif->INSL = ide_insl;
105} 93}
@@ -123,11 +111,6 @@ static void ide_mm_insw (unsigned long port, void *addr, u32 count)
123 __ide_mm_insw((void __iomem *) port, addr, count); 111 __ide_mm_insw((void __iomem *) port, addr, count);
124} 112}
125 113
126static u32 ide_mm_inl (unsigned long port)
127{
128 return (u32) readl((void __iomem *) port);
129}
130
131static void ide_mm_insl (unsigned long port, void *addr, u32 count) 114static void ide_mm_insl (unsigned long port, void *addr, u32 count)
132{ 115{
133 __ide_mm_insl((void __iomem *) port, addr, count); 116 __ide_mm_insl((void __iomem *) port, addr, count);
@@ -153,11 +136,6 @@ static void ide_mm_outsw (unsigned long port, void *addr, u32 count)
153 __ide_mm_outsw((void __iomem *) port, addr, count); 136 __ide_mm_outsw((void __iomem *) port, addr, count);
154} 137}
155 138
156static void ide_mm_outl (u32 value, unsigned long port)
157{
158 writel(value, (void __iomem *) port);
159}
160
161static void ide_mm_outsl (unsigned long port, void *addr, u32 count) 139static void ide_mm_outsl (unsigned long port, void *addr, u32 count)
162{ 140{
163 __ide_mm_outsl((void __iomem *) port, addr, count); 141 __ide_mm_outsl((void __iomem *) port, addr, count);
@@ -170,12 +148,10 @@ void default_hwif_mmiops (ide_hwif_t *hwif)
170 this one is controller specific! */ 148 this one is controller specific! */
171 hwif->OUTBSYNC = ide_mm_outbsync; 149 hwif->OUTBSYNC = ide_mm_outbsync;
172 hwif->OUTW = ide_mm_outw; 150 hwif->OUTW = ide_mm_outw;
173 hwif->OUTL = ide_mm_outl;
174 hwif->OUTSW = ide_mm_outsw; 151 hwif->OUTSW = ide_mm_outsw;
175 hwif->OUTSL = ide_mm_outsl; 152 hwif->OUTSL = ide_mm_outsl;
176 hwif->INB = ide_mm_inb; 153 hwif->INB = ide_mm_inb;
177 hwif->INW = ide_mm_inw; 154 hwif->INW = ide_mm_inw;
178 hwif->INL = ide_mm_inl;
179 hwif->INSW = ide_mm_insw; 155 hwif->INSW = ide_mm_insw;
180 hwif->INSL = ide_mm_insl; 156 hwif->INSL = ide_mm_insl;
181} 157}
@@ -777,7 +753,7 @@ int ide_config_drive_speed (ide_drive_t *drive, u8 speed)
777 753
778#ifdef CONFIG_BLK_DEV_IDEDMA 754#ifdef CONFIG_BLK_DEV_IDEDMA
779 if (hwif->ide_dma_check) /* check if host supports DMA */ 755 if (hwif->ide_dma_check) /* check if host supports DMA */
780 hwif->ide_dma_host_off(drive); 756 hwif->dma_host_off(drive);
781#endif 757#endif
782 758
783 /* 759 /*
@@ -854,9 +830,9 @@ int ide_config_drive_speed (ide_drive_t *drive, u8 speed)
854 830
855#ifdef CONFIG_BLK_DEV_IDEDMA 831#ifdef CONFIG_BLK_DEV_IDEDMA
856 if (speed >= XFER_SW_DMA_0) 832 if (speed >= XFER_SW_DMA_0)
857 hwif->ide_dma_host_on(drive); 833 hwif->dma_host_on(drive);
858 else if (hwif->ide_dma_check) /* check if host supports DMA */ 834 else if (hwif->ide_dma_check) /* check if host supports DMA */
859 hwif->ide_dma_off_quietly(drive); 835 hwif->dma_off_quietly(drive);
860#endif 836#endif
861 837
862 switch(speed) { 838 switch(speed) {
@@ -1066,12 +1042,12 @@ static void check_dma_crc(ide_drive_t *drive)
1066{ 1042{
1067#ifdef CONFIG_BLK_DEV_IDEDMA 1043#ifdef CONFIG_BLK_DEV_IDEDMA
1068 if (drive->crc_count) { 1044 if (drive->crc_count) {
1069 (void) HWIF(drive)->ide_dma_off_quietly(drive); 1045 drive->hwif->dma_off_quietly(drive);
1070 ide_set_xfer_rate(drive, ide_auto_reduce_xfer(drive)); 1046 ide_set_xfer_rate(drive, ide_auto_reduce_xfer(drive));
1071 if (drive->current_speed >= XFER_SW_DMA_0) 1047 if (drive->current_speed >= XFER_SW_DMA_0)
1072 (void) HWIF(drive)->ide_dma_on(drive); 1048 (void) HWIF(drive)->ide_dma_on(drive);
1073 } else 1049 } else
1074 (void)__ide_dma_off(drive); 1050 ide_dma_off(drive);
1075#endif 1051#endif
1076} 1052}
1077 1053
diff --git a/drivers/ide/ide-lib.c b/drivers/ide/ide-lib.c
index 8237d89eec6e..8afce4ceea31 100644
--- a/drivers/ide/ide-lib.c
+++ b/drivers/ide/ide-lib.c
@@ -205,6 +205,21 @@ int ide_dma_enable (ide_drive_t *drive)
205 205
206EXPORT_SYMBOL(ide_dma_enable); 206EXPORT_SYMBOL(ide_dma_enable);
207 207
208int ide_use_fast_pio(ide_drive_t *drive)
209{
210 struct hd_driveid *id = drive->id;
211
212 if ((id->capability & 1) && drive->autodma)
213 return 1;
214
215 if ((id->capability & 8) || (id->field_valid & 2))
216 return 1;
217
218 return 0;
219}
220
221EXPORT_SYMBOL_GPL(ide_use_fast_pio);
222
208/* 223/*
209 * Standard (generic) timings for PIO modes, from ATA2 specification. 224 * Standard (generic) timings for PIO modes, from ATA2 specification.
210 * These timings are for access to the IDE data port register *only*. 225 * These timings are for access to the IDE data port register *only*.
@@ -349,7 +364,6 @@ u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode, ide_p
349 int use_iordy = 0; 364 int use_iordy = 0;
350 struct hd_driveid* id = drive->id; 365 struct hd_driveid* id = drive->id;
351 int overridden = 0; 366 int overridden = 0;
352 int blacklisted = 0;
353 367
354 if (mode_wanted != 255) { 368 if (mode_wanted != 255) {
355 pio_mode = mode_wanted; 369 pio_mode = mode_wanted;
@@ -357,7 +371,6 @@ u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode, ide_p
357 pio_mode = 0; 371 pio_mode = 0;
358 } else if ((pio_mode = ide_scan_pio_blacklist(id->model)) != -1) { 372 } else if ((pio_mode = ide_scan_pio_blacklist(id->model)) != -1) {
359 overridden = 1; 373 overridden = 1;
360 blacklisted = 1;
361 use_iordy = (pio_mode > 2); 374 use_iordy = (pio_mode > 2);
362 } else { 375 } else {
363 pio_mode = id->tPIO; 376 pio_mode = id->tPIO;
@@ -409,7 +422,6 @@ u8 ide_get_best_pio_mode (ide_drive_t *drive, u8 mode_wanted, u8 max_mode, ide_p
409 d->cycle_time = cycle_time ? cycle_time : ide_pio_timings[pio_mode].cycle_time; 422 d->cycle_time = cycle_time ? cycle_time : ide_pio_timings[pio_mode].cycle_time;
410 d->use_iordy = use_iordy; 423 d->use_iordy = use_iordy;
411 d->overridden = overridden; 424 d->overridden = overridden;
412 d->blacklisted = blacklisted;
413 } 425 }
414 return pio_mode; 426 return pio_mode;
415} 427}
@@ -462,8 +474,6 @@ int ide_set_xfer_rate(ide_drive_t *drive, u8 rate)
462 return -1; 474 return -1;
463} 475}
464 476
465EXPORT_SYMBOL_GPL(ide_set_xfer_rate);
466
467static void ide_dump_opcode(ide_drive_t *drive) 477static void ide_dump_opcode(ide_drive_t *drive)
468{ 478{
469 struct request *rq; 479 struct request *rq;
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index 176bbc850d6b..8afbd6cb94be 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -853,11 +853,11 @@ static void probe_hwif(ide_hwif_t *hwif)
853 * things, if not checked and cleared. 853 * things, if not checked and cleared.
854 * PARANOIA!!! 854 * PARANOIA!!!
855 */ 855 */
856 hwif->ide_dma_off_quietly(drive); 856 hwif->dma_off_quietly(drive);
857#ifdef CONFIG_IDEDMA_ONLYDISK 857#ifdef CONFIG_IDEDMA_ONLYDISK
858 if (drive->media == ide_disk) 858 if (drive->media == ide_disk)
859#endif 859#endif
860 hwif->ide_dma_check(drive); 860 ide_set_dma(drive);
861 } 861 }
862 } 862 }
863 } 863 }
diff --git a/drivers/ide/ide-tape.c b/drivers/ide/ide-tape.c
index c6eec0413a6c..4e59239fef75 100644
--- a/drivers/ide/ide-tape.c
+++ b/drivers/ide/ide-tape.c
@@ -1970,7 +1970,7 @@ static ide_startstop_t idetape_pc_intr (ide_drive_t *drive)
1970 printk(KERN_ERR "ide-tape: The tape wants to issue more " 1970 printk(KERN_ERR "ide-tape: The tape wants to issue more "
1971 "interrupts in DMA mode\n"); 1971 "interrupts in DMA mode\n");
1972 printk(KERN_ERR "ide-tape: DMA disabled, reverting to PIO\n"); 1972 printk(KERN_ERR "ide-tape: DMA disabled, reverting to PIO\n");
1973 (void)__ide_dma_off(drive); 1973 ide_dma_off(drive);
1974 return ide_do_reset(drive); 1974 return ide_do_reset(drive);
1975 } 1975 }
1976 /* Get the number of bytes to transfer on this interrupt. */ 1976 /* Get the number of bytes to transfer on this interrupt. */
@@ -2176,7 +2176,7 @@ static ide_startstop_t idetape_issue_packet_command (ide_drive_t *drive, idetape
2176 if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) { 2176 if (test_and_clear_bit(PC_DMA_ERROR, &pc->flags)) {
2177 printk(KERN_WARNING "ide-tape: DMA disabled, " 2177 printk(KERN_WARNING "ide-tape: DMA disabled, "
2178 "reverting to PIO\n"); 2178 "reverting to PIO\n");
2179 (void)__ide_dma_off(drive); 2179 ide_dma_off(drive);
2180 } 2180 }
2181 if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma) 2181 if (test_bit(PC_DMA_RECOMMENDED, &pc->flags) && drive->using_dma)
2182 dma_ok = !hwif->dma_setup(drive); 2182 dma_ok = !hwif->dma_setup(drive);
@@ -4792,15 +4792,10 @@ static int idetape_open(struct inode *inode, struct file *filp)
4792{ 4792{
4793 struct gendisk *disk = inode->i_bdev->bd_disk; 4793 struct gendisk *disk = inode->i_bdev->bd_disk;
4794 struct ide_tape_obj *tape; 4794 struct ide_tape_obj *tape;
4795 ide_drive_t *drive;
4796 4795
4797 if (!(tape = ide_tape_get(disk))) 4796 if (!(tape = ide_tape_get(disk)))
4798 return -ENXIO; 4797 return -ENXIO;
4799 4798
4800 drive = tape->drive;
4801
4802 drive->usage++;
4803
4804 return 0; 4799 return 0;
4805} 4800}
4806 4801
@@ -4808,9 +4803,6 @@ static int idetape_release(struct inode *inode, struct file *filp)
4808{ 4803{
4809 struct gendisk *disk = inode->i_bdev->bd_disk; 4804 struct gendisk *disk = inode->i_bdev->bd_disk;
4810 struct ide_tape_obj *tape = ide_tape_g(disk); 4805 struct ide_tape_obj *tape = ide_tape_g(disk);
4811 ide_drive_t *drive = tape->drive;
4812
4813 drive->usage--;
4814 4806
4815 ide_tape_put(tape); 4807 ide_tape_put(tape);
4816 4808
diff --git a/drivers/ide/ide.c b/drivers/ide/ide.c
index c750f6ce770a..b3c0818c5c6c 100644
--- a/drivers/ide/ide.c
+++ b/drivers/ide/ide.c
@@ -389,9 +389,8 @@ int ide_hwif_request_regions(ide_hwif_t *hwif)
389 unsigned long addr; 389 unsigned long addr;
390 unsigned int i; 390 unsigned int i;
391 391
392 if (hwif->mmio == 2) 392 if (hwif->mmio)
393 return 0; 393 return 0;
394 BUG_ON(hwif->mmio == 1);
395 addr = hwif->io_ports[IDE_CONTROL_OFFSET]; 394 addr = hwif->io_ports[IDE_CONTROL_OFFSET];
396 if (addr && !hwif_request_region(hwif, addr, 1)) 395 if (addr && !hwif_request_region(hwif, addr, 1))
397 goto control_region_busy; 396 goto control_region_busy;
@@ -438,7 +437,7 @@ void ide_hwif_release_regions(ide_hwif_t *hwif)
438{ 437{
439 u32 i = 0; 438 u32 i = 0;
440 439
441 if (hwif->mmio == 2) 440 if (hwif->mmio)
442 return; 441 return;
443 if (hwif->io_ports[IDE_CONTROL_OFFSET]) 442 if (hwif->io_ports[IDE_CONTROL_OFFSET])
444 release_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1); 443 release_region(hwif->io_ports[IDE_CONTROL_OFFSET], 1);
@@ -507,23 +506,22 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
507 hwif->ide_dma_end = tmp_hwif->ide_dma_end; 506 hwif->ide_dma_end = tmp_hwif->ide_dma_end;
508 hwif->ide_dma_check = tmp_hwif->ide_dma_check; 507 hwif->ide_dma_check = tmp_hwif->ide_dma_check;
509 hwif->ide_dma_on = tmp_hwif->ide_dma_on; 508 hwif->ide_dma_on = tmp_hwif->ide_dma_on;
510 hwif->ide_dma_off_quietly = tmp_hwif->ide_dma_off_quietly; 509 hwif->dma_off_quietly = tmp_hwif->dma_off_quietly;
511 hwif->ide_dma_test_irq = tmp_hwif->ide_dma_test_irq; 510 hwif->ide_dma_test_irq = tmp_hwif->ide_dma_test_irq;
512 hwif->ide_dma_host_on = tmp_hwif->ide_dma_host_on; 511 hwif->ide_dma_clear_irq = tmp_hwif->ide_dma_clear_irq;
513 hwif->ide_dma_host_off = tmp_hwif->ide_dma_host_off; 512 hwif->dma_host_on = tmp_hwif->dma_host_on;
513 hwif->dma_host_off = tmp_hwif->dma_host_off;
514 hwif->ide_dma_lostirq = tmp_hwif->ide_dma_lostirq; 514 hwif->ide_dma_lostirq = tmp_hwif->ide_dma_lostirq;
515 hwif->ide_dma_timeout = tmp_hwif->ide_dma_timeout; 515 hwif->ide_dma_timeout = tmp_hwif->ide_dma_timeout;
516 516
517 hwif->OUTB = tmp_hwif->OUTB; 517 hwif->OUTB = tmp_hwif->OUTB;
518 hwif->OUTBSYNC = tmp_hwif->OUTBSYNC; 518 hwif->OUTBSYNC = tmp_hwif->OUTBSYNC;
519 hwif->OUTW = tmp_hwif->OUTW; 519 hwif->OUTW = tmp_hwif->OUTW;
520 hwif->OUTL = tmp_hwif->OUTL;
521 hwif->OUTSW = tmp_hwif->OUTSW; 520 hwif->OUTSW = tmp_hwif->OUTSW;
522 hwif->OUTSL = tmp_hwif->OUTSL; 521 hwif->OUTSL = tmp_hwif->OUTSL;
523 522
524 hwif->INB = tmp_hwif->INB; 523 hwif->INB = tmp_hwif->INB;
525 hwif->INW = tmp_hwif->INW; 524 hwif->INW = tmp_hwif->INW;
526 hwif->INL = tmp_hwif->INL;
527 hwif->INSW = tmp_hwif->INSW; 525 hwif->INSW = tmp_hwif->INSW;
528 hwif->INSL = tmp_hwif->INSL; 526 hwif->INSL = tmp_hwif->INSL;
529 527
@@ -551,7 +549,6 @@ static void ide_hwif_restore(ide_hwif_t *hwif, ide_hwif_t *tmp_hwif)
551 hwif->extra_ports = tmp_hwif->extra_ports; 549 hwif->extra_ports = tmp_hwif->extra_ports;
552 hwif->autodma = tmp_hwif->autodma; 550 hwif->autodma = tmp_hwif->autodma;
553 hwif->udma_four = tmp_hwif->udma_four; 551 hwif->udma_four = tmp_hwif->udma_four;
554 hwif->no_dsc = tmp_hwif->no_dsc;
555 552
556 hwif->hwif_data = tmp_hwif->hwif_data; 553 hwif->hwif_data = tmp_hwif->hwif_data;
557} 554}
@@ -1138,12 +1135,11 @@ static int set_using_dma (ide_drive_t *drive, int arg)
1138 if (HWIF(drive)->ide_dma_check == NULL) 1135 if (HWIF(drive)->ide_dma_check == NULL)
1139 return -EPERM; 1136 return -EPERM;
1140 if (arg) { 1137 if (arg) {
1141 if (HWIF(drive)->ide_dma_check(drive)) return -EIO; 1138 if (ide_set_dma(drive))
1142 if (HWIF(drive)->ide_dma_on(drive)) return -EIO;
1143 } else {
1144 if (__ide_dma_off(drive))
1145 return -EIO; 1139 return -EIO;
1146 } 1140 if (HWIF(drive)->ide_dma_on(drive)) return -EIO;
1141 } else
1142 ide_dma_off(drive);
1147 return 0; 1143 return 0;
1148#else 1144#else
1149 return -EPERM; 1145 return -EPERM;
diff --git a/drivers/ide/legacy/buddha.c b/drivers/ide/legacy/buddha.c
index 0391a3122878..1ed224a01f79 100644
--- a/drivers/ide/legacy/buddha.c
+++ b/drivers/ide/legacy/buddha.c
@@ -215,7 +215,7 @@ fail_base2:
215 215
216 index = ide_register_hw(&hw, &hwif); 216 index = ide_register_hw(&hw, &hwif);
217 if (index != -1) { 217 if (index != -1) {
218 hwif->mmio = 2; 218 hwif->mmio = 1;
219 printk("ide%d: ", index); 219 printk("ide%d: ", index);
220 switch(type) { 220 switch(type) {
221 case BOARD_BUDDHA: 221 case BOARD_BUDDHA:
diff --git a/drivers/ide/legacy/gayle.c b/drivers/ide/legacy/gayle.c
index 64d42619ab06..dcfadbbf55d8 100644
--- a/drivers/ide/legacy/gayle.c
+++ b/drivers/ide/legacy/gayle.c
@@ -167,7 +167,7 @@ found:
167 167
168 index = ide_register_hw(&hw, &hwif); 168 index = ide_register_hw(&hw, &hwif);
169 if (index != -1) { 169 if (index != -1) {
170 hwif->mmio = 2; 170 hwif->mmio = 1;
171 switch (i) { 171 switch (i) {
172 case 0: 172 case 0:
173 printk("ide%d: Gayle IDE interface (A%d style)\n", index, 173 printk("ide%d: Gayle IDE interface (A%d style)\n", index,
diff --git a/drivers/ide/legacy/ht6560b.c b/drivers/ide/legacy/ht6560b.c
index c48e87e512d3..19ccd006f205 100644
--- a/drivers/ide/legacy/ht6560b.c
+++ b/drivers/ide/legacy/ht6560b.c
@@ -143,16 +143,16 @@ static void ht6560b_selectproc (ide_drive_t *drive)
143 current_timing = timing; 143 current_timing = timing;
144 if (drive->media != ide_disk || !drive->present) 144 if (drive->media != ide_disk || !drive->present)
145 select |= HT_PREFETCH_MODE; 145 select |= HT_PREFETCH_MODE;
146 (void) HWIF(drive)->INB(HT_CONFIG_PORT); 146 (void)inb(HT_CONFIG_PORT);
147 (void) HWIF(drive)->INB(HT_CONFIG_PORT); 147 (void)inb(HT_CONFIG_PORT);
148 (void) HWIF(drive)->INB(HT_CONFIG_PORT); 148 (void)inb(HT_CONFIG_PORT);
149 (void) HWIF(drive)->INB(HT_CONFIG_PORT); 149 (void)inb(HT_CONFIG_PORT);
150 HWIF(drive)->OUTB(select, HT_CONFIG_PORT); 150 outb(select, HT_CONFIG_PORT);
151 /* 151 /*
152 * Set timing for this drive: 152 * Set timing for this drive:
153 */ 153 */
154 HWIF(drive)->OUTB(timing, IDE_SELECT_REG); 154 outb(timing, IDE_SELECT_REG);
155 (void) HWIF(drive)->INB(IDE_STATUS_REG); 155 (void)inb(IDE_STATUS_REG);
156#ifdef DEBUG 156#ifdef DEBUG
157 printk("ht6560b: %s: select=%#x timing=%#x\n", 157 printk("ht6560b: %s: select=%#x timing=%#x\n",
158 drive->name, select, timing); 158 drive->name, select, timing);
diff --git a/drivers/ide/legacy/macide.c b/drivers/ide/legacy/macide.c
index b1730d7e414c..4c0079ad52ac 100644
--- a/drivers/ide/legacy/macide.c
+++ b/drivers/ide/legacy/macide.c
@@ -141,7 +141,7 @@ void macide_init(void)
141 } 141 }
142 142
143 if (index != -1) { 143 if (index != -1) {
144 hwif->mmio = 2; 144 hwif->mmio = 1;
145 if (macintosh_config->ide_type == MAC_IDE_QUADRA) 145 if (macintosh_config->ide_type == MAC_IDE_QUADRA)
146 printk(KERN_INFO "ide%d: Macintosh Quadra IDE interface\n", index); 146 printk(KERN_INFO "ide%d: Macintosh Quadra IDE interface\n", index);
147 else if (macintosh_config->ide_type == MAC_IDE_PB) 147 else if (macintosh_config->ide_type == MAC_IDE_PB)
diff --git a/drivers/ide/legacy/q40ide.c b/drivers/ide/legacy/q40ide.c
index 434a94faa3b7..74f08124eabb 100644
--- a/drivers/ide/legacy/q40ide.c
+++ b/drivers/ide/legacy/q40ide.c
@@ -145,7 +145,7 @@ void q40ide_init(void)
145 index = ide_register_hw(&hw, &hwif); 145 index = ide_register_hw(&hw, &hwif);
146 // **FIXME** 146 // **FIXME**
147 if (index != -1) 147 if (index != -1)
148 hwif->mmio = 2; 148 hwif->mmio = 1;
149 } 149 }
150} 150}
151 151
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
index c7854ea57b52..0a59d5ef1599 100644
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -181,12 +181,6 @@ static int auide_tune_chipset (ide_drive_t *drive, u8 speed)
181{ 181{
182 int mem_sttime; 182 int mem_sttime;
183 int mem_stcfg; 183 int mem_stcfg;
184 unsigned long mode;
185
186#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
187 if (ide_use_dma(drive))
188 mode = ide_dma_speed(drive, 0);
189#endif
190 184
191 mem_sttime = 0; 185 mem_sttime = 0;
192 mem_stcfg = au_readl(MEM_STCFG2); 186 mem_stcfg = au_readl(MEM_STCFG2);
@@ -195,7 +189,7 @@ static int auide_tune_chipset (ide_drive_t *drive, u8 speed)
195 auide_tune_drive(drive, speed - XFER_PIO_0); 189 auide_tune_drive(drive, speed - XFER_PIO_0);
196 return 0; 190 return 0;
197 } 191 }
198 192
199 switch(speed) { 193 switch(speed) {
200#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA 194#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
201 case XFER_MW_DMA_2: 195 case XFER_MW_DMA_2:
@@ -207,7 +201,6 @@ static int auide_tune_chipset (ide_drive_t *drive, u8 speed)
207 mem_stcfg &= ~TOECS_MASK; 201 mem_stcfg &= ~TOECS_MASK;
208 mem_stcfg |= SBC_IDE_MDMA2_TCSOE | SBC_IDE_MDMA2_TOECS; 202 mem_stcfg |= SBC_IDE_MDMA2_TCSOE | SBC_IDE_MDMA2_TOECS;
209 203
210 mode = XFER_MW_DMA_2;
211 break; 204 break;
212 case XFER_MW_DMA_1: 205 case XFER_MW_DMA_1:
213 mem_sttime = SBC_IDE_TIMING(MDMA1); 206 mem_sttime = SBC_IDE_TIMING(MDMA1);
@@ -218,7 +211,6 @@ static int auide_tune_chipset (ide_drive_t *drive, u8 speed)
218 mem_stcfg &= ~TOECS_MASK; 211 mem_stcfg &= ~TOECS_MASK;
219 mem_stcfg |= SBC_IDE_MDMA1_TCSOE | SBC_IDE_MDMA1_TOECS; 212 mem_stcfg |= SBC_IDE_MDMA1_TCSOE | SBC_IDE_MDMA1_TOECS;
220 213
221 mode = XFER_MW_DMA_1;
222 break; 214 break;
223 case XFER_MW_DMA_0: 215 case XFER_MW_DMA_0:
224 mem_sttime = SBC_IDE_TIMING(MDMA0); 216 mem_sttime = SBC_IDE_TIMING(MDMA0);
@@ -229,14 +221,13 @@ static int auide_tune_chipset (ide_drive_t *drive, u8 speed)
229 mem_stcfg &= ~TOECS_MASK; 221 mem_stcfg &= ~TOECS_MASK;
230 mem_stcfg |= SBC_IDE_MDMA0_TCSOE | SBC_IDE_MDMA0_TOECS; 222 mem_stcfg |= SBC_IDE_MDMA0_TCSOE | SBC_IDE_MDMA0_TOECS;
231 223
232 mode = XFER_MW_DMA_0;
233 break; 224 break;
234#endif 225#endif
235 default: 226 default:
236 return 1; 227 return 1;
237 } 228 }
238 229
239 if (ide_config_drive_speed(drive, mode)) 230 if (ide_config_drive_speed(drive, speed))
240 return 1; 231 return 1;
241 232
242 au_writel(mem_sttime,MEM_STTIME2); 233 au_writel(mem_sttime,MEM_STTIME2);
@@ -423,9 +414,9 @@ static int auide_dma_check(ide_drive_t *drive)
423 speed = ide_find_best_mode(drive, XFER_PIO | XFER_MWDMA); 414 speed = ide_find_best_mode(drive, XFER_PIO | XFER_MWDMA);
424 415
425 if (drive->autodma && (speed & XFER_MODE) != XFER_PIO) 416 if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
426 return HWIF(drive)->ide_dma_on(drive); 417 return 0;
427 418
428 return HWIF(drive)->ide_dma_off_quietly(drive); 419 return -1;
429} 420}
430 421
431static int auide_dma_test_irq(ide_drive_t *drive) 422static int auide_dma_test_irq(ide_drive_t *drive)
@@ -447,27 +438,24 @@ static int auide_dma_test_irq(ide_drive_t *drive)
447 return 0; 438 return 0;
448} 439}
449 440
450static int auide_dma_host_on(ide_drive_t *drive) 441static void auide_dma_host_on(ide_drive_t *drive)
451{ 442{
452 return 0;
453} 443}
454 444
455static int auide_dma_on(ide_drive_t *drive) 445static int auide_dma_on(ide_drive_t *drive)
456{ 446{
457 drive->using_dma = 1; 447 drive->using_dma = 1;
458 return auide_dma_host_on(drive);
459}
460 448
449 return 0;
450}
461 451
462static int auide_dma_host_off(ide_drive_t *drive) 452static void auide_dma_host_off(ide_drive_t *drive)
463{ 453{
464 return 0;
465} 454}
466 455
467static int auide_dma_off_quietly(ide_drive_t *drive) 456static void auide_dma_off_quietly(ide_drive_t *drive)
468{ 457{
469 drive->using_dma = 0; 458 drive->using_dma = 0;
470 return auide_dma_host_off(drive);
471} 459}
472 460
473static int auide_dma_lostirq(ide_drive_t *drive) 461static int auide_dma_lostirq(ide_drive_t *drive)
@@ -717,7 +705,8 @@ static int au_ide_probe(struct device *dev)
717 705
718 /* hold should be on in all cases */ 706 /* hold should be on in all cases */
719 hwif->hold = 1; 707 hwif->hold = 1;
720 hwif->mmio = 2; 708
709 hwif->mmio = 1;
721 710
722 /* If the user has selected DDMA assisted copies, 711 /* If the user has selected DDMA assisted copies,
723 then set up a few local I/O function entry points 712 then set up a few local I/O function entry points
@@ -732,7 +721,7 @@ static int au_ide_probe(struct device *dev)
732 hwif->speedproc = &auide_tune_chipset; 721 hwif->speedproc = &auide_tune_chipset;
733 722
734#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA 723#ifdef CONFIG_BLK_DEV_IDE_AU1XXX_MDMA2_DBDMA
735 hwif->ide_dma_off_quietly = &auide_dma_off_quietly; 724 hwif->dma_off_quietly = &auide_dma_off_quietly;
736 hwif->ide_dma_timeout = &auide_dma_timeout; 725 hwif->ide_dma_timeout = &auide_dma_timeout;
737 726
738 hwif->ide_dma_check = &auide_dma_check; 727 hwif->ide_dma_check = &auide_dma_check;
@@ -741,8 +730,8 @@ static int au_ide_probe(struct device *dev)
741 hwif->ide_dma_end = &auide_dma_end; 730 hwif->ide_dma_end = &auide_dma_end;
742 hwif->dma_setup = &auide_dma_setup; 731 hwif->dma_setup = &auide_dma_setup;
743 hwif->ide_dma_test_irq = &auide_dma_test_irq; 732 hwif->ide_dma_test_irq = &auide_dma_test_irq;
744 hwif->ide_dma_host_off = &auide_dma_host_off; 733 hwif->dma_host_off = &auide_dma_host_off;
745 hwif->ide_dma_host_on = &auide_dma_host_on; 734 hwif->dma_host_on = &auide_dma_host_on;
746 hwif->ide_dma_lostirq = &auide_dma_lostirq; 735 hwif->ide_dma_lostirq = &auide_dma_lostirq;
747 hwif->ide_dma_on = &auide_dma_on; 736 hwif->ide_dma_on = &auide_dma_on;
748 737
diff --git a/drivers/ide/mips/swarm.c b/drivers/ide/mips/swarm.c
index 09c9e7936b0d..81fa06851b27 100644
--- a/drivers/ide/mips/swarm.c
+++ b/drivers/ide/mips/swarm.c
@@ -115,7 +115,7 @@ static int __devinit swarm_ide_probe(struct device *dev)
115 /* Setup MMIO ops. */ 115 /* Setup MMIO ops. */
116 default_hwif_mmiops(hwif); 116 default_hwif_mmiops(hwif);
117 /* Prevent resource map manipulation. */ 117 /* Prevent resource map manipulation. */
118 hwif->mmio = 2; 118 hwif->mmio = 1;
119 hwif->noprobe = 0; 119 hwif->noprobe = 0;
120 120
121 for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) 121 for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++)
diff --git a/drivers/ide/pci/aec62xx.c b/drivers/ide/pci/aec62xx.c
index d261bfbad222..990eafe5ea11 100644
--- a/drivers/ide/pci/aec62xx.c
+++ b/drivers/ide/pci/aec62xx.c
@@ -94,9 +94,9 @@ static u8 aec62xx_ratemask (ide_drive_t *drive)
94 switch(hwif->pci_dev->device) { 94 switch(hwif->pci_dev->device) {
95 case PCI_DEVICE_ID_ARTOP_ATP865: 95 case PCI_DEVICE_ID_ARTOP_ATP865:
96 case PCI_DEVICE_ID_ARTOP_ATP865R: 96 case PCI_DEVICE_ID_ARTOP_ATP865R:
97 mode = (hwif->INB(((hwif->channel) ? 97 mode = (inb(hwif->channel ?
98 hwif->mate->dma_status : 98 hwif->mate->dma_status :
99 hwif->dma_status)) & 0x10) ? 4 : 3; 99 hwif->dma_status) & 0x10) ? 4 : 3;
100 break; 100 break;
101 case PCI_DEVICE_ID_ARTOP_ATP860: 101 case PCI_DEVICE_ID_ARTOP_ATP860:
102 case PCI_DEVICE_ID_ARTOP_ATP860R: 102 case PCI_DEVICE_ID_ARTOP_ATP860R:
@@ -209,25 +209,13 @@ static void aec62xx_tune_drive (ide_drive_t *drive, u8 pio)
209 209
210static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive) 210static int aec62xx_config_drive_xfer_rate (ide_drive_t *drive)
211{ 211{
212 ide_hwif_t *hwif = HWIF(drive); 212 if (ide_use_dma(drive) && config_chipset_for_dma(drive))
213 struct hd_driveid *id = drive->id; 213 return 0;
214
215 if ((id->capability & 1) && drive->autodma) {
216
217 if (ide_use_dma(drive)) {
218 if (config_chipset_for_dma(drive))
219 return hwif->ide_dma_on(drive);
220 }
221
222 goto fast_ata_pio;
223 214
224 } else if ((id->capability & 8) || (id->field_valid & 2)) { 215 if (ide_use_fast_pio(drive))
225fast_ata_pio:
226 aec62xx_tune_drive(drive, 5); 216 aec62xx_tune_drive(drive, 5);
227 return hwif->ide_dma_off_quietly(drive); 217
228 } 218 return -1;
229 /* IORDY not supported */
230 return 0;
231} 219}
232 220
233static int aec62xx_irq_timeout (ide_drive_t *drive) 221static int aec62xx_irq_timeout (ide_drive_t *drive)
@@ -286,10 +274,8 @@ static void __devinit init_hwif_aec62xx(ide_hwif_t *hwif)
286 hwif->tuneproc = &aec62xx_tune_drive; 274 hwif->tuneproc = &aec62xx_tune_drive;
287 hwif->speedproc = &aec62xx_tune_chipset; 275 hwif->speedproc = &aec62xx_tune_chipset;
288 276
289 if (hwif->pci_dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF) { 277 if (hwif->pci_dev->device == PCI_DEVICE_ID_ARTOP_ATP850UF)
290 hwif->serialized = hwif->channel; 278 hwif->serialized = hwif->channel;
291 hwif->no_dsc = 1;
292 }
293 279
294 if (hwif->mate) 280 if (hwif->mate)
295 hwif->mate->serialized = hwif->serialized; 281 hwif->mate->serialized = hwif->serialized;
diff --git a/drivers/ide/pci/alim15x3.c b/drivers/ide/pci/alim15x3.c
index 68df77ec502b..4debd18d52f8 100644
--- a/drivers/ide/pci/alim15x3.c
+++ b/drivers/ide/pci/alim15x3.c
@@ -507,17 +507,15 @@ static int config_chipset_for_dma (ide_drive_t *drive)
507 * 507 *
508 * Configure a drive for DMA operation. If DMA is not possible we 508 * Configure a drive for DMA operation. If DMA is not possible we
509 * drop the drive into PIO mode instead. 509 * drop the drive into PIO mode instead.
510 *
511 * FIXME: exactly what are we trying to return here
512 */ 510 */
513 511
514static int ali15x3_config_drive_for_dma(ide_drive_t *drive) 512static int ali15x3_config_drive_for_dma(ide_drive_t *drive)
515{ 513{
516 ide_hwif_t *hwif = HWIF(drive); 514 ide_hwif_t *hwif = HWIF(drive);
517 struct hd_driveid *id = drive->id; 515 struct hd_driveid *id = drive->id;
518 516
519 if ((m5229_revision<=0x20) && (drive->media!=ide_disk)) 517 if ((m5229_revision<=0x20) && (drive->media!=ide_disk))
520 return hwif->ide_dma_off_quietly(drive); 518 goto no_dma_set;
521 519
522 drive->init_speed = 0; 520 drive->init_speed = 0;
523 521
@@ -552,9 +550,10 @@ try_dma_modes:
552ata_pio: 550ata_pio:
553 hwif->tuneproc(drive, 255); 551 hwif->tuneproc(drive, 255);
554no_dma_set: 552no_dma_set:
555 return hwif->ide_dma_off_quietly(drive); 553 return -1;
556 } 554 }
557 return hwif->ide_dma_on(drive); 555
556 return 0;
558} 557}
559 558
560/** 559/**
@@ -852,8 +851,8 @@ static void __devinit init_dma_ali15x3 (ide_hwif_t *hwif, unsigned long dmabase)
852{ 851{
853 if (m5229_revision < 0x20) 852 if (m5229_revision < 0x20)
854 return; 853 return;
855 if (!(hwif->channel)) 854 if (!hwif->channel)
856 hwif->OUTB(hwif->INB(dmabase+2) & 0x60, dmabase+2); 855 outb(inb(dmabase + 2) & 0x60, dmabase + 2);
857 ide_setup_dma(hwif, dmabase, 8); 856 ide_setup_dma(hwif, dmabase, 8);
858} 857}
859 858
diff --git a/drivers/ide/pci/amd74xx.c b/drivers/ide/pci/amd74xx.c
index a4336995a410..7989bdd842a2 100644
--- a/drivers/ide/pci/amd74xx.c
+++ b/drivers/ide/pci/amd74xx.c
@@ -304,8 +304,9 @@ static int amd74xx_ide_dma_check(ide_drive_t *drive)
304 amd_set_drive(drive, speed); 304 amd_set_drive(drive, speed);
305 305
306 if (drive->autodma && (speed & XFER_MODE) != XFER_PIO) 306 if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
307 return HWIF(drive)->ide_dma_on(drive); 307 return 0;
308 return HWIF(drive)->ide_dma_off_quietly(drive); 308
309 return -1;
309} 310}
310 311
311/* 312/*
diff --git a/drivers/ide/pci/atiixp.c b/drivers/ide/pci/atiixp.c
index 982ac31fa995..2d48af32e3f4 100644
--- a/drivers/ide/pci/atiixp.c
+++ b/drivers/ide/pci/atiixp.c
@@ -101,7 +101,7 @@ static u8 atiixp_dma_2_pio(u8 xfer_rate) {
101 } 101 }
102} 102}
103 103
104static int atiixp_ide_dma_host_on(ide_drive_t *drive) 104static void atiixp_dma_host_on(ide_drive_t *drive)
105{ 105{
106 struct pci_dev *dev = drive->hwif->pci_dev; 106 struct pci_dev *dev = drive->hwif->pci_dev;
107 unsigned long flags; 107 unsigned long flags;
@@ -118,10 +118,10 @@ static int atiixp_ide_dma_host_on(ide_drive_t *drive)
118 118
119 spin_unlock_irqrestore(&atiixp_lock, flags); 119 spin_unlock_irqrestore(&atiixp_lock, flags);
120 120
121 return __ide_dma_host_on(drive); 121 ide_dma_host_on(drive);
122} 122}
123 123
124static int atiixp_ide_dma_host_off(ide_drive_t *drive) 124static void atiixp_dma_host_off(ide_drive_t *drive)
125{ 125{
126 struct pci_dev *dev = drive->hwif->pci_dev; 126 struct pci_dev *dev = drive->hwif->pci_dev;
127 unsigned long flags; 127 unsigned long flags;
@@ -135,7 +135,7 @@ static int atiixp_ide_dma_host_off(ide_drive_t *drive)
135 135
136 spin_unlock_irqrestore(&atiixp_lock, flags); 136 spin_unlock_irqrestore(&atiixp_lock, flags);
137 137
138 return __ide_dma_host_off(drive); 138 ide_dma_host_off(drive);
139} 139}
140 140
141/** 141/**
@@ -235,11 +235,8 @@ static int atiixp_config_drive_for_dma(ide_drive_t *drive)
235{ 235{
236 u8 speed = ide_dma_speed(drive, atiixp_ratemask(drive)); 236 u8 speed = ide_dma_speed(drive, atiixp_ratemask(drive));
237 237
238 /* If no DMA speed was available then disable DMA and use PIO. */ 238 if (!speed)
239 if (!speed) { 239 return 0;
240 u8 tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL);
241 speed = atiixp_dma_2_pio(XFER_PIO_0 + tspeed) + XFER_PIO_0;
242 }
243 240
244 (void) atiixp_speedproc(drive, speed); 241 (void) atiixp_speedproc(drive, speed);
245 return ide_dma_enable(drive); 242 return ide_dma_enable(drive);
@@ -255,30 +252,20 @@ static int atiixp_config_drive_for_dma(ide_drive_t *drive)
255 252
256static int atiixp_dma_check(ide_drive_t *drive) 253static int atiixp_dma_check(ide_drive_t *drive)
257{ 254{
258 ide_hwif_t *hwif = HWIF(drive);
259 struct hd_driveid *id = drive->id;
260 u8 tspeed, speed; 255 u8 tspeed, speed;
261 256
262 drive->init_speed = 0; 257 drive->init_speed = 0;
263 258
264 if ((id->capability & 1) && drive->autodma) { 259 if (ide_use_dma(drive) && atiixp_config_drive_for_dma(drive))
265 260 return 0;
266 if (ide_use_dma(drive)) {
267 if (atiixp_config_drive_for_dma(drive))
268 return hwif->ide_dma_on(drive);
269 }
270
271 goto fast_ata_pio;
272 261
273 } else if ((id->capability & 8) || (id->field_valid & 2)) { 262 if (ide_use_fast_pio(drive)) {
274fast_ata_pio:
275 tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL); 263 tspeed = ide_get_best_pio_mode(drive, 255, 5, NULL);
276 speed = atiixp_dma_2_pio(XFER_PIO_0 + tspeed) + XFER_PIO_0; 264 speed = atiixp_dma_2_pio(XFER_PIO_0 + tspeed) + XFER_PIO_0;
277 hwif->speedproc(drive, speed); 265 atiixp_speedproc(drive, speed);
278 return hwif->ide_dma_off_quietly(drive);
279 } 266 }
280 /* IORDY not supported */ 267
281 return 0; 268 return -1;
282} 269}
283 270
284/** 271/**
@@ -318,8 +305,8 @@ static void __devinit init_hwif_atiixp(ide_hwif_t *hwif)
318 else 305 else
319 hwif->udma_four = 0; 306 hwif->udma_four = 0;
320 307
321 hwif->ide_dma_host_on = &atiixp_ide_dma_host_on; 308 hwif->dma_host_on = &atiixp_dma_host_on;
322 hwif->ide_dma_host_off = &atiixp_ide_dma_host_off; 309 hwif->dma_host_off = &atiixp_dma_host_off;
323 hwif->ide_dma_check = &atiixp_dma_check; 310 hwif->ide_dma_check = &atiixp_dma_check;
324 if (!noautodma) 311 if (!noautodma)
325 hwif->autodma = 1; 312 hwif->autodma = 1;
diff --git a/drivers/ide/pci/cmd64x.c b/drivers/ide/pci/cmd64x.c
index aee947e8fc38..49df27513da7 100644
--- a/drivers/ide/pci/cmd64x.c
+++ b/drivers/ide/pci/cmd64x.c
@@ -466,36 +466,21 @@ static int config_chipset_for_dma (ide_drive_t *drive)
466 if (!speed) 466 if (!speed)
467 return 0; 467 return 0;
468 468
469 if(ide_set_xfer_rate(drive, speed)) 469 if (cmd64x_tune_chipset(drive, speed))
470 return 0; 470 return 0;
471
472 if (!drive->init_speed)
473 drive->init_speed = speed;
474 471
475 return ide_dma_enable(drive); 472 return ide_dma_enable(drive);
476} 473}
477 474
478static int cmd64x_config_drive_for_dma (ide_drive_t *drive) 475static int cmd64x_config_drive_for_dma (ide_drive_t *drive)
479{ 476{
480 ide_hwif_t *hwif = HWIF(drive); 477 if (ide_use_dma(drive) && config_chipset_for_dma(drive))
481 struct hd_driveid *id = drive->id; 478 return 0;
482
483 if ((id != NULL) && ((id->capability & 1) != 0) && drive->autodma) {
484
485 if (ide_use_dma(drive)) {
486 if (config_chipset_for_dma(drive))
487 return hwif->ide_dma_on(drive);
488 }
489
490 goto fast_ata_pio;
491 479
492 } else if ((id->capability & 8) || (id->field_valid & 2)) { 480 if (ide_use_fast_pio(drive))
493fast_ata_pio:
494 config_chipset_for_pio(drive, 1); 481 config_chipset_for_pio(drive, 1);
495 return hwif->ide_dma_off_quietly(drive); 482
496 } 483 return -1;
497 /* IORDY not supported */
498 return 0;
499} 484}
500 485
501static int cmd64x_alt_dma_status (struct pci_dev *dev) 486static int cmd64x_alt_dma_status (struct pci_dev *dev)
@@ -518,13 +503,13 @@ static int cmd64x_ide_dma_end (ide_drive_t *drive)
518 503
519 drive->waiting_for_dma = 0; 504 drive->waiting_for_dma = 0;
520 /* read DMA command state */ 505 /* read DMA command state */
521 dma_cmd = hwif->INB(hwif->dma_command); 506 dma_cmd = inb(hwif->dma_command);
522 /* stop DMA */ 507 /* stop DMA */
523 hwif->OUTB((dma_cmd & ~1), hwif->dma_command); 508 outb(dma_cmd & ~1, hwif->dma_command);
524 /* get DMA status */ 509 /* get DMA status */
525 dma_stat = hwif->INB(hwif->dma_status); 510 dma_stat = inb(hwif->dma_status);
526 /* clear the INTR & ERROR bits */ 511 /* clear the INTR & ERROR bits */
527 hwif->OUTB(dma_stat|6, hwif->dma_status); 512 outb(dma_stat | 6, hwif->dma_status);
528 if (cmd64x_alt_dma_status(dev)) { 513 if (cmd64x_alt_dma_status(dev)) {
529 u8 dma_intr = 0; 514 u8 dma_intr = 0;
530 u8 dma_mask = (hwif->channel) ? ARTTIM23_INTR_CH1 : 515 u8 dma_mask = (hwif->channel) ? ARTTIM23_INTR_CH1 :
@@ -546,7 +531,7 @@ static int cmd64x_ide_dma_test_irq (ide_drive_t *drive)
546 struct pci_dev *dev = hwif->pci_dev; 531 struct pci_dev *dev = hwif->pci_dev;
547 u8 dma_alt_stat = 0, mask = (hwif->channel) ? MRDMODE_INTR_CH1 : 532 u8 dma_alt_stat = 0, mask = (hwif->channel) ? MRDMODE_INTR_CH1 :
548 MRDMODE_INTR_CH0; 533 MRDMODE_INTR_CH0;
549 u8 dma_stat = hwif->INB(hwif->dma_status); 534 u8 dma_stat = inb(hwif->dma_status);
550 535
551 (void) pci_read_config_byte(dev, MRDMODE, &dma_alt_stat); 536 (void) pci_read_config_byte(dev, MRDMODE, &dma_alt_stat);
552#ifdef DEBUG 537#ifdef DEBUG
@@ -576,13 +561,13 @@ static int cmd646_1_ide_dma_end (ide_drive_t *drive)
576 561
577 drive->waiting_for_dma = 0; 562 drive->waiting_for_dma = 0;
578 /* get DMA status */ 563 /* get DMA status */
579 dma_stat = hwif->INB(hwif->dma_status); 564 dma_stat = inb(hwif->dma_status);
580 /* read DMA command state */ 565 /* read DMA command state */
581 dma_cmd = hwif->INB(hwif->dma_command); 566 dma_cmd = inb(hwif->dma_command);
582 /* stop DMA */ 567 /* stop DMA */
583 hwif->OUTB((dma_cmd & ~1), hwif->dma_command); 568 outb(dma_cmd & ~1, hwif->dma_command);
584 /* clear the INTR & ERROR bits */ 569 /* clear the INTR & ERROR bits */
585 hwif->OUTB(dma_stat|6, hwif->dma_status); 570 outb(dma_stat | 6, hwif->dma_status);
586 /* and free any DMA resources */ 571 /* and free any DMA resources */
587 ide_destroy_dmatable(drive); 572 ide_destroy_dmatable(drive);
588 /* verify good DMA status */ 573 /* verify good DMA status */
diff --git a/drivers/ide/pci/cs5520.c b/drivers/ide/pci/cs5520.c
index ba6786aabf3b..400859a839f7 100644
--- a/drivers/ide/pci/cs5520.c
+++ b/drivers/ide/pci/cs5520.c
@@ -132,12 +132,11 @@ static void cs5520_tune_drive(ide_drive_t *drive, u8 pio)
132 132
133static int cs5520_config_drive_xfer_rate(ide_drive_t *drive) 133static int cs5520_config_drive_xfer_rate(ide_drive_t *drive)
134{ 134{
135 ide_hwif_t *hwif = HWIF(drive);
136
137 /* Tune the drive for PIO modes up to PIO 4 */ 135 /* Tune the drive for PIO modes up to PIO 4 */
138 cs5520_tune_drive(drive, 4); 136 cs5520_tune_drive(drive, 4);
137
139 /* Then tell the core to use DMA operations */ 138 /* Then tell the core to use DMA operations */
140 return hwif->ide_dma_on(drive); 139 return 0;
141} 140}
142 141
143/* 142/*
diff --git a/drivers/ide/pci/cs5530.c b/drivers/ide/pci/cs5530.c
index 9bf5fdfc5b1f..b2d7c132ef4b 100644
--- a/drivers/ide/pci/cs5530.c
+++ b/drivers/ide/pci/cs5530.c
@@ -81,8 +81,8 @@ static void cs5530_tuneproc (ide_drive_t *drive, u8 pio) /* pio=255 means "autot
81 81
82 pio = ide_get_best_pio_mode(drive, pio, 4, NULL); 82 pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
83 if (!cs5530_set_xfer_mode(drive, modes[pio])) { 83 if (!cs5530_set_xfer_mode(drive, modes[pio])) {
84 format = (hwif->INL(basereg+4) >> 31) & 1; 84 format = (inl(basereg + 4) >> 31) & 1;
85 hwif->OUTL(cs5530_pio_timings[format][pio], 85 outl(cs5530_pio_timings[format][pio],
86 basereg+(drive->select.b.unit<<3)); 86 basereg+(drive->select.b.unit<<3));
87 } 87 }
88} 88}
@@ -103,16 +103,13 @@ static int cs5530_config_dma (ide_drive_t *drive)
103 int unit = drive->select.b.unit; 103 int unit = drive->select.b.unit;
104 ide_drive_t *mate = &hwif->drives[unit^1]; 104 ide_drive_t *mate = &hwif->drives[unit^1];
105 struct hd_driveid *id = drive->id; 105 struct hd_driveid *id = drive->id;
106 unsigned int reg, timings; 106 unsigned int reg, timings = 0;
107 unsigned long basereg; 107 unsigned long basereg;
108 108
109 /* 109 /*
110 * Default to DMA-off in case we run into trouble here. 110 * Default to DMA-off in case we run into trouble here.
111 */ 111 */
112 hwif->ide_dma_off_quietly(drive); 112 hwif->dma_off_quietly(drive);
113 /* turn off DMA while we fiddle */
114 hwif->ide_dma_host_off(drive);
115 /* clear DMA_capable bit */
116 113
117 /* 114 /*
118 * The CS5530 specifies that two drives sharing a cable cannot 115 * The CS5530 specifies that two drives sharing a cable cannot
@@ -182,30 +179,24 @@ static int cs5530_config_dma (ide_drive_t *drive)
182 case XFER_MW_DMA_1: timings = 0x00012121; break; 179 case XFER_MW_DMA_1: timings = 0x00012121; break;
183 case XFER_MW_DMA_2: timings = 0x00002020; break; 180 case XFER_MW_DMA_2: timings = 0x00002020; break;
184 default: 181 default:
185 printk(KERN_ERR "%s: cs5530_config_dma: huh? mode=%02x\n", 182 BUG();
186 drive->name, mode); 183 break;
187 return 1; /* failure */
188 } 184 }
189 basereg = CS5530_BASEREG(hwif); 185 basereg = CS5530_BASEREG(hwif);
190 reg = hwif->INL(basereg+4); /* get drive0 config register */ 186 reg = inl(basereg + 4); /* get drive0 config register */
191 timings |= reg & 0x80000000; /* preserve PIO format bit */ 187 timings |= reg & 0x80000000; /* preserve PIO format bit */
192 if (unit == 0) { /* are we configuring drive0? */ 188 if (unit == 0) { /* are we configuring drive0? */
193 hwif->OUTL(timings, basereg+4); /* write drive0 config register */ 189 outl(timings, basereg + 4); /* write drive0 config register */
194 } else { 190 } else {
195 if (timings & 0x00100000) 191 if (timings & 0x00100000)
196 reg |= 0x00100000; /* enable UDMA timings for both drives */ 192 reg |= 0x00100000; /* enable UDMA timings for both drives */
197 else 193 else
198 reg &= ~0x00100000; /* disable UDMA timings for both drives */ 194 reg &= ~0x00100000; /* disable UDMA timings for both drives */
199 hwif->OUTL(reg, basereg+4); /* write drive0 config register */ 195 outl(reg, basereg + 4); /* write drive0 config register */
200 hwif->OUTL(timings, basereg+12); /* write drive1 config register */ 196 outl(timings, basereg + 12); /* write drive1 config register */
201 } 197 }
202 (void) hwif->ide_dma_host_on(drive);
203 /* set DMA_capable bit */
204 198
205 /* 199 return 0; /* success */
206 * Finally, turn DMA on in software, and exit.
207 */
208 return hwif->ide_dma_on(drive); /* success */
209} 200}
210 201
211/** 202/**
@@ -321,17 +312,17 @@ static void __devinit init_hwif_cs5530 (ide_hwif_t *hwif)
321 312
322 hwif->tuneproc = &cs5530_tuneproc; 313 hwif->tuneproc = &cs5530_tuneproc;
323 basereg = CS5530_BASEREG(hwif); 314 basereg = CS5530_BASEREG(hwif);
324 d0_timings = hwif->INL(basereg+0); 315 d0_timings = inl(basereg + 0);
325 if (CS5530_BAD_PIO(d0_timings)) { 316 if (CS5530_BAD_PIO(d0_timings)) {
326 /* PIO timings not initialized? */ 317 /* PIO timings not initialized? */
327 hwif->OUTL(cs5530_pio_timings[(d0_timings>>31)&1][0], basereg+0); 318 outl(cs5530_pio_timings[(d0_timings >> 31) & 1][0], basereg + 0);
328 if (!hwif->drives[0].autotune) 319 if (!hwif->drives[0].autotune)
329 hwif->drives[0].autotune = 1; 320 hwif->drives[0].autotune = 1;
330 /* needs autotuning later */ 321 /* needs autotuning later */
331 } 322 }
332 if (CS5530_BAD_PIO(hwif->INL(basereg+8))) { 323 if (CS5530_BAD_PIO(inl(basereg + 8))) {
333 /* PIO timings not initialized? */ 324 /* PIO timings not initialized? */
334 hwif->OUTL(cs5530_pio_timings[(d0_timings>>31)&1][0], basereg+8); 325 outl(cs5530_pio_timings[(d0_timings >> 31) & 1][0], basereg + 8);
335 if (!hwif->drives[1].autotune) 326 if (!hwif->drives[1].autotune)
336 hwif->drives[1].autotune = 1; 327 hwif->drives[1].autotune = 1;
337 /* needs autotuning later */ 328 /* needs autotuning later */
diff --git a/drivers/ide/pci/cs5535.c b/drivers/ide/pci/cs5535.c
index 5c5aec28e671..45f43efbf92c 100644
--- a/drivers/ide/pci/cs5535.c
+++ b/drivers/ide/pci/cs5535.c
@@ -195,28 +195,19 @@ static int cs5535_config_drive_for_dma(ide_drive_t *drive)
195 195
196static int cs5535_dma_check(ide_drive_t *drive) 196static int cs5535_dma_check(ide_drive_t *drive)
197{ 197{
198 ide_hwif_t *hwif = drive->hwif;
199 struct hd_driveid *id = drive->id;
200 u8 speed; 198 u8 speed;
201 199
202 drive->init_speed = 0; 200 drive->init_speed = 0;
203 201
204 if ((id->capability & 1) && drive->autodma) { 202 if (ide_use_dma(drive) && cs5535_config_drive_for_dma(drive))
205 if (ide_use_dma(drive)) { 203 return 0;
206 if (cs5535_config_drive_for_dma(drive))
207 return hwif->ide_dma_on(drive);
208 }
209
210 goto fast_ata_pio;
211 204
212 } else if ((id->capability & 8) || (id->field_valid & 2)) { 205 if (ide_use_fast_pio(drive)) {
213fast_ata_pio:
214 speed = ide_get_best_pio_mode(drive, 255, 4, NULL); 206 speed = ide_get_best_pio_mode(drive, 255, 4, NULL);
215 cs5535_set_drive(drive, speed); 207 cs5535_set_drive(drive, speed);
216 return hwif->ide_dma_off_quietly(drive);
217 } 208 }
218 /* IORDY not supported */ 209
219 return 0; 210 return -1;
220} 211}
221 212
222static u8 __devinit cs5535_cable_detect(struct pci_dev *dev) 213static u8 __devinit cs5535_cable_detect(struct pci_dev *dev)
diff --git a/drivers/ide/pci/cy82c693.c b/drivers/ide/pci/cy82c693.c
index 9eafcbf444f4..103b9db97853 100644
--- a/drivers/ide/pci/cy82c693.c
+++ b/drivers/ide/pci/cy82c693.c
@@ -197,8 +197,8 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
197#if CY82C693_DEBUG_LOGS 197#if CY82C693_DEBUG_LOGS
198 /* for debug let's show the previous values */ 198 /* for debug let's show the previous values */
199 199
200 HWIF(drive)->OUTB(index, CY82_INDEX_PORT); 200 outb(index, CY82_INDEX_PORT);
201 data = HWIF(drive)->INB(CY82_DATA_PORT); 201 data = inb(CY82_DATA_PORT);
202 202
203 printk (KERN_INFO "%s (ch=%d, dev=%d): DMA mode is %d (single=%d)\n", 203 printk (KERN_INFO "%s (ch=%d, dev=%d): DMA mode is %d (single=%d)\n",
204 drive->name, HWIF(drive)->channel, drive->select.b.unit, 204 drive->name, HWIF(drive)->channel, drive->select.b.unit,
@@ -207,8 +207,8 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
207 207
208 data = (u8)mode|(u8)(single<<2); 208 data = (u8)mode|(u8)(single<<2);
209 209
210 HWIF(drive)->OUTB(index, CY82_INDEX_PORT); 210 outb(index, CY82_INDEX_PORT);
211 HWIF(drive)->OUTB(data, CY82_DATA_PORT); 211 outb(data, CY82_DATA_PORT);
212 212
213#if CY82C693_DEBUG_INFO 213#if CY82C693_DEBUG_INFO
214 printk(KERN_INFO "%s (ch=%d, dev=%d): set DMA mode to %d (single=%d)\n", 214 printk(KERN_INFO "%s (ch=%d, dev=%d): set DMA mode to %d (single=%d)\n",
@@ -227,8 +227,8 @@ static void cy82c693_dma_enable (ide_drive_t *drive, int mode, int single)
227 */ 227 */
228 228
229 data = BUSMASTER_TIMEOUT; 229 data = BUSMASTER_TIMEOUT;
230 HWIF(drive)->OUTB(CY82_INDEX_TIMEOUT, CY82_INDEX_PORT); 230 outb(CY82_INDEX_TIMEOUT, CY82_INDEX_PORT);
231 HWIF(drive)->OUTB(data, CY82_DATA_PORT); 231 outb(data, CY82_DATA_PORT);
232 232
233#if CY82C693_DEBUG_INFO 233#if CY82C693_DEBUG_INFO
234 printk (KERN_INFO "%s: Set IDE Bus Master TimeOut Register to 0x%X\n", 234 printk (KERN_INFO "%s: Set IDE Bus Master TimeOut Register to 0x%X\n",
@@ -478,21 +478,18 @@ static void __devinit init_iops_cy82c693(ide_hwif_t *hwif)
478 } 478 }
479} 479}
480 480
481static ide_pci_device_t cy82c693_chipsets[] __devinitdata = { 481static ide_pci_device_t cy82c693_chipset __devinitdata = {
482 { /* 0 */ 482 .name = "CY82C693",
483 .name = "CY82C693", 483 .init_chipset = init_chipset_cy82c693,
484 .init_chipset = init_chipset_cy82c693, 484 .init_iops = init_iops_cy82c693,
485 .init_iops = init_iops_cy82c693, 485 .init_hwif = init_hwif_cy82c693,
486 .init_hwif = init_hwif_cy82c693, 486 .channels = 1,
487 .channels = 1, 487 .autodma = AUTODMA,
488 .autodma = AUTODMA, 488 .bootable = ON_BOARD,
489 .bootable = ON_BOARD,
490 }
491}; 489};
492 490
493static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id) 491static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_device_id *id)
494{ 492{
495 ide_pci_device_t *d = &cy82c693_chipsets[id->driver_data];
496 struct pci_dev *dev2; 493 struct pci_dev *dev2;
497 int ret = -ENODEV; 494 int ret = -ENODEV;
498 495
@@ -501,7 +498,7 @@ static int __devinit cy82c693_init_one(struct pci_dev *dev, const struct pci_dev
501 if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE && 498 if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE &&
502 PCI_FUNC(dev->devfn) == 1) { 499 PCI_FUNC(dev->devfn) == 1) {
503 dev2 = pci_get_slot(dev->bus, dev->devfn + 1); 500 dev2 = pci_get_slot(dev->bus, dev->devfn + 1);
504 ret = ide_setup_pci_devices(dev, dev2, d); 501 ret = ide_setup_pci_devices(dev, dev2, &cy82c693_chipset);
505 /* We leak pci refs here but thats ok - we can't be unloaded */ 502 /* We leak pci refs here but thats ok - we can't be unloaded */
506 } 503 }
507 return ret; 504 return ret;
diff --git a/drivers/ide/pci/hpt34x.c b/drivers/ide/pci/hpt34x.c
index ce7b08f08a09..924eaa3a5708 100644
--- a/drivers/ide/pci/hpt34x.c
+++ b/drivers/ide/pci/hpt34x.c
@@ -48,19 +48,6 @@ static u8 hpt34x_ratemask (ide_drive_t *drive)
48 return 1; 48 return 1;
49} 49}
50 50
51static void hpt34x_clear_chipset (ide_drive_t *drive)
52{
53 struct pci_dev *dev = HWIF(drive)->pci_dev;
54 u32 reg1 = 0, tmp1 = 0, reg2 = 0, tmp2 = 0;
55
56 pci_read_config_dword(dev, 0x44, &reg1);
57 pci_read_config_dword(dev, 0x48, &reg2);
58 tmp1 = ((0x00 << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn))));
59 tmp2 = (reg2 & ~(0x11 << drive->dn));
60 pci_write_config_dword(dev, 0x44, tmp1);
61 pci_write_config_dword(dev, 0x48, tmp2);
62}
63
64static int hpt34x_tune_chipset (ide_drive_t *drive, u8 xferspeed) 51static int hpt34x_tune_chipset (ide_drive_t *drive, u8 xferspeed)
65{ 52{
66 struct pci_dev *dev = HWIF(drive)->pci_dev; 53 struct pci_dev *dev = HWIF(drive)->pci_dev;
@@ -81,7 +68,7 @@ static int hpt34x_tune_chipset (ide_drive_t *drive, u8 xferspeed)
81 pci_read_config_dword(dev, 0x44, &reg1); 68 pci_read_config_dword(dev, 0x44, &reg1);
82 pci_read_config_dword(dev, 0x48, &reg2); 69 pci_read_config_dword(dev, 0x48, &reg2);
83 tmp1 = ((lo_speed << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn)))); 70 tmp1 = ((lo_speed << (3*drive->dn)) | (reg1 & ~(7 << (3*drive->dn))));
84 tmp2 = ((hi_speed << drive->dn) | reg2); 71 tmp2 = ((hi_speed << drive->dn) | (reg2 & ~(0x11 << drive->dn)));
85 pci_write_config_dword(dev, 0x44, tmp1); 72 pci_write_config_dword(dev, 0x44, tmp1);
86 pci_write_config_dword(dev, 0x48, tmp2); 73 pci_write_config_dword(dev, 0x48, tmp2);
87 74
@@ -99,7 +86,6 @@ static int hpt34x_tune_chipset (ide_drive_t *drive, u8 xferspeed)
99static void hpt34x_tune_drive (ide_drive_t *drive, u8 pio) 86static void hpt34x_tune_drive (ide_drive_t *drive, u8 pio)
100{ 87{
101 pio = ide_get_best_pio_mode(drive, pio, 5, NULL); 88 pio = ide_get_best_pio_mode(drive, pio, 5, NULL);
102 hpt34x_clear_chipset(drive);
103 (void) hpt34x_tune_chipset(drive, (XFER_PIO_0 + pio)); 89 (void) hpt34x_tune_chipset(drive, (XFER_PIO_0 + pio));
104} 90}
105 91
@@ -117,38 +103,25 @@ static int config_chipset_for_dma (ide_drive_t *drive)
117 if (!(speed)) 103 if (!(speed))
118 return 0; 104 return 0;
119 105
120 hpt34x_clear_chipset(drive);
121 (void) hpt34x_tune_chipset(drive, speed); 106 (void) hpt34x_tune_chipset(drive, speed);
122 return ide_dma_enable(drive); 107 return ide_dma_enable(drive);
123} 108}
124 109
125static int hpt34x_config_drive_xfer_rate (ide_drive_t *drive) 110static int hpt34x_config_drive_xfer_rate (ide_drive_t *drive)
126{ 111{
127 ide_hwif_t *hwif = HWIF(drive);
128 struct hd_driveid *id = drive->id;
129
130 drive->init_speed = 0; 112 drive->init_speed = 0;
131 113
132 if (id && (id->capability & 1) && drive->autodma) { 114 if (ide_use_dma(drive) && config_chipset_for_dma(drive))
133
134 if (ide_use_dma(drive)) {
135 if (config_chipset_for_dma(drive))
136#ifndef CONFIG_HPT34X_AUTODMA 115#ifndef CONFIG_HPT34X_AUTODMA
137 return hwif->ide_dma_off_quietly(drive); 116 return -1;
138#else 117#else
139 return hwif->ide_dma_on(drive); 118 return 0;
140#endif 119#endif
141 }
142
143 goto fast_ata_pio;
144 120
145 } else if ((id->capability & 8) || (id->field_valid & 2)) { 121 if (ide_use_fast_pio(drive))
146fast_ata_pio:
147 hpt34x_tune_drive(drive, 255); 122 hpt34x_tune_drive(drive, 255);
148 return hwif->ide_dma_off_quietly(drive); 123
149 } 124 return -1;
150 /* IORDY not supported */
151 return 0;
152} 125}
153 126
154/* 127/*
@@ -209,7 +182,6 @@ static void __devinit init_hwif_hpt34x(ide_hwif_t *hwif)
209 182
210 hwif->tuneproc = &hpt34x_tune_drive; 183 hwif->tuneproc = &hpt34x_tune_drive;
211 hwif->speedproc = &hpt34x_tune_chipset; 184 hwif->speedproc = &hpt34x_tune_chipset;
212 hwif->no_dsc = 1;
213 hwif->drives[0].autotune = 1; 185 hwif->drives[0].autotune = 1;
214 hwif->drives[1].autotune = 1; 186 hwif->drives[1].autotune = 1;
215 187
diff --git a/drivers/ide/pci/hpt366.c b/drivers/ide/pci/hpt366.c
index 05be8fadda7a..60ecdc258c7c 100644
--- a/drivers/ide/pci/hpt366.c
+++ b/drivers/ide/pci/hpt366.c
@@ -736,24 +736,15 @@ static void hpt3xx_maskproc(ide_drive_t *drive, int mask)
736 736
737static int hpt366_config_drive_xfer_rate(ide_drive_t *drive) 737static int hpt366_config_drive_xfer_rate(ide_drive_t *drive)
738{ 738{
739 ide_hwif_t *hwif = HWIF(drive);
740 struct hd_driveid *id = drive->id;
741
742 drive->init_speed = 0; 739 drive->init_speed = 0;
743 740
744 if ((id->capability & 1) && drive->autodma) { 741 if (ide_use_dma(drive) && config_chipset_for_dma(drive))
745 if (ide_use_dma(drive) && config_chipset_for_dma(drive)) 742 return 0;
746 return hwif->ide_dma_on(drive);
747
748 goto fast_ata_pio;
749 743
750 } else if ((id->capability & 8) || (id->field_valid & 2)) { 744 if (ide_use_fast_pio(drive))
751fast_ata_pio:
752 hpt3xx_tune_drive(drive, 255); 745 hpt3xx_tune_drive(drive, 255);
753 return hwif->ide_dma_off_quietly(drive); 746
754 } 747 return -1;
755 /* IORDY not supported */
756 return 0;
757} 748}
758 749
759/* 750/*
@@ -841,7 +832,7 @@ static int hpt374_ide_dma_test_irq(ide_drive_t *drive)
841 return 0; 832 return 0;
842 } 833 }
843 834
844 dma_stat = hwif->INB(hwif->dma_status); 835 dma_stat = inb(hwif->dma_status);
845 /* return 1 if INTR asserted */ 836 /* return 1 if INTR asserted */
846 if (dma_stat & 4) 837 if (dma_stat & 4)
847 return 1; 838 return 1;
@@ -1391,9 +1382,6 @@ static void __devinit init_dma_hpt366(ide_hwif_t *hwif, unsigned long dmabase)
1391 u8 dma_new = 0, dma_old = 0; 1382 u8 dma_new = 0, dma_old = 0;
1392 unsigned long flags; 1383 unsigned long flags;
1393 1384
1394 if (!dmabase)
1395 return;
1396
1397 dma_old = hwif->INB(dmabase + 2); 1385 dma_old = hwif->INB(dmabase + 2);
1398 1386
1399 local_irq_save(flags); 1387 local_irq_save(flags);
diff --git a/drivers/ide/pci/it8213.c b/drivers/ide/pci/it8213.c
index 63248b6909fa..424f00bb160d 100644
--- a/drivers/ide/pci/it8213.c
+++ b/drivers/ide/pci/it8213.c
@@ -244,17 +244,15 @@ static int config_chipset_for_dma (ide_drive_t *drive)
244 244
245static int it8213_config_drive_for_dma (ide_drive_t *drive) 245static int it8213_config_drive_for_dma (ide_drive_t *drive)
246{ 246{
247 ide_hwif_t *hwif = drive->hwif; 247 u8 pio;
248 248
249 if (ide_use_dma(drive)) { 249 if (ide_use_dma(drive) && config_chipset_for_dma(drive))
250 if (config_chipset_for_dma(drive)) 250 return 0;
251 return hwif->ide_dma_on(drive);
252 }
253 251
254 hwif->speedproc(drive, XFER_PIO_0 252 pio = ide_get_best_pio_mode(drive, 255, 4, NULL);
255 + ide_get_best_pio_mode(drive, 255, 4, NULL)); 253 it8213_tune_chipset(drive, XFER_PIO_0 + pio);
256 254
257 return hwif->ide_dma_off_quietly(drive); 255 return -1;
258} 256}
259 257
260/** 258/**
diff --git a/drivers/ide/pci/it821x.c b/drivers/ide/pci/it821x.c
index e9bad185968a..a132767f7d90 100644
--- a/drivers/ide/pci/it821x.c
+++ b/drivers/ide/pci/it821x.c
@@ -520,14 +520,12 @@ static int config_chipset_for_dma (ide_drive_t *drive)
520 520
521static int it821x_config_drive_for_dma (ide_drive_t *drive) 521static int it821x_config_drive_for_dma (ide_drive_t *drive)
522{ 522{
523 ide_hwif_t *hwif = drive->hwif; 523 if (ide_use_dma(drive) && config_chipset_for_dma(drive))
524 return 0;
524 525
525 if (ide_use_dma(drive)) {
526 if (config_chipset_for_dma(drive))
527 return hwif->ide_dma_on(drive);
528 }
529 config_it821x_chipset_for_pio(drive, 1); 526 config_it821x_chipset_for_pio(drive, 1);
530 return hwif->ide_dma_off_quietly(drive); 527
528 return -1;
531} 529}
532 530
533/** 531/**
@@ -608,11 +606,11 @@ static void __devinit it821x_fixups(ide_hwif_t *hwif)
608 printk(".\n"); 606 printk(".\n");
609 /* Now the core code will have wrongly decided no DMA 607 /* Now the core code will have wrongly decided no DMA
610 so we need to fix this */ 608 so we need to fix this */
611 hwif->ide_dma_off_quietly(drive); 609 hwif->dma_off_quietly(drive);
612#ifdef CONFIG_IDEDMA_ONLYDISK 610#ifdef CONFIG_IDEDMA_ONLYDISK
613 if (drive->media == ide_disk) 611 if (drive->media == ide_disk)
614#endif 612#endif
615 hwif->ide_dma_check(drive); 613 ide_set_dma(drive);
616 } else { 614 } else {
617 /* Non RAID volume. Fixups to stop the core code 615 /* Non RAID volume. Fixups to stop the core code
618 doing unsupported things */ 616 doing unsupported things */
diff --git a/drivers/ide/pci/jmicron.c b/drivers/ide/pci/jmicron.c
index f07bbbed1778..53f25500c22b 100644
--- a/drivers/ide/pci/jmicron.c
+++ b/drivers/ide/pci/jmicron.c
@@ -147,7 +147,9 @@ static int config_chipset_for_dma (ide_drive_t *drive)
147{ 147{
148 u8 speed = ide_dma_speed(drive, jmicron_ratemask(drive)); 148 u8 speed = ide_dma_speed(drive, jmicron_ratemask(drive));
149 149
150 config_jmicron_chipset_for_pio(drive, !speed); 150 if (!speed)
151 return 0;
152
151 jmicron_tune_chipset(drive, speed); 153 jmicron_tune_chipset(drive, speed);
152 return ide_dma_enable(drive); 154 return ide_dma_enable(drive);
153} 155}
@@ -162,14 +164,12 @@ static int config_chipset_for_dma (ide_drive_t *drive)
162 164
163static int jmicron_config_drive_for_dma (ide_drive_t *drive) 165static int jmicron_config_drive_for_dma (ide_drive_t *drive)
164{ 166{
165 ide_hwif_t *hwif = drive->hwif; 167 if (ide_use_dma(drive) && config_chipset_for_dma(drive))
168 return 0;
166 169
167 if (ide_use_dma(drive)) {
168 if (config_chipset_for_dma(drive))
169 return hwif->ide_dma_on(drive);
170 }
171 config_jmicron_chipset_for_pio(drive, 1); 170 config_jmicron_chipset_for_pio(drive, 1);
172 return hwif->ide_dma_off_quietly(drive); 171
172 return -1;
173} 173}
174 174
175/** 175/**
diff --git a/drivers/ide/pci/ns87415.c b/drivers/ide/pci/ns87415.c
index 8aaea4ea5549..b310c4f51077 100644
--- a/drivers/ide/pci/ns87415.c
+++ b/drivers/ide/pci/ns87415.c
@@ -166,10 +166,10 @@ static int ns87415_ide_dma_end (ide_drive_t *drive)
166 /* get dma command mode */ 166 /* get dma command mode */
167 dma_cmd = hwif->INB(hwif->dma_command); 167 dma_cmd = hwif->INB(hwif->dma_command);
168 /* stop DMA */ 168 /* stop DMA */
169 hwif->OUTB(dma_cmd & ~1, hwif->dma_command); 169 outb(dma_cmd & ~1, hwif->dma_command);
170 /* from ERRATA: clear the INTR & ERROR bits */ 170 /* from ERRATA: clear the INTR & ERROR bits */
171 dma_cmd = hwif->INB(hwif->dma_command); 171 dma_cmd = hwif->INB(hwif->dma_command);
172 hwif->OUTB(dma_cmd|6, hwif->dma_command); 172 outb(dma_cmd | 6, hwif->dma_command);
173 /* and free any DMA resources */ 173 /* and free any DMA resources */
174 ide_destroy_dmatable(drive); 174 ide_destroy_dmatable(drive);
175 /* verify good DMA status */ 175 /* verify good DMA status */
@@ -190,7 +190,8 @@ static int ns87415_ide_dma_setup(ide_drive_t *drive)
190static int ns87415_ide_dma_check (ide_drive_t *drive) 190static int ns87415_ide_dma_check (ide_drive_t *drive)
191{ 191{
192 if (drive->media != ide_disk) 192 if (drive->media != ide_disk)
193 return HWIF(drive)->ide_dma_off_quietly(drive); 193 return -1;
194
194 return __ide_dma_check(drive); 195 return __ide_dma_check(drive);
195} 196}
196 197
@@ -243,9 +244,9 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
243 * to SELECT_DRIVE() properly during first probe_hwif(). 244 * to SELECT_DRIVE() properly during first probe_hwif().
244 */ 245 */
245 timeout = 10000; 246 timeout = 10000;
246 hwif->OUTB(12, hwif->io_ports[IDE_CONTROL_OFFSET]); 247 outb(12, hwif->io_ports[IDE_CONTROL_OFFSET]);
247 udelay(10); 248 udelay(10);
248 hwif->OUTB(8, hwif->io_ports[IDE_CONTROL_OFFSET]); 249 outb(8, hwif->io_ports[IDE_CONTROL_OFFSET]);
249 do { 250 do {
250 udelay(50); 251 udelay(50);
251 stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]); 252 stat = hwif->INB(hwif->io_ports[IDE_STATUS_OFFSET]);
@@ -263,7 +264,7 @@ static void __devinit init_hwif_ns87415 (ide_hwif_t *hwif)
263 if (!hwif->dma_base) 264 if (!hwif->dma_base)
264 return; 265 return;
265 266
266 hwif->OUTB(0x60, hwif->dma_status); 267 outb(0x60, hwif->dma_status);
267 hwif->dma_setup = &ns87415_ide_dma_setup; 268 hwif->dma_setup = &ns87415_ide_dma_setup;
268 hwif->ide_dma_check = &ns87415_ide_dma_check; 269 hwif->ide_dma_check = &ns87415_ide_dma_check;
269 hwif->ide_dma_end = &ns87415_ide_dma_end; 270 hwif->ide_dma_end = &ns87415_ide_dma_end;
diff --git a/drivers/ide/pci/opti621.c b/drivers/ide/pci/opti621.c
index 22bbf613f948..9ca60dd2185e 100644
--- a/drivers/ide/pci/opti621.c
+++ b/drivers/ide/pci/opti621.c
@@ -176,34 +176,35 @@ static int cmpt_clk(int time, int bus_speed)
176 return ((time*bus_speed+999)/1000); 176 return ((time*bus_speed+999)/1000);
177} 177}
178 178
179static void write_reg(ide_hwif_t *hwif, u8 value, int reg)
180/* Write value to register reg, base of register 179/* Write value to register reg, base of register
181 * is at reg_base (0x1f0 primary, 0x170 secondary, 180 * is at reg_base (0x1f0 primary, 0x170 secondary,
182 * if not changed by PCI configuration). 181 * if not changed by PCI configuration).
183 * This is from setupvic.exe program. 182 * This is from setupvic.exe program.
184 */ 183 */
184static void write_reg(u8 value, int reg)
185{ 185{
186 hwif->INW(reg_base+1); 186 inw(reg_base + 1);
187 hwif->INW(reg_base+1); 187 inw(reg_base + 1);
188 hwif->OUTB(3, reg_base+2); 188 outb(3, reg_base + 2);
189 hwif->OUTB(value, reg_base+reg); 189 outb(value, reg_base + reg);
190 hwif->OUTB(0x83, reg_base+2); 190 outb(0x83, reg_base + 2);
191} 191}
192 192
193static u8 read_reg(ide_hwif_t *hwif, int reg)
194/* Read value from register reg, base of register 193/* Read value from register reg, base of register
195 * is at reg_base (0x1f0 primary, 0x170 secondary, 194 * is at reg_base (0x1f0 primary, 0x170 secondary,
196 * if not changed by PCI configuration). 195 * if not changed by PCI configuration).
197 * This is from setupvic.exe program. 196 * This is from setupvic.exe program.
198 */ 197 */
198static u8 read_reg(int reg)
199{ 199{
200 u8 ret = 0; 200 u8 ret = 0;
201 201
202 hwif->INW(reg_base+1); 202 inw(reg_base + 1);
203 hwif->INW(reg_base+1); 203 inw(reg_base + 1);
204 hwif->OUTB(3, reg_base+2); 204 outb(3, reg_base + 2);
205 ret = hwif->INB(reg_base+reg); 205 ret = inb(reg_base + reg);
206 hwif->OUTB(0x83, reg_base+2); 206 outb(0x83, reg_base + 2);
207
207 return ret; 208 return ret;
208} 209}
209 210
@@ -286,39 +287,39 @@ static void opti621_tune_drive (ide_drive_t *drive, u8 pio)
286 reg_base = hwif->io_ports[IDE_DATA_OFFSET]; 287 reg_base = hwif->io_ports[IDE_DATA_OFFSET];
287 288
288 /* allow Register-B */ 289 /* allow Register-B */
289 hwif->OUTB(0xc0, reg_base+CNTRL_REG); 290 outb(0xc0, reg_base + CNTRL_REG);
290 /* hmm, setupvic.exe does this ;-) */ 291 /* hmm, setupvic.exe does this ;-) */
291 hwif->OUTB(0xff, reg_base+5); 292 outb(0xff, reg_base + 5);
292 /* if reads 0xff, adapter not exist? */ 293 /* if reads 0xff, adapter not exist? */
293 (void) hwif->INB(reg_base+CNTRL_REG); 294 (void)inb(reg_base + CNTRL_REG);
294 /* if reads 0xc0, no interface exist? */ 295 /* if reads 0xc0, no interface exist? */
295 read_reg(hwif, CNTRL_REG); 296 read_reg(CNTRL_REG);
296 /* read version, probably 0 */ 297 /* read version, probably 0 */
297 read_reg(hwif, STRAP_REG); 298 read_reg(STRAP_REG);
298 299
299 /* program primary drive */ 300 /* program primary drive */
300 /* select Index-0 for Register-A */ 301 /* select Index-0 for Register-A */
301 write_reg(hwif, 0, MISC_REG); 302 write_reg(0, MISC_REG);
302 /* set read cycle timings */ 303 /* set read cycle timings */
303 write_reg(hwif, cycle1, READ_REG); 304 write_reg(cycle1, READ_REG);
304 /* set write cycle timings */ 305 /* set write cycle timings */
305 write_reg(hwif, cycle1, WRITE_REG); 306 write_reg(cycle1, WRITE_REG);
306 307
307 /* program secondary drive */ 308 /* program secondary drive */
308 /* select Index-1 for Register-B */ 309 /* select Index-1 for Register-B */
309 write_reg(hwif, 1, MISC_REG); 310 write_reg(1, MISC_REG);
310 /* set read cycle timings */ 311 /* set read cycle timings */
311 write_reg(hwif, cycle2, READ_REG); 312 write_reg(cycle2, READ_REG);
312 /* set write cycle timings */ 313 /* set write cycle timings */
313 write_reg(hwif, cycle2, WRITE_REG); 314 write_reg(cycle2, WRITE_REG);
314 315
315 /* use Register-A for drive 0 */ 316 /* use Register-A for drive 0 */
316 /* use Register-B for drive 1 */ 317 /* use Register-B for drive 1 */
317 write_reg(hwif, 0x85, CNTRL_REG); 318 write_reg(0x85, CNTRL_REG);
318 319
319 /* set address setup, DRDY timings, */ 320 /* set address setup, DRDY timings, */
320 /* and read prefetch for both drives */ 321 /* and read prefetch for both drives */
321 write_reg(hwif, misc, MISC_REG); 322 write_reg(misc, MISC_REG);
322 323
323 spin_unlock_irqrestore(&ide_lock, flags); 324 spin_unlock_irqrestore(&ide_lock, flags);
324} 325}
diff --git a/drivers/ide/pci/pdc202xx_new.c b/drivers/ide/pci/pdc202xx_new.c
index 236a03144a27..6ceb25bc5a7b 100644
--- a/drivers/ide/pci/pdc202xx_new.c
+++ b/drivers/ide/pci/pdc202xx_new.c
@@ -101,8 +101,8 @@ static u8 get_indexed_reg(ide_hwif_t *hwif, u8 index)
101{ 101{
102 u8 value; 102 u8 value;
103 103
104 hwif->OUTB(index, hwif->dma_vendor1); 104 outb(index, hwif->dma_vendor1);
105 value = hwif->INB(hwif->dma_vendor3); 105 value = inb(hwif->dma_vendor3);
106 106
107 DBG("index[%02X] value[%02X]\n", index, value); 107 DBG("index[%02X] value[%02X]\n", index, value);
108 return value; 108 return value;
@@ -115,8 +115,8 @@ static u8 get_indexed_reg(ide_hwif_t *hwif, u8 index)
115 */ 115 */
116static void set_indexed_reg(ide_hwif_t *hwif, u8 index, u8 value) 116static void set_indexed_reg(ide_hwif_t *hwif, u8 index, u8 value)
117{ 117{
118 hwif->OUTB(index, hwif->dma_vendor1); 118 outb(index, hwif->dma_vendor1);
119 hwif->OUTB(value, hwif->dma_vendor3); 119 outb(value, hwif->dma_vendor3);
120 DBG("index[%02X] value[%02X]\n", index, value); 120 DBG("index[%02X] value[%02X]\n", index, value);
121} 121}
122 122
@@ -281,25 +281,15 @@ static int config_chipset_for_dma(ide_drive_t *drive)
281 281
282static int pdcnew_config_drive_xfer_rate(ide_drive_t *drive) 282static int pdcnew_config_drive_xfer_rate(ide_drive_t *drive)
283{ 283{
284 ide_hwif_t *hwif = HWIF(drive);
285 struct hd_driveid *id = drive->id;
286
287 drive->init_speed = 0; 284 drive->init_speed = 0;
288 285
289 if ((id->capability & 1) && drive->autodma) { 286 if (ide_use_dma(drive) && config_chipset_for_dma(drive))
290 287 return 0;
291 if (ide_use_dma(drive) && config_chipset_for_dma(drive))
292 return hwif->ide_dma_on(drive);
293 288
294 goto fast_ata_pio; 289 if (ide_use_fast_pio(drive))
290 pdcnew_tune_drive(drive, 255);
295 291
296 } else if ((id->capability & 8) || (id->field_valid & 2)) { 292 return -1;
297fast_ata_pio:
298 hwif->tuneproc(drive, 255);
299 return hwif->ide_dma_off_quietly(drive);
300 }
301 /* IORDY not supported */
302 return 0;
303} 293}
304 294
305static int pdcnew_quirkproc(ide_drive_t *drive) 295static int pdcnew_quirkproc(ide_drive_t *drive)
diff --git a/drivers/ide/pci/pdc202xx_old.c b/drivers/ide/pci/pdc202xx_old.c
index 730e8d1ec2f5..a7a639fe1eaf 100644
--- a/drivers/ide/pci/pdc202xx_old.c
+++ b/drivers/ide/pci/pdc202xx_old.c
@@ -2,6 +2,7 @@
2 * linux/drivers/ide/pci/pdc202xx_old.c Version 0.36 Sept 11, 2002 2 * linux/drivers/ide/pci/pdc202xx_old.c Version 0.36 Sept 11, 2002
3 * 3 *
4 * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org> 4 * Copyright (C) 1998-2002 Andre Hedrick <andre@linux-ide.org>
5 * Copyright (C) 2006-2007 MontaVista Software, Inc.
5 * 6 *
6 * Promise Ultra33 cards with BIOS v1.20 through 1.28 will need this 7 * Promise Ultra33 cards with BIOS v1.20 through 1.28 will need this
7 * compiled into the kernel if you have more than one card installed. 8 * compiled into the kernel if you have more than one card installed.
@@ -216,21 +217,10 @@ static int pdc202xx_tune_chipset (ide_drive_t *drive, u8 xferspeed)
216} 217}
217 218
218 219
219/* 0 1 2 3 4 5 6 7 8 220static void pdc202xx_tune_drive(ide_drive_t *drive, u8 pio)
220 * 960, 480, 390, 300, 240, 180, 120, 90, 60
221 * 180, 150, 120, 90, 60
222 * DMA_Speed
223 * 180, 120, 90, 90, 90, 60, 30
224 * 11, 5, 4, 3, 2, 1, 0
225 */
226static void config_chipset_for_pio (ide_drive_t *drive, u8 pio)
227{ 221{
228 u8 speed = 0; 222 pio = ide_get_best_pio_mode(drive, pio, 4, NULL);
229 223 pdc202xx_tune_chipset(drive, XFER_PIO_0 + pio);
230 if (pio == 5) pio = 4;
231 speed = XFER_PIO_0 + ide_get_best_pio_mode(drive, 255, pio, NULL);
232
233 pdc202xx_tune_chipset(drive, speed);
234} 224}
235 225
236static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif) 226static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif)
@@ -250,17 +240,17 @@ static u8 pdc202xx_old_cable_detect (ide_hwif_t *hwif)
250static void pdc_old_enable_66MHz_clock(ide_hwif_t *hwif) 240static void pdc_old_enable_66MHz_clock(ide_hwif_t *hwif)
251{ 241{
252 unsigned long clock_reg = hwif->dma_master + 0x11; 242 unsigned long clock_reg = hwif->dma_master + 0x11;
253 u8 clock = hwif->INB(clock_reg); 243 u8 clock = inb(clock_reg);
254 244
255 hwif->OUTB(clock | (hwif->channel ? 0x08 : 0x02), clock_reg); 245 outb(clock | (hwif->channel ? 0x08 : 0x02), clock_reg);
256} 246}
257 247
258static void pdc_old_disable_66MHz_clock(ide_hwif_t *hwif) 248static void pdc_old_disable_66MHz_clock(ide_hwif_t *hwif)
259{ 249{
260 unsigned long clock_reg = hwif->dma_master + 0x11; 250 unsigned long clock_reg = hwif->dma_master + 0x11;
261 u8 clock = hwif->INB(clock_reg); 251 u8 clock = inb(clock_reg);
262 252
263 hwif->OUTB(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg); 253 outb(clock & ~(hwif->channel ? 0x08 : 0x02), clock_reg);
264} 254}
265 255
266static int config_chipset_for_dma (ide_drive_t *drive) 256static int config_chipset_for_dma (ide_drive_t *drive)
@@ -332,27 +322,15 @@ chipset_is_set:
332 322
333static int pdc202xx_config_drive_xfer_rate (ide_drive_t *drive) 323static int pdc202xx_config_drive_xfer_rate (ide_drive_t *drive)
334{ 324{
335 ide_hwif_t *hwif = HWIF(drive);
336 struct hd_driveid *id = drive->id;
337
338 drive->init_speed = 0; 325 drive->init_speed = 0;
339 326
340 if (id && (id->capability & 1) && drive->autodma) { 327 if (ide_use_dma(drive) && config_chipset_for_dma(drive))
341 328 return 0;
342 if (ide_use_dma(drive)) {
343 if (config_chipset_for_dma(drive))
344 return hwif->ide_dma_on(drive);
345 }
346 329
347 goto fast_ata_pio; 330 if (ide_use_fast_pio(drive))
331 pdc202xx_tune_drive(drive, 255);
348 332
349 } else if ((id->capability & 8) || (id->field_valid & 2)) { 333 return -1;
350fast_ata_pio:
351 hwif->tuneproc(drive, 5);
352 return hwif->ide_dma_off_quietly(drive);
353 }
354 /* IORDY not supported */
355 return 0;
356} 334}
357 335
358static int pdc202xx_quirkproc (ide_drive_t *drive) 336static int pdc202xx_quirkproc (ide_drive_t *drive)
@@ -375,14 +353,14 @@ static void pdc202xx_old_ide_dma_start(ide_drive_t *drive)
375 unsigned long high_16 = hwif->dma_master; 353 unsigned long high_16 = hwif->dma_master;
376 unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20); 354 unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20);
377 u32 word_count = 0; 355 u32 word_count = 0;
378 u8 clock = hwif->INB(high_16 + 0x11); 356 u8 clock = inb(high_16 + 0x11);
379 357
380 hwif->OUTB(clock|(hwif->channel ? 0x08 : 0x02), high_16+0x11); 358 outb(clock | (hwif->channel ? 0x08 : 0x02), high_16 + 0x11);
381 word_count = (rq->nr_sectors << 8); 359 word_count = (rq->nr_sectors << 8);
382 word_count = (rq_data_dir(rq) == READ) ? 360 word_count = (rq_data_dir(rq) == READ) ?
383 word_count | 0x05000000 : 361 word_count | 0x05000000 :
384 word_count | 0x06000000; 362 word_count | 0x06000000;
385 hwif->OUTL(word_count, atapi_reg); 363 outl(word_count, atapi_reg);
386 } 364 }
387 ide_dma_start(drive); 365 ide_dma_start(drive);
388} 366}
@@ -395,9 +373,9 @@ static int pdc202xx_old_ide_dma_end(ide_drive_t *drive)
395 unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20); 373 unsigned long atapi_reg = high_16 + (hwif->channel ? 0x24 : 0x20);
396 u8 clock = 0; 374 u8 clock = 0;
397 375
398 hwif->OUTL(0, atapi_reg); /* zero out extra */ 376 outl(0, atapi_reg); /* zero out extra */
399 clock = hwif->INB(high_16 + 0x11); 377 clock = inb(high_16 + 0x11);
400 hwif->OUTB(clock & ~(hwif->channel ? 0x08:0x02), high_16+0x11); 378 outb(clock & ~(hwif->channel ? 0x08:0x02), high_16 + 0x11);
401 } 379 }
402 if (drive->current_speed > XFER_UDMA_2) 380 if (drive->current_speed > XFER_UDMA_2)
403 pdc_old_disable_66MHz_clock(drive->hwif); 381 pdc_old_disable_66MHz_clock(drive->hwif);
@@ -408,8 +386,8 @@ static int pdc202xx_old_ide_dma_test_irq(ide_drive_t *drive)
408{ 386{
409 ide_hwif_t *hwif = HWIF(drive); 387 ide_hwif_t *hwif = HWIF(drive);
410 unsigned long high_16 = hwif->dma_master; 388 unsigned long high_16 = hwif->dma_master;
411 u8 dma_stat = hwif->INB(hwif->dma_status); 389 u8 dma_stat = inb(hwif->dma_status);
412 u8 sc1d = hwif->INB((high_16 + 0x001d)); 390 u8 sc1d = inb(high_16 + 0x001d);
413 391
414 if (hwif->channel) { 392 if (hwif->channel) {
415 /* bit7: Error, bit6: Interrupting, bit5: FIFO Full, bit4: FIFO Empty */ 393 /* bit7: Error, bit6: Interrupting, bit5: FIFO Full, bit4: FIFO Empty */
@@ -445,11 +423,11 @@ static int pdc202xx_ide_dma_timeout(ide_drive_t *drive)
445static void pdc202xx_reset_host (ide_hwif_t *hwif) 423static void pdc202xx_reset_host (ide_hwif_t *hwif)
446{ 424{
447 unsigned long high_16 = hwif->dma_master; 425 unsigned long high_16 = hwif->dma_master;
448 u8 udma_speed_flag = hwif->INB(high_16|0x001f); 426 u8 udma_speed_flag = inb(high_16 | 0x001f);
449 427
450 hwif->OUTB((udma_speed_flag | 0x10), (high_16|0x001f)); 428 outb(udma_speed_flag | 0x10, high_16 | 0x001f);
451 mdelay(100); 429 mdelay(100);
452 hwif->OUTB((udma_speed_flag & ~0x10), (high_16|0x001f)); 430 outb(udma_speed_flag & ~0x10, high_16 | 0x001f);
453 mdelay(2000); /* 2 seconds ?! */ 431 mdelay(2000); /* 2 seconds ?! */
454 432
455 printk(KERN_WARNING "PDC202XX: %s channel reset.\n", 433 printk(KERN_WARNING "PDC202XX: %s channel reset.\n",
@@ -463,7 +441,7 @@ static void pdc202xx_reset (ide_drive_t *drive)
463 441
464 pdc202xx_reset_host(hwif); 442 pdc202xx_reset_host(hwif);
465 pdc202xx_reset_host(mate); 443 pdc202xx_reset_host(mate);
466 hwif->tuneproc(drive, 5); 444 pdc202xx_tune_drive(drive, 255);
467} 445}
468 446
469static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev, 447static unsigned int __devinit init_chipset_pdc202xx(struct pci_dev *dev,
@@ -490,7 +468,7 @@ static void __devinit init_hwif_pdc202xx(ide_hwif_t *hwif)
490 hwif->rqsize = 256; 468 hwif->rqsize = 256;
491 469
492 hwif->autodma = 0; 470 hwif->autodma = 0;
493 hwif->tuneproc = &config_chipset_for_pio; 471 hwif->tuneproc = &pdc202xx_tune_drive;
494 hwif->quirkproc = &pdc202xx_quirkproc; 472 hwif->quirkproc = &pdc202xx_quirkproc;
495 473
496 if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246) 474 if (hwif->pci_dev->device != PCI_DEVICE_ID_PROMISE_20246)
@@ -537,9 +515,9 @@ static void __devinit init_dma_pdc202xx(ide_hwif_t *hwif, unsigned long dmabase)
537 return; 515 return;
538 } 516 }
539 517
540 udma_speed_flag = hwif->INB((dmabase|0x1f)); 518 udma_speed_flag = inb(dmabase | 0x1f);
541 primary_mode = hwif->INB((dmabase|0x1a)); 519 primary_mode = inb(dmabase | 0x1a);
542 secondary_mode = hwif->INB((dmabase|0x1b)); 520 secondary_mode = inb(dmabase | 0x1b);
543 printk(KERN_INFO "%s: (U)DMA Burst Bit %sABLED " \ 521 printk(KERN_INFO "%s: (U)DMA Burst Bit %sABLED " \
544 "Primary %s Mode " \ 522 "Primary %s Mode " \
545 "Secondary %s Mode.\n", hwif->cds->name, 523 "Secondary %s Mode.\n", hwif->cds->name,
@@ -552,30 +530,10 @@ static void __devinit init_dma_pdc202xx(ide_hwif_t *hwif, unsigned long dmabase)
552 printk(KERN_INFO "%s: FORCING BURST BIT 0x%02x->0x%02x ", 530 printk(KERN_INFO "%s: FORCING BURST BIT 0x%02x->0x%02x ",
553 hwif->cds->name, udma_speed_flag, 531 hwif->cds->name, udma_speed_flag,
554 (udma_speed_flag|1)); 532 (udma_speed_flag|1));
555 hwif->OUTB(udma_speed_flag|1,(dmabase|0x1f)); 533 outb(udma_speed_flag | 1, dmabase | 0x1f);
556 printk("%sACTIVE\n", 534 printk("%sACTIVE\n", (inb(dmabase | 0x1f) & 1) ? "" : "IN");
557 (hwif->INB(dmabase|0x1f)&1) ? "":"IN");
558 } 535 }
559#endif /* CONFIG_PDC202XX_BURST */ 536#endif /* CONFIG_PDC202XX_BURST */
560#ifdef CONFIG_PDC202XX_MASTER
561 if (!(primary_mode & 1)) {
562 printk(KERN_INFO "%s: FORCING PRIMARY MODE BIT "
563 "0x%02x -> 0x%02x ", hwif->cds->name,
564 primary_mode, (primary_mode|1));
565 hwif->OUTB(primary_mode|1, (dmabase|0x1a));
566 printk("%s\n",
567 (hwif->INB((dmabase|0x1a)) & 1) ? "MASTER" : "PCI");
568 }
569
570 if (!(secondary_mode & 1)) {
571 printk(KERN_INFO "%s: FORCING SECONDARY MODE BIT "
572 "0x%02x -> 0x%02x ", hwif->cds->name,
573 secondary_mode, (secondary_mode|1));
574 hwif->OUTB(secondary_mode|1, (dmabase|0x1b));
575 printk("%s\n",
576 (hwif->INB((dmabase|0x1b)) & 1) ? "MASTER" : "PCI");
577 }
578#endif /* CONFIG_PDC202XX_MASTER */
579 537
580 ide_setup_dma(hwif, dmabase, 8); 538 ide_setup_dma(hwif, dmabase, 8);
581} 539}
diff --git a/drivers/ide/pci/piix.c b/drivers/ide/pci/piix.c
index 52cfc2ac22c1..569822f4cf55 100644
--- a/drivers/ide/pci/piix.c
+++ b/drivers/ide/pci/piix.c
@@ -369,7 +369,7 @@ static int piix_config_drive_for_dma (ide_drive_t *drive)
369 * If no DMA speed was available or the chipset has DMA bugs 369 * If no DMA speed was available or the chipset has DMA bugs
370 * then disable DMA and use PIO 370 * then disable DMA and use PIO
371 */ 371 */
372 if (!speed || no_piix_dma) 372 if (!speed)
373 return 0; 373 return 0;
374 374
375 (void) piix_tune_chipset(drive, speed); 375 (void) piix_tune_chipset(drive, speed);
@@ -386,41 +386,28 @@ static int piix_config_drive_for_dma (ide_drive_t *drive)
386 386
387static int piix_config_drive_xfer_rate (ide_drive_t *drive) 387static int piix_config_drive_xfer_rate (ide_drive_t *drive)
388{ 388{
389 ide_hwif_t *hwif = HWIF(drive);
390 struct hd_driveid *id = drive->id;
391
392 drive->init_speed = 0; 389 drive->init_speed = 0;
393 390
394 if ((id->capability & 1) && drive->autodma) { 391 if (ide_use_dma(drive) && piix_config_drive_for_dma(drive))
395 392 return 0;
396 if (ide_use_dma(drive) && piix_config_drive_for_dma(drive))
397 return hwif->ide_dma_on(drive);
398
399 goto fast_ata_pio;
400 393
401 } else if ((id->capability & 8) || (id->field_valid & 2)) { 394 if (ide_use_fast_pio(drive))
402fast_ata_pio:
403 /* Find best PIO mode. */ 395 /* Find best PIO mode. */
404 (void) hwif->speedproc(drive, XFER_PIO_0 + 396 piix_tune_chipset(drive, XFER_PIO_0 +
405 ide_get_best_pio_mode(drive, 255, 4, NULL)); 397 ide_get_best_pio_mode(drive, 255, 4, NULL));
406 return hwif->ide_dma_off_quietly(drive); 398
407 } 399 return -1;
408 /* IORDY not supported */
409 return 0;
410} 400}
411 401
412/** 402/**
413 * init_chipset_piix - set up the PIIX chipset 403 * piix_is_ichx - check if ICHx
414 * @dev: PCI device to set up 404 * @dev: PCI device to check
415 * @name: Name of the device
416 * 405 *
417 * Initialize the PCI device as required. For the PIIX this turns 406 * returns 1 if ICHx, 0 otherwise.
418 * out to be nice and simple
419 */ 407 */
420 408static int piix_is_ichx(struct pci_dev *dev)
421static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char *name)
422{ 409{
423 switch(dev->device) { 410 switch (dev->device) {
424 case PCI_DEVICE_ID_INTEL_82801EB_1: 411 case PCI_DEVICE_ID_INTEL_82801EB_1:
425 case PCI_DEVICE_ID_INTEL_82801AA_1: 412 case PCI_DEVICE_ID_INTEL_82801AA_1:
426 case PCI_DEVICE_ID_INTEL_82801AB_1: 413 case PCI_DEVICE_ID_INTEL_82801AB_1:
@@ -438,19 +425,61 @@ static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char
438 case PCI_DEVICE_ID_INTEL_ICH7_21: 425 case PCI_DEVICE_ID_INTEL_ICH7_21:
439 case PCI_DEVICE_ID_INTEL_ESB2_18: 426 case PCI_DEVICE_ID_INTEL_ESB2_18:
440 case PCI_DEVICE_ID_INTEL_ICH8_6: 427 case PCI_DEVICE_ID_INTEL_ICH8_6:
441 { 428 return 1;
442 unsigned int extra = 0;
443 pci_read_config_dword(dev, 0x54, &extra);
444 pci_write_config_dword(dev, 0x54, extra|0x400);
445 }
446 default:
447 break;
448 } 429 }
449 430
450 return 0; 431 return 0;
451} 432}
452 433
453/** 434/**
435 * init_chipset_piix - set up the PIIX chipset
436 * @dev: PCI device to set up
437 * @name: Name of the device
438 *
439 * Initialize the PCI device as required. For the PIIX this turns
440 * out to be nice and simple
441 */
442
443static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char *name)
444{
445 if (piix_is_ichx(dev)) {
446 unsigned int extra = 0;
447 pci_read_config_dword(dev, 0x54, &extra);
448 pci_write_config_dword(dev, 0x54, extra|0x400);
449 }
450
451 return 0;
452}
453
454/**
455 * piix_dma_clear_irq - clear BMDMA status
456 * @drive: IDE drive to clear
457 *
458 * Called from ide_intr() for PIO interrupts
459 * to clear BMDMA status as needed by ICHx
460 */
461static void piix_dma_clear_irq(ide_drive_t *drive)
462{
463 ide_hwif_t *hwif = HWIF(drive);
464 u8 dma_stat;
465
466 /* clear the INTR & ERROR bits */
467 dma_stat = hwif->INB(hwif->dma_status);
468 /* Should we force the bit as well ? */
469 hwif->OUTB(dma_stat, hwif->dma_status);
470}
471
472static int __devinit piix_cable_detect(ide_hwif_t *hwif)
473{
474 struct pci_dev *dev = hwif->pci_dev;
475 u8 reg54h = 0, mask = hwif->channel ? 0xc0 : 0x30;
476
477 pci_read_config_byte(dev, 0x54, &reg54h);
478
479 return (reg54h & mask) ? 1 : 0;
480}
481
482/**
454 * init_hwif_piix - fill in the hwif for the PIIX 483 * init_hwif_piix - fill in the hwif for the PIIX
455 * @hwif: IDE interface 484 * @hwif: IDE interface
456 * 485 *
@@ -460,9 +489,6 @@ static unsigned int __devinit init_chipset_piix (struct pci_dev *dev, const char
460 489
461static void __devinit init_hwif_piix(ide_hwif_t *hwif) 490static void __devinit init_hwif_piix(ide_hwif_t *hwif)
462{ 491{
463 u8 reg54h = 0, reg55h = 0, ata66 = 0;
464 u8 mask = hwif->channel ? 0xc0 : 0x30;
465
466#ifndef CONFIG_IA64 492#ifndef CONFIG_IA64
467 if (!hwif->irq) 493 if (!hwif->irq)
468 hwif->irq = hwif->channel ? 15 : 14; 494 hwif->irq = hwif->channel ? 15 : 14;
@@ -472,10 +498,6 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif)
472 /* This is a painful system best to let it self tune for now */ 498 /* This is a painful system best to let it self tune for now */
473 return; 499 return;
474 } 500 }
475 /* ESB2 appears to generate spurious DMA interrupts in PIO mode
476 when in native mode */
477 if (hwif->pci_dev->device == PCI_DEVICE_ID_INTEL_ESB2_18)
478 hwif->atapi_irq_bogon = 1;
479 501
480 hwif->autodma = 0; 502 hwif->autodma = 0;
481 hwif->tuneproc = &piix_tune_drive; 503 hwif->tuneproc = &piix_tune_drive;
@@ -486,15 +508,16 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif)
486 if (!hwif->dma_base) 508 if (!hwif->dma_base)
487 return; 509 return;
488 510
511 /* ICHx need to clear the bmdma status for all interrupts */
512 if (piix_is_ichx(hwif->pci_dev))
513 hwif->ide_dma_clear_irq = &piix_dma_clear_irq;
514
489 hwif->atapi_dma = 1; 515 hwif->atapi_dma = 1;
490 hwif->ultra_mask = 0x3f; 516 hwif->ultra_mask = 0x3f;
491 hwif->mwdma_mask = 0x06; 517 hwif->mwdma_mask = 0x06;
492 hwif->swdma_mask = 0x04; 518 hwif->swdma_mask = 0x04;
493 519
494 switch(hwif->pci_dev->device) { 520 switch(hwif->pci_dev->device) {
495 case PCI_DEVICE_ID_INTEL_82371MX:
496 hwif->mwdma_mask = 0x80;
497 hwif->swdma_mask = 0x80;
498 case PCI_DEVICE_ID_INTEL_82371FB_0: 521 case PCI_DEVICE_ID_INTEL_82371FB_0:
499 case PCI_DEVICE_ID_INTEL_82371FB_1: 522 case PCI_DEVICE_ID_INTEL_82371FB_1:
500 case PCI_DEVICE_ID_INTEL_82371SB_1: 523 case PCI_DEVICE_ID_INTEL_82371SB_1:
@@ -507,14 +530,14 @@ static void __devinit init_hwif_piix(ide_hwif_t *hwif)
507 hwif->ultra_mask = 0x07; 530 hwif->ultra_mask = 0x07;
508 break; 531 break;
509 default: 532 default:
510 pci_read_config_byte(hwif->pci_dev, 0x54, &reg54h); 533 if (!hwif->udma_four)
511 pci_read_config_byte(hwif->pci_dev, 0x55, &reg55h); 534 hwif->udma_four = piix_cable_detect(hwif);
512 ata66 = (reg54h & mask) ? 1 : 0;
513 break; 535 break;
514 } 536 }
515 537
516 if (!(hwif->udma_four)) 538 if (no_piix_dma)
517 hwif->udma_four = ata66; 539 hwif->ultra_mask = hwif->mwdma_mask = hwif->swdma_mask = 0;
540
518 hwif->ide_dma_check = &piix_config_drive_xfer_rate; 541 hwif->ide_dma_check = &piix_config_drive_xfer_rate;
519 if (!noautodma) 542 if (!noautodma)
520 hwif->autodma = 1; 543 hwif->autodma = 1;
diff --git a/drivers/ide/pci/sc1200.c b/drivers/ide/pci/sc1200.c
index 8d762d323f8b..b5ae0c50e216 100644
--- a/drivers/ide/pci/sc1200.c
+++ b/drivers/ide/pci/sc1200.c
@@ -161,7 +161,7 @@ static int sc1200_config_dma2 (ide_drive_t *drive, int mode)
161 /* 161 /*
162 * Default to DMA-off in case we run into trouble here. 162 * Default to DMA-off in case we run into trouble here.
163 */ 163 */
164 hwif->ide_dma_off_quietly(drive); /* turn off DMA while we fiddle */ 164 hwif->dma_off_quietly(drive); /* turn off DMA while we fiddle */
165 outb(inb(hwif->dma_base+2)&~(unit?0x40:0x20), hwif->dma_base+2); /* clear DMA_capable bit */ 165 outb(inb(hwif->dma_base+2)&~(unit?0x40:0x20), hwif->dma_base+2); /* clear DMA_capable bit */
166 166
167 /* 167 /*
@@ -241,10 +241,7 @@ static int sc1200_config_dma2 (ide_drive_t *drive, int mode)
241 241
242 outb(inb(hwif->dma_base+2)|(unit?0x40:0x20), hwif->dma_base+2); /* set DMA_capable bit */ 242 outb(inb(hwif->dma_base+2)|(unit?0x40:0x20), hwif->dma_base+2); /* set DMA_capable bit */
243 243
244 /* 244 return 0; /* success */
245 * Finally, turn DMA on in software, and exit.
246 */
247 return hwif->ide_dma_on(drive); /* success */
248} 245}
249 246
250/* 247/*
@@ -442,10 +439,10 @@ static int sc1200_resume (struct pci_dev *dev)
442 ide_drive_t *drive = &(hwif->drives[d]); 439 ide_drive_t *drive = &(hwif->drives[d]);
443 if (drive->present && !__ide_dma_bad_drive(drive)) { 440 if (drive->present && !__ide_dma_bad_drive(drive)) {
444 int was_using_dma = drive->using_dma; 441 int was_using_dma = drive->using_dma;
445 hwif->ide_dma_off_quietly(drive); 442 hwif->dma_off_quietly(drive);
446 sc1200_config_dma(drive); 443 sc1200_config_dma(drive);
447 if (!was_using_dma && drive->using_dma) { 444 if (!was_using_dma && drive->using_dma) {
448 hwif->ide_dma_off_quietly(drive); 445 hwif->dma_off_quietly(drive);
449 } 446 }
450 } 447 }
451 } 448 }
diff --git a/drivers/ide/pci/serverworks.c b/drivers/ide/pci/serverworks.c
index ea9a28a45853..dbcd37a0c652 100644
--- a/drivers/ide/pci/serverworks.c
+++ b/drivers/ide/pci/serverworks.c
@@ -160,7 +160,7 @@ static int svwks_tune_chipset (ide_drive_t *drive, u8 xferspeed)
160 if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) || 160 if ((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
161 (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) { 161 (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) {
162 if (!drive->init_speed) { 162 if (!drive->init_speed) {
163 u8 dma_stat = hwif->INB(hwif->dma_status); 163 u8 dma_stat = inb(hwif->dma_status);
164 164
165dma_pio: 165dma_pio:
166 if (((ultra_enable << (7-drive->dn) & 0x80) == 0x80) && 166 if (((ultra_enable << (7-drive->dn) & 0x80) == 0x80) &&
@@ -315,35 +315,15 @@ static int config_chipset_for_dma (ide_drive_t *drive)
315 315
316static int svwks_config_drive_xfer_rate (ide_drive_t *drive) 316static int svwks_config_drive_xfer_rate (ide_drive_t *drive)
317{ 317{
318 ide_hwif_t *hwif = HWIF(drive);
319 struct hd_driveid *id = drive->id;
320
321 drive->init_speed = 0; 318 drive->init_speed = 0;
322 319
323 if ((id->capability & 1) && drive->autodma) { 320 if (ide_use_dma(drive) && config_chipset_for_dma(drive))
324 321 return 0;
325 if (ide_use_dma(drive)) {
326 if (config_chipset_for_dma(drive))
327 return hwif->ide_dma_on(drive);
328 }
329
330 goto fast_ata_pio;
331 322
332 } else if ((id->capability & 8) || (id->field_valid & 2)) { 323 if (ide_use_fast_pio(drive))
333fast_ata_pio:
334 config_chipset_for_pio(drive); 324 config_chipset_for_pio(drive);
335 // hwif->tuneproc(drive, 5);
336 return hwif->ide_dma_off_quietly(drive);
337 }
338 /* IORDY not supported */
339 return 0;
340}
341
342/* This can go soon */
343 325
344static int svwks_ide_dma_end (ide_drive_t *drive) 326 return -1;
345{
346 return __ide_dma_end(drive);
347} 327}
348 328
349static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const char *name) 329static unsigned int __devinit init_chipset_svwks (struct pci_dev *dev, const char *name)
@@ -537,35 +517,20 @@ static void __devinit init_hwif_svwks (ide_hwif_t *hwif)
537 } 517 }
538 518
539 hwif->ide_dma_check = &svwks_config_drive_xfer_rate; 519 hwif->ide_dma_check = &svwks_config_drive_xfer_rate;
540 if (hwif->pci_dev->device == PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) 520 if (hwif->pci_dev->device != PCI_DEVICE_ID_SERVERWORKS_OSB4IDE) {
541 hwif->ide_dma_end = &svwks_ide_dma_end; 521 if (!hwif->udma_four)
542 else if (!(hwif->udma_four)) 522 hwif->udma_four = ata66_svwks(hwif);
543 hwif->udma_four = ata66_svwks(hwif); 523 }
544 if (!noautodma) 524 if (!noautodma)
545 hwif->autodma = 1; 525 hwif->autodma = 1;
546 526
547 dma_stat = hwif->INB(hwif->dma_status); 527 dma_stat = inb(hwif->dma_status);
548 hwif->drives[0].autodma = (dma_stat & 0x20); 528 hwif->drives[0].autodma = (dma_stat & 0x20);
549 hwif->drives[1].autodma = (dma_stat & 0x40); 529 hwif->drives[1].autodma = (dma_stat & 0x40);
550 hwif->drives[0].autotune = (!(dma_stat & 0x20)); 530 hwif->drives[0].autotune = (!(dma_stat & 0x20));
551 hwif->drives[1].autotune = (!(dma_stat & 0x40)); 531 hwif->drives[1].autotune = (!(dma_stat & 0x40));
552} 532}
553 533
554/*
555 * We allow the BM-DMA driver to only work on enabled interfaces.
556 */
557static void __devinit init_dma_svwks (ide_hwif_t *hwif, unsigned long dmabase)
558{
559 struct pci_dev *dev = hwif->pci_dev;
560
561 if (((dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE) ||
562 (dev->device == PCI_DEVICE_ID_SERVERWORKS_CSB6IDE2)) &&
563 (!(PCI_FUNC(dev->devfn) & 1)) && (hwif->channel))
564 return;
565
566 ide_setup_dma(hwif, dmabase, 8);
567}
568
569static int __devinit init_setup_svwks (struct pci_dev *dev, ide_pci_device_t *d) 534static int __devinit init_setup_svwks (struct pci_dev *dev, ide_pci_device_t *d)
570{ 535{
571 return ide_setup_pci_device(dev, d); 536 return ide_setup_pci_device(dev, d);
@@ -600,7 +565,6 @@ static ide_pci_device_t serverworks_chipsets[] __devinitdata = {
600 .init_setup = init_setup_svwks, 565 .init_setup = init_setup_svwks,
601 .init_chipset = init_chipset_svwks, 566 .init_chipset = init_chipset_svwks,
602 .init_hwif = init_hwif_svwks, 567 .init_hwif = init_hwif_svwks,
603 .init_dma = init_dma_svwks,
604 .channels = 2, 568 .channels = 2,
605 .autodma = AUTODMA, 569 .autodma = AUTODMA,
606 .bootable = ON_BOARD, 570 .bootable = ON_BOARD,
@@ -609,7 +573,6 @@ static ide_pci_device_t serverworks_chipsets[] __devinitdata = {
609 .init_setup = init_setup_csb6, 573 .init_setup = init_setup_csb6,
610 .init_chipset = init_chipset_svwks, 574 .init_chipset = init_chipset_svwks,
611 .init_hwif = init_hwif_svwks, 575 .init_hwif = init_hwif_svwks,
612 .init_dma = init_dma_svwks,
613 .channels = 2, 576 .channels = 2,
614 .autodma = AUTODMA, 577 .autodma = AUTODMA,
615 .bootable = ON_BOARD, 578 .bootable = ON_BOARD,
@@ -618,7 +581,6 @@ static ide_pci_device_t serverworks_chipsets[] __devinitdata = {
618 .init_setup = init_setup_csb6, 581 .init_setup = init_setup_csb6,
619 .init_chipset = init_chipset_svwks, 582 .init_chipset = init_chipset_svwks,
620 .init_hwif = init_hwif_svwks, 583 .init_hwif = init_hwif_svwks,
621 .init_dma = init_dma_svwks,
622 .channels = 1, /* 2 */ 584 .channels = 1, /* 2 */
623 .autodma = AUTODMA, 585 .autodma = AUTODMA,
624 .bootable = ON_BOARD, 586 .bootable = ON_BOARD,
@@ -627,7 +589,6 @@ static ide_pci_device_t serverworks_chipsets[] __devinitdata = {
627 .init_setup = init_setup_svwks, 589 .init_setup = init_setup_svwks,
628 .init_chipset = init_chipset_svwks, 590 .init_chipset = init_chipset_svwks,
629 .init_hwif = init_hwif_svwks, 591 .init_hwif = init_hwif_svwks,
630 .init_dma = init_dma_svwks,
631 .channels = 1, /* 2 */ 592 .channels = 1, /* 2 */
632 .autodma = AUTODMA, 593 .autodma = AUTODMA,
633 .bootable = ON_BOARD, 594 .bootable = ON_BOARD,
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index b0bf01809279..fd09b295a69d 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -110,24 +110,24 @@ sgiioc4_init_hwif_ports(hw_regs_t * hw, unsigned long data_port,
110static void 110static void
111sgiioc4_maskproc(ide_drive_t * drive, int mask) 111sgiioc4_maskproc(ide_drive_t * drive, int mask)
112{ 112{
113 ide_hwif_t *hwif = HWIF(drive); 113 writeb(mask ? (drive->ctl | 2) : (drive->ctl & ~2),
114 hwif->OUTB(mask ? (drive->ctl | 2) : (drive->ctl & ~2), 114 (void __iomem *)IDE_CONTROL_REG);
115 IDE_CONTROL_REG);
116} 115}
117 116
118 117
119static int 118static int
120sgiioc4_checkirq(ide_hwif_t * hwif) 119sgiioc4_checkirq(ide_hwif_t * hwif)
121{ 120{
122 u8 intr_reg = 121 unsigned long intr_addr =
123 hwif->INL(hwif->io_ports[IDE_IRQ_OFFSET] + IOC4_INTR_REG * 4); 122 hwif->io_ports[IDE_IRQ_OFFSET] + IOC4_INTR_REG * 4;
124 123
125 if (intr_reg & 0x03) 124 if ((u8)readl((void __iomem *)intr_addr) & 0x03)
126 return 1; 125 return 1;
127 126
128 return 0; 127 return 0;
129} 128}
130 129
130static u8 sgiioc4_INB(unsigned long);
131 131
132static int 132static int
133sgiioc4_clearirq(ide_drive_t * drive) 133sgiioc4_clearirq(ide_drive_t * drive)
@@ -138,21 +138,21 @@ sgiioc4_clearirq(ide_drive_t * drive)
138 hwif->io_ports[IDE_IRQ_OFFSET] + (IOC4_INTR_REG << 2); 138 hwif->io_ports[IDE_IRQ_OFFSET] + (IOC4_INTR_REG << 2);
139 139
140 /* Code to check for PCI error conditions */ 140 /* Code to check for PCI error conditions */
141 intr_reg = hwif->INL(other_ir); 141 intr_reg = readl((void __iomem *)other_ir);
142 if (intr_reg & 0x03) { /* Valid IOC4-IDE interrupt */ 142 if (intr_reg & 0x03) { /* Valid IOC4-IDE interrupt */
143 /* 143 /*
144 * Using hwif->INB to read the IDE_STATUS_REG has a side effect 144 * Using sgiioc4_INB to read the IDE_STATUS_REG has a side effect
145 * of clearing the interrupt. The first read should clear it 145 * of clearing the interrupt. The first read should clear it
146 * if it is set. The second read should return a "clear" status 146 * if it is set. The second read should return a "clear" status
147 * if it got cleared. If not, then spin for a bit trying to 147 * if it got cleared. If not, then spin for a bit trying to
148 * clear it. 148 * clear it.
149 */ 149 */
150 u8 stat = hwif->INB(IDE_STATUS_REG); 150 u8 stat = sgiioc4_INB(IDE_STATUS_REG);
151 int count = 0; 151 int count = 0;
152 stat = hwif->INB(IDE_STATUS_REG); 152 stat = sgiioc4_INB(IDE_STATUS_REG);
153 while ((stat & 0x80) && (count++ < 100)) { 153 while ((stat & 0x80) && (count++ < 100)) {
154 udelay(1); 154 udelay(1);
155 stat = hwif->INB(IDE_STATUS_REG); 155 stat = sgiioc4_INB(IDE_STATUS_REG);
156 } 156 }
157 157
158 if (intr_reg & 0x02) { 158 if (intr_reg & 0x02) {
@@ -161,9 +161,9 @@ sgiioc4_clearirq(ide_drive_t * drive)
161 pci_stat_cmd_reg; 161 pci_stat_cmd_reg;
162 162
163 pci_err_addr_low = 163 pci_err_addr_low =
164 hwif->INL(hwif->io_ports[IDE_IRQ_OFFSET]); 164 readl((void __iomem *)hwif->io_ports[IDE_IRQ_OFFSET]);
165 pci_err_addr_high = 165 pci_err_addr_high =
166 hwif->INL(hwif->io_ports[IDE_IRQ_OFFSET] + 4); 166 readl((void __iomem *)(hwif->io_ports[IDE_IRQ_OFFSET] + 4));
167 pci_read_config_dword(hwif->pci_dev, PCI_COMMAND, 167 pci_read_config_dword(hwif->pci_dev, PCI_COMMAND,
168 &pci_stat_cmd_reg); 168 &pci_stat_cmd_reg);
169 printk(KERN_ERR 169 printk(KERN_ERR
@@ -180,9 +180,9 @@ sgiioc4_clearirq(ide_drive_t * drive)
180 } 180 }
181 181
182 /* Clear the Interrupt, Error bits on the IOC4 */ 182 /* Clear the Interrupt, Error bits on the IOC4 */
183 hwif->OUTL(0x03, other_ir); 183 writel(0x03, (void __iomem *)other_ir);
184 184
185 intr_reg = hwif->INL(other_ir); 185 intr_reg = readl((void __iomem *)other_ir);
186 } 186 }
187 187
188 return intr_reg & 3; 188 return intr_reg & 3;
@@ -191,23 +191,25 @@ sgiioc4_clearirq(ide_drive_t * drive)
191static void sgiioc4_ide_dma_start(ide_drive_t * drive) 191static void sgiioc4_ide_dma_start(ide_drive_t * drive)
192{ 192{
193 ide_hwif_t *hwif = HWIF(drive); 193 ide_hwif_t *hwif = HWIF(drive);
194 unsigned int reg = hwif->INL(hwif->dma_base + IOC4_DMA_CTRL * 4); 194 unsigned long ioc4_dma_addr = hwif->dma_base + IOC4_DMA_CTRL * 4;
195 unsigned int reg = readl((void __iomem *)ioc4_dma_addr);
195 unsigned int temp_reg = reg | IOC4_S_DMA_START; 196 unsigned int temp_reg = reg | IOC4_S_DMA_START;
196 197
197 hwif->OUTL(temp_reg, hwif->dma_base + IOC4_DMA_CTRL * 4); 198 writel(temp_reg, (void __iomem *)ioc4_dma_addr);
198} 199}
199 200
200static u32 201static u32
201sgiioc4_ide_dma_stop(ide_hwif_t *hwif, u64 dma_base) 202sgiioc4_ide_dma_stop(ide_hwif_t *hwif, u64 dma_base)
202{ 203{
204 unsigned long ioc4_dma_addr = dma_base + IOC4_DMA_CTRL * 4;
203 u32 ioc4_dma; 205 u32 ioc4_dma;
204 int count; 206 int count;
205 207
206 count = 0; 208 count = 0;
207 ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4); 209 ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
208 while ((ioc4_dma & IOC4_S_DMA_STOP) && (count++ < 200)) { 210 while ((ioc4_dma & IOC4_S_DMA_STOP) && (count++ < 200)) {
209 udelay(1); 211 udelay(1);
210 ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4); 212 ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
211 } 213 }
212 return ioc4_dma; 214 return ioc4_dma;
213} 215}
@@ -218,11 +220,11 @@ sgiioc4_ide_dma_end(ide_drive_t * drive)
218{ 220{
219 u32 ioc4_dma, bc_dev, bc_mem, num, valid = 0, cnt = 0; 221 u32 ioc4_dma, bc_dev, bc_mem, num, valid = 0, cnt = 0;
220 ide_hwif_t *hwif = HWIF(drive); 222 ide_hwif_t *hwif = HWIF(drive);
221 u64 dma_base = hwif->dma_base; 223 unsigned long dma_base = hwif->dma_base;
222 int dma_stat = 0; 224 int dma_stat = 0;
223 unsigned long *ending_dma = ide_get_hwifdata(hwif); 225 unsigned long *ending_dma = ide_get_hwifdata(hwif);
224 226
225 hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4); 227 writel(IOC4_S_DMA_STOP, (void __iomem *)(dma_base + IOC4_DMA_CTRL * 4));
226 228
227 ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base); 229 ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
228 230
@@ -254,8 +256,8 @@ sgiioc4_ide_dma_end(ide_drive_t * drive)
254 dma_stat = 1; 256 dma_stat = 1;
255 } 257 }
256 258
257 bc_dev = hwif->INL(dma_base + IOC4_BC_DEV * 4); 259 bc_dev = readl((void __iomem *)(dma_base + IOC4_BC_DEV * 4));
258 bc_mem = hwif->INL(dma_base + IOC4_BC_MEM * 4); 260 bc_mem = readl((void __iomem *)(dma_base + IOC4_BC_MEM * 4));
259 261
260 if ((bc_dev & 0x01FF) || (bc_mem & 0x1FF)) { 262 if ((bc_dev & 0x01FF) || (bc_mem & 0x1FF)) {
261 if (bc_dev > bc_mem + 8) { 263 if (bc_dev > bc_mem + 8) {
@@ -273,34 +275,29 @@ sgiioc4_ide_dma_end(ide_drive_t * drive)
273} 275}
274 276
275static int 277static int
276sgiioc4_ide_dma_check(ide_drive_t * drive) 278sgiioc4_ide_dma_on(ide_drive_t * drive)
277{ 279{
278 if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) { 280 drive->using_dma = 1;
279 printk(KERN_INFO
280 "Couldnot set %s in Multimode-2 DMA mode | "
281 "Drive %s using PIO instead\n",
282 drive->name, drive->name);
283 drive->using_dma = 0;
284 } else
285 drive->using_dma = 1;
286 281
287 return 0; 282 return 0;
288} 283}
289 284
290static int 285static void sgiioc4_dma_off_quietly(ide_drive_t *drive)
291sgiioc4_ide_dma_on(ide_drive_t * drive)
292{ 286{
293 drive->using_dma = 1; 287 drive->using_dma = 0;
294 288
295 return HWIF(drive)->ide_dma_host_on(drive); 289 drive->hwif->dma_host_off(drive);
296} 290}
297 291
298static int 292static int sgiioc4_ide_dma_check(ide_drive_t *drive)
299sgiioc4_ide_dma_off_quietly(ide_drive_t * drive)
300{ 293{
301 drive->using_dma = 0; 294 /* FIXME: check for available DMA modes */
302 295 if (ide_config_drive_speed(drive, XFER_MW_DMA_2) != 0) {
303 return HWIF(drive)->ide_dma_host_off(drive); 296 printk(KERN_WARNING "%s: couldn't set MWDMA2 mode, "
297 "using PIO instead\n", drive->name);
298 return -1;
299 } else
300 return 0;
304} 301}
305 302
306/* returns 1 if dma irq issued, 0 otherwise */ 303/* returns 1 if dma irq issued, 0 otherwise */
@@ -310,21 +307,13 @@ sgiioc4_ide_dma_test_irq(ide_drive_t * drive)
310 return sgiioc4_checkirq(HWIF(drive)); 307 return sgiioc4_checkirq(HWIF(drive));
311} 308}
312 309
313static int 310static void sgiioc4_dma_host_on(ide_drive_t * drive)
314sgiioc4_ide_dma_host_on(ide_drive_t * drive)
315{ 311{
316 if (drive->using_dma)
317 return 0;
318
319 return 1;
320} 312}
321 313
322static int 314static void sgiioc4_dma_host_off(ide_drive_t * drive)
323sgiioc4_ide_dma_host_off(ide_drive_t * drive)
324{ 315{
325 sgiioc4_clearirq(drive); 316 sgiioc4_clearirq(drive);
326
327 return 0;
328} 317}
329 318
330static int 319static int
@@ -436,16 +425,17 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
436{ 425{
437 u32 ioc4_dma; 426 u32 ioc4_dma;
438 ide_hwif_t *hwif = HWIF(drive); 427 ide_hwif_t *hwif = HWIF(drive);
439 u64 dma_base = hwif->dma_base; 428 unsigned long dma_base = hwif->dma_base;
429 unsigned long ioc4_dma_addr = dma_base + IOC4_DMA_CTRL * 4;
440 u32 dma_addr, ending_dma_addr; 430 u32 dma_addr, ending_dma_addr;
441 431
442 ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4); 432 ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
443 433
444 if (ioc4_dma & IOC4_S_DMA_ACTIVE) { 434 if (ioc4_dma & IOC4_S_DMA_ACTIVE) {
445 printk(KERN_WARNING 435 printk(KERN_WARNING
446 "%s(%s):Warning!! DMA from previous transfer was still active\n", 436 "%s(%s):Warning!! DMA from previous transfer was still active\n",
447 __FUNCTION__, drive->name); 437 __FUNCTION__, drive->name);
448 hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4); 438 writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr);
449 ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base); 439 ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
450 440
451 if (ioc4_dma & IOC4_S_DMA_STOP) 441 if (ioc4_dma & IOC4_S_DMA_STOP)
@@ -454,13 +444,13 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
454 __FUNCTION__, drive->name); 444 __FUNCTION__, drive->name);
455 } 445 }
456 446
457 ioc4_dma = hwif->INL(dma_base + IOC4_DMA_CTRL * 4); 447 ioc4_dma = readl((void __iomem *)ioc4_dma_addr);
458 if (ioc4_dma & IOC4_S_DMA_ERROR) { 448 if (ioc4_dma & IOC4_S_DMA_ERROR) {
459 printk(KERN_WARNING 449 printk(KERN_WARNING
460 "%s(%s) : Warning!! - DMA Error during Previous" 450 "%s(%s) : Warning!! - DMA Error during Previous"
461 " transfer | status 0x%x\n", 451 " transfer | status 0x%x\n",
462 __FUNCTION__, drive->name, ioc4_dma); 452 __FUNCTION__, drive->name, ioc4_dma);
463 hwif->OUTL(IOC4_S_DMA_STOP, dma_base + IOC4_DMA_CTRL * 4); 453 writel(IOC4_S_DMA_STOP, (void __iomem *)ioc4_dma_addr);
464 ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base); 454 ioc4_dma = sgiioc4_ide_dma_stop(hwif, dma_base);
465 455
466 if (ioc4_dma & IOC4_S_DMA_STOP) 456 if (ioc4_dma & IOC4_S_DMA_STOP)
@@ -471,14 +461,14 @@ sgiioc4_configure_for_dma(int dma_direction, ide_drive_t * drive)
471 461
472 /* Address of the Scatter Gather List */ 462 /* Address of the Scatter Gather List */
473 dma_addr = cpu_to_le32(hwif->dmatable_dma); 463 dma_addr = cpu_to_le32(hwif->dmatable_dma);
474 hwif->OUTL(dma_addr, dma_base + IOC4_DMA_PTR_L * 4); 464 writel(dma_addr, (void __iomem *)(dma_base + IOC4_DMA_PTR_L * 4));
475 465
476 /* Address of the Ending DMA */ 466 /* Address of the Ending DMA */
477 memset(ide_get_hwifdata(hwif), 0, IOC4_IDE_CACHELINE_SIZE); 467 memset(ide_get_hwifdata(hwif), 0, IOC4_IDE_CACHELINE_SIZE);
478 ending_dma_addr = cpu_to_le32(hwif->dma_status); 468 ending_dma_addr = cpu_to_le32(hwif->dma_status);
479 hwif->OUTL(ending_dma_addr, dma_base + IOC4_DMA_END_ADDR * 4); 469 writel(ending_dma_addr, (void __iomem *)(dma_base + IOC4_DMA_END_ADDR * 4));
480 470
481 hwif->OUTL(dma_direction, dma_base + IOC4_DMA_CTRL * 4); 471 writel(dma_direction, (void __iomem *)ioc4_dma_addr);
482 drive->waiting_for_dma = 1; 472 drive->waiting_for_dma = 1;
483} 473}
484 474
@@ -590,7 +580,7 @@ static int sgiioc4_ide_dma_setup(ide_drive_t *drive)
590static void __devinit 580static void __devinit
591ide_init_sgiioc4(ide_hwif_t * hwif) 581ide_init_sgiioc4(ide_hwif_t * hwif)
592{ 582{
593 hwif->mmio = 2; 583 hwif->mmio = 1;
594 hwif->autodma = 1; 584 hwif->autodma = 1;
595 hwif->atapi_dma = 1; 585 hwif->atapi_dma = 1;
596 hwif->ultra_mask = 0x0; /* Disable Ultra DMA */ 586 hwif->ultra_mask = 0x0; /* Disable Ultra DMA */
@@ -613,10 +603,10 @@ ide_init_sgiioc4(ide_hwif_t * hwif)
613 hwif->ide_dma_end = &sgiioc4_ide_dma_end; 603 hwif->ide_dma_end = &sgiioc4_ide_dma_end;
614 hwif->ide_dma_check = &sgiioc4_ide_dma_check; 604 hwif->ide_dma_check = &sgiioc4_ide_dma_check;
615 hwif->ide_dma_on = &sgiioc4_ide_dma_on; 605 hwif->ide_dma_on = &sgiioc4_ide_dma_on;
616 hwif->ide_dma_off_quietly = &sgiioc4_ide_dma_off_quietly; 606 hwif->dma_off_quietly = &sgiioc4_dma_off_quietly;
617 hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq; 607 hwif->ide_dma_test_irq = &sgiioc4_ide_dma_test_irq;
618 hwif->ide_dma_host_on = &sgiioc4_ide_dma_host_on; 608 hwif->dma_host_on = &sgiioc4_dma_host_on;
619 hwif->ide_dma_host_off = &sgiioc4_ide_dma_host_off; 609 hwif->dma_host_off = &sgiioc4_dma_host_off;
620 hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq; 610 hwif->ide_dma_lostirq = &sgiioc4_ide_dma_lostirq;
621 hwif->ide_dma_timeout = &__ide_dma_timeout; 611 hwif->ide_dma_timeout = &__ide_dma_timeout;
622 612
@@ -688,7 +678,7 @@ sgiioc4_ide_setup_pci_device(struct pci_dev *dev, ide_pci_device_t * d)
688 default_hwif_mmiops(hwif); 678 default_hwif_mmiops(hwif);
689 679
690 /* Initializing chipset IRQ Registers */ 680 /* Initializing chipset IRQ Registers */
691 hwif->OUTL(0x03, irqport + IOC4_INTR_SET * 4); 681 writel(0x03, (void __iomem *)(irqport + IOC4_INTR_SET * 4));
692 682
693 ide_init_sgiioc4(hwif); 683 ide_init_sgiioc4(hwif);
694 684
@@ -729,8 +719,7 @@ out:
729 return ret; 719 return ret;
730} 720}
731 721
732static ide_pci_device_t sgiioc4_chipsets[] __devinitdata = { 722static ide_pci_device_t sgiioc4_chipset __devinitdata = {
733 {
734 /* Channel 0 */ 723 /* Channel 0 */
735 .name = "SGIIOC4", 724 .name = "SGIIOC4",
736 .init_hwif = ide_init_sgiioc4, 725 .init_hwif = ide_init_sgiioc4,
@@ -739,7 +728,6 @@ static ide_pci_device_t sgiioc4_chipsets[] __devinitdata = {
739 .autodma = AUTODMA, 728 .autodma = AUTODMA,
740 /* SGI IOC4 doesn't have enablebits. */ 729 /* SGI IOC4 doesn't have enablebits. */
741 .bootable = ON_BOARD, 730 .bootable = ON_BOARD,
742 }
743}; 731};
744 732
745int 733int
@@ -751,8 +739,7 @@ ioc4_ide_attach_one(struct ioc4_driver_data *idd)
751 if (idd->idd_variant == IOC4_VARIANT_PCI_RT) 739 if (idd->idd_variant == IOC4_VARIANT_PCI_RT)
752 return 0; 740 return 0;
753 741
754 return pci_init_sgiioc4(idd->idd_pdev, 742 return pci_init_sgiioc4(idd->idd_pdev, &sgiioc4_chipset);
755 &sgiioc4_chipsets[idd->idd_pci_id->driver_data]);
756} 743}
757 744
758static struct ioc4_submodule ioc4_ide_submodule = { 745static struct ioc4_submodule ioc4_ide_submodule = {
diff --git a/drivers/ide/pci/siimage.c b/drivers/ide/pci/siimage.c
index 4ff89c7d990a..7b4c189a9d99 100644
--- a/drivers/ide/pci/siimage.c
+++ b/drivers/ide/pci/siimage.c
@@ -1,8 +1,9 @@
1/* 1/*
2 * linux/drivers/ide/pci/siimage.c Version 1.07 Nov 30, 2003 2 * linux/drivers/ide/pci/siimage.c Version 1.11 Jan 27, 2007
3 * 3 *
4 * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org> 4 * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org>
5 * Copyright (C) 2003 Red Hat <alan@redhat.com> 5 * Copyright (C) 2003 Red Hat <alan@redhat.com>
6 * Copyright (C) 2007 MontaVista Software, Inc.
6 * 7 *
7 * May be copied or modified under the terms of the GNU General Public License 8 * May be copied or modified under the terms of the GNU General Public License
8 * 9 *
@@ -205,41 +206,39 @@ static void siimage_tuneproc (ide_drive_t *drive, byte mode_wanted)
205 unsigned long tfaddr = siimage_selreg(hwif, 0x02); 206 unsigned long tfaddr = siimage_selreg(hwif, 0x02);
206 207
207 /* cheat for now and use the docs */ 208 /* cheat for now and use the docs */
208 switch(mode_wanted) { 209 switch (mode_wanted) {
209 case 4: 210 case 4:
210 speedp = 0x10c1; 211 speedp = 0x10c1;
211 speedt = 0x10c1; 212 speedt = 0x10c1;
212 break; 213 break;
213 case 3: 214 case 3:
214 speedp = 0x10C3; 215 speedp = 0x10c3;
215 speedt = 0x10C3; 216 speedt = 0x10c3;
216 break; 217 break;
217 case 2: 218 case 2:
218 speedp = 0x1104; 219 speedp = 0x1104;
219 speedt = 0x1281; 220 speedt = 0x1281;
220 break; 221 break;
221 case 1: 222 case 1:
222 speedp = 0x2283; 223 speedp = 0x2283;
223 speedt = 0x1281; 224 speedt = 0x2283;
224 break; 225 break;
225 case 0: 226 case 0:
226 default: 227 default:
227 speedp = 0x328A; 228 speedp = 0x328a;
228 speedt = 0x328A; 229 speedt = 0x328a;
229 break; 230 break;
230 } 231 }
231 if (hwif->mmio) 232
232 { 233 if (hwif->mmio) {
233 hwif->OUTW(speedt, addr); 234 hwif->OUTW(speedp, addr);
234 hwif->OUTW(speedp, tfaddr); 235 hwif->OUTW(speedt, tfaddr);
235 /* Now set up IORDY */ 236 /* Now set up IORDY */
236 if(mode_wanted == 3 || mode_wanted == 4) 237 if(mode_wanted == 3 || mode_wanted == 4)
237 hwif->OUTW(hwif->INW(tfaddr-2)|0x200, tfaddr-2); 238 hwif->OUTW(hwif->INW(tfaddr-2)|0x200, tfaddr-2);
238 else 239 else
239 hwif->OUTW(hwif->INW(tfaddr-2)&~0x200, tfaddr-2); 240 hwif->OUTW(hwif->INW(tfaddr-2)&~0x200, tfaddr-2);
240 } 241 } else {
241 else
242 {
243 pci_write_config_word(hwif->pci_dev, addr, speedp); 242 pci_write_config_word(hwif->pci_dev, addr, speedp);
244 pci_write_config_word(hwif->pci_dev, tfaddr, speedt); 243 pci_write_config_word(hwif->pci_dev, tfaddr, speedt);
245 pci_read_config_word(hwif->pci_dev, tfaddr-2, &speedp); 244 pci_read_config_word(hwif->pci_dev, tfaddr-2, &speedp);
@@ -397,12 +396,9 @@ static int config_chipset_for_dma (ide_drive_t *drive)
397 if (!speed) 396 if (!speed)
398 return 0; 397 return 0;
399 398
400 if (ide_set_xfer_rate(drive, speed)) 399 if (siimage_tune_chipset(drive, speed))
401 return 0; 400 return 0;
402 401
403 if (!drive->init_speed)
404 drive->init_speed = speed;
405
406 return ide_dma_enable(drive); 402 return ide_dma_enable(drive);
407} 403}
408 404
@@ -418,25 +414,13 @@ static int config_chipset_for_dma (ide_drive_t *drive)
418 414
419static int siimage_config_drive_for_dma (ide_drive_t *drive) 415static int siimage_config_drive_for_dma (ide_drive_t *drive)
420{ 416{
421 ide_hwif_t *hwif = HWIF(drive); 417 if (ide_use_dma(drive) && config_chipset_for_dma(drive))
422 struct hd_driveid *id = drive->id; 418 return 0;
423
424 if ((id->capability & 1) != 0 && drive->autodma) {
425
426 if (ide_use_dma(drive)) {
427 if (config_chipset_for_dma(drive))
428 return hwif->ide_dma_on(drive);
429 }
430
431 goto fast_ata_pio;
432 419
433 } else if ((id->capability & 8) || (id->field_valid & 2)) { 420 if (ide_use_fast_pio(drive))
434fast_ata_pio:
435 config_chipset_for_pio(drive, 1); 421 config_chipset_for_pio(drive, 1);
436 return hwif->ide_dma_off_quietly(drive); 422
437 } 423 return -1;
438 /* IORDY not supported */
439 return 0;
440} 424}
441 425
442/* returns 1 if dma irq issued, 0 otherwise */ 426/* returns 1 if dma irq issued, 0 otherwise */
@@ -472,11 +456,11 @@ static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive)
472 unsigned long addr = siimage_selreg(hwif, 0x1); 456 unsigned long addr = siimage_selreg(hwif, 0x1);
473 457
474 if (SATA_ERROR_REG) { 458 if (SATA_ERROR_REG) {
475 u32 ext_stat = hwif->INL(base + 0x10); 459 u32 ext_stat = readl((void __iomem *)(base + 0x10));
476 u8 watchdog = 0; 460 u8 watchdog = 0;
477 if (ext_stat & ((hwif->channel) ? 0x40 : 0x10)) { 461 if (ext_stat & ((hwif->channel) ? 0x40 : 0x10)) {
478 u32 sata_error = hwif->INL(SATA_ERROR_REG); 462 u32 sata_error = readl((void __iomem *)SATA_ERROR_REG);
479 hwif->OUTL(sata_error, SATA_ERROR_REG); 463 writel(sata_error, (void __iomem *)SATA_ERROR_REG);
480 watchdog = (sata_error & 0x00680000) ? 1 : 0; 464 watchdog = (sata_error & 0x00680000) ? 1 : 0;
481 printk(KERN_WARNING "%s: sata_error = 0x%08x, " 465 printk(KERN_WARNING "%s: sata_error = 0x%08x, "
482 "watchdog = %d, %s\n", 466 "watchdog = %d, %s\n",
@@ -493,11 +477,11 @@ static int siimage_mmio_ide_dma_test_irq (ide_drive_t *drive)
493 } 477 }
494 478
495 /* return 1 if INTR asserted */ 479 /* return 1 if INTR asserted */
496 if ((hwif->INB(hwif->dma_status) & 0x04) == 0x04) 480 if ((readb((void __iomem *)hwif->dma_status) & 0x04) == 0x04)
497 return 1; 481 return 1;
498 482
499 /* return 1 if Device INTR asserted */ 483 /* return 1 if Device INTR asserted */
500 if ((hwif->INB(addr) & 8) == 8) 484 if ((readb((void __iomem *)addr) & 8) == 8)
501 return 0; //return 1; 485 return 0; //return 1;
502 486
503 return 0; 487 return 0;
@@ -519,9 +503,9 @@ static int siimage_busproc (ide_drive_t * drive, int state)
519 u32 stat_config = 0; 503 u32 stat_config = 0;
520 unsigned long addr = siimage_selreg(hwif, 0); 504 unsigned long addr = siimage_selreg(hwif, 0);
521 505
522 if (hwif->mmio) { 506 if (hwif->mmio)
523 stat_config = hwif->INL(addr); 507 stat_config = readl((void __iomem *)addr);
524 } else 508 else
525 pci_read_config_dword(hwif->pci_dev, addr, &stat_config); 509 pci_read_config_dword(hwif->pci_dev, addr, &stat_config);
526 510
527 switch (state) { 511 switch (state) {
@@ -557,9 +541,10 @@ static int siimage_reset_poll (ide_drive_t *drive)
557 if (SATA_STATUS_REG) { 541 if (SATA_STATUS_REG) {
558 ide_hwif_t *hwif = HWIF(drive); 542 ide_hwif_t *hwif = HWIF(drive);
559 543
560 if ((hwif->INL(SATA_STATUS_REG) & 0x03) != 0x03) { 544 /* SATA_STATUS_REG is valid only when in MMIO mode */
545 if ((readl((void __iomem *)SATA_STATUS_REG) & 0x03) != 0x03) {
561 printk(KERN_WARNING "%s: reset phy dead, status=0x%08x\n", 546 printk(KERN_WARNING "%s: reset phy dead, status=0x%08x\n",
562 hwif->name, hwif->INL(SATA_STATUS_REG)); 547 hwif->name, readl((void __iomem *)SATA_STATUS_REG));
563 HWGROUP(drive)->polling = 0; 548 HWGROUP(drive)->polling = 0;
564 return ide_started; 549 return ide_started;
565 } 550 }
@@ -619,7 +604,8 @@ static void siimage_reset (ide_drive_t *drive)
619 } 604 }
620 605
621 if (SATA_STATUS_REG) { 606 if (SATA_STATUS_REG) {
622 u32 sata_stat = hwif->INL(SATA_STATUS_REG); 607 /* SATA_STATUS_REG is valid only when in MMIO mode */
608 u32 sata_stat = readl((void __iomem *)SATA_STATUS_REG);
623 printk(KERN_WARNING "%s: reset phy, status=0x%08x, %s\n", 609 printk(KERN_WARNING "%s: reset phy, status=0x%08x, %s\n",
624 hwif->name, sata_stat, __FUNCTION__); 610 hwif->name, sata_stat, __FUNCTION__);
625 if (!(sata_stat)) { 611 if (!(sata_stat)) {
@@ -898,7 +884,8 @@ static void __devinit init_mmio_iops_siimage(ide_hwif_t *hwif)
898 base = (unsigned long) addr; 884 base = (unsigned long) addr;
899 885
900 hwif->dma_base = base + (ch ? 0x08 : 0x00); 886 hwif->dma_base = base + (ch ? 0x08 : 0x00);
901 hwif->mmio = 2; 887
888 hwif->mmio = 1;
902} 889}
903 890
904static int is_dev_seagate_sata(ide_drive_t *drive) 891static int is_dev_seagate_sata(ide_drive_t *drive)
diff --git a/drivers/ide/pci/sis5513.c b/drivers/ide/pci/sis5513.c
index 1afff659ab55..2ba0669f36a1 100644
--- a/drivers/ide/pci/sis5513.c
+++ b/drivers/ide/pci/sis5513.c
@@ -667,67 +667,20 @@ static int config_chipset_for_dma (ide_drive_t *drive)
667 return ide_dma_enable(drive); 667 return ide_dma_enable(drive);
668} 668}
669 669
670static int sis5513_config_drive_xfer_rate (ide_drive_t *drive) 670static int sis5513_config_xfer_rate(ide_drive_t *drive)
671{ 671{
672 ide_hwif_t *hwif = HWIF(drive); 672 config_art_rwp_pio(drive, 5);
673 struct hd_driveid *id = drive->id;
674 673
675 drive->init_speed = 0; 674 drive->init_speed = 0;
676 675
677 if (id && (id->capability & 1) && drive->autodma) { 676 if (ide_use_dma(drive) && config_chipset_for_dma(drive))
678 677 return 0;
679 if (ide_use_dma(drive)) {
680 if (config_chipset_for_dma(drive))
681 return hwif->ide_dma_on(drive);
682 }
683
684 goto fast_ata_pio;
685 678
686 } else if ((id->capability & 8) || (id->field_valid & 2)) { 679 if (ide_use_fast_pio(drive))
687fast_ata_pio:
688 sis5513_tune_drive(drive, 5); 680 sis5513_tune_drive(drive, 5);
689 return hwif->ide_dma_off_quietly(drive);
690 }
691 /* IORDY not supported */
692 return 0;
693}
694
695/* initiates/aborts (U)DMA read/write operations on a drive. */
696static int sis5513_config_xfer_rate (ide_drive_t *drive)
697{
698 config_drive_art_rwp(drive);
699 config_art_rwp_pio(drive, 5);
700 return sis5513_config_drive_xfer_rate(drive);
701}
702
703/*
704 Future simpler config_xfer_rate :
705 When ide_find_best_mode is made bad-drive aware
706 - remove config_drive_xfer_rate and config_chipset_for_dma,
707 - replace config_xfer_rate with the following
708
709static int sis5513_config_xfer_rate (ide_drive_t *drive)
710{
711 u16 w80 = HWIF(drive)->udma_four;
712 u16 speed;
713
714 config_drive_art_rwp(drive);
715 config_art_rwp_pio(drive, 5);
716
717 speed = ide_find_best_mode(drive,
718 XFER_PIO | XFER_EPIO | XFER_SWDMA | XFER_MWDMA |
719 (chipset_family >= ATA_33 ? XFER_UDMA : 0) |
720 (w80 && chipset_family >= ATA_66 ? XFER_UDMA_66 : 0) |
721 (w80 && chipset_family >= ATA_100a ? XFER_UDMA_100 : 0) |
722 (w80 && chipset_family >= ATA_133a ? XFER_UDMA_133 : 0));
723
724 sis5513_tune_chipset(drive, speed);
725 681
726 if (drive->autodma && (speed & XFER_MODE) != XFER_PIO) 682 return -1;
727 return HWIF(drive)->ide_dma_on(drive);
728 return HWIF(drive)->ide_dma_off_quietly(drive);
729} 683}
730*/
731 684
732/* Chip detection and general config */ 685/* Chip detection and general config */
733static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const char *name) 686static unsigned int __devinit init_chipset_sis5513 (struct pci_dev *dev, const char *name)
diff --git a/drivers/ide/pci/sl82c105.c b/drivers/ide/pci/sl82c105.c
index 170a26199050..3a8a76fc78c7 100644
--- a/drivers/ide/pci/sl82c105.c
+++ b/drivers/ide/pci/sl82c105.c
@@ -161,14 +161,14 @@ static int sl82c105_check_drive (ide_drive_t *drive)
161 if (id->field_valid & 2) { 161 if (id->field_valid & 2) {
162 if ((id->dma_mword & hwif->mwdma_mask) || 162 if ((id->dma_mword & hwif->mwdma_mask) ||
163 (id->dma_1word & hwif->swdma_mask)) 163 (id->dma_1word & hwif->swdma_mask))
164 return hwif->ide_dma_on(drive); 164 return 0;
165 } 165 }
166 166
167 if (__ide_dma_good_drive(drive)) 167 if (__ide_dma_good_drive(drive) && id->eide_dma_time < 150)
168 return hwif->ide_dma_on(drive); 168 return 0;
169 } while (0); 169 } while (0);
170 170
171 return hwif->ide_dma_off_quietly(drive); 171 return -1;
172} 172}
173 173
174/* 174/*
@@ -215,7 +215,7 @@ static int sl82c105_ide_dma_lost_irq(ide_drive_t *drive)
215 * Was DMA enabled? If so, disable it - we're resetting the 215 * Was DMA enabled? If so, disable it - we're resetting the
216 * host. The IDE layer will be handling the drive for us. 216 * host. The IDE layer will be handling the drive for us.
217 */ 217 */
218 val = hwif->INB(dma_base); 218 val = inb(dma_base);
219 if (val & 1) { 219 if (val & 1) {
220 outb(val & ~1, dma_base); 220 outb(val & ~1, dma_base);
221 printk("sl82c105: DMA was enabled\n"); 221 printk("sl82c105: DMA was enabled\n");
@@ -259,28 +259,22 @@ static int sl82c105_ide_dma_on (ide_drive_t *drive)
259{ 259{
260 DBG(("sl82c105_ide_dma_on(drive:%s)\n", drive->name)); 260 DBG(("sl82c105_ide_dma_on(drive:%s)\n", drive->name));
261 261
262 if (config_for_dma(drive)) { 262 if (config_for_dma(drive))
263 config_for_pio(drive, 4, 0, 0); 263 return 1;
264 return HWIF(drive)->ide_dma_off_quietly(drive);
265 }
266 printk(KERN_INFO "%s: DMA enabled\n", drive->name); 264 printk(KERN_INFO "%s: DMA enabled\n", drive->name);
267 return __ide_dma_on(drive); 265 return __ide_dma_on(drive);
268} 266}
269 267
270static int sl82c105_ide_dma_off_quietly (ide_drive_t *drive) 268static void sl82c105_dma_off_quietly(ide_drive_t *drive)
271{ 269{
272 u8 speed = XFER_PIO_0; 270 u8 speed = XFER_PIO_0;
273 int rc;
274
275 DBG(("sl82c105_ide_dma_off_quietly(drive:%s)\n", drive->name));
276 271
277 rc = __ide_dma_off_quietly(drive); 272 DBG(("sl82c105_dma_off_quietly(drive:%s)\n", drive->name));
273
274 ide_dma_off_quietly(drive);
278 if (drive->pio_speed) 275 if (drive->pio_speed)
279 speed = drive->pio_speed - XFER_PIO_0; 276 speed = drive->pio_speed - XFER_PIO_0;
280 config_for_pio(drive, speed, 0, 1); 277 config_for_pio(drive, speed, 0, 1);
281 drive->current_speed = drive->pio_speed;
282
283 return rc;
284} 278}
285 279
286/* 280/*
@@ -401,11 +395,9 @@ static unsigned int __devinit init_chipset_sl82c105(struct pci_dev *dev, const c
401/* 395/*
402 * Initialise the chip 396 * Initialise the chip
403 */ 397 */
404
405static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif) 398static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
406{ 399{
407 unsigned int rev; 400 unsigned int rev;
408 u8 dma_state;
409 401
410 DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index)); 402 DBG(("init_hwif_sl82c105(hwif: ide%d)\n", hwif->index));
411 403
@@ -431,7 +423,6 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
431 if (!hwif->dma_base) 423 if (!hwif->dma_base)
432 return; 424 return;
433 425
434 dma_state = hwif->INB(hwif->dma_base + 2) & ~0x60;
435 rev = sl82c105_bridge_revision(hwif->pci_dev); 426 rev = sl82c105_bridge_revision(hwif->pci_dev);
436 if (rev <= 5) { 427 if (rev <= 5) {
437 /* 428 /*
@@ -441,15 +432,12 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
441 printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n", 432 printk(" %s: Winbond 553 bridge revision %d, BM-DMA disabled\n",
442 hwif->name, rev); 433 hwif->name, rev);
443 } else { 434 } else {
444 dma_state |= 0x60;
445
446 hwif->atapi_dma = 1; 435 hwif->atapi_dma = 1;
447 hwif->mwdma_mask = 0x07; 436 hwif->mwdma_mask = 0x04;
448 hwif->swdma_mask = 0x07;
449 437
450 hwif->ide_dma_check = &sl82c105_check_drive; 438 hwif->ide_dma_check = &sl82c105_check_drive;
451 hwif->ide_dma_on = &sl82c105_ide_dma_on; 439 hwif->ide_dma_on = &sl82c105_ide_dma_on;
452 hwif->ide_dma_off_quietly = &sl82c105_ide_dma_off_quietly; 440 hwif->dma_off_quietly = &sl82c105_dma_off_quietly;
453 hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq; 441 hwif->ide_dma_lostirq = &sl82c105_ide_dma_lost_irq;
454 hwif->dma_start = &sl82c105_ide_dma_start; 442 hwif->dma_start = &sl82c105_ide_dma_start;
455 hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout; 443 hwif->ide_dma_timeout = &sl82c105_ide_dma_timeout;
@@ -462,7 +450,6 @@ static void __devinit init_hwif_sl82c105(ide_hwif_t *hwif)
462 if (hwif->mate) 450 if (hwif->mate)
463 hwif->serialized = hwif->mate->serialized = 1; 451 hwif->serialized = hwif->mate->serialized = 1;
464 } 452 }
465 hwif->OUTB(dma_state, hwif->dma_base + 2);
466} 453}
467 454
468static ide_pci_device_t sl82c105_chipset __devinitdata = { 455static ide_pci_device_t sl82c105_chipset __devinitdata = {
diff --git a/drivers/ide/pci/slc90e66.c b/drivers/ide/pci/slc90e66.c
index 2663ddbd9b67..ae7eb58d961c 100644
--- a/drivers/ide/pci/slc90e66.c
+++ b/drivers/ide/pci/slc90e66.c
@@ -179,26 +179,16 @@ static int slc90e66_config_drive_for_dma (ide_drive_t *drive)
179 179
180static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive) 180static int slc90e66_config_drive_xfer_rate (ide_drive_t *drive)
181{ 181{
182 ide_hwif_t *hwif = HWIF(drive);
183 struct hd_driveid *id = drive->id;
184
185 drive->init_speed = 0; 182 drive->init_speed = 0;
186 183
187 if ((id->capability & 1) && drive->autodma) { 184 if (ide_use_dma(drive) && slc90e66_config_drive_for_dma(drive))
188 185 return 0;
189 if (ide_use_dma(drive) && slc90e66_config_drive_for_dma(drive))
190 return hwif->ide_dma_on(drive);
191 186
192 goto fast_ata_pio; 187 if (ide_use_fast_pio(drive))
188 (void)slc90e66_tune_chipset(drive, XFER_PIO_0 +
189 ide_get_best_pio_mode(drive, 255, 4, NULL));
193 190
194 } else if ((id->capability & 8) || (id->field_valid & 2)) { 191 return -1;
195fast_ata_pio:
196 (void) hwif->speedproc(drive, XFER_PIO_0 +
197 ide_get_best_pio_mode(drive, 255, 4, NULL));
198 return hwif->ide_dma_off_quietly(drive);
199 }
200 /* IORDY not supported */
201 return 0;
202} 192}
203 193
204static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif) 194static void __devinit init_hwif_slc90e66 (ide_hwif_t *hwif)
diff --git a/drivers/ide/pci/tc86c001.c b/drivers/ide/pci/tc86c001.c
index 2ad72bbda342..0b6d81d6ce48 100644
--- a/drivers/ide/pci/tc86c001.c
+++ b/drivers/ide/pci/tc86c001.c
@@ -45,7 +45,7 @@ static int tc86c001_tune_chipset(ide_drive_t *drive, u8 speed)
45 45
46 scr &= (speed < XFER_MW_DMA_0) ? 0xf8ff : 0xff0f; 46 scr &= (speed < XFER_MW_DMA_0) ? 0xf8ff : 0xff0f;
47 scr |= mode; 47 scr |= mode;
48 hwif->OUTW(scr, scr_port); 48 outw(scr, scr_port);
49 49
50 return ide_config_drive_speed(drive, speed); 50 return ide_config_drive_speed(drive, speed);
51} 51}
@@ -89,15 +89,15 @@ static int tc86c001_timer_expiry(ide_drive_t *drive)
89 "attempting recovery...\n", drive->name); 89 "attempting recovery...\n", drive->name);
90 90
91 /* Stop DMA */ 91 /* Stop DMA */
92 hwif->OUTB(dma_cmd & ~0x01, hwif->dma_command); 92 outb(dma_cmd & ~0x01, hwif->dma_command);
93 93
94 /* Setup the dummy DMA transfer */ 94 /* Setup the dummy DMA transfer */
95 hwif->OUTW(0, sc_base + 0x0a); /* Sector Count */ 95 outw(0, sc_base + 0x0a); /* Sector Count */
96 hwif->OUTW(0, twcr_port); /* Transfer Word Count 1 or 2 */ 96 outw(0, twcr_port); /* Transfer Word Count 1 or 2 */
97 97
98 /* Start the dummy DMA transfer */ 98 /* Start the dummy DMA transfer */
99 hwif->OUTB(0x00, hwif->dma_command); /* clear R_OR_WCTR for write */ 99 outb(0x00, hwif->dma_command); /* clear R_OR_WCTR for write */
100 hwif->OUTB(0x01, hwif->dma_command); /* set START_STOPBM */ 100 outb(0x01, hwif->dma_command); /* set START_STOPBM */
101 101
102 /* 102 /*
103 * If an interrupt was pending, it should come thru shortly. 103 * If an interrupt was pending, it should come thru shortly.
@@ -128,8 +128,8 @@ static void tc86c001_dma_start(ide_drive_t *drive)
128 * the appropriate system control registers for DMA to work 128 * the appropriate system control registers for DMA to work
129 * with LBA48 and ATAPI devices... 129 * with LBA48 and ATAPI devices...
130 */ 130 */
131 hwif->OUTW(nsectors, sc_base + 0x0a); /* Sector Count */ 131 outw(nsectors, sc_base + 0x0a); /* Sector Count */
132 hwif->OUTW(SECTOR_SIZE / 2, twcr_port); /* Transfer Word Count 1/2 */ 132 outw(SECTOR_SIZE / 2, twcr_port); /* Transfer Word Count 1/2 */
133 133
134 /* Install our timeout expiry hook, saving the current handler... */ 134 /* Install our timeout expiry hook, saving the current handler... */
135 ide_set_hwifdata(hwif, hwgroup->expiry); 135 ide_set_hwifdata(hwif, hwgroup->expiry);
@@ -168,7 +168,7 @@ static int tc86c001_busproc(ide_drive_t *drive, int state)
168 } 168 }
169 169
170 /* System Control 1 Register bit 11 (ATA Hard Reset) write */ 170 /* System Control 1 Register bit 11 (ATA Hard Reset) write */
171 hwif->OUTW(scr1, sc_base + 0x00); 171 outw(scr1, sc_base + 0x00);
172 return 0; 172 return 0;
173} 173}
174 174
@@ -185,23 +185,13 @@ static int config_chipset_for_dma(ide_drive_t *drive)
185 185
186static int tc86c001_config_drive_xfer_rate(ide_drive_t *drive) 186static int tc86c001_config_drive_xfer_rate(ide_drive_t *drive)
187{ 187{
188 ide_hwif_t *hwif = HWIF(drive); 188 if (ide_use_dma(drive) && config_chipset_for_dma(drive))
189 struct hd_driveid *id = drive->id; 189 return 0;
190
191 if ((id->capability & 1) && drive->autodma) {
192
193 if (ide_use_dma(drive) && config_chipset_for_dma(drive))
194 return hwif->ide_dma_on(drive);
195
196 goto fast_ata_pio;
197 190
198 } else if ((id->capability & 8) || (id->field_valid & 2)) { 191 if (ide_use_fast_pio(drive))
199fast_ata_pio:
200 tc86c001_tune_drive(drive, 255); 192 tc86c001_tune_drive(drive, 255);
201 return hwif->ide_dma_off_quietly(drive); 193
202 } 194 return -1;
203 /* IORDY not supported */
204 return 0;
205} 195}
206 196
207static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif) 197static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
@@ -210,13 +200,13 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
210 u16 scr1 = hwif->INW(sc_base + 0x00);; 200 u16 scr1 = hwif->INW(sc_base + 0x00);;
211 201
212 /* System Control 1 Register bit 15 (Soft Reset) set */ 202 /* System Control 1 Register bit 15 (Soft Reset) set */
213 hwif->OUTW(scr1 | 0x8000, sc_base + 0x00); 203 outw(scr1 | 0x8000, sc_base + 0x00);
214 204
215 /* System Control 1 Register bit 14 (FIFO Reset) set */ 205 /* System Control 1 Register bit 14 (FIFO Reset) set */
216 hwif->OUTW(scr1 | 0x4000, sc_base + 0x00); 206 outw(scr1 | 0x4000, sc_base + 0x00);
217 207
218 /* System Control 1 Register: reset clear */ 208 /* System Control 1 Register: reset clear */
219 hwif->OUTW(scr1 & ~0xc000, sc_base + 0x00); 209 outw(scr1 & ~0xc000, sc_base + 0x00);
220 210
221 /* Store the system control register base for convenience... */ 211 /* Store the system control register base for convenience... */
222 hwif->config_data = sc_base; 212 hwif->config_data = sc_base;
@@ -234,7 +224,7 @@ static void __devinit init_hwif_tc86c001(ide_hwif_t *hwif)
234 * Sector Count Control Register bits 0 and 1 set: 224 * Sector Count Control Register bits 0 and 1 set:
235 * software sets Sector Count Register for master and slave device 225 * software sets Sector Count Register for master and slave device
236 */ 226 */
237 hwif->OUTW(0x0003, sc_base + 0x0c); 227 outw(0x0003, sc_base + 0x0c);
238 228
239 /* Sector Count Register limit */ 229 /* Sector Count Register limit */
240 hwif->rqsize = 0xffff; 230 hwif->rqsize = 0xffff;
diff --git a/drivers/ide/pci/triflex.c b/drivers/ide/pci/triflex.c
index b13cce1fd1a6..5e06179c3469 100644
--- a/drivers/ide/pci/triflex.c
+++ b/drivers/ide/pci/triflex.c
@@ -104,29 +104,21 @@ static int triflex_config_drive_for_dma(ide_drive_t *drive)
104{ 104{
105 int speed = ide_dma_speed(drive, 0); /* No ultra speeds */ 105 int speed = ide_dma_speed(drive, 0); /* No ultra speeds */
106 106
107 if (!speed) { 107 if (!speed)
108 u8 pspeed = ide_get_best_pio_mode(drive, 255, 4, NULL); 108 return 0;
109 speed = XFER_PIO_0 + pspeed; 109
110 }
111
112 (void) triflex_tune_chipset(drive, speed); 110 (void) triflex_tune_chipset(drive, speed);
113 return ide_dma_enable(drive); 111 return ide_dma_enable(drive);
114} 112}
115 113
116static int triflex_config_drive_xfer_rate(ide_drive_t *drive) 114static int triflex_config_drive_xfer_rate(ide_drive_t *drive)
117{ 115{
118 ide_hwif_t *hwif = HWIF(drive); 116 if (ide_use_dma(drive) && triflex_config_drive_for_dma(drive))
119 struct hd_driveid *id = drive->id; 117 return 0;
120 118
121 if ((id->capability & 1) && drive->autodma) { 119 triflex_tune_drive(drive, 255);
122 if (ide_use_dma(drive)) {
123 if (triflex_config_drive_for_dma(drive))
124 return hwif->ide_dma_on(drive);
125 }
126 }
127 120
128 hwif->tuneproc(drive, 255); 121 return -1;
129 return hwif->ide_dma_off_quietly(drive);
130} 122}
131 123
132static void __devinit init_hwif_triflex(ide_hwif_t *hwif) 124static void __devinit init_hwif_triflex(ide_hwif_t *hwif)
diff --git a/drivers/ide/pci/trm290.c b/drivers/ide/pci/trm290.c
index 174b88c4780e..cbb1b11119a5 100644
--- a/drivers/ide/pci/trm290.c
+++ b/drivers/ide/pci/trm290.c
@@ -157,16 +157,16 @@ static void trm290_prepare_drive (ide_drive_t *drive, unsigned int use_dma)
157 if (reg != hwif->select_data) { 157 if (reg != hwif->select_data) {
158 hwif->select_data = reg; 158 hwif->select_data = reg;
159 /* set PIO/DMA */ 159 /* set PIO/DMA */
160 hwif->OUTB(0x51|(hwif->channel<<3), hwif->config_data+1); 160 outb(0x51 | (hwif->channel << 3), hwif->config_data + 1);
161 hwif->OUTW(reg & 0xff, hwif->config_data); 161 outw(reg & 0xff, hwif->config_data);
162 } 162 }
163 163
164 /* enable IRQ if not probing */ 164 /* enable IRQ if not probing */
165 if (drive->present) { 165 if (drive->present) {
166 reg = hwif->INW(hwif->config_data + 3); 166 reg = inw(hwif->config_data + 3);
167 reg &= 0x13; 167 reg &= 0x13;
168 reg &= ~(1 << hwif->channel); 168 reg &= ~(1 << hwif->channel);
169 hwif->OUTW(reg, hwif->config_data+3); 169 outw(reg, hwif->config_data + 3);
170 } 170 }
171 171
172 local_irq_restore(flags); 172 local_irq_restore(flags);
@@ -177,15 +177,12 @@ static void trm290_selectproc (ide_drive_t *drive)
177 trm290_prepare_drive(drive, drive->using_dma); 177 trm290_prepare_drive(drive, drive->using_dma);
178} 178}
179 179
180#ifdef CONFIG_BLK_DEV_IDEDMA
181static void trm290_ide_dma_exec_cmd(ide_drive_t *drive, u8 command) 180static void trm290_ide_dma_exec_cmd(ide_drive_t *drive, u8 command)
182{ 181{
183 ide_hwif_t *hwif = HWIF(drive);
184
185 BUG_ON(HWGROUP(drive)->handler != NULL); /* paranoia check */ 182 BUG_ON(HWGROUP(drive)->handler != NULL); /* paranoia check */
186 ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL); 183 ide_set_handler(drive, &ide_dma_intr, WAIT_CMD, NULL);
187 /* issue cmd to drive */ 184 /* issue cmd to drive */
188 hwif->OUTB(command, IDE_COMMAND_REG); 185 outb(command, IDE_COMMAND_REG);
189} 186}
190 187
191static int trm290_ide_dma_setup(ide_drive_t *drive) 188static int trm290_ide_dma_setup(ide_drive_t *drive)
@@ -211,10 +208,10 @@ static int trm290_ide_dma_setup(ide_drive_t *drive)
211 } 208 }
212 /* select DMA xfer */ 209 /* select DMA xfer */
213 trm290_prepare_drive(drive, 1); 210 trm290_prepare_drive(drive, 1);
214 hwif->OUTL(hwif->dmatable_dma|rw, hwif->dma_command); 211 outl(hwif->dmatable_dma | rw, hwif->dma_command);
215 drive->waiting_for_dma = 1; 212 drive->waiting_for_dma = 1;
216 /* start DMA */ 213 /* start DMA */
217 hwif->OUTW((count * 2) - 1, hwif->dma_status); 214 outw((count * 2) - 1, hwif->dma_status);
218 return 0; 215 return 0;
219} 216}
220 217
@@ -230,7 +227,7 @@ static int trm290_ide_dma_end (ide_drive_t *drive)
230 drive->waiting_for_dma = 0; 227 drive->waiting_for_dma = 0;
231 /* purge DMA mappings */ 228 /* purge DMA mappings */
232 ide_destroy_dmatable(drive); 229 ide_destroy_dmatable(drive);
233 status = hwif->INW(hwif->dma_status); 230 status = inw(hwif->dma_status);
234 return (status != 0x00ff); 231 return (status != 0x00ff);
235} 232}
236 233
@@ -239,10 +236,9 @@ static int trm290_ide_dma_test_irq (ide_drive_t *drive)
239 ide_hwif_t *hwif = HWIF(drive); 236 ide_hwif_t *hwif = HWIF(drive);
240 u16 status = 0; 237 u16 status = 0;
241 238
242 status = hwif->INW(hwif->dma_status); 239 status = inw(hwif->dma_status);
243 return (status == 0x00ff); 240 return (status == 0x00ff);
244} 241}
245#endif /* CONFIG_BLK_DEV_IDEDMA */
246 242
247/* 243/*
248 * Invoked from ide-dma.c at boot time. 244 * Invoked from ide-dma.c at boot time.
@@ -269,15 +265,15 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
269 265
270 local_irq_save(flags); 266 local_irq_save(flags);
271 /* put config reg into first byte of hwif->select_data */ 267 /* put config reg into first byte of hwif->select_data */
272 hwif->OUTB(0x51|(hwif->channel<<3), hwif->config_data+1); 268 outb(0x51 | (hwif->channel << 3), hwif->config_data + 1);
273 /* select PIO as default */ 269 /* select PIO as default */
274 hwif->select_data = 0x21; 270 hwif->select_data = 0x21;
275 hwif->OUTB(hwif->select_data, hwif->config_data); 271 outb(hwif->select_data, hwif->config_data);
276 /* get IRQ info */ 272 /* get IRQ info */
277 reg = hwif->INB(hwif->config_data+3); 273 reg = inb(hwif->config_data + 3);
278 /* mask IRQs for both ports */ 274 /* mask IRQs for both ports */
279 reg = (reg & 0x10) | 0x03; 275 reg = (reg & 0x10) | 0x03;
280 hwif->OUTB(reg, hwif->config_data+3); 276 outb(reg, hwif->config_data + 3);
281 local_irq_restore(flags); 277 local_irq_restore(flags);
282 278
283 if ((reg & 0x10)) 279 if ((reg & 0x10))
@@ -289,13 +285,11 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
289 285
290 ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->channel ? 0x0080 : 0x0000), 3); 286 ide_setup_dma(hwif, (hwif->config_data + 4) ^ (hwif->channel ? 0x0080 : 0x0000), 3);
291 287
292#ifdef CONFIG_BLK_DEV_IDEDMA
293 hwif->dma_setup = &trm290_ide_dma_setup; 288 hwif->dma_setup = &trm290_ide_dma_setup;
294 hwif->dma_exec_cmd = &trm290_ide_dma_exec_cmd; 289 hwif->dma_exec_cmd = &trm290_ide_dma_exec_cmd;
295 hwif->dma_start = &trm290_ide_dma_start; 290 hwif->dma_start = &trm290_ide_dma_start;
296 hwif->ide_dma_end = &trm290_ide_dma_end; 291 hwif->ide_dma_end = &trm290_ide_dma_end;
297 hwif->ide_dma_test_irq = &trm290_ide_dma_test_irq; 292 hwif->ide_dma_test_irq = &trm290_ide_dma_test_irq;
298#endif /* CONFIG_BLK_DEV_IDEDMA */
299 293
300 hwif->selectproc = &trm290_selectproc; 294 hwif->selectproc = &trm290_selectproc;
301 hwif->autodma = 0; /* play it safe for now */ 295 hwif->autodma = 0; /* play it safe for now */
@@ -312,16 +306,16 @@ static void __devinit init_hwif_trm290(ide_hwif_t *hwif)
312 static u16 next_offset = 0; 306 static u16 next_offset = 0;
313 u8 old_mask; 307 u8 old_mask;
314 308
315 hwif->OUTB(0x54|(hwif->channel<<3), hwif->config_data+1); 309 outb(0x54 | (hwif->channel << 3), hwif->config_data + 1);
316 old = hwif->INW(hwif->config_data); 310 old = inw(hwif->config_data);
317 old &= ~1; 311 old &= ~1;
318 old_mask = hwif->INB(old+2); 312 old_mask = inb(old + 2);
319 if (old != compat && old_mask == 0xff) { 313 if (old != compat && old_mask == 0xff) {
320 /* leave lower 10 bits untouched */ 314 /* leave lower 10 bits untouched */
321 compat += (next_offset += 0x400); 315 compat += (next_offset += 0x400);
322 hwif->io_ports[IDE_CONTROL_OFFSET] = compat + 2; 316 hwif->io_ports[IDE_CONTROL_OFFSET] = compat + 2;
323 hwif->OUTW(compat|1, hwif->config_data); 317 outw(compat | 1, hwif->config_data);
324 new = hwif->INW(hwif->config_data); 318 new = inw(hwif->config_data);
325 printk(KERN_INFO "%s: control basereg workaround: " 319 printk(KERN_INFO "%s: control basereg workaround: "
326 "old=0x%04x, new=0x%04x\n", 320 "old=0x%04x, new=0x%04x\n",
327 hwif->name, old, new & ~1); 321 hwif->name, old, new & ~1);
diff --git a/drivers/ide/pci/via82cxxx.c b/drivers/ide/pci/via82cxxx.c
index 6fb6e50b8231..a508550c4095 100644
--- a/drivers/ide/pci/via82cxxx.c
+++ b/drivers/ide/pci/via82cxxx.c
@@ -240,8 +240,9 @@ static int via82cxxx_ide_dma_check (ide_drive_t *drive)
240 via_set_drive(drive, speed); 240 via_set_drive(drive, speed);
241 241
242 if (drive->autodma && (speed & XFER_MODE) != XFER_PIO) 242 if (drive->autodma && (speed & XFER_MODE) != XFER_PIO)
243 return hwif->ide_dma_on(drive); 243 return 0;
244 return hwif->ide_dma_off_quietly(drive); 244
245 return -1;
245} 246}
246 247
247static struct via_isa_bridge *via_config_find(struct pci_dev **isa) 248static struct via_isa_bridge *via_config_find(struct pci_dev **isa)
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index d8ea23710bf0..395d35253d5d 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1237,7 +1237,7 @@ pmac_ide_setup_device(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
1237 hwif->OUTBSYNC = pmac_outbsync; 1237 hwif->OUTBSYNC = pmac_outbsync;
1238 1238
1239 /* Tell common code _not_ to mess with resources */ 1239 /* Tell common code _not_ to mess with resources */
1240 hwif->mmio = 2; 1240 hwif->mmio = 1;
1241 hwif->hwif_data = pmif; 1241 hwif->hwif_data = pmif;
1242 pmac_ide_init_hwif_ports(&hwif->hw, pmif->regbase, 0, &hwif->irq); 1242 pmac_ide_init_hwif_ports(&hwif->hw, pmif->regbase, 0, &hwif->irq);
1243 memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports)); 1243 memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
@@ -1979,16 +1979,12 @@ pmac_ide_dma_test_irq (ide_drive_t *drive)
1979 return 1; 1979 return 1;
1980} 1980}
1981 1981
1982static int 1982static void pmac_ide_dma_host_off(ide_drive_t *drive)
1983pmac_ide_dma_host_off (ide_drive_t *drive)
1984{ 1983{
1985 return 0;
1986} 1984}
1987 1985
1988static int 1986static int pmac_ide_dma_host_on(ide_drive_t *drive)
1989pmac_ide_dma_host_on (ide_drive_t *drive)
1990{ 1987{
1991 return 0;
1992} 1988}
1993 1989
1994static int 1990static int
@@ -2034,7 +2030,7 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
2034 return; 2030 return;
2035 } 2031 }
2036 2032
2037 hwif->ide_dma_off_quietly = &__ide_dma_off_quietly; 2033 hwif->dma_off_quietly = &ide_dma_off_quietly;
2038 hwif->ide_dma_on = &__ide_dma_on; 2034 hwif->ide_dma_on = &__ide_dma_on;
2039 hwif->ide_dma_check = &pmac_ide_dma_check; 2035 hwif->ide_dma_check = &pmac_ide_dma_check;
2040 hwif->dma_setup = &pmac_ide_dma_setup; 2036 hwif->dma_setup = &pmac_ide_dma_setup;
@@ -2042,8 +2038,8 @@ pmac_ide_setup_dma(pmac_ide_hwif_t *pmif, ide_hwif_t *hwif)
2042 hwif->dma_start = &pmac_ide_dma_start; 2038 hwif->dma_start = &pmac_ide_dma_start;
2043 hwif->ide_dma_end = &pmac_ide_dma_end; 2039 hwif->ide_dma_end = &pmac_ide_dma_end;
2044 hwif->ide_dma_test_irq = &pmac_ide_dma_test_irq; 2040 hwif->ide_dma_test_irq = &pmac_ide_dma_test_irq;
2045 hwif->ide_dma_host_off = &pmac_ide_dma_host_off; 2041 hwif->dma_host_off = &pmac_ide_dma_host_off;
2046 hwif->ide_dma_host_on = &pmac_ide_dma_host_on; 2042 hwif->dma_host_on = &pmac_ide_dma_host_on;
2047 hwif->ide_dma_timeout = &__ide_dma_timeout; 2043 hwif->ide_dma_timeout = &__ide_dma_timeout;
2048 hwif->ide_dma_lostirq = &pmac_ide_dma_lostirq; 2044 hwif->ide_dma_lostirq = &pmac_ide_dma_lostirq;
2049 2045
diff --git a/drivers/ide/ppc/scc_pata.c b/drivers/ide/ppc/scc_pata.c
new file mode 100644
index 000000000000..de64b022478b
--- /dev/null
+++ b/drivers/ide/ppc/scc_pata.c
@@ -0,0 +1,831 @@
1/*
2 * Support for IDE interfaces on Celleb platform
3 *
4 * (C) Copyright 2006 TOSHIBA CORPORATION
5 *
6 * This code is based on drivers/ide/pci/siimage.c:
7 * Copyright (C) 2001-2002 Andre Hedrick <andre@linux-ide.org>
8 * Copyright (C) 2003 Red Hat <alan@redhat.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 of the License, or
13 * (at your option) 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 along
21 * with this program; if not, write to the Free Software Foundation, Inc.,
22 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 */
24
25#include <linux/types.h>
26#include <linux/module.h>
27#include <linux/pci.h>
28#include <linux/delay.h>
29#include <linux/hdreg.h>
30#include <linux/ide.h>
31#include <linux/init.h>
32
33#define PCI_DEVICE_ID_TOSHIBA_SCC_ATA 0x01b4
34
35#define SCC_PATA_NAME "scc IDE"
36
37#define TDVHSEL_MASTER 0x00000001
38#define TDVHSEL_SLAVE 0x00000004
39
40#define MODE_JCUSFEN 0x00000080
41
42#define CCKCTRL_ATARESET 0x00040000
43#define CCKCTRL_BUFCNT 0x00020000
44#define CCKCTRL_CRST 0x00010000
45#define CCKCTRL_OCLKEN 0x00000100
46#define CCKCTRL_ATACLKOEN 0x00000002
47#define CCKCTRL_LCLKEN 0x00000001
48
49#define QCHCD_IOS_SS 0x00000001
50
51#define QCHSD_STPDIAG 0x00020000
52
53#define INTMASK_MSK 0xD1000012
54#define INTSTS_SERROR 0x80000000
55#define INTSTS_PRERR 0x40000000
56#define INTSTS_RERR 0x10000000
57#define INTSTS_ICERR 0x01000000
58#define INTSTS_BMSINT 0x00000010
59#define INTSTS_BMHE 0x00000008
60#define INTSTS_IOIRQS 0x00000004
61#define INTSTS_INTRQ 0x00000002
62#define INTSTS_ACTEINT 0x00000001
63
64#define ECMODE_VALUE 0x01
65
66static struct scc_ports {
67 unsigned long ctl, dma;
68 unsigned char hwif_id; /* for removing hwif from system */
69} scc_ports[MAX_HWIFS];
70
71/* PIO transfer mode table */
72/* JCHST */
73static unsigned long JCHSTtbl[2][7] = {
74 {0x0E, 0x05, 0x02, 0x03, 0x02, 0x00, 0x00}, /* 100MHz */
75 {0x13, 0x07, 0x04, 0x04, 0x03, 0x00, 0x00} /* 133MHz */
76};
77
78/* JCHHT */
79static unsigned long JCHHTtbl[2][7] = {
80 {0x0E, 0x02, 0x02, 0x02, 0x02, 0x00, 0x00}, /* 100MHz */
81 {0x13, 0x03, 0x03, 0x03, 0x03, 0x00, 0x00} /* 133MHz */
82};
83
84/* JCHCT */
85static unsigned long JCHCTtbl[2][7] = {
86 {0x1D, 0x1D, 0x1C, 0x0B, 0x06, 0x00, 0x00}, /* 100MHz */
87 {0x27, 0x26, 0x26, 0x0E, 0x09, 0x00, 0x00} /* 133MHz */
88};
89
90
91/* DMA transfer mode table */
92/* JCHDCTM/JCHDCTS */
93static unsigned long JCHDCTxtbl[2][7] = {
94 {0x0A, 0x06, 0x04, 0x03, 0x01, 0x00, 0x00}, /* 100MHz */
95 {0x0E, 0x09, 0x06, 0x04, 0x02, 0x01, 0x00} /* 133MHz */
96};
97
98/* JCSTWTM/JCSTWTS */
99static unsigned long JCSTWTxtbl[2][7] = {
100 {0x06, 0x04, 0x03, 0x02, 0x02, 0x02, 0x00}, /* 100MHz */
101 {0x09, 0x06, 0x04, 0x02, 0x02, 0x02, 0x02} /* 133MHz */
102};
103
104/* JCTSS */
105static unsigned long JCTSStbl[2][7] = {
106 {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00}, /* 100MHz */
107 {0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05} /* 133MHz */
108};
109
110/* JCENVT */
111static unsigned long JCENVTtbl[2][7] = {
112 {0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x00}, /* 100MHz */
113 {0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02} /* 133MHz */
114};
115
116/* JCACTSELS/JCACTSELM */
117static unsigned long JCACTSELtbl[2][7] = {
118 {0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00}, /* 100MHz */
119 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01} /* 133MHz */
120};
121
122
123static u8 scc_ide_inb(unsigned long port)
124{
125 u32 data = in_be32((void*)port);
126 return (u8)data;
127}
128
129static u16 scc_ide_inw(unsigned long port)
130{
131 u32 data = in_be32((void*)port);
132 return (u16)data;
133}
134
135static void scc_ide_insw(unsigned long port, void *addr, u32 count)
136{
137 u16 *ptr = (u16 *)addr;
138 while (count--) {
139 *ptr++ = le16_to_cpu(in_be32((void*)port));
140 }
141}
142
143static void scc_ide_insl(unsigned long port, void *addr, u32 count)
144{
145 u16 *ptr = (u16 *)addr;
146 while (count--) {
147 *ptr++ = le16_to_cpu(in_be32((void*)port));
148 *ptr++ = le16_to_cpu(in_be32((void*)port));
149 }
150}
151
152static void scc_ide_outb(u8 addr, unsigned long port)
153{
154 out_be32((void*)port, addr);
155}
156
157static void scc_ide_outw(u16 addr, unsigned long port)
158{
159 out_be32((void*)port, addr);
160}
161
162static void
163scc_ide_outbsync(ide_drive_t * drive, u8 addr, unsigned long port)
164{
165 ide_hwif_t *hwif = HWIF(drive);
166
167 out_be32((void*)port, addr);
168 __asm__ __volatile__("eieio":::"memory");
169 in_be32((void*)(hwif->dma_base + 0x01c));
170 __asm__ __volatile__("eieio":::"memory");
171}
172
173static void
174scc_ide_outsw(unsigned long port, void *addr, u32 count)
175{
176 u16 *ptr = (u16 *)addr;
177 while (count--) {
178 out_be32((void*)port, cpu_to_le16(*ptr++));
179 }
180}
181
182static void
183scc_ide_outsl(unsigned long port, void *addr, u32 count)
184{
185 u16 *ptr = (u16 *)addr;
186 while (count--) {
187 out_be32((void*)port, cpu_to_le16(*ptr++));
188 out_be32((void*)port, cpu_to_le16(*ptr++));
189 }
190}
191
192/**
193 * scc_ratemask - Compute available modes
194 * @drive: IDE drive
195 *
196 * Compute the available speeds for the devices on the interface.
197 * Enforce UDMA33 as a limit if there is no 80pin cable present.
198 */
199
200static u8 scc_ratemask(ide_drive_t *drive)
201{
202 u8 mode = 4;
203
204 if (!eighty_ninty_three(drive))
205 mode = min(mode, (u8)1);
206 return mode;
207}
208
209/**
210 * scc_tuneproc - tune a drive PIO mode
211 * @drive: drive to tune
212 * @mode_wanted: the target operating mode
213 *
214 * Load the timing settings for this device mode into the
215 * controller.
216 */
217
218static void scc_tuneproc(ide_drive_t *drive, byte mode_wanted)
219{
220 ide_hwif_t *hwif = HWIF(drive);
221 struct scc_ports *ports = ide_get_hwifdata(hwif);
222 unsigned long ctl_base = ports->ctl;
223 unsigned long cckctrl_port = ctl_base + 0xff0;
224 unsigned long piosht_port = ctl_base + 0x000;
225 unsigned long pioct_port = ctl_base + 0x004;
226 unsigned long reg;
227 unsigned char speed = XFER_PIO_0;
228 int offset;
229
230 mode_wanted = ide_get_best_pio_mode(drive, mode_wanted, 4, NULL);
231 switch (mode_wanted) {
232 case 4:
233 speed = XFER_PIO_4;
234 break;
235 case 3:
236 speed = XFER_PIO_3;
237 break;
238 case 2:
239 speed = XFER_PIO_2;
240 break;
241 case 1:
242 speed = XFER_PIO_1;
243 break;
244 case 0:
245 default:
246 speed = XFER_PIO_0;
247 break;
248 }
249
250 reg = in_be32((void __iomem *)cckctrl_port);
251 if (reg & CCKCTRL_ATACLKOEN) {
252 offset = 1; /* 133MHz */
253 } else {
254 offset = 0; /* 100MHz */
255 }
256 reg = JCHSTtbl[offset][mode_wanted] << 16 | JCHHTtbl[offset][mode_wanted];
257 out_be32((void __iomem *)piosht_port, reg);
258 reg = JCHCTtbl[offset][mode_wanted];
259 out_be32((void __iomem *)pioct_port, reg);
260
261 ide_config_drive_speed(drive, speed);
262}
263
264/**
265 * scc_tune_chipset - tune a drive DMA mode
266 * @drive: Drive to set up
267 * @xferspeed: speed we want to achieve
268 *
269 * Load the timing settings for this device mode into the
270 * controller.
271 */
272
273static int scc_tune_chipset(ide_drive_t *drive, byte xferspeed)
274{
275 ide_hwif_t *hwif = HWIF(drive);
276 u8 speed = ide_rate_filter(scc_ratemask(drive), xferspeed);
277 struct scc_ports *ports = ide_get_hwifdata(hwif);
278 unsigned long ctl_base = ports->ctl;
279 unsigned long cckctrl_port = ctl_base + 0xff0;
280 unsigned long mdmact_port = ctl_base + 0x008;
281 unsigned long mcrcst_port = ctl_base + 0x00c;
282 unsigned long sdmact_port = ctl_base + 0x010;
283 unsigned long scrcst_port = ctl_base + 0x014;
284 unsigned long udenvt_port = ctl_base + 0x018;
285 unsigned long tdvhsel_port = ctl_base + 0x020;
286 int is_slave = (&hwif->drives[1] == drive);
287 int offset, idx;
288 unsigned long reg;
289 unsigned long jcactsel;
290
291 reg = in_be32((void __iomem *)cckctrl_port);
292 if (reg & CCKCTRL_ATACLKOEN) {
293 offset = 1; /* 133MHz */
294 } else {
295 offset = 0; /* 100MHz */
296 }
297
298 switch (speed) {
299 case XFER_UDMA_6:
300 idx = 6;
301 break;
302 case XFER_UDMA_5:
303 idx = 5;
304 break;
305 case XFER_UDMA_4:
306 idx = 4;
307 break;
308 case XFER_UDMA_3:
309 idx = 3;
310 break;
311 case XFER_UDMA_2:
312 idx = 2;
313 break;
314 case XFER_UDMA_1:
315 idx = 1;
316 break;
317 case XFER_UDMA_0:
318 idx = 0;
319 break;
320 default:
321 return 1;
322 }
323
324 jcactsel = JCACTSELtbl[offset][idx];
325 if (is_slave) {
326 out_be32((void __iomem *)sdmact_port, JCHDCTxtbl[offset][idx]);
327 out_be32((void __iomem *)scrcst_port, JCSTWTxtbl[offset][idx]);
328 jcactsel = jcactsel << 2;
329 out_be32((void __iomem *)tdvhsel_port, (in_be32((void __iomem *)tdvhsel_port) & ~TDVHSEL_SLAVE) | jcactsel);
330 } else {
331 out_be32((void __iomem *)mdmact_port, JCHDCTxtbl[offset][idx]);
332 out_be32((void __iomem *)mcrcst_port, JCSTWTxtbl[offset][idx]);
333 out_be32((void __iomem *)tdvhsel_port, (in_be32((void __iomem *)tdvhsel_port) & ~TDVHSEL_MASTER) | jcactsel);
334 }
335 reg = JCTSStbl[offset][idx] << 16 | JCENVTtbl[offset][idx];
336 out_be32((void __iomem *)udenvt_port, reg);
337
338 return ide_config_drive_speed(drive, speed);
339}
340
341/**
342 * scc_config_chipset_for_dma - configure for DMA
343 * @drive: drive to configure
344 *
345 * Called by scc_config_drive_for_dma().
346 */
347
348static int scc_config_chipset_for_dma(ide_drive_t *drive)
349{
350 u8 speed = ide_dma_speed(drive, scc_ratemask(drive));
351
352 if (!speed)
353 return 0;
354
355 if (scc_tune_chipset(drive, speed))
356 return 0;
357
358 return ide_dma_enable(drive);
359}
360
361/**
362 * scc_configure_drive_for_dma - set up for DMA transfers
363 * @drive: drive we are going to set up
364 *
365 * Set up the drive for DMA, tune the controller and drive as
366 * required.
367 * If the drive isn't suitable for DMA or we hit other problems
368 * then we will drop down to PIO and set up PIO appropriately.
369 * (return 1)
370 */
371
372static int scc_config_drive_for_dma(ide_drive_t *drive)
373{
374 if (ide_use_dma(drive) && scc_config_chipset_for_dma(drive))
375 return 0;
376
377 if (ide_use_fast_pio(drive))
378 scc_tuneproc(drive, 4);
379
380 return -1;
381}
382
383/**
384 * scc_ide_dma_setup - begin a DMA phase
385 * @drive: target device
386 *
387 * Build an IDE DMA PRD (IDE speak for scatter gather table)
388 * and then set up the DMA transfer registers.
389 *
390 * Returns 0 on success. If a PIO fallback is required then 1
391 * is returned.
392 */
393
394static int scc_dma_setup(ide_drive_t *drive)
395{
396 ide_hwif_t *hwif = drive->hwif;
397 struct request *rq = HWGROUP(drive)->rq;
398 unsigned int reading;
399 u8 dma_stat;
400
401 if (rq_data_dir(rq))
402 reading = 0;
403 else
404 reading = 1 << 3;
405
406 /* fall back to pio! */
407 if (!ide_build_dmatable(drive, rq)) {
408 ide_map_sg(drive, rq);
409 return 1;
410 }
411
412 /* PRD table */
413 out_be32((void __iomem *)hwif->dma_prdtable, hwif->dmatable_dma);
414
415 /* specify r/w */
416 out_be32((void __iomem *)hwif->dma_command, reading);
417
418 /* read dma_status for INTR & ERROR flags */
419 dma_stat = in_be32((void __iomem *)hwif->dma_status);
420
421 /* clear INTR & ERROR flags */
422 out_be32((void __iomem *)hwif->dma_status, dma_stat|6);
423 drive->waiting_for_dma = 1;
424 return 0;
425}
426
427
428/**
429 * scc_ide_dma_end - Stop DMA
430 * @drive: IDE drive
431 *
432 * Check and clear INT Status register.
433 * Then call __ide_dma_end().
434 */
435
436static int scc_ide_dma_end(ide_drive_t * drive)
437{
438 ide_hwif_t *hwif = HWIF(drive);
439 unsigned long intsts_port = hwif->dma_base + 0x014;
440 u32 reg;
441
442 while (1) {
443 reg = in_be32((void __iomem *)intsts_port);
444
445 if (reg & INTSTS_SERROR) {
446 printk(KERN_WARNING "%s: SERROR\n", SCC_PATA_NAME);
447 out_be32((void __iomem *)intsts_port, INTSTS_SERROR|INTSTS_BMSINT);
448
449 out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS);
450 continue;
451 }
452
453 if (reg & INTSTS_PRERR) {
454 u32 maea0, maec0;
455 unsigned long ctl_base = hwif->config_data;
456
457 maea0 = in_be32((void __iomem *)(ctl_base + 0xF50));
458 maec0 = in_be32((void __iomem *)(ctl_base + 0xF54));
459
460 printk(KERN_WARNING "%s: PRERR [addr:%x cmd:%x]\n", SCC_PATA_NAME, maea0, maec0);
461
462 out_be32((void __iomem *)intsts_port, INTSTS_PRERR|INTSTS_BMSINT);
463
464 out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS);
465 continue;
466 }
467
468 if (reg & INTSTS_RERR) {
469 printk(KERN_WARNING "%s: Response Error\n", SCC_PATA_NAME);
470 out_be32((void __iomem *)intsts_port, INTSTS_RERR|INTSTS_BMSINT);
471
472 out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS);
473 continue;
474 }
475
476 if (reg & INTSTS_ICERR) {
477 out_be32((void __iomem *)hwif->dma_command, in_be32((void __iomem *)hwif->dma_command) & ~QCHCD_IOS_SS);
478
479 printk(KERN_WARNING "%s: Illegal Configuration\n", SCC_PATA_NAME);
480 out_be32((void __iomem *)intsts_port, INTSTS_ICERR|INTSTS_BMSINT);
481 continue;
482 }
483
484 if (reg & INTSTS_BMSINT) {
485 printk(KERN_WARNING "%s: Internal Bus Error\n", SCC_PATA_NAME);
486 out_be32((void __iomem *)intsts_port, INTSTS_BMSINT);
487
488 ide_do_reset(drive);
489 continue;
490 }
491
492 if (reg & INTSTS_BMHE) {
493 out_be32((void __iomem *)intsts_port, INTSTS_BMHE);
494 continue;
495 }
496
497 if (reg & INTSTS_ACTEINT) {
498 out_be32((void __iomem *)intsts_port, INTSTS_ACTEINT);
499 continue;
500 }
501
502 if (reg & INTSTS_IOIRQS) {
503 out_be32((void __iomem *)intsts_port, INTSTS_IOIRQS);
504 continue;
505 }
506 break;
507 }
508
509 return __ide_dma_end(drive);
510}
511
512/**
513 * setup_mmio_scc - map CTRL/BMID region
514 * @dev: PCI device we are configuring
515 * @name: device name
516 *
517 */
518
519static int setup_mmio_scc (struct pci_dev *dev, const char *name)
520{
521 unsigned long ctl_base = pci_resource_start(dev, 0);
522 unsigned long dma_base = pci_resource_start(dev, 1);
523 unsigned long ctl_size = pci_resource_len(dev, 0);
524 unsigned long dma_size = pci_resource_len(dev, 1);
525 void *ctl_addr;
526 void *dma_addr;
527 int i;
528
529 for (i = 0; i < MAX_HWIFS; i++) {
530 if (scc_ports[i].ctl == 0)
531 break;
532 }
533 if (i >= MAX_HWIFS)
534 return -ENOMEM;
535
536 if (!request_mem_region(ctl_base, ctl_size, name)) {
537 printk(KERN_WARNING "%s: IDE controller MMIO ports not available.\n", SCC_PATA_NAME);
538 goto fail_0;
539 }
540
541 if (!request_mem_region(dma_base, dma_size, name)) {
542 printk(KERN_WARNING "%s: IDE controller MMIO ports not available.\n", SCC_PATA_NAME);
543 goto fail_1;
544 }
545
546 if ((ctl_addr = ioremap(ctl_base, ctl_size)) == NULL)
547 goto fail_2;
548
549 if ((dma_addr = ioremap(dma_base, dma_size)) == NULL)
550 goto fail_3;
551
552 pci_set_master(dev);
553 scc_ports[i].ctl = (unsigned long)ctl_addr;
554 scc_ports[i].dma = (unsigned long)dma_addr;
555 pci_set_drvdata(dev, (void *) &scc_ports[i]);
556
557 return 1;
558
559 fail_3:
560 iounmap(ctl_addr);
561 fail_2:
562 release_mem_region(dma_base, dma_size);
563 fail_1:
564 release_mem_region(ctl_base, ctl_size);
565 fail_0:
566 return -ENOMEM;
567}
568
569/**
570 * init_setup_scc - set up an SCC PATA Controller
571 * @dev: PCI device
572 * @d: IDE PCI device
573 *
574 * Perform the initial set up for this device.
575 */
576
577static int __devinit init_setup_scc(struct pci_dev *dev, ide_pci_device_t *d)
578{
579 unsigned long ctl_base;
580 unsigned long dma_base;
581 unsigned long cckctrl_port;
582 unsigned long intmask_port;
583 unsigned long mode_port;
584 unsigned long ecmode_port;
585 unsigned long dma_status_port;
586 u32 reg = 0;
587 struct scc_ports *ports;
588 int rc;
589
590 rc = setup_mmio_scc(dev, d->name);
591 if (rc < 0) {
592 return rc;
593 }
594
595 ports = pci_get_drvdata(dev);
596 ctl_base = ports->ctl;
597 dma_base = ports->dma;
598 cckctrl_port = ctl_base + 0xff0;
599 intmask_port = dma_base + 0x010;
600 mode_port = ctl_base + 0x024;
601 ecmode_port = ctl_base + 0xf00;
602 dma_status_port = dma_base + 0x004;
603
604 /* controller initialization */
605 reg = 0;
606 out_be32((void*)cckctrl_port, reg);
607 reg |= CCKCTRL_ATACLKOEN;
608 out_be32((void*)cckctrl_port, reg);
609 reg |= CCKCTRL_LCLKEN | CCKCTRL_OCLKEN;
610 out_be32((void*)cckctrl_port, reg);
611 reg |= CCKCTRL_CRST;
612 out_be32((void*)cckctrl_port, reg);
613
614 for (;;) {
615 reg = in_be32((void*)cckctrl_port);
616 if (reg & CCKCTRL_CRST)
617 break;
618 udelay(5000);
619 }
620
621 reg |= CCKCTRL_ATARESET;
622 out_be32((void*)cckctrl_port, reg);
623
624 out_be32((void*)ecmode_port, ECMODE_VALUE);
625 out_be32((void*)mode_port, MODE_JCUSFEN);
626 out_be32((void*)intmask_port, INTMASK_MSK);
627
628 return ide_setup_pci_device(dev, d);
629}
630
631/**
632 * init_mmio_iops_scc - set up the iops for MMIO
633 * @hwif: interface to set up
634 *
635 */
636
637static void __devinit init_mmio_iops_scc(ide_hwif_t *hwif)
638{
639 struct pci_dev *dev = hwif->pci_dev;
640 struct scc_ports *ports = pci_get_drvdata(dev);
641 unsigned long dma_base = ports->dma;
642
643 ide_set_hwifdata(hwif, ports);
644
645 hwif->INB = scc_ide_inb;
646 hwif->INW = scc_ide_inw;
647 hwif->INSW = scc_ide_insw;
648 hwif->INSL = scc_ide_insl;
649 hwif->OUTB = scc_ide_outb;
650 hwif->OUTBSYNC = scc_ide_outbsync;
651 hwif->OUTW = scc_ide_outw;
652 hwif->OUTSW = scc_ide_outsw;
653 hwif->OUTSL = scc_ide_outsl;
654
655 hwif->io_ports[IDE_DATA_OFFSET] = dma_base + 0x20;
656 hwif->io_ports[IDE_ERROR_OFFSET] = dma_base + 0x24;
657 hwif->io_ports[IDE_NSECTOR_OFFSET] = dma_base + 0x28;
658 hwif->io_ports[IDE_SECTOR_OFFSET] = dma_base + 0x2c;
659 hwif->io_ports[IDE_LCYL_OFFSET] = dma_base + 0x30;
660 hwif->io_ports[IDE_HCYL_OFFSET] = dma_base + 0x34;
661 hwif->io_ports[IDE_SELECT_OFFSET] = dma_base + 0x38;
662 hwif->io_ports[IDE_STATUS_OFFSET] = dma_base + 0x3c;
663 hwif->io_ports[IDE_CONTROL_OFFSET] = dma_base + 0x40;
664
665 hwif->irq = hwif->pci_dev->irq;
666 hwif->dma_base = dma_base;
667 hwif->config_data = ports->ctl;
668 hwif->mmio = 1;
669}
670
671/**
672 * init_iops_scc - set up iops
673 * @hwif: interface to set up
674 *
675 * Do the basic setup for the SCC hardware interface
676 * and then do the MMIO setup.
677 */
678
679static void __devinit init_iops_scc(ide_hwif_t *hwif)
680{
681 struct pci_dev *dev = hwif->pci_dev;
682 hwif->hwif_data = NULL;
683 if (pci_get_drvdata(dev) == NULL)
684 return;
685 init_mmio_iops_scc(hwif);
686}
687
688/**
689 * init_hwif_scc - set up hwif
690 * @hwif: interface to set up
691 *
692 * We do the basic set up of the interface structure. The SCC
693 * requires several custom handlers so we override the default
694 * ide DMA handlers appropriately.
695 */
696
697static void __devinit init_hwif_scc(ide_hwif_t *hwif)
698{
699 struct scc_ports *ports = ide_get_hwifdata(hwif);
700
701 ports->hwif_id = hwif->index;
702
703 hwif->dma_command = hwif->dma_base;
704 hwif->dma_status = hwif->dma_base + 0x04;
705 hwif->dma_prdtable = hwif->dma_base + 0x08;
706
707 /* PTERADD */
708 out_be32((void __iomem *)(hwif->dma_base + 0x018), hwif->dmatable_dma);
709
710 hwif->dma_setup = scc_dma_setup;
711 hwif->ide_dma_end = scc_ide_dma_end;
712 hwif->speedproc = scc_tune_chipset;
713 hwif->tuneproc = scc_tuneproc;
714 hwif->ide_dma_check = scc_config_drive_for_dma;
715
716 hwif->drives[0].autotune = IDE_TUNE_AUTO;
717 hwif->drives[1].autotune = IDE_TUNE_AUTO;
718
719 if (in_be32((void __iomem *)(hwif->config_data + 0xff0)) & CCKCTRL_ATACLKOEN) {
720 hwif->ultra_mask = 0x7f; /* 133MHz */
721 } else {
722 hwif->ultra_mask = 0x3f; /* 100MHz */
723 }
724 hwif->mwdma_mask = 0x00;
725 hwif->swdma_mask = 0x00;
726 hwif->atapi_dma = 1;
727
728 /* we support 80c cable only. */
729 hwif->udma_four = 1;
730
731 hwif->autodma = 0;
732 if (!noautodma)
733 hwif->autodma = 1;
734 hwif->drives[0].autodma = hwif->autodma;
735 hwif->drives[1].autodma = hwif->autodma;
736}
737
738#define DECLARE_SCC_DEV(name_str) \
739 { \
740 .name = name_str, \
741 .init_setup = init_setup_scc, \
742 .init_iops = init_iops_scc, \
743 .init_hwif = init_hwif_scc, \
744 .channels = 1, \
745 .autodma = AUTODMA, \
746 .bootable = ON_BOARD, \
747 }
748
749static ide_pci_device_t scc_chipsets[] __devinitdata = {
750 /* 0 */ DECLARE_SCC_DEV("sccIDE"),
751};
752
753/**
754 * scc_init_one - pci layer discovery entry
755 * @dev: PCI device
756 * @id: ident table entry
757 *
758 * Called by the PCI code when it finds an SCC PATA controller.
759 * We then use the IDE PCI generic helper to do most of the work.
760 */
761
762static int __devinit scc_init_one(struct pci_dev *dev, const struct pci_device_id *id)
763{
764 ide_pci_device_t *d = &scc_chipsets[id->driver_data];
765 return d->init_setup(dev, d);
766}
767
768/**
769 * scc_remove - pci layer remove entry
770 * @dev: PCI device
771 *
772 * Called by the PCI code when it removes an SCC PATA controller.
773 */
774
775static void __devexit scc_remove(struct pci_dev *dev)
776{
777 struct scc_ports *ports = pci_get_drvdata(dev);
778 ide_hwif_t *hwif = &ide_hwifs[ports->hwif_id];
779 unsigned long ctl_base = pci_resource_start(dev, 0);
780 unsigned long dma_base = pci_resource_start(dev, 1);
781 unsigned long ctl_size = pci_resource_len(dev, 0);
782 unsigned long dma_size = pci_resource_len(dev, 1);
783
784 if (hwif->dmatable_cpu) {
785 pci_free_consistent(hwif->pci_dev,
786 PRD_ENTRIES * PRD_BYTES,
787 hwif->dmatable_cpu,
788 hwif->dmatable_dma);
789 hwif->dmatable_cpu = NULL;
790 }
791
792 ide_unregister(hwif->index);
793
794 hwif->chipset = ide_unknown;
795 iounmap((void*)ports->dma);
796 iounmap((void*)ports->ctl);
797 release_mem_region(dma_base, dma_size);
798 release_mem_region(ctl_base, ctl_size);
799 memset(ports, 0, sizeof(*ports));
800}
801
802static struct pci_device_id scc_pci_tbl[] = {
803 { PCI_VENDOR_ID_TOSHIBA_2, PCI_DEVICE_ID_TOSHIBA_SCC_ATA, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
804 { 0, },
805};
806MODULE_DEVICE_TABLE(pci, scc_pci_tbl);
807
808static struct pci_driver driver = {
809 .name = "SCC IDE",
810 .id_table = scc_pci_tbl,
811 .probe = scc_init_one,
812 .remove = scc_remove,
813};
814
815static int scc_ide_init(void)
816{
817 return ide_pci_register_driver(&driver);
818}
819
820module_init(scc_ide_init);
821/* -- No exit code?
822static void scc_ide_exit(void)
823{
824 ide_pci_unregister_driver(&driver);
825}
826module_exit(scc_ide_exit);
827 */
828
829
830MODULE_DESCRIPTION("PCI driver module for Toshiba SCC IDE");
831MODULE_LICENSE("GPL");
diff --git a/drivers/ieee1394/ieee1394-ioctl.h b/drivers/ieee1394/ieee1394-ioctl.h
index 8f207508ed1d..46878fef136c 100644
--- a/drivers/ieee1394/ieee1394-ioctl.h
+++ b/drivers/ieee1394/ieee1394-ioctl.h
@@ -100,5 +100,7 @@
100 _IO ('#', 0x28) 100 _IO ('#', 0x28)
101#define RAW1394_IOC_ISO_RECV_FLUSH \ 101#define RAW1394_IOC_ISO_RECV_FLUSH \
102 _IO ('#', 0x29) 102 _IO ('#', 0x29)
103#define RAW1394_IOC_GET_CYCLE_TIMER \
104 _IOR ('#', 0x30, struct raw1394_cycle_timer)
103 105
104#endif /* __IEEE1394_IOCTL_H */ 106#endif /* __IEEE1394_IOCTL_H */
diff --git a/drivers/ieee1394/ieee1394_core.c b/drivers/ieee1394/ieee1394_core.c
index 1521e57e124b..d791d08c743c 100644
--- a/drivers/ieee1394/ieee1394_core.c
+++ b/drivers/ieee1394/ieee1394_core.c
@@ -33,7 +33,10 @@
33#include <linux/skbuff.h> 33#include <linux/skbuff.h>
34#include <linux/suspend.h> 34#include <linux/suspend.h>
35#include <linux/kthread.h> 35#include <linux/kthread.h>
36#include <linux/preempt.h>
37#include <linux/time.h>
36 38
39#include <asm/system.h>
37#include <asm/byteorder.h> 40#include <asm/byteorder.h>
38 41
39#include "ieee1394_types.h" 42#include "ieee1394_types.h"
@@ -186,6 +189,45 @@ int hpsb_reset_bus(struct hpsb_host *host, int type)
186 } 189 }
187} 190}
188 191
192/**
193 * hpsb_read_cycle_timer - read cycle timer register and system time
194 * @host: host whose isochronous cycle timer register is read
195 * @cycle_timer: address of bitfield to return the register contents
196 * @local_time: address to return the system time
197 *
198 * The format of * @cycle_timer, is described in OHCI 1.1 clause 5.13. This
199 * format is also read from non-OHCI controllers. * @local_time contains the
200 * system time in microseconds since the Epoch, read at the moment when the
201 * cycle timer was read.
202 *
203 * Return value: 0 for success or error number otherwise.
204 */
205int hpsb_read_cycle_timer(struct hpsb_host *host, u32 *cycle_timer,
206 u64 *local_time)
207{
208 int ctr;
209 struct timeval tv;
210 unsigned long flags;
211
212 if (!host || !cycle_timer || !local_time)
213 return -EINVAL;
214
215 preempt_disable();
216 local_irq_save(flags);
217
218 ctr = host->driver->devctl(host, GET_CYCLE_COUNTER, 0);
219 if (ctr)
220 do_gettimeofday(&tv);
221
222 local_irq_restore(flags);
223 preempt_enable();
224
225 if (!ctr)
226 return -EIO;
227 *cycle_timer = ctr;
228 *local_time = tv.tv_sec * 1000000ULL + tv.tv_usec;
229 return 0;
230}
189 231
190int hpsb_bus_reset(struct hpsb_host *host) 232int hpsb_bus_reset(struct hpsb_host *host)
191{ 233{
@@ -1190,6 +1232,7 @@ EXPORT_SYMBOL(hpsb_alloc_packet);
1190EXPORT_SYMBOL(hpsb_free_packet); 1232EXPORT_SYMBOL(hpsb_free_packet);
1191EXPORT_SYMBOL(hpsb_send_packet); 1233EXPORT_SYMBOL(hpsb_send_packet);
1192EXPORT_SYMBOL(hpsb_reset_bus); 1234EXPORT_SYMBOL(hpsb_reset_bus);
1235EXPORT_SYMBOL(hpsb_read_cycle_timer);
1193EXPORT_SYMBOL(hpsb_bus_reset); 1236EXPORT_SYMBOL(hpsb_bus_reset);
1194EXPORT_SYMBOL(hpsb_selfid_received); 1237EXPORT_SYMBOL(hpsb_selfid_received);
1195EXPORT_SYMBOL(hpsb_selfid_complete); 1238EXPORT_SYMBOL(hpsb_selfid_complete);
diff --git a/drivers/ieee1394/ieee1394_core.h b/drivers/ieee1394/ieee1394_core.h
index 536ba3f580fd..bd29d8ef5bbd 100644
--- a/drivers/ieee1394/ieee1394_core.h
+++ b/drivers/ieee1394/ieee1394_core.h
@@ -127,6 +127,9 @@ int hpsb_send_packet_and_wait(struct hpsb_packet *packet);
127 * progress, 0 otherwise. */ 127 * progress, 0 otherwise. */
128int hpsb_reset_bus(struct hpsb_host *host, int type); 128int hpsb_reset_bus(struct hpsb_host *host, int type);
129 129
130int hpsb_read_cycle_timer(struct hpsb_host *host, u32 *cycle_timer,
131 u64 *local_time);
132
130/* 133/*
131 * The following functions are exported for host driver module usage. All of 134 * The following functions are exported for host driver module usage. All of
132 * them are safe to use in interrupt contexts, although some are quite 135 * them are safe to use in interrupt contexts, although some are quite
diff --git a/drivers/ieee1394/nodemgr.c b/drivers/ieee1394/nodemgr.c
index ba9faeff4793..c5ace190bfe6 100644
--- a/drivers/ieee1394/nodemgr.c
+++ b/drivers/ieee1394/nodemgr.c
@@ -1681,7 +1681,8 @@ static int nodemgr_host_thread(void *__hi)
1681 for (;;) { 1681 for (;;) {
1682 /* Sleep until next bus reset */ 1682 /* Sleep until next bus reset */
1683 set_current_state(TASK_INTERRUPTIBLE); 1683 set_current_state(TASK_INTERRUPTIBLE);
1684 if (get_hpsb_generation(host) == generation) 1684 if (get_hpsb_generation(host) == generation &&
1685 !kthread_should_stop())
1685 schedule(); 1686 schedule();
1686 __set_current_state(TASK_RUNNING); 1687 __set_current_state(TASK_RUNNING);
1687 1688
diff --git a/drivers/ieee1394/raw1394.c b/drivers/ieee1394/raw1394.c
index aa9ca8385ec7..bb897a37d9f7 100644
--- a/drivers/ieee1394/raw1394.c
+++ b/drivers/ieee1394/raw1394.c
@@ -2669,6 +2669,18 @@ static void raw1394_iso_shutdown(struct file_info *fi)
2669 fi->iso_state = RAW1394_ISO_INACTIVE; 2669 fi->iso_state = RAW1394_ISO_INACTIVE;
2670} 2670}
2671 2671
2672static int raw1394_read_cycle_timer(struct file_info *fi, void __user * uaddr)
2673{
2674 struct raw1394_cycle_timer ct;
2675 int err;
2676
2677 err = hpsb_read_cycle_timer(fi->host, &ct.cycle_timer, &ct.local_time);
2678 if (!err)
2679 if (copy_to_user(uaddr, &ct, sizeof(ct)))
2680 err = -EFAULT;
2681 return err;
2682}
2683
2672/* mmap the rawiso xmit/recv buffer */ 2684/* mmap the rawiso xmit/recv buffer */
2673static int raw1394_mmap(struct file *file, struct vm_area_struct *vma) 2685static int raw1394_mmap(struct file *file, struct vm_area_struct *vma)
2674{ 2686{
@@ -2777,6 +2789,14 @@ static int raw1394_ioctl(struct inode *inode, struct file *file,
2777 break; 2789 break;
2778 } 2790 }
2779 2791
2792 /* state-independent commands */
2793 switch(cmd) {
2794 case RAW1394_IOC_GET_CYCLE_TIMER:
2795 return raw1394_read_cycle_timer(fi, argp);
2796 default:
2797 break;
2798 }
2799
2780 return -EINVAL; 2800 return -EINVAL;
2781} 2801}
2782 2802
diff --git a/drivers/ieee1394/raw1394.h b/drivers/ieee1394/raw1394.h
index 35bfc38f013c..7bd22ee1afbb 100644
--- a/drivers/ieee1394/raw1394.h
+++ b/drivers/ieee1394/raw1394.h
@@ -178,4 +178,14 @@ struct raw1394_iso_status {
178 __s16 xmit_cycle; 178 __s16 xmit_cycle;
179}; 179};
180 180
181/* argument to RAW1394_IOC_GET_CYCLE_TIMER ioctl */
182struct raw1394_cycle_timer {
183 /* contents of Isochronous Cycle Timer register,
184 as in OHCI 1.1 clause 5.13 (also with non-OHCI hosts) */
185 __u32 cycle_timer;
186
187 /* local time in microseconds since Epoch,
188 simultaneously read with cycle timer */
189 __u64 local_time;
190};
181#endif /* IEEE1394_RAW1394_H */ 191#endif /* IEEE1394_RAW1394_H */
diff --git a/drivers/infiniband/core/Makefile b/drivers/infiniband/core/Makefile
index 50fb1cd447b7..189e5d4b9b17 100644
--- a/drivers/infiniband/core/Makefile
+++ b/drivers/infiniband/core/Makefile
@@ -12,7 +12,7 @@ ib_core-y := packer.o ud_header.o verbs.o sysfs.o \
12 12
13ib_mad-y := mad.o smi.o agent.o mad_rmpp.o 13ib_mad-y := mad.o smi.o agent.o mad_rmpp.o
14 14
15ib_sa-y := sa_query.o 15ib_sa-y := sa_query.o multicast.o
16 16
17ib_cm-y := cm.o 17ib_cm-y := cm.o
18 18
diff --git a/drivers/infiniband/core/cma.c b/drivers/infiniband/core/cma.c
index db88e609bf42..f8d69b3fa307 100644
--- a/drivers/infiniband/core/cma.c
+++ b/drivers/infiniband/core/cma.c
@@ -71,6 +71,7 @@ static struct workqueue_struct *cma_wq;
71static DEFINE_IDR(sdp_ps); 71static DEFINE_IDR(sdp_ps);
72static DEFINE_IDR(tcp_ps); 72static DEFINE_IDR(tcp_ps);
73static DEFINE_IDR(udp_ps); 73static DEFINE_IDR(udp_ps);
74static DEFINE_IDR(ipoib_ps);
74static int next_port; 75static int next_port;
75 76
76struct cma_device { 77struct cma_device {
@@ -116,6 +117,7 @@ struct rdma_id_private {
116 struct list_head list; 117 struct list_head list;
117 struct list_head listen_list; 118 struct list_head listen_list;
118 struct cma_device *cma_dev; 119 struct cma_device *cma_dev;
120 struct list_head mc_list;
119 121
120 enum cma_state state; 122 enum cma_state state;
121 spinlock_t lock; 123 spinlock_t lock;
@@ -134,10 +136,23 @@ struct rdma_id_private {
134 } cm_id; 136 } cm_id;
135 137
136 u32 seq_num; 138 u32 seq_num;
139 u32 qkey;
137 u32 qp_num; 140 u32 qp_num;
138 u8 srq; 141 u8 srq;
139}; 142};
140 143
144struct cma_multicast {
145 struct rdma_id_private *id_priv;
146 union {
147 struct ib_sa_multicast *ib;
148 } multicast;
149 struct list_head list;
150 void *context;
151 struct sockaddr addr;
152 u8 pad[sizeof(struct sockaddr_in6) -
153 sizeof(struct sockaddr)];
154};
155
141struct cma_work { 156struct cma_work {
142 struct work_struct work; 157 struct work_struct work;
143 struct rdma_id_private *id; 158 struct rdma_id_private *id;
@@ -243,6 +258,11 @@ static inline void sdp_set_ip_ver(struct sdp_hh *hh, u8 ip_ver)
243 hh->ip_version = (ip_ver << 4) | (hh->ip_version & 0xF); 258 hh->ip_version = (ip_ver << 4) | (hh->ip_version & 0xF);
244} 259}
245 260
261static inline int cma_is_ud_ps(enum rdma_port_space ps)
262{
263 return (ps == RDMA_PS_UDP || ps == RDMA_PS_IPOIB);
264}
265
246static void cma_attach_to_dev(struct rdma_id_private *id_priv, 266static void cma_attach_to_dev(struct rdma_id_private *id_priv,
247 struct cma_device *cma_dev) 267 struct cma_device *cma_dev)
248{ 268{
@@ -265,19 +285,41 @@ static void cma_detach_from_dev(struct rdma_id_private *id_priv)
265 id_priv->cma_dev = NULL; 285 id_priv->cma_dev = NULL;
266} 286}
267 287
288static int cma_set_qkey(struct ib_device *device, u8 port_num,
289 enum rdma_port_space ps,
290 struct rdma_dev_addr *dev_addr, u32 *qkey)
291{
292 struct ib_sa_mcmember_rec rec;
293 int ret = 0;
294
295 switch (ps) {
296 case RDMA_PS_UDP:
297 *qkey = RDMA_UDP_QKEY;
298 break;
299 case RDMA_PS_IPOIB:
300 ib_addr_get_mgid(dev_addr, &rec.mgid);
301 ret = ib_sa_get_mcmember_rec(device, port_num, &rec.mgid, &rec);
302 *qkey = be32_to_cpu(rec.qkey);
303 break;
304 default:
305 break;
306 }
307 return ret;
308}
309
268static int cma_acquire_dev(struct rdma_id_private *id_priv) 310static int cma_acquire_dev(struct rdma_id_private *id_priv)
269{ 311{
270 enum rdma_node_type dev_type = id_priv->id.route.addr.dev_addr.dev_type; 312 struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr;
271 struct cma_device *cma_dev; 313 struct cma_device *cma_dev;
272 union ib_gid gid; 314 union ib_gid gid;
273 int ret = -ENODEV; 315 int ret = -ENODEV;
274 316
275 switch (rdma_node_get_transport(dev_type)) { 317 switch (rdma_node_get_transport(dev_addr->dev_type)) {
276 case RDMA_TRANSPORT_IB: 318 case RDMA_TRANSPORT_IB:
277 ib_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid); 319 ib_addr_get_sgid(dev_addr, &gid);
278 break; 320 break;
279 case RDMA_TRANSPORT_IWARP: 321 case RDMA_TRANSPORT_IWARP:
280 iw_addr_get_sgid(&id_priv->id.route.addr.dev_addr, &gid); 322 iw_addr_get_sgid(dev_addr, &gid);
281 break; 323 break;
282 default: 324 default:
283 return -ENODEV; 325 return -ENODEV;
@@ -287,7 +329,12 @@ static int cma_acquire_dev(struct rdma_id_private *id_priv)
287 ret = ib_find_cached_gid(cma_dev->device, &gid, 329 ret = ib_find_cached_gid(cma_dev->device, &gid,
288 &id_priv->id.port_num, NULL); 330 &id_priv->id.port_num, NULL);
289 if (!ret) { 331 if (!ret) {
290 cma_attach_to_dev(id_priv, cma_dev); 332 ret = cma_set_qkey(cma_dev->device,
333 id_priv->id.port_num,
334 id_priv->id.ps, dev_addr,
335 &id_priv->qkey);
336 if (!ret)
337 cma_attach_to_dev(id_priv, cma_dev);
291 break; 338 break;
292 } 339 }
293 } 340 }
@@ -325,40 +372,50 @@ struct rdma_cm_id *rdma_create_id(rdma_cm_event_handler event_handler,
325 init_waitqueue_head(&id_priv->wait_remove); 372 init_waitqueue_head(&id_priv->wait_remove);
326 atomic_set(&id_priv->dev_remove, 0); 373 atomic_set(&id_priv->dev_remove, 0);
327 INIT_LIST_HEAD(&id_priv->listen_list); 374 INIT_LIST_HEAD(&id_priv->listen_list);
375 INIT_LIST_HEAD(&id_priv->mc_list);
328 get_random_bytes(&id_priv->seq_num, sizeof id_priv->seq_num); 376 get_random_bytes(&id_priv->seq_num, sizeof id_priv->seq_num);
329 377
330 return &id_priv->id; 378 return &id_priv->id;
331} 379}
332EXPORT_SYMBOL(rdma_create_id); 380EXPORT_SYMBOL(rdma_create_id);
333 381
334static int cma_init_ib_qp(struct rdma_id_private *id_priv, struct ib_qp *qp) 382static int cma_init_ud_qp(struct rdma_id_private *id_priv, struct ib_qp *qp)
335{ 383{
336 struct ib_qp_attr qp_attr; 384 struct ib_qp_attr qp_attr;
337 struct rdma_dev_addr *dev_addr; 385 int qp_attr_mask, ret;
338 int ret;
339 386
340 dev_addr = &id_priv->id.route.addr.dev_addr; 387 qp_attr.qp_state = IB_QPS_INIT;
341 ret = ib_find_cached_pkey(id_priv->id.device, id_priv->id.port_num, 388 ret = rdma_init_qp_attr(&id_priv->id, &qp_attr, &qp_attr_mask);
342 ib_addr_get_pkey(dev_addr),
343 &qp_attr.pkey_index);
344 if (ret) 389 if (ret)
345 return ret; 390 return ret;
346 391
347 qp_attr.qp_state = IB_QPS_INIT; 392 ret = ib_modify_qp(qp, &qp_attr, qp_attr_mask);
348 qp_attr.qp_access_flags = 0; 393 if (ret)
349 qp_attr.port_num = id_priv->id.port_num; 394 return ret;
350 return ib_modify_qp(qp, &qp_attr, IB_QP_STATE | IB_QP_ACCESS_FLAGS | 395
351 IB_QP_PKEY_INDEX | IB_QP_PORT); 396 qp_attr.qp_state = IB_QPS_RTR;
397 ret = ib_modify_qp(qp, &qp_attr, IB_QP_STATE);
398 if (ret)
399 return ret;
400
401 qp_attr.qp_state = IB_QPS_RTS;
402 qp_attr.sq_psn = 0;
403 ret = ib_modify_qp(qp, &qp_attr, IB_QP_STATE | IB_QP_SQ_PSN);
404
405 return ret;
352} 406}
353 407
354static int cma_init_iw_qp(struct rdma_id_private *id_priv, struct ib_qp *qp) 408static int cma_init_conn_qp(struct rdma_id_private *id_priv, struct ib_qp *qp)
355{ 409{
356 struct ib_qp_attr qp_attr; 410 struct ib_qp_attr qp_attr;
411 int qp_attr_mask, ret;
357 412
358 qp_attr.qp_state = IB_QPS_INIT; 413 qp_attr.qp_state = IB_QPS_INIT;
359 qp_attr.qp_access_flags = IB_ACCESS_LOCAL_WRITE; 414 ret = rdma_init_qp_attr(&id_priv->id, &qp_attr, &qp_attr_mask);
415 if (ret)
416 return ret;
360 417
361 return ib_modify_qp(qp, &qp_attr, IB_QP_STATE | IB_QP_ACCESS_FLAGS); 418 return ib_modify_qp(qp, &qp_attr, qp_attr_mask);
362} 419}
363 420
364int rdma_create_qp(struct rdma_cm_id *id, struct ib_pd *pd, 421int rdma_create_qp(struct rdma_cm_id *id, struct ib_pd *pd,
@@ -376,18 +433,10 @@ int rdma_create_qp(struct rdma_cm_id *id, struct ib_pd *pd,
376 if (IS_ERR(qp)) 433 if (IS_ERR(qp))
377 return PTR_ERR(qp); 434 return PTR_ERR(qp);
378 435
379 switch (rdma_node_get_transport(id->device->node_type)) { 436 if (cma_is_ud_ps(id_priv->id.ps))
380 case RDMA_TRANSPORT_IB: 437 ret = cma_init_ud_qp(id_priv, qp);
381 ret = cma_init_ib_qp(id_priv, qp); 438 else
382 break; 439 ret = cma_init_conn_qp(id_priv, qp);
383 case RDMA_TRANSPORT_IWARP:
384 ret = cma_init_iw_qp(id_priv, qp);
385 break;
386 default:
387 ret = -ENOSYS;
388 break;
389 }
390
391 if (ret) 440 if (ret)
392 goto err; 441 goto err;
393 442
@@ -460,23 +509,55 @@ static int cma_modify_qp_err(struct rdma_cm_id *id)
460 return ib_modify_qp(id->qp, &qp_attr, IB_QP_STATE); 509 return ib_modify_qp(id->qp, &qp_attr, IB_QP_STATE);
461} 510}
462 511
512static int cma_ib_init_qp_attr(struct rdma_id_private *id_priv,
513 struct ib_qp_attr *qp_attr, int *qp_attr_mask)
514{
515 struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr;
516 int ret;
517
518 ret = ib_find_cached_pkey(id_priv->id.device, id_priv->id.port_num,
519 ib_addr_get_pkey(dev_addr),
520 &qp_attr->pkey_index);
521 if (ret)
522 return ret;
523
524 qp_attr->port_num = id_priv->id.port_num;
525 *qp_attr_mask = IB_QP_STATE | IB_QP_PKEY_INDEX | IB_QP_PORT;
526
527 if (cma_is_ud_ps(id_priv->id.ps)) {
528 qp_attr->qkey = id_priv->qkey;
529 *qp_attr_mask |= IB_QP_QKEY;
530 } else {
531 qp_attr->qp_access_flags = 0;
532 *qp_attr_mask |= IB_QP_ACCESS_FLAGS;
533 }
534 return 0;
535}
536
463int rdma_init_qp_attr(struct rdma_cm_id *id, struct ib_qp_attr *qp_attr, 537int rdma_init_qp_attr(struct rdma_cm_id *id, struct ib_qp_attr *qp_attr,
464 int *qp_attr_mask) 538 int *qp_attr_mask)
465{ 539{
466 struct rdma_id_private *id_priv; 540 struct rdma_id_private *id_priv;
467 int ret; 541 int ret = 0;
468 542
469 id_priv = container_of(id, struct rdma_id_private, id); 543 id_priv = container_of(id, struct rdma_id_private, id);
470 switch (rdma_node_get_transport(id_priv->id.device->node_type)) { 544 switch (rdma_node_get_transport(id_priv->id.device->node_type)) {
471 case RDMA_TRANSPORT_IB: 545 case RDMA_TRANSPORT_IB:
472 ret = ib_cm_init_qp_attr(id_priv->cm_id.ib, qp_attr, 546 if (!id_priv->cm_id.ib || cma_is_ud_ps(id_priv->id.ps))
473 qp_attr_mask); 547 ret = cma_ib_init_qp_attr(id_priv, qp_attr, qp_attr_mask);
548 else
549 ret = ib_cm_init_qp_attr(id_priv->cm_id.ib, qp_attr,
550 qp_attr_mask);
474 if (qp_attr->qp_state == IB_QPS_RTR) 551 if (qp_attr->qp_state == IB_QPS_RTR)
475 qp_attr->rq_psn = id_priv->seq_num; 552 qp_attr->rq_psn = id_priv->seq_num;
476 break; 553 break;
477 case RDMA_TRANSPORT_IWARP: 554 case RDMA_TRANSPORT_IWARP:
478 ret = iw_cm_init_qp_attr(id_priv->cm_id.iw, qp_attr, 555 if (!id_priv->cm_id.iw) {
479 qp_attr_mask); 556 qp_attr->qp_access_flags = IB_ACCESS_LOCAL_WRITE;
557 *qp_attr_mask = IB_QP_STATE | IB_QP_ACCESS_FLAGS;
558 } else
559 ret = iw_cm_init_qp_attr(id_priv->cm_id.iw, qp_attr,
560 qp_attr_mask);
480 break; 561 break;
481 default: 562 default:
482 ret = -ENOSYS; 563 ret = -ENOSYS;
@@ -698,6 +779,19 @@ static void cma_release_port(struct rdma_id_private *id_priv)
698 mutex_unlock(&lock); 779 mutex_unlock(&lock);
699} 780}
700 781
782static void cma_leave_mc_groups(struct rdma_id_private *id_priv)
783{
784 struct cma_multicast *mc;
785
786 while (!list_empty(&id_priv->mc_list)) {
787 mc = container_of(id_priv->mc_list.next,
788 struct cma_multicast, list);
789 list_del(&mc->list);
790 ib_sa_free_multicast(mc->multicast.ib);
791 kfree(mc);
792 }
793}
794
701void rdma_destroy_id(struct rdma_cm_id *id) 795void rdma_destroy_id(struct rdma_cm_id *id)
702{ 796{
703 struct rdma_id_private *id_priv; 797 struct rdma_id_private *id_priv;
@@ -722,6 +816,7 @@ void rdma_destroy_id(struct rdma_cm_id *id)
722 default: 816 default:
723 break; 817 break;
724 } 818 }
819 cma_leave_mc_groups(id_priv);
725 mutex_lock(&lock); 820 mutex_lock(&lock);
726 cma_detach_from_dev(id_priv); 821 cma_detach_from_dev(id_priv);
727 } 822 }
@@ -972,7 +1067,7 @@ static int cma_req_handler(struct ib_cm_id *cm_id, struct ib_cm_event *ib_event)
972 memset(&event, 0, sizeof event); 1067 memset(&event, 0, sizeof event);
973 offset = cma_user_data_offset(listen_id->id.ps); 1068 offset = cma_user_data_offset(listen_id->id.ps);
974 event.event = RDMA_CM_EVENT_CONNECT_REQUEST; 1069 event.event = RDMA_CM_EVENT_CONNECT_REQUEST;
975 if (listen_id->id.ps == RDMA_PS_UDP) { 1070 if (cma_is_ud_ps(listen_id->id.ps)) {
976 conn_id = cma_new_udp_id(&listen_id->id, ib_event); 1071 conn_id = cma_new_udp_id(&listen_id->id, ib_event);
977 event.param.ud.private_data = ib_event->private_data + offset; 1072 event.param.ud.private_data = ib_event->private_data + offset;
978 event.param.ud.private_data_len = 1073 event.param.ud.private_data_len =
@@ -1725,7 +1820,7 @@ static int cma_alloc_port(struct idr *ps, struct rdma_id_private *id_priv,
1725 struct rdma_bind_list *bind_list; 1820 struct rdma_bind_list *bind_list;
1726 int port, ret; 1821 int port, ret;
1727 1822
1728 bind_list = kzalloc(sizeof *bind_list, GFP_KERNEL); 1823 bind_list = kmalloc(sizeof *bind_list, GFP_KERNEL);
1729 if (!bind_list) 1824 if (!bind_list)
1730 return -ENOMEM; 1825 return -ENOMEM;
1731 1826
@@ -1847,6 +1942,9 @@ static int cma_get_port(struct rdma_id_private *id_priv)
1847 case RDMA_PS_UDP: 1942 case RDMA_PS_UDP:
1848 ps = &udp_ps; 1943 ps = &udp_ps;
1849 break; 1944 break;
1945 case RDMA_PS_IPOIB:
1946 ps = &ipoib_ps;
1947 break;
1850 default: 1948 default:
1851 return -EPROTONOSUPPORT; 1949 return -EPROTONOSUPPORT;
1852 } 1950 }
@@ -1961,7 +2059,7 @@ static int cma_sidr_rep_handler(struct ib_cm_id *cm_id,
1961 event.status = ib_event->param.sidr_rep_rcvd.status; 2059 event.status = ib_event->param.sidr_rep_rcvd.status;
1962 break; 2060 break;
1963 } 2061 }
1964 if (rep->qkey != RDMA_UD_QKEY) { 2062 if (id_priv->qkey != rep->qkey) {
1965 event.event = RDMA_CM_EVENT_UNREACHABLE; 2063 event.event = RDMA_CM_EVENT_UNREACHABLE;
1966 event.status = -EINVAL; 2064 event.status = -EINVAL;
1967 break; 2065 break;
@@ -2160,7 +2258,7 @@ int rdma_connect(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)
2160 2258
2161 switch (rdma_node_get_transport(id->device->node_type)) { 2259 switch (rdma_node_get_transport(id->device->node_type)) {
2162 case RDMA_TRANSPORT_IB: 2260 case RDMA_TRANSPORT_IB:
2163 if (id->ps == RDMA_PS_UDP) 2261 if (cma_is_ud_ps(id->ps))
2164 ret = cma_resolve_ib_udp(id_priv, conn_param); 2262 ret = cma_resolve_ib_udp(id_priv, conn_param);
2165 else 2263 else
2166 ret = cma_connect_ib(id_priv, conn_param); 2264 ret = cma_connect_ib(id_priv, conn_param);
@@ -2256,7 +2354,7 @@ static int cma_send_sidr_rep(struct rdma_id_private *id_priv,
2256 rep.status = status; 2354 rep.status = status;
2257 if (status == IB_SIDR_SUCCESS) { 2355 if (status == IB_SIDR_SUCCESS) {
2258 rep.qp_num = id_priv->qp_num; 2356 rep.qp_num = id_priv->qp_num;
2259 rep.qkey = RDMA_UD_QKEY; 2357 rep.qkey = id_priv->qkey;
2260 } 2358 }
2261 rep.private_data = private_data; 2359 rep.private_data = private_data;
2262 rep.private_data_len = private_data_len; 2360 rep.private_data_len = private_data_len;
@@ -2280,7 +2378,7 @@ int rdma_accept(struct rdma_cm_id *id, struct rdma_conn_param *conn_param)
2280 2378
2281 switch (rdma_node_get_transport(id->device->node_type)) { 2379 switch (rdma_node_get_transport(id->device->node_type)) {
2282 case RDMA_TRANSPORT_IB: 2380 case RDMA_TRANSPORT_IB:
2283 if (id->ps == RDMA_PS_UDP) 2381 if (cma_is_ud_ps(id->ps))
2284 ret = cma_send_sidr_rep(id_priv, IB_SIDR_SUCCESS, 2382 ret = cma_send_sidr_rep(id_priv, IB_SIDR_SUCCESS,
2285 conn_param->private_data, 2383 conn_param->private_data,
2286 conn_param->private_data_len); 2384 conn_param->private_data_len);
@@ -2341,7 +2439,7 @@ int rdma_reject(struct rdma_cm_id *id, const void *private_data,
2341 2439
2342 switch (rdma_node_get_transport(id->device->node_type)) { 2440 switch (rdma_node_get_transport(id->device->node_type)) {
2343 case RDMA_TRANSPORT_IB: 2441 case RDMA_TRANSPORT_IB:
2344 if (id->ps == RDMA_PS_UDP) 2442 if (cma_is_ud_ps(id->ps))
2345 ret = cma_send_sidr_rep(id_priv, IB_SIDR_REJECT, 2443 ret = cma_send_sidr_rep(id_priv, IB_SIDR_REJECT,
2346 private_data, private_data_len); 2444 private_data, private_data_len);
2347 else 2445 else
@@ -2392,6 +2490,178 @@ out:
2392} 2490}
2393EXPORT_SYMBOL(rdma_disconnect); 2491EXPORT_SYMBOL(rdma_disconnect);
2394 2492
2493static int cma_ib_mc_handler(int status, struct ib_sa_multicast *multicast)
2494{
2495 struct rdma_id_private *id_priv;
2496 struct cma_multicast *mc = multicast->context;
2497 struct rdma_cm_event event;
2498 int ret;
2499
2500 id_priv = mc->id_priv;
2501 atomic_inc(&id_priv->dev_remove);
2502 if (!cma_comp(id_priv, CMA_ADDR_BOUND) &&
2503 !cma_comp(id_priv, CMA_ADDR_RESOLVED))
2504 goto out;
2505
2506 if (!status && id_priv->id.qp)
2507 status = ib_attach_mcast(id_priv->id.qp, &multicast->rec.mgid,
2508 multicast->rec.mlid);
2509
2510 memset(&event, 0, sizeof event);
2511 event.status = status;
2512 event.param.ud.private_data = mc->context;
2513 if (!status) {
2514 event.event = RDMA_CM_EVENT_MULTICAST_JOIN;
2515 ib_init_ah_from_mcmember(id_priv->id.device,
2516 id_priv->id.port_num, &multicast->rec,
2517 &event.param.ud.ah_attr);
2518 event.param.ud.qp_num = 0xFFFFFF;
2519 event.param.ud.qkey = be32_to_cpu(multicast->rec.qkey);
2520 } else
2521 event.event = RDMA_CM_EVENT_MULTICAST_ERROR;
2522
2523 ret = id_priv->id.event_handler(&id_priv->id, &event);
2524 if (ret) {
2525 cma_exch(id_priv, CMA_DESTROYING);
2526 cma_release_remove(id_priv);
2527 rdma_destroy_id(&id_priv->id);
2528 return 0;
2529 }
2530out:
2531 cma_release_remove(id_priv);
2532 return 0;
2533}
2534
2535static void cma_set_mgid(struct rdma_id_private *id_priv,
2536 struct sockaddr *addr, union ib_gid *mgid)
2537{
2538 unsigned char mc_map[MAX_ADDR_LEN];
2539 struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr;
2540 struct sockaddr_in *sin = (struct sockaddr_in *) addr;
2541 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) addr;
2542
2543 if (cma_any_addr(addr)) {
2544 memset(mgid, 0, sizeof *mgid);
2545 } else if ((addr->sa_family == AF_INET6) &&
2546 ((be32_to_cpu(sin6->sin6_addr.s6_addr32[0]) & 0xFF10A01B) ==
2547 0xFF10A01B)) {
2548 /* IPv6 address is an SA assigned MGID. */
2549 memcpy(mgid, &sin6->sin6_addr, sizeof *mgid);
2550 } else {
2551 ip_ib_mc_map(sin->sin_addr.s_addr, mc_map);
2552 if (id_priv->id.ps == RDMA_PS_UDP)
2553 mc_map[7] = 0x01; /* Use RDMA CM signature */
2554 mc_map[8] = ib_addr_get_pkey(dev_addr) >> 8;
2555 mc_map[9] = (unsigned char) ib_addr_get_pkey(dev_addr);
2556 *mgid = *(union ib_gid *) (mc_map + 4);
2557 }
2558}
2559
2560static int cma_join_ib_multicast(struct rdma_id_private *id_priv,
2561 struct cma_multicast *mc)
2562{
2563 struct ib_sa_mcmember_rec rec;
2564 struct rdma_dev_addr *dev_addr = &id_priv->id.route.addr.dev_addr;
2565 ib_sa_comp_mask comp_mask;
2566 int ret;
2567
2568 ib_addr_get_mgid(dev_addr, &rec.mgid);
2569 ret = ib_sa_get_mcmember_rec(id_priv->id.device, id_priv->id.port_num,
2570 &rec.mgid, &rec);
2571 if (ret)
2572 return ret;
2573
2574 cma_set_mgid(id_priv, &mc->addr, &rec.mgid);
2575 if (id_priv->id.ps == RDMA_PS_UDP)
2576 rec.qkey = cpu_to_be32(RDMA_UDP_QKEY);
2577 ib_addr_get_sgid(dev_addr, &rec.port_gid);
2578 rec.pkey = cpu_to_be16(ib_addr_get_pkey(dev_addr));
2579 rec.join_state = 1;
2580
2581 comp_mask = IB_SA_MCMEMBER_REC_MGID | IB_SA_MCMEMBER_REC_PORT_GID |
2582 IB_SA_MCMEMBER_REC_PKEY | IB_SA_MCMEMBER_REC_JOIN_STATE |
2583 IB_SA_MCMEMBER_REC_QKEY | IB_SA_MCMEMBER_REC_SL |
2584 IB_SA_MCMEMBER_REC_FLOW_LABEL |
2585 IB_SA_MCMEMBER_REC_TRAFFIC_CLASS;
2586
2587 mc->multicast.ib = ib_sa_join_multicast(&sa_client, id_priv->id.device,
2588 id_priv->id.port_num, &rec,
2589 comp_mask, GFP_KERNEL,
2590 cma_ib_mc_handler, mc);
2591 if (IS_ERR(mc->multicast.ib))
2592 return PTR_ERR(mc->multicast.ib);
2593
2594 return 0;
2595}
2596
2597int rdma_join_multicast(struct rdma_cm_id *id, struct sockaddr *addr,
2598 void *context)
2599{
2600 struct rdma_id_private *id_priv;
2601 struct cma_multicast *mc;
2602 int ret;
2603
2604 id_priv = container_of(id, struct rdma_id_private, id);
2605 if (!cma_comp(id_priv, CMA_ADDR_BOUND) &&
2606 !cma_comp(id_priv, CMA_ADDR_RESOLVED))
2607 return -EINVAL;
2608
2609 mc = kmalloc(sizeof *mc, GFP_KERNEL);
2610 if (!mc)
2611 return -ENOMEM;
2612
2613 memcpy(&mc->addr, addr, ip_addr_size(addr));
2614 mc->context = context;
2615 mc->id_priv = id_priv;
2616
2617 spin_lock(&id_priv->lock);
2618 list_add(&mc->list, &id_priv->mc_list);
2619 spin_unlock(&id_priv->lock);
2620
2621 switch (rdma_node_get_transport(id->device->node_type)) {
2622 case RDMA_TRANSPORT_IB:
2623 ret = cma_join_ib_multicast(id_priv, mc);
2624 break;
2625 default:
2626 ret = -ENOSYS;
2627 break;
2628 }
2629
2630 if (ret) {
2631 spin_lock_irq(&id_priv->lock);
2632 list_del(&mc->list);
2633 spin_unlock_irq(&id_priv->lock);
2634 kfree(mc);
2635 }
2636 return ret;
2637}
2638EXPORT_SYMBOL(rdma_join_multicast);
2639
2640void rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr)
2641{
2642 struct rdma_id_private *id_priv;
2643 struct cma_multicast *mc;
2644
2645 id_priv = container_of(id, struct rdma_id_private, id);
2646 spin_lock_irq(&id_priv->lock);
2647 list_for_each_entry(mc, &id_priv->mc_list, list) {
2648 if (!memcmp(&mc->addr, addr, ip_addr_size(addr))) {
2649 list_del(&mc->list);
2650 spin_unlock_irq(&id_priv->lock);
2651
2652 if (id->qp)
2653 ib_detach_mcast(id->qp,
2654 &mc->multicast.ib->rec.mgid,
2655 mc->multicast.ib->rec.mlid);
2656 ib_sa_free_multicast(mc->multicast.ib);
2657 kfree(mc);
2658 return;
2659 }
2660 }
2661 spin_unlock_irq(&id_priv->lock);
2662}
2663EXPORT_SYMBOL(rdma_leave_multicast);
2664
2395static void cma_add_one(struct ib_device *device) 2665static void cma_add_one(struct ib_device *device)
2396{ 2666{
2397 struct cma_device *cma_dev; 2667 struct cma_device *cma_dev;
@@ -2522,6 +2792,7 @@ static void cma_cleanup(void)
2522 idr_destroy(&sdp_ps); 2792 idr_destroy(&sdp_ps);
2523 idr_destroy(&tcp_ps); 2793 idr_destroy(&tcp_ps);
2524 idr_destroy(&udp_ps); 2794 idr_destroy(&udp_ps);
2795 idr_destroy(&ipoib_ps);
2525} 2796}
2526 2797
2527module_init(cma_init); 2798module_init(cma_init);
diff --git a/drivers/infiniband/core/fmr_pool.c b/drivers/infiniband/core/fmr_pool.c
index 8926a2bd4a87..1d796e7c8199 100644
--- a/drivers/infiniband/core/fmr_pool.c
+++ b/drivers/infiniband/core/fmr_pool.c
@@ -301,7 +301,7 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd,
301 301
302 { 302 {
303 struct ib_pool_fmr *fmr; 303 struct ib_pool_fmr *fmr;
304 struct ib_fmr_attr attr = { 304 struct ib_fmr_attr fmr_attr = {
305 .max_pages = params->max_pages_per_fmr, 305 .max_pages = params->max_pages_per_fmr,
306 .max_maps = pool->max_remaps, 306 .max_maps = pool->max_remaps,
307 .page_shift = params->page_shift 307 .page_shift = params->page_shift
@@ -321,7 +321,7 @@ struct ib_fmr_pool *ib_create_fmr_pool(struct ib_pd *pd,
321 fmr->ref_count = 0; 321 fmr->ref_count = 0;
322 INIT_HLIST_NODE(&fmr->cache_node); 322 INIT_HLIST_NODE(&fmr->cache_node);
323 323
324 fmr->fmr = ib_alloc_fmr(pd, params->access, &attr); 324 fmr->fmr = ib_alloc_fmr(pd, params->access, &fmr_attr);
325 if (IS_ERR(fmr->fmr)) { 325 if (IS_ERR(fmr->fmr)) {
326 printk(KERN_WARNING "fmr_create failed for FMR %d", i); 326 printk(KERN_WARNING "fmr_create failed for FMR %d", i);
327 kfree(fmr); 327 kfree(fmr);
diff --git a/drivers/infiniband/core/iwcm.c b/drivers/infiniband/core/iwcm.c
index 1039ad57d53b..891d1fa7b2eb 100644
--- a/drivers/infiniband/core/iwcm.c
+++ b/drivers/infiniband/core/iwcm.c
@@ -146,6 +146,12 @@ static int copy_private_data(struct iw_cm_event *event)
146 return 0; 146 return 0;
147} 147}
148 148
149static void free_cm_id(struct iwcm_id_private *cm_id_priv)
150{
151 dealloc_work_entries(cm_id_priv);
152 kfree(cm_id_priv);
153}
154
149/* 155/*
150 * Release a reference on cm_id. If the last reference is being 156 * Release a reference on cm_id. If the last reference is being
151 * released, enable the waiting thread (in iw_destroy_cm_id) to 157 * released, enable the waiting thread (in iw_destroy_cm_id) to
@@ -153,21 +159,14 @@ static int copy_private_data(struct iw_cm_event *event)
153 */ 159 */
154static int iwcm_deref_id(struct iwcm_id_private *cm_id_priv) 160static int iwcm_deref_id(struct iwcm_id_private *cm_id_priv)
155{ 161{
156 int ret = 0;
157
158 BUG_ON(atomic_read(&cm_id_priv->refcount)==0); 162 BUG_ON(atomic_read(&cm_id_priv->refcount)==0);
159 if (atomic_dec_and_test(&cm_id_priv->refcount)) { 163 if (atomic_dec_and_test(&cm_id_priv->refcount)) {
160 BUG_ON(!list_empty(&cm_id_priv->work_list)); 164 BUG_ON(!list_empty(&cm_id_priv->work_list));
161 if (waitqueue_active(&cm_id_priv->destroy_comp.wait)) {
162 BUG_ON(cm_id_priv->state != IW_CM_STATE_DESTROYING);
163 BUG_ON(test_bit(IWCM_F_CALLBACK_DESTROY,
164 &cm_id_priv->flags));
165 ret = 1;
166 }
167 complete(&cm_id_priv->destroy_comp); 165 complete(&cm_id_priv->destroy_comp);
166 return 1;
168 } 167 }
169 168
170 return ret; 169 return 0;
171} 170}
172 171
173static void add_ref(struct iw_cm_id *cm_id) 172static void add_ref(struct iw_cm_id *cm_id)
@@ -181,7 +180,11 @@ static void rem_ref(struct iw_cm_id *cm_id)
181{ 180{
182 struct iwcm_id_private *cm_id_priv; 181 struct iwcm_id_private *cm_id_priv;
183 cm_id_priv = container_of(cm_id, struct iwcm_id_private, id); 182 cm_id_priv = container_of(cm_id, struct iwcm_id_private, id);
184 iwcm_deref_id(cm_id_priv); 183 if (iwcm_deref_id(cm_id_priv) &&
184 test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags)) {
185 BUG_ON(!list_empty(&cm_id_priv->work_list));
186 free_cm_id(cm_id_priv);
187 }
185} 188}
186 189
187static int cm_event_handler(struct iw_cm_id *cm_id, struct iw_cm_event *event); 190static int cm_event_handler(struct iw_cm_id *cm_id, struct iw_cm_event *event);
@@ -355,7 +358,9 @@ static void destroy_cm_id(struct iw_cm_id *cm_id)
355 case IW_CM_STATE_CONN_RECV: 358 case IW_CM_STATE_CONN_RECV:
356 /* 359 /*
357 * App called destroy before/without calling accept after 360 * App called destroy before/without calling accept after
358 * receiving connection request event notification. 361 * receiving connection request event notification or
362 * returned non zero from the event callback function.
363 * In either case, must tell the provider to reject.
359 */ 364 */
360 cm_id_priv->state = IW_CM_STATE_DESTROYING; 365 cm_id_priv->state = IW_CM_STATE_DESTROYING;
361 break; 366 break;
@@ -391,9 +396,7 @@ void iw_destroy_cm_id(struct iw_cm_id *cm_id)
391 396
392 wait_for_completion(&cm_id_priv->destroy_comp); 397 wait_for_completion(&cm_id_priv->destroy_comp);
393 398
394 dealloc_work_entries(cm_id_priv); 399 free_cm_id(cm_id_priv);
395
396 kfree(cm_id_priv);
397} 400}
398EXPORT_SYMBOL(iw_destroy_cm_id); 401EXPORT_SYMBOL(iw_destroy_cm_id);
399 402
@@ -647,10 +650,11 @@ static void cm_conn_req_handler(struct iwcm_id_private *listen_id_priv,
647 /* Call the client CM handler */ 650 /* Call the client CM handler */
648 ret = cm_id->cm_handler(cm_id, iw_event); 651 ret = cm_id->cm_handler(cm_id, iw_event);
649 if (ret) { 652 if (ret) {
653 iw_cm_reject(cm_id, NULL, 0);
650 set_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags); 654 set_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags);
651 destroy_cm_id(cm_id); 655 destroy_cm_id(cm_id);
652 if (atomic_read(&cm_id_priv->refcount)==0) 656 if (atomic_read(&cm_id_priv->refcount)==0)
653 kfree(cm_id); 657 free_cm_id(cm_id_priv);
654 } 658 }
655 659
656out: 660out:
@@ -854,13 +858,12 @@ static void cm_work_handler(struct work_struct *_work)
854 destroy_cm_id(&cm_id_priv->id); 858 destroy_cm_id(&cm_id_priv->id);
855 } 859 }
856 BUG_ON(atomic_read(&cm_id_priv->refcount)==0); 860 BUG_ON(atomic_read(&cm_id_priv->refcount)==0);
857 if (iwcm_deref_id(cm_id_priv)) 861 if (iwcm_deref_id(cm_id_priv)) {
858 return; 862 if (test_bit(IWCM_F_CALLBACK_DESTROY,
859 863 &cm_id_priv->flags)) {
860 if (atomic_read(&cm_id_priv->refcount)==0 && 864 BUG_ON(!list_empty(&cm_id_priv->work_list));
861 test_bit(IWCM_F_CALLBACK_DESTROY, &cm_id_priv->flags)) { 865 free_cm_id(cm_id_priv);
862 dealloc_work_entries(cm_id_priv); 866 }
863 kfree(cm_id_priv);
864 return; 867 return;
865 } 868 }
866 spin_lock_irqsave(&cm_id_priv->lock, flags); 869 spin_lock_irqsave(&cm_id_priv->lock, flags);
diff --git a/drivers/infiniband/core/multicast.c b/drivers/infiniband/core/multicast.c
new file mode 100644
index 000000000000..4a579b3a1c90
--- /dev/null
+++ b/drivers/infiniband/core/multicast.c
@@ -0,0 +1,837 @@
1/*
2 * Copyright (c) 2006 Intel Corporation.  All rights reserved.
3 *
4 * This software is available to you under a choice of one of two
5 * licenses. You may choose to be licensed under the terms of the GNU
6 * General Public License (GPL) Version 2, available from the file
7 * COPYING in the main directory of this source tree, or the
8 * OpenIB.org BSD license below:
9 *
10 * Redistribution and use in source and binary forms, with or
11 * without modification, are permitted provided that the following
12 * conditions are met:
13 *
14 * - Redistributions of source code must retain the above
15 * copyright notice, this list of conditions and the following
16 * disclaimer.
17 *
18 * - Redistributions in binary form must reproduce the above
19 * copyright notice, this list of conditions and the following
20 * disclaimer in the documentation and/or other materials
21 * provided with the distribution.
22 *
23 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
27 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
28 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
29 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
30 * SOFTWARE.
31 */
32
33#include <linux/completion.h>
34#include <linux/dma-mapping.h>
35#include <linux/err.h>
36#include <linux/interrupt.h>
37#include <linux/pci.h>
38#include <linux/bitops.h>
39#include <linux/random.h>
40
41#include <rdma/ib_cache.h>
42#include "sa.h"
43
44static void mcast_add_one(struct ib_device *device);
45static void mcast_remove_one(struct ib_device *device);
46
47static struct ib_client mcast_client = {
48 .name = "ib_multicast",
49 .add = mcast_add_one,
50 .remove = mcast_remove_one
51};
52
53static struct ib_sa_client sa_client;
54static struct workqueue_struct *mcast_wq;
55static union ib_gid mgid0;
56
57struct mcast_device;
58
59struct mcast_port {
60 struct mcast_device *dev;
61 spinlock_t lock;
62 struct rb_root table;
63 atomic_t refcount;
64 struct completion comp;
65 u8 port_num;
66};
67
68struct mcast_device {
69 struct ib_device *device;
70 struct ib_event_handler event_handler;
71 int start_port;
72 int end_port;
73 struct mcast_port port[0];
74};
75
76enum mcast_state {
77 MCAST_IDLE,
78 MCAST_JOINING,
79 MCAST_MEMBER,
80 MCAST_BUSY,
81 MCAST_ERROR
82};
83
84struct mcast_member;
85
86struct mcast_group {
87 struct ib_sa_mcmember_rec rec;
88 struct rb_node node;
89 struct mcast_port *port;
90 spinlock_t lock;
91 struct work_struct work;
92 struct list_head pending_list;
93 struct list_head active_list;
94 struct mcast_member *last_join;
95 int members[3];
96 atomic_t refcount;
97 enum mcast_state state;
98 struct ib_sa_query *query;
99 int query_id;
100};
101
102struct mcast_member {
103 struct ib_sa_multicast multicast;
104 struct ib_sa_client *client;
105 struct mcast_group *group;
106 struct list_head list;
107 enum mcast_state state;
108 atomic_t refcount;
109 struct completion comp;
110};
111
112static void join_handler(int status, struct ib_sa_mcmember_rec *rec,
113 void *context);
114static void leave_handler(int status, struct ib_sa_mcmember_rec *rec,
115 void *context);
116
117static struct mcast_group *mcast_find(struct mcast_port *port,
118 union ib_gid *mgid)
119{
120 struct rb_node *node = port->table.rb_node;
121 struct mcast_group *group;
122 int ret;
123
124 while (node) {
125 group = rb_entry(node, struct mcast_group, node);
126 ret = memcmp(mgid->raw, group->rec.mgid.raw, sizeof *mgid);
127 if (!ret)
128 return group;
129
130 if (ret < 0)
131 node = node->rb_left;
132 else
133 node = node->rb_right;
134 }
135 return NULL;
136}
137
138static struct mcast_group *mcast_insert(struct mcast_port *port,
139 struct mcast_group *group,
140 int allow_duplicates)
141{
142 struct rb_node **link = &port->table.rb_node;
143 struct rb_node *parent = NULL;
144 struct mcast_group *cur_group;
145 int ret;
146
147 while (*link) {
148 parent = *link;
149 cur_group = rb_entry(parent, struct mcast_group, node);
150
151 ret = memcmp(group->rec.mgid.raw, cur_group->rec.mgid.raw,
152 sizeof group->rec.mgid);
153 if (ret < 0)
154 link = &(*link)->rb_left;
155 else if (ret > 0)
156 link = &(*link)->rb_right;
157 else if (allow_duplicates)
158 link = &(*link)->rb_left;
159 else
160 return cur_group;
161 }
162 rb_link_node(&group->node, parent, link);
163 rb_insert_color(&group->node, &port->table);
164 return NULL;
165}
166
167static void deref_port(struct mcast_port *port)
168{
169 if (atomic_dec_and_test(&port->refcount))
170 complete(&port->comp);
171}
172
173static void release_group(struct mcast_group *group)
174{
175 struct mcast_port *port = group->port;
176 unsigned long flags;
177
178 spin_lock_irqsave(&port->lock, flags);
179 if (atomic_dec_and_test(&group->refcount)) {
180 rb_erase(&group->node, &port->table);
181 spin_unlock_irqrestore(&port->lock, flags);
182 kfree(group);
183 deref_port(port);
184 } else
185 spin_unlock_irqrestore(&port->lock, flags);
186}
187
188static void deref_member(struct mcast_member *member)
189{
190 if (atomic_dec_and_test(&member->refcount))
191 complete(&member->comp);
192}
193
194static void queue_join(struct mcast_member *member)
195{
196 struct mcast_group *group = member->group;
197 unsigned long flags;
198
199 spin_lock_irqsave(&group->lock, flags);
200 list_add(&member->list, &group->pending_list);
201 if (group->state == MCAST_IDLE) {
202 group->state = MCAST_BUSY;
203 atomic_inc(&group->refcount);
204 queue_work(mcast_wq, &group->work);
205 }
206 spin_unlock_irqrestore(&group->lock, flags);
207}
208
209/*
210 * A multicast group has three types of members: full member, non member, and
211 * send only member. We need to keep track of the number of members of each
212 * type based on their join state. Adjust the number of members the belong to
213 * the specified join states.
214 */
215static void adjust_membership(struct mcast_group *group, u8 join_state, int inc)
216{
217 int i;
218
219 for (i = 0; i < 3; i++, join_state >>= 1)
220 if (join_state & 0x1)
221 group->members[i] += inc;
222}
223
224/*
225 * If a multicast group has zero members left for a particular join state, but
226 * the group is still a member with the SA, we need to leave that join state.
227 * Determine which join states we still belong to, but that do not have any
228 * active members.
229 */
230static u8 get_leave_state(struct mcast_group *group)
231{
232 u8 leave_state = 0;
233 int i;
234
235 for (i = 0; i < 3; i++)
236 if (!group->members[i])
237 leave_state |= (0x1 << i);
238
239 return leave_state & group->rec.join_state;
240}
241
242static int check_selector(ib_sa_comp_mask comp_mask,
243 ib_sa_comp_mask selector_mask,
244 ib_sa_comp_mask value_mask,
245 u8 selector, u8 src_value, u8 dst_value)
246{
247 int err;
248
249 if (!(comp_mask & selector_mask) || !(comp_mask & value_mask))
250 return 0;
251
252 switch (selector) {
253 case IB_SA_GT:
254 err = (src_value <= dst_value);
255 break;
256 case IB_SA_LT:
257 err = (src_value >= dst_value);
258 break;
259 case IB_SA_EQ:
260 err = (src_value != dst_value);
261 break;
262 default:
263 err = 0;
264 break;
265 }
266
267 return err;
268}
269
270static int cmp_rec(struct ib_sa_mcmember_rec *src,
271 struct ib_sa_mcmember_rec *dst, ib_sa_comp_mask comp_mask)
272{
273 /* MGID must already match */
274
275 if (comp_mask & IB_SA_MCMEMBER_REC_PORT_GID &&
276 memcmp(&src->port_gid, &dst->port_gid, sizeof src->port_gid))
277 return -EINVAL;
278 if (comp_mask & IB_SA_MCMEMBER_REC_QKEY && src->qkey != dst->qkey)
279 return -EINVAL;
280 if (comp_mask & IB_SA_MCMEMBER_REC_MLID && src->mlid != dst->mlid)
281 return -EINVAL;
282 if (check_selector(comp_mask, IB_SA_MCMEMBER_REC_MTU_SELECTOR,
283 IB_SA_MCMEMBER_REC_MTU, dst->mtu_selector,
284 src->mtu, dst->mtu))
285 return -EINVAL;
286 if (comp_mask & IB_SA_MCMEMBER_REC_TRAFFIC_CLASS &&
287 src->traffic_class != dst->traffic_class)
288 return -EINVAL;
289 if (comp_mask & IB_SA_MCMEMBER_REC_PKEY && src->pkey != dst->pkey)
290 return -EINVAL;
291 if (check_selector(comp_mask, IB_SA_MCMEMBER_REC_RATE_SELECTOR,
292 IB_SA_MCMEMBER_REC_RATE, dst->rate_selector,
293 src->rate, dst->rate))
294 return -EINVAL;
295 if (check_selector(comp_mask,
296 IB_SA_MCMEMBER_REC_PACKET_LIFE_TIME_SELECTOR,
297 IB_SA_MCMEMBER_REC_PACKET_LIFE_TIME,
298 dst->packet_life_time_selector,
299 src->packet_life_time, dst->packet_life_time))
300 return -EINVAL;
301 if (comp_mask & IB_SA_MCMEMBER_REC_SL && src->sl != dst->sl)
302 return -EINVAL;
303 if (comp_mask & IB_SA_MCMEMBER_REC_FLOW_LABEL &&
304 src->flow_label != dst->flow_label)
305 return -EINVAL;
306 if (comp_mask & IB_SA_MCMEMBER_REC_HOP_LIMIT &&
307 src->hop_limit != dst->hop_limit)
308 return -EINVAL;
309 if (comp_mask & IB_SA_MCMEMBER_REC_SCOPE && src->scope != dst->scope)
310 return -EINVAL;
311
312 /* join_state checked separately, proxy_join ignored */
313
314 return 0;
315}
316
317static int send_join(struct mcast_group *group, struct mcast_member *member)
318{
319 struct mcast_port *port = group->port;
320 int ret;
321
322 group->last_join = member;
323 ret = ib_sa_mcmember_rec_query(&sa_client, port->dev->device,
324 port->port_num, IB_MGMT_METHOD_SET,
325 &member->multicast.rec,
326 member->multicast.comp_mask,
327 3000, GFP_KERNEL, join_handler, group,
328 &group->query);
329 if (ret >= 0) {
330 group->query_id = ret;
331 ret = 0;
332 }
333 return ret;
334}
335
336static int send_leave(struct mcast_group *group, u8 leave_state)
337{
338 struct mcast_port *port = group->port;
339 struct ib_sa_mcmember_rec rec;
340 int ret;
341
342 rec = group->rec;
343 rec.join_state = leave_state;
344
345 ret = ib_sa_mcmember_rec_query(&sa_client, port->dev->device,
346 port->port_num, IB_SA_METHOD_DELETE, &rec,
347 IB_SA_MCMEMBER_REC_MGID |
348 IB_SA_MCMEMBER_REC_PORT_GID |
349 IB_SA_MCMEMBER_REC_JOIN_STATE,
350 3000, GFP_KERNEL, leave_handler,
351 group, &group->query);
352 if (ret >= 0) {
353 group->query_id = ret;
354 ret = 0;
355 }
356 return ret;
357}
358
359static void join_group(struct mcast_group *group, struct mcast_member *member,
360 u8 join_state)
361{
362 member->state = MCAST_MEMBER;
363 adjust_membership(group, join_state, 1);
364 group->rec.join_state |= join_state;
365 member->multicast.rec = group->rec;
366 member->multicast.rec.join_state = join_state;
367 list_move(&member->list, &group->active_list);
368}
369
370static int fail_join(struct mcast_group *group, struct mcast_member *member,
371 int status)
372{
373 spin_lock_irq(&group->lock);
374 list_del_init(&member->list);
375 spin_unlock_irq(&group->lock);
376 return member->multicast.callback(status, &member->multicast);
377}
378
379static void process_group_error(struct mcast_group *group)
380{
381 struct mcast_member *member;
382 int ret;
383
384 spin_lock_irq(&group->lock);
385 while (!list_empty(&group->active_list)) {
386 member = list_entry(group->active_list.next,
387 struct mcast_member, list);
388 atomic_inc(&member->refcount);
389 list_del_init(&member->list);
390 adjust_membership(group, member->multicast.rec.join_state, -1);
391 member->state = MCAST_ERROR;
392 spin_unlock_irq(&group->lock);
393
394 ret = member->multicast.callback(-ENETRESET,
395 &member->multicast);
396 deref_member(member);
397 if (ret)
398 ib_sa_free_multicast(&member->multicast);
399 spin_lock_irq(&group->lock);
400 }
401
402 group->rec.join_state = 0;
403 group->state = MCAST_BUSY;
404 spin_unlock_irq(&group->lock);
405}
406
407static void mcast_work_handler(struct work_struct *work)
408{
409 struct mcast_group *group;
410 struct mcast_member *member;
411 struct ib_sa_multicast *multicast;
412 int status, ret;
413 u8 join_state;
414
415 group = container_of(work, typeof(*group), work);
416retest:
417 spin_lock_irq(&group->lock);
418 while (!list_empty(&group->pending_list) ||
419 (group->state == MCAST_ERROR)) {
420
421 if (group->state == MCAST_ERROR) {
422 spin_unlock_irq(&group->lock);
423 process_group_error(group);
424 goto retest;
425 }
426
427 member = list_entry(group->pending_list.next,
428 struct mcast_member, list);
429 multicast = &member->multicast;
430 join_state = multicast->rec.join_state;
431 atomic_inc(&member->refcount);
432
433 if (join_state == (group->rec.join_state & join_state)) {
434 status = cmp_rec(&group->rec, &multicast->rec,
435 multicast->comp_mask);
436 if (!status)
437 join_group(group, member, join_state);
438 else
439 list_del_init(&member->list);
440 spin_unlock_irq(&group->lock);
441 ret = multicast->callback(status, multicast);
442 } else {
443 spin_unlock_irq(&group->lock);
444 status = send_join(group, member);
445 if (!status) {
446 deref_member(member);
447 return;
448 }
449 ret = fail_join(group, member, status);
450 }
451
452 deref_member(member);
453 if (ret)
454 ib_sa_free_multicast(&member->multicast);
455 spin_lock_irq(&group->lock);
456 }
457
458 join_state = get_leave_state(group);
459 if (join_state) {
460 group->rec.join_state &= ~join_state;
461 spin_unlock_irq(&group->lock);
462 if (send_leave(group, join_state))
463 goto retest;
464 } else {
465 group->state = MCAST_IDLE;
466 spin_unlock_irq(&group->lock);
467 release_group(group);
468 }
469}
470
471/*
472 * Fail a join request if it is still active - at the head of the pending queue.
473 */
474static void process_join_error(struct mcast_group *group, int status)
475{
476 struct mcast_member *member;
477 int ret;
478
479 spin_lock_irq(&group->lock);
480 member = list_entry(group->pending_list.next,
481 struct mcast_member, list);
482 if (group->last_join == member) {
483 atomic_inc(&member->refcount);
484 list_del_init(&member->list);
485 spin_unlock_irq(&group->lock);
486 ret = member->multicast.callback(status, &member->multicast);
487 deref_member(member);
488 if (ret)
489 ib_sa_free_multicast(&member->multicast);
490 } else
491 spin_unlock_irq(&group->lock);
492}
493
494static void join_handler(int status, struct ib_sa_mcmember_rec *rec,
495 void *context)
496{
497 struct mcast_group *group = context;
498
499 if (status)
500 process_join_error(group, status);
501 else {
502 spin_lock_irq(&group->port->lock);
503 group->rec = *rec;
504 if (!memcmp(&mgid0, &group->rec.mgid, sizeof mgid0)) {
505 rb_erase(&group->node, &group->port->table);
506 mcast_insert(group->port, group, 1);
507 }
508 spin_unlock_irq(&group->port->lock);
509 }
510 mcast_work_handler(&group->work);
511}
512
513static void leave_handler(int status, struct ib_sa_mcmember_rec *rec,
514 void *context)
515{
516 struct mcast_group *group = context;
517
518 mcast_work_handler(&group->work);
519}
520
521static struct mcast_group *acquire_group(struct mcast_port *port,
522 union ib_gid *mgid, gfp_t gfp_mask)
523{
524 struct mcast_group *group, *cur_group;
525 unsigned long flags;
526 int is_mgid0;
527
528 is_mgid0 = !memcmp(&mgid0, mgid, sizeof mgid0);
529 if (!is_mgid0) {
530 spin_lock_irqsave(&port->lock, flags);
531 group = mcast_find(port, mgid);
532 if (group)
533 goto found;
534 spin_unlock_irqrestore(&port->lock, flags);
535 }
536
537 group = kzalloc(sizeof *group, gfp_mask);
538 if (!group)
539 return NULL;
540
541 group->port = port;
542 group->rec.mgid = *mgid;
543 INIT_LIST_HEAD(&group->pending_list);
544 INIT_LIST_HEAD(&group->active_list);
545 INIT_WORK(&group->work, mcast_work_handler);
546 spin_lock_init(&group->lock);
547
548 spin_lock_irqsave(&port->lock, flags);
549 cur_group = mcast_insert(port, group, is_mgid0);
550 if (cur_group) {
551 kfree(group);
552 group = cur_group;
553 } else
554 atomic_inc(&port->refcount);
555found:
556 atomic_inc(&group->refcount);
557 spin_unlock_irqrestore(&port->lock, flags);
558 return group;
559}
560
561/*
562 * We serialize all join requests to a single group to make our lives much
563 * easier. Otherwise, two users could try to join the same group
564 * simultaneously, with different configurations, one could leave while the
565 * join is in progress, etc., which makes locking around error recovery
566 * difficult.
567 */
568struct ib_sa_multicast *
569ib_sa_join_multicast(struct ib_sa_client *client,
570 struct ib_device *device, u8 port_num,
571 struct ib_sa_mcmember_rec *rec,
572 ib_sa_comp_mask comp_mask, gfp_t gfp_mask,
573 int (*callback)(int status,
574 struct ib_sa_multicast *multicast),
575 void *context)
576{
577 struct mcast_device *dev;
578 struct mcast_member *member;
579 struct ib_sa_multicast *multicast;
580 int ret;
581
582 dev = ib_get_client_data(device, &mcast_client);
583 if (!dev)
584 return ERR_PTR(-ENODEV);
585
586 member = kmalloc(sizeof *member, gfp_mask);
587 if (!member)
588 return ERR_PTR(-ENOMEM);
589
590 ib_sa_client_get(client);
591 member->client = client;
592 member->multicast.rec = *rec;
593 member->multicast.comp_mask = comp_mask;
594 member->multicast.callback = callback;
595 member->multicast.context = context;
596 init_completion(&member->comp);
597 atomic_set(&member->refcount, 1);
598 member->state = MCAST_JOINING;
599
600 member->group = acquire_group(&dev->port[port_num - dev->start_port],
601 &rec->mgid, gfp_mask);
602 if (!member->group) {
603 ret = -ENOMEM;
604 goto err;
605 }
606
607 /*
608 * The user will get the multicast structure in their callback. They
609 * could then free the multicast structure before we can return from
610 * this routine. So we save the pointer to return before queuing
611 * any callback.
612 */
613 multicast = &member->multicast;
614 queue_join(member);
615 return multicast;
616
617err:
618 ib_sa_client_put(client);
619 kfree(member);
620 return ERR_PTR(ret);
621}
622EXPORT_SYMBOL(ib_sa_join_multicast);
623
624void ib_sa_free_multicast(struct ib_sa_multicast *multicast)
625{
626 struct mcast_member *member;
627 struct mcast_group *group;
628
629 member = container_of(multicast, struct mcast_member, multicast);
630 group = member->group;
631
632 spin_lock_irq(&group->lock);
633 if (member->state == MCAST_MEMBER)
634 adjust_membership(group, multicast->rec.join_state, -1);
635
636 list_del_init(&member->list);
637
638 if (group->state == MCAST_IDLE) {
639 group->state = MCAST_BUSY;
640 spin_unlock_irq(&group->lock);
641 /* Continue to hold reference on group until callback */
642 queue_work(mcast_wq, &group->work);
643 } else {
644 spin_unlock_irq(&group->lock);
645 release_group(group);
646 }
647
648 deref_member(member);
649 wait_for_completion(&member->comp);
650 ib_sa_client_put(member->client);
651 kfree(member);
652}
653EXPORT_SYMBOL(ib_sa_free_multicast);
654
655int ib_sa_get_mcmember_rec(struct ib_device *device, u8 port_num,
656 union ib_gid *mgid, struct ib_sa_mcmember_rec *rec)
657{
658 struct mcast_device *dev;
659 struct mcast_port *port;
660 struct mcast_group *group;
661 unsigned long flags;
662 int ret = 0;
663
664 dev = ib_get_client_data(device, &mcast_client);
665 if (!dev)
666 return -ENODEV;
667
668 port = &dev->port[port_num - dev->start_port];
669 spin_lock_irqsave(&port->lock, flags);
670 group = mcast_find(port, mgid);
671 if (group)
672 *rec = group->rec;
673 else
674 ret = -EADDRNOTAVAIL;
675 spin_unlock_irqrestore(&port->lock, flags);
676
677 return ret;
678}
679EXPORT_SYMBOL(ib_sa_get_mcmember_rec);
680
681int ib_init_ah_from_mcmember(struct ib_device *device, u8 port_num,
682 struct ib_sa_mcmember_rec *rec,
683 struct ib_ah_attr *ah_attr)
684{
685 int ret;
686 u16 gid_index;
687 u8 p;
688
689 ret = ib_find_cached_gid(device, &rec->port_gid, &p, &gid_index);
690 if (ret)
691 return ret;
692
693 memset(ah_attr, 0, sizeof *ah_attr);
694 ah_attr->dlid = be16_to_cpu(rec->mlid);
695 ah_attr->sl = rec->sl;
696 ah_attr->port_num = port_num;
697 ah_attr->static_rate = rec->rate;
698
699 ah_attr->ah_flags = IB_AH_GRH;
700 ah_attr->grh.dgid = rec->mgid;
701
702 ah_attr->grh.sgid_index = (u8) gid_index;
703 ah_attr->grh.flow_label = be32_to_cpu(rec->flow_label);
704 ah_attr->grh.hop_limit = rec->hop_limit;
705 ah_attr->grh.traffic_class = rec->traffic_class;
706
707 return 0;
708}
709EXPORT_SYMBOL(ib_init_ah_from_mcmember);
710
711static void mcast_groups_lost(struct mcast_port *port)
712{
713 struct mcast_group *group;
714 struct rb_node *node;
715 unsigned long flags;
716
717 spin_lock_irqsave(&port->lock, flags);
718 for (node = rb_first(&port->table); node; node = rb_next(node)) {
719 group = rb_entry(node, struct mcast_group, node);
720 spin_lock(&group->lock);
721 if (group->state == MCAST_IDLE) {
722 atomic_inc(&group->refcount);
723 queue_work(mcast_wq, &group->work);
724 }
725 group->state = MCAST_ERROR;
726 spin_unlock(&group->lock);
727 }
728 spin_unlock_irqrestore(&port->lock, flags);
729}
730
731static void mcast_event_handler(struct ib_event_handler *handler,
732 struct ib_event *event)
733{
734 struct mcast_device *dev;
735
736 dev = container_of(handler, struct mcast_device, event_handler);
737
738 switch (event->event) {
739 case IB_EVENT_PORT_ERR:
740 case IB_EVENT_LID_CHANGE:
741 case IB_EVENT_SM_CHANGE:
742 case IB_EVENT_CLIENT_REREGISTER:
743 mcast_groups_lost(&dev->port[event->element.port_num -
744 dev->start_port]);
745 break;
746 default:
747 break;
748 }
749}
750
751static void mcast_add_one(struct ib_device *device)
752{
753 struct mcast_device *dev;
754 struct mcast_port *port;
755 int i;
756
757 if (rdma_node_get_transport(device->node_type) != RDMA_TRANSPORT_IB)
758 return;
759
760 dev = kmalloc(sizeof *dev + device->phys_port_cnt * sizeof *port,
761 GFP_KERNEL);
762 if (!dev)
763 return;
764
765 if (device->node_type == RDMA_NODE_IB_SWITCH)
766 dev->start_port = dev->end_port = 0;
767 else {
768 dev->start_port = 1;
769 dev->end_port = device->phys_port_cnt;
770 }
771
772 for (i = 0; i <= dev->end_port - dev->start_port; i++) {
773 port = &dev->port[i];
774 port->dev = dev;
775 port->port_num = dev->start_port + i;
776 spin_lock_init(&port->lock);
777 port->table = RB_ROOT;
778 init_completion(&port->comp);
779 atomic_set(&port->refcount, 1);
780 }
781
782 dev->device = device;
783 ib_set_client_data(device, &mcast_client, dev);
784
785 INIT_IB_EVENT_HANDLER(&dev->event_handler, device, mcast_event_handler);
786 ib_register_event_handler(&dev->event_handler);
787}
788
789static void mcast_remove_one(struct ib_device *device)
790{
791 struct mcast_device *dev;
792 struct mcast_port *port;
793 int i;
794
795 dev = ib_get_client_data(device, &mcast_client);
796 if (!dev)
797 return;
798
799 ib_unregister_event_handler(&dev->event_handler);
800 flush_workqueue(mcast_wq);
801
802 for (i = 0; i <= dev->end_port - dev->start_port; i++) {
803 port = &dev->port[i];
804 deref_port(port);
805 wait_for_completion(&port->comp);
806 }
807
808 kfree(dev);
809}
810
811int mcast_init(void)
812{
813 int ret;
814
815 mcast_wq = create_singlethread_workqueue("ib_mcast");
816 if (!mcast_wq)
817 return -ENOMEM;
818
819 ib_sa_register_client(&sa_client);
820
821 ret = ib_register_client(&mcast_client);
822 if (ret)
823 goto err;
824 return 0;
825
826err:
827 ib_sa_unregister_client(&sa_client);
828 destroy_workqueue(mcast_wq);
829 return ret;
830}
831
832void mcast_cleanup(void)
833{
834 ib_unregister_client(&mcast_client);
835 ib_sa_unregister_client(&sa_client);
836 destroy_workqueue(mcast_wq);
837}
diff --git a/drivers/infiniband/core/sa.h b/drivers/infiniband/core/sa.h
new file mode 100644
index 000000000000..24c93fd320fb
--- /dev/null
+++ b/drivers/infiniband/core/sa.h
@@ -0,0 +1,66 @@
1/*
2 * Copyright (c) 2004 Topspin Communications. All rights reserved.
3 * Copyright (c) 2005 Voltaire, Inc.  All rights reserved.
4 * Copyright (c) 2006 Intel Corporation. All rights reserved.
5 *
6 * This software is available to you under a choice of one of two
7 * licenses. You may choose to be licensed under the terms of the GNU
8 * General Public License (GPL) Version 2, available from the file
9 * COPYING in the main directory of this source tree, or the
10 * OpenIB.org BSD license below:
11 *
12 * Redistribution and use in source and binary forms, with or
13 * without modification, are permitted provided that the following
14 * conditions are met:
15 *
16 * - Redistributions of source code must retain the above
17 * copyright notice, this list of conditions and the following
18 * disclaimer.
19 *
20 * - Redistributions in binary form must reproduce the above
21 * copyright notice, this list of conditions and the following
22 * disclaimer in the documentation and/or other materials
23 * provided with the distribution.
24 *
25 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
26 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
27 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
28 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
29 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
30 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
31 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
32 * SOFTWARE.
33 */
34
35#ifndef SA_H
36#define SA_H
37
38#include <rdma/ib_sa.h>
39
40static inline void ib_sa_client_get(struct ib_sa_client *client)
41{
42 atomic_inc(&client->users);
43}
44
45static inline void ib_sa_client_put(struct ib_sa_client *client)
46{
47 if (atomic_dec_and_test(&client->users))
48 complete(&client->comp);
49}
50
51int ib_sa_mcmember_rec_query(struct ib_sa_client *client,
52 struct ib_device *device, u8 port_num,
53 u8 method,
54 struct ib_sa_mcmember_rec *rec,
55 ib_sa_comp_mask comp_mask,
56 int timeout_ms, gfp_t gfp_mask,
57 void (*callback)(int status,
58 struct ib_sa_mcmember_rec *resp,
59 void *context),
60 void *context,
61 struct ib_sa_query **sa_query);
62
63int mcast_init(void);
64void mcast_cleanup(void);
65
66#endif /* SA_H */
diff --git a/drivers/infiniband/core/sa_query.c b/drivers/infiniband/core/sa_query.c
index e45afba75341..68db633711c5 100644
--- a/drivers/infiniband/core/sa_query.c
+++ b/drivers/infiniband/core/sa_query.c
@@ -47,8 +47,8 @@
47#include <linux/workqueue.h> 47#include <linux/workqueue.h>
48 48
49#include <rdma/ib_pack.h> 49#include <rdma/ib_pack.h>
50#include <rdma/ib_sa.h>
51#include <rdma/ib_cache.h> 50#include <rdma/ib_cache.h>
51#include "sa.h"
52 52
53MODULE_AUTHOR("Roland Dreier"); 53MODULE_AUTHOR("Roland Dreier");
54MODULE_DESCRIPTION("InfiniBand subnet administration query support"); 54MODULE_DESCRIPTION("InfiniBand subnet administration query support");
@@ -425,17 +425,6 @@ void ib_sa_register_client(struct ib_sa_client *client)
425} 425}
426EXPORT_SYMBOL(ib_sa_register_client); 426EXPORT_SYMBOL(ib_sa_register_client);
427 427
428static inline void ib_sa_client_get(struct ib_sa_client *client)
429{
430 atomic_inc(&client->users);
431}
432
433static inline void ib_sa_client_put(struct ib_sa_client *client)
434{
435 if (atomic_dec_and_test(&client->users))
436 complete(&client->comp);
437}
438
439void ib_sa_unregister_client(struct ib_sa_client *client) 428void ib_sa_unregister_client(struct ib_sa_client *client)
440{ 429{
441 ib_sa_client_put(client); 430 ib_sa_client_put(client);
@@ -482,6 +471,7 @@ int ib_init_ah_from_path(struct ib_device *device, u8 port_num,
482 ah_attr->sl = rec->sl; 471 ah_attr->sl = rec->sl;
483 ah_attr->src_path_bits = be16_to_cpu(rec->slid) & 0x7f; 472 ah_attr->src_path_bits = be16_to_cpu(rec->slid) & 0x7f;
484 ah_attr->port_num = port_num; 473 ah_attr->port_num = port_num;
474 ah_attr->static_rate = rec->rate;
485 475
486 if (rec->hop_limit > 1) { 476 if (rec->hop_limit > 1) {
487 ah_attr->ah_flags = IB_AH_GRH; 477 ah_attr->ah_flags = IB_AH_GRH;
@@ -901,7 +891,6 @@ err1:
901 kfree(query); 891 kfree(query);
902 return ret; 892 return ret;
903} 893}
904EXPORT_SYMBOL(ib_sa_mcmember_rec_query);
905 894
906static void send_handler(struct ib_mad_agent *agent, 895static void send_handler(struct ib_mad_agent *agent,
907 struct ib_mad_send_wc *mad_send_wc) 896 struct ib_mad_send_wc *mad_send_wc)
@@ -1053,14 +1042,27 @@ static int __init ib_sa_init(void)
1053 get_random_bytes(&tid, sizeof tid); 1042 get_random_bytes(&tid, sizeof tid);
1054 1043
1055 ret = ib_register_client(&sa_client); 1044 ret = ib_register_client(&sa_client);
1056 if (ret) 1045 if (ret) {
1057 printk(KERN_ERR "Couldn't register ib_sa client\n"); 1046 printk(KERN_ERR "Couldn't register ib_sa client\n");
1047 goto err1;
1048 }
1049
1050 ret = mcast_init();
1051 if (ret) {
1052 printk(KERN_ERR "Couldn't initialize multicast handling\n");
1053 goto err2;
1054 }
1058 1055
1056 return 0;
1057err2:
1058 ib_unregister_client(&sa_client);
1059err1:
1059 return ret; 1060 return ret;
1060} 1061}
1061 1062
1062static void __exit ib_sa_cleanup(void) 1063static void __exit ib_sa_cleanup(void)
1063{ 1064{
1065 mcast_cleanup();
1064 ib_unregister_client(&sa_client); 1066 ib_unregister_client(&sa_client);
1065 idr_destroy(&query_idr); 1067 idr_destroy(&query_idr);
1066} 1068}
diff --git a/drivers/infiniband/core/sysfs.c b/drivers/infiniband/core/sysfs.c
index 709323c14c5d..000c086bf2e9 100644
--- a/drivers/infiniband/core/sysfs.c
+++ b/drivers/infiniband/core/sysfs.c
@@ -714,8 +714,6 @@ int ib_device_register_sysfs(struct ib_device *device)
714 if (ret) 714 if (ret)
715 goto err_put; 715 goto err_put;
716 } else { 716 } else {
717 int i;
718
719 for (i = 1; i <= device->phys_port_cnt; ++i) { 717 for (i = 1; i <= device->phys_port_cnt; ++i) {
720 ret = add_port(device, i); 718 ret = add_port(device, i);
721 if (ret) 719 if (ret)
diff --git a/drivers/infiniband/core/ucma.c b/drivers/infiniband/core/ucma.c
index 6b81b98961c7..b516b93b8550 100644
--- a/drivers/infiniband/core/ucma.c
+++ b/drivers/infiniband/core/ucma.c
@@ -70,10 +70,24 @@ struct ucma_context {
70 u64 uid; 70 u64 uid;
71 71
72 struct list_head list; 72 struct list_head list;
73 struct list_head mc_list;
74};
75
76struct ucma_multicast {
77 struct ucma_context *ctx;
78 int id;
79 int events_reported;
80
81 u64 uid;
82 struct list_head list;
83 struct sockaddr addr;
84 u8 pad[sizeof(struct sockaddr_in6) -
85 sizeof(struct sockaddr)];
73}; 86};
74 87
75struct ucma_event { 88struct ucma_event {
76 struct ucma_context *ctx; 89 struct ucma_context *ctx;
90 struct ucma_multicast *mc;
77 struct list_head list; 91 struct list_head list;
78 struct rdma_cm_id *cm_id; 92 struct rdma_cm_id *cm_id;
79 struct rdma_ucm_event_resp resp; 93 struct rdma_ucm_event_resp resp;
@@ -81,6 +95,7 @@ struct ucma_event {
81 95
82static DEFINE_MUTEX(mut); 96static DEFINE_MUTEX(mut);
83static DEFINE_IDR(ctx_idr); 97static DEFINE_IDR(ctx_idr);
98static DEFINE_IDR(multicast_idr);
84 99
85static inline struct ucma_context *_ucma_find_context(int id, 100static inline struct ucma_context *_ucma_find_context(int id,
86 struct ucma_file *file) 101 struct ucma_file *file)
@@ -124,6 +139,7 @@ static struct ucma_context *ucma_alloc_ctx(struct ucma_file *file)
124 139
125 atomic_set(&ctx->ref, 1); 140 atomic_set(&ctx->ref, 1);
126 init_completion(&ctx->comp); 141 init_completion(&ctx->comp);
142 INIT_LIST_HEAD(&ctx->mc_list);
127 ctx->file = file; 143 ctx->file = file;
128 144
129 do { 145 do {
@@ -147,6 +163,37 @@ error:
147 return NULL; 163 return NULL;
148} 164}
149 165
166static struct ucma_multicast* ucma_alloc_multicast(struct ucma_context *ctx)
167{
168 struct ucma_multicast *mc;
169 int ret;
170
171 mc = kzalloc(sizeof(*mc), GFP_KERNEL);
172 if (!mc)
173 return NULL;
174
175 do {
176 ret = idr_pre_get(&multicast_idr, GFP_KERNEL);
177 if (!ret)
178 goto error;
179
180 mutex_lock(&mut);
181 ret = idr_get_new(&multicast_idr, mc, &mc->id);
182 mutex_unlock(&mut);
183 } while (ret == -EAGAIN);
184
185 if (ret)
186 goto error;
187
188 mc->ctx = ctx;
189 list_add_tail(&mc->list, &ctx->mc_list);
190 return mc;
191
192error:
193 kfree(mc);
194 return NULL;
195}
196
150static void ucma_copy_conn_event(struct rdma_ucm_conn_param *dst, 197static void ucma_copy_conn_event(struct rdma_ucm_conn_param *dst,
151 struct rdma_conn_param *src) 198 struct rdma_conn_param *src)
152{ 199{
@@ -180,8 +227,19 @@ static void ucma_set_event_context(struct ucma_context *ctx,
180 struct ucma_event *uevent) 227 struct ucma_event *uevent)
181{ 228{
182 uevent->ctx = ctx; 229 uevent->ctx = ctx;
183 uevent->resp.uid = ctx->uid; 230 switch (event->event) {
184 uevent->resp.id = ctx->id; 231 case RDMA_CM_EVENT_MULTICAST_JOIN:
232 case RDMA_CM_EVENT_MULTICAST_ERROR:
233 uevent->mc = (struct ucma_multicast *)
234 event->param.ud.private_data;
235 uevent->resp.uid = uevent->mc->uid;
236 uevent->resp.id = uevent->mc->id;
237 break;
238 default:
239 uevent->resp.uid = ctx->uid;
240 uevent->resp.id = ctx->id;
241 break;
242 }
185} 243}
186 244
187static int ucma_event_handler(struct rdma_cm_id *cm_id, 245static int ucma_event_handler(struct rdma_cm_id *cm_id,
@@ -199,7 +257,7 @@ static int ucma_event_handler(struct rdma_cm_id *cm_id,
199 ucma_set_event_context(ctx, event, uevent); 257 ucma_set_event_context(ctx, event, uevent);
200 uevent->resp.event = event->event; 258 uevent->resp.event = event->event;
201 uevent->resp.status = event->status; 259 uevent->resp.status = event->status;
202 if (cm_id->ps == RDMA_PS_UDP) 260 if (cm_id->ps == RDMA_PS_UDP || cm_id->ps == RDMA_PS_IPOIB)
203 ucma_copy_ud_event(&uevent->resp.param.ud, &event->param.ud); 261 ucma_copy_ud_event(&uevent->resp.param.ud, &event->param.ud);
204 else 262 else
205 ucma_copy_conn_event(&uevent->resp.param.conn, 263 ucma_copy_conn_event(&uevent->resp.param.conn,
@@ -290,6 +348,8 @@ static ssize_t ucma_get_event(struct ucma_file *file, const char __user *inbuf,
290 348
291 list_del(&uevent->list); 349 list_del(&uevent->list);
292 uevent->ctx->events_reported++; 350 uevent->ctx->events_reported++;
351 if (uevent->mc)
352 uevent->mc->events_reported++;
293 kfree(uevent); 353 kfree(uevent);
294done: 354done:
295 mutex_unlock(&file->mut); 355 mutex_unlock(&file->mut);
@@ -342,6 +402,19 @@ err1:
342 return ret; 402 return ret;
343} 403}
344 404
405static void ucma_cleanup_multicast(struct ucma_context *ctx)
406{
407 struct ucma_multicast *mc, *tmp;
408
409 mutex_lock(&mut);
410 list_for_each_entry_safe(mc, tmp, &ctx->mc_list, list) {
411 list_del(&mc->list);
412 idr_remove(&multicast_idr, mc->id);
413 kfree(mc);
414 }
415 mutex_unlock(&mut);
416}
417
345static void ucma_cleanup_events(struct ucma_context *ctx) 418static void ucma_cleanup_events(struct ucma_context *ctx)
346{ 419{
347 struct ucma_event *uevent, *tmp; 420 struct ucma_event *uevent, *tmp;
@@ -360,6 +433,19 @@ static void ucma_cleanup_events(struct ucma_context *ctx)
360 } 433 }
361} 434}
362 435
436static void ucma_cleanup_mc_events(struct ucma_multicast *mc)
437{
438 struct ucma_event *uevent, *tmp;
439
440 list_for_each_entry_safe(uevent, tmp, &mc->ctx->file->event_list, list) {
441 if (uevent->mc != mc)
442 continue;
443
444 list_del(&uevent->list);
445 kfree(uevent);
446 }
447}
448
363static int ucma_free_ctx(struct ucma_context *ctx) 449static int ucma_free_ctx(struct ucma_context *ctx)
364{ 450{
365 int events_reported; 451 int events_reported;
@@ -367,6 +453,8 @@ static int ucma_free_ctx(struct ucma_context *ctx)
367 /* No new events will be generated after destroying the id. */ 453 /* No new events will be generated after destroying the id. */
368 rdma_destroy_id(ctx->cm_id); 454 rdma_destroy_id(ctx->cm_id);
369 455
456 ucma_cleanup_multicast(ctx);
457
370 /* Cleanup events not yet reported to the user. */ 458 /* Cleanup events not yet reported to the user. */
371 mutex_lock(&ctx->file->mut); 459 mutex_lock(&ctx->file->mut);
372 ucma_cleanup_events(ctx); 460 ucma_cleanup_events(ctx);
@@ -731,6 +819,114 @@ static ssize_t ucma_notify(struct ucma_file *file, const char __user *inbuf,
731 return ret; 819 return ret;
732} 820}
733 821
822static ssize_t ucma_join_multicast(struct ucma_file *file,
823 const char __user *inbuf,
824 int in_len, int out_len)
825{
826 struct rdma_ucm_join_mcast cmd;
827 struct rdma_ucm_create_id_resp resp;
828 struct ucma_context *ctx;
829 struct ucma_multicast *mc;
830 int ret;
831
832 if (out_len < sizeof(resp))
833 return -ENOSPC;
834
835 if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
836 return -EFAULT;
837
838 ctx = ucma_get_ctx(file, cmd.id);
839 if (IS_ERR(ctx))
840 return PTR_ERR(ctx);
841
842 mutex_lock(&file->mut);
843 mc = ucma_alloc_multicast(ctx);
844 if (IS_ERR(mc)) {
845 ret = PTR_ERR(mc);
846 goto err1;
847 }
848
849 mc->uid = cmd.uid;
850 memcpy(&mc->addr, &cmd.addr, sizeof cmd.addr);
851 ret = rdma_join_multicast(ctx->cm_id, &mc->addr, mc);
852 if (ret)
853 goto err2;
854
855 resp.id = mc->id;
856 if (copy_to_user((void __user *)(unsigned long)cmd.response,
857 &resp, sizeof(resp))) {
858 ret = -EFAULT;
859 goto err3;
860 }
861
862 mutex_unlock(&file->mut);
863 ucma_put_ctx(ctx);
864 return 0;
865
866err3:
867 rdma_leave_multicast(ctx->cm_id, &mc->addr);
868 ucma_cleanup_mc_events(mc);
869err2:
870 mutex_lock(&mut);
871 idr_remove(&multicast_idr, mc->id);
872 mutex_unlock(&mut);
873 list_del(&mc->list);
874 kfree(mc);
875err1:
876 mutex_unlock(&file->mut);
877 ucma_put_ctx(ctx);
878 return ret;
879}
880
881static ssize_t ucma_leave_multicast(struct ucma_file *file,
882 const char __user *inbuf,
883 int in_len, int out_len)
884{
885 struct rdma_ucm_destroy_id cmd;
886 struct rdma_ucm_destroy_id_resp resp;
887 struct ucma_multicast *mc;
888 int ret = 0;
889
890 if (out_len < sizeof(resp))
891 return -ENOSPC;
892
893 if (copy_from_user(&cmd, inbuf, sizeof(cmd)))
894 return -EFAULT;
895
896 mutex_lock(&mut);
897 mc = idr_find(&multicast_idr, cmd.id);
898 if (!mc)
899 mc = ERR_PTR(-ENOENT);
900 else if (mc->ctx->file != file)
901 mc = ERR_PTR(-EINVAL);
902 else {
903 idr_remove(&multicast_idr, mc->id);
904 atomic_inc(&mc->ctx->ref);
905 }
906 mutex_unlock(&mut);
907
908 if (IS_ERR(mc)) {
909 ret = PTR_ERR(mc);
910 goto out;
911 }
912
913 rdma_leave_multicast(mc->ctx->cm_id, &mc->addr);
914 mutex_lock(&mc->ctx->file->mut);
915 ucma_cleanup_mc_events(mc);
916 list_del(&mc->list);
917 mutex_unlock(&mc->ctx->file->mut);
918
919 ucma_put_ctx(mc->ctx);
920 resp.events_reported = mc->events_reported;
921 kfree(mc);
922
923 if (copy_to_user((void __user *)(unsigned long)cmd.response,
924 &resp, sizeof(resp)))
925 ret = -EFAULT;
926out:
927 return ret;
928}
929
734static ssize_t (*ucma_cmd_table[])(struct ucma_file *file, 930static ssize_t (*ucma_cmd_table[])(struct ucma_file *file,
735 const char __user *inbuf, 931 const char __user *inbuf,
736 int in_len, int out_len) = { 932 int in_len, int out_len) = {
@@ -750,6 +946,8 @@ static ssize_t (*ucma_cmd_table[])(struct ucma_file *file,
750 [RDMA_USER_CM_CMD_GET_OPTION] = NULL, 946 [RDMA_USER_CM_CMD_GET_OPTION] = NULL,
751 [RDMA_USER_CM_CMD_SET_OPTION] = NULL, 947 [RDMA_USER_CM_CMD_SET_OPTION] = NULL,
752 [RDMA_USER_CM_CMD_NOTIFY] = ucma_notify, 948 [RDMA_USER_CM_CMD_NOTIFY] = ucma_notify,
949 [RDMA_USER_CM_CMD_JOIN_MCAST] = ucma_join_multicast,
950 [RDMA_USER_CM_CMD_LEAVE_MCAST] = ucma_leave_multicast,
753}; 951};
754 952
755static ssize_t ucma_write(struct file *filp, const char __user *buf, 953static ssize_t ucma_write(struct file *filp, const char __user *buf,
diff --git a/drivers/infiniband/hw/cxgb3/cxio_dbg.c b/drivers/infiniband/hw/cxgb3/cxio_dbg.c
index 5a7306f5efae..75f7b16a271d 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_dbg.c
+++ b/drivers/infiniband/hw/cxgb3/cxio_dbg.c
@@ -1,6 +1,5 @@
1/* 1/*
2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
3 * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
4 * 3 *
5 * This software is available to you under a choice of one of two 4 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 5 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.c b/drivers/infiniband/hw/cxgb3/cxio_hal.c
index 82fa72041989..114ac3b775dc 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.c
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.c
@@ -1,6 +1,5 @@
1/* 1/*
2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
3 * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
4 * 3 *
5 * This software is available to you under a choice of one of two 4 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 5 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/cxio_hal.h b/drivers/infiniband/hw/cxgb3/cxio_hal.h
index 1b97e80b8780..8ab04a7c6f6e 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_hal.h
+++ b/drivers/infiniband/hw/cxgb3/cxio_hal.h
@@ -1,6 +1,5 @@
1/* 1/*
2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
3 * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
4 * 3 *
5 * This software is available to you under a choice of one of two 4 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 5 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/cxio_resource.c b/drivers/infiniband/hw/cxgb3/cxio_resource.c
index 997aa32cbf07..65bf577311aa 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_resource.c
+++ b/drivers/infiniband/hw/cxgb3/cxio_resource.c
@@ -1,6 +1,5 @@
1/* 1/*
2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
3 * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
4 * 3 *
5 * This software is available to you under a choice of one of two 4 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 5 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/cxio_resource.h b/drivers/infiniband/hw/cxgb3/cxio_resource.h
index a6bbe8370d81..a2703a3d882d 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_resource.h
+++ b/drivers/infiniband/hw/cxgb3/cxio_resource.h
@@ -1,6 +1,5 @@
1/* 1/*
2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
3 * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
4 * 3 *
5 * This software is available to you under a choice of one of two 4 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 5 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/cxio_wr.h b/drivers/infiniband/hw/cxgb3/cxio_wr.h
index 103fc42d6976..90d7b8972cb4 100644
--- a/drivers/infiniband/hw/cxgb3/cxio_wr.h
+++ b/drivers/infiniband/hw/cxgb3/cxio_wr.h
@@ -1,6 +1,5 @@
1/* 1/*
2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
3 * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
4 * 3 *
5 * This software is available to you under a choice of one of two 4 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 5 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/iwch.c b/drivers/infiniband/hw/cxgb3/iwch.c
index 4611afa52220..0315c9d9fce9 100644
--- a/drivers/infiniband/hw/cxgb3/iwch.c
+++ b/drivers/infiniband/hw/cxgb3/iwch.c
@@ -1,6 +1,5 @@
1/* 1/*
2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
3 * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
4 * 3 *
5 * This software is available to you under a choice of one of two 4 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 5 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/iwch.h b/drivers/infiniband/hw/cxgb3/iwch.h
index 6517ef85026f..caf4e6007a44 100644
--- a/drivers/infiniband/hw/cxgb3/iwch.h
+++ b/drivers/infiniband/hw/cxgb3/iwch.h
@@ -1,6 +1,5 @@
1/* 1/*
2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
3 * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
4 * 3 *
5 * This software is available to you under a choice of one of two 4 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 5 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.c b/drivers/infiniband/hw/cxgb3/iwch_cm.c
index a522b1baa3b4..e5442e34b788 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.c
@@ -1,6 +1,5 @@
1/* 1/*
2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
3 * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
4 * 3 *
5 * This software is available to you under a choice of one of two 4 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 5 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cm.h b/drivers/infiniband/hw/cxgb3/iwch_cm.h
index 7c810d904279..0c6f281bd4a0 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cm.h
+++ b/drivers/infiniband/hw/cxgb3/iwch_cm.h
@@ -1,6 +1,5 @@
1/* 1/*
2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
3 * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
4 * 3 *
5 * This software is available to you under a choice of one of two 4 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 5 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/iwch_cq.c b/drivers/infiniband/hw/cxgb3/iwch_cq.c
index 98b3bdb5de9e..d7624c170ee7 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_cq.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_cq.c
@@ -1,6 +1,5 @@
1/* 1/*
2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
3 * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
4 * 3 *
5 * This software is available to you under a choice of one of two 4 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 5 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/iwch_ev.c b/drivers/infiniband/hw/cxgb3/iwch_ev.c
index a6efa8fe15d8..54362afbf72f 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_ev.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_ev.c
@@ -1,6 +1,5 @@
1/* 1/*
2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
3 * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
4 * 3 *
5 * This software is available to you under a choice of one of two 4 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 5 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/iwch_mem.c b/drivers/infiniband/hw/cxgb3/iwch_mem.c
index 2b6cd53bb3fc..a6c2c4ba29e6 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_mem.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_mem.c
@@ -1,6 +1,5 @@
1/* 1/*
2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
3 * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
4 * 3 *
5 * This software is available to you under a choice of one of two 4 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 5 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.c b/drivers/infiniband/hw/cxgb3/iwch_provider.c
index 6861087d776c..2aef122f9955 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.c
@@ -1,6 +1,5 @@
1/* 1/*
2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
3 * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
4 * 3 *
5 * This software is available to you under a choice of one of two 4 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 5 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/iwch_provider.h b/drivers/infiniband/hw/cxgb3/iwch_provider.h
index 61e3278fd7a8..2af3e93b607f 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_provider.h
+++ b/drivers/infiniband/hw/cxgb3/iwch_provider.h
@@ -1,6 +1,5 @@
1/* 1/*
2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
3 * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
4 * 3 *
5 * This software is available to you under a choice of one of two 4 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 5 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/cxgb3/iwch_qp.c b/drivers/infiniband/hw/cxgb3/iwch_qp.c
index e066727504b6..4dda2f6da2de 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_qp.c
+++ b/drivers/infiniband/hw/cxgb3/iwch_qp.c
@@ -1,6 +1,5 @@
1/* 1/*
2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
3 * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
4 * 3 *
5 * This software is available to you under a choice of one of two 4 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 5 * licenses. You may choose to be licensed under the terms of the GNU
@@ -846,6 +845,8 @@ int iwch_modify_qp(struct iwch_dev *rhp, struct iwch_qp *qhp,
846 break; 845 break;
847 case IWCH_QP_STATE_TERMINATE: 846 case IWCH_QP_STATE_TERMINATE:
848 qhp->attr.state = IWCH_QP_STATE_TERMINATE; 847 qhp->attr.state = IWCH_QP_STATE_TERMINATE;
848 if (t3b_device(qhp->rhp))
849 cxio_set_wq_in_error(&qhp->wq);
849 if (!internal) 850 if (!internal)
850 terminate = 1; 851 terminate = 1;
851 break; 852 break;
diff --git a/drivers/infiniband/hw/cxgb3/iwch_user.h b/drivers/infiniband/hw/cxgb3/iwch_user.h
index c4e7fbea8bbd..cb7086f558c1 100644
--- a/drivers/infiniband/hw/cxgb3/iwch_user.h
+++ b/drivers/infiniband/hw/cxgb3/iwch_user.h
@@ -1,6 +1,5 @@
1/* 1/*
2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved. 2 * Copyright (c) 2006 Chelsio, Inc. All rights reserved.
3 * Copyright (c) 2006 Open Grid Computing, Inc. All rights reserved.
4 * 3 *
5 * This software is available to you under a choice of one of two 4 * This software is available to you under a choice of one of two
6 * licenses. You may choose to be licensed under the terms of the GNU 5 * licenses. You may choose to be licensed under the terms of the GNU
diff --git a/drivers/infiniband/hw/ehca/Kconfig b/drivers/infiniband/hw/ehca/Kconfig
index 727b10d89686..1a854598e0e6 100644
--- a/drivers/infiniband/hw/ehca/Kconfig
+++ b/drivers/infiniband/hw/ehca/Kconfig
@@ -7,11 +7,3 @@ config INFINIBAND_EHCA
7 To compile the driver as a module, choose M here. The module 7 To compile the driver as a module, choose M here. The module
8 will be called ib_ehca. 8 will be called ib_ehca.
9 9
10config INFINIBAND_EHCA_SCALING
11 bool "Scaling support (EXPERIMENTAL)"
12 depends on IBMEBUS && INFINIBAND_EHCA && HOTPLUG_CPU && EXPERIMENTAL
13 default y
14 ---help---
15 eHCA scaling support schedules the CQ callbacks to different CPUs.
16
17 To enable this feature choose Y here.
diff --git a/drivers/infiniband/hw/ehca/ehca_classes.h b/drivers/infiniband/hw/ehca/ehca_classes.h
index cf95ee474b0f..40404c9e2817 100644
--- a/drivers/infiniband/hw/ehca/ehca_classes.h
+++ b/drivers/infiniband/hw/ehca/ehca_classes.h
@@ -42,8 +42,6 @@
42#ifndef __EHCA_CLASSES_H__ 42#ifndef __EHCA_CLASSES_H__
43#define __EHCA_CLASSES_H__ 43#define __EHCA_CLASSES_H__
44 44
45#include "ehca_classes.h"
46#include "ipz_pt_fn.h"
47 45
48struct ehca_module; 46struct ehca_module;
49struct ehca_qp; 47struct ehca_qp;
@@ -54,14 +52,22 @@ struct ehca_mw;
54struct ehca_pd; 52struct ehca_pd;
55struct ehca_av; 53struct ehca_av;
56 54
55#include <rdma/ib_verbs.h>
56#include <rdma/ib_user_verbs.h>
57
57#ifdef CONFIG_PPC64 58#ifdef CONFIG_PPC64
58#include "ehca_classes_pSeries.h" 59#include "ehca_classes_pSeries.h"
59#endif 60#endif
61#include "ipz_pt_fn.h"
62#include "ehca_qes.h"
63#include "ehca_irq.h"
60 64
61#include <rdma/ib_verbs.h> 65#define EHCA_EQE_CACHE_SIZE 20
62#include <rdma/ib_user_verbs.h>
63 66
64#include "ehca_irq.h" 67struct ehca_eqe_cache_entry {
68 struct ehca_eqe *eqe;
69 struct ehca_cq *cq;
70};
65 71
66struct ehca_eq { 72struct ehca_eq {
67 u32 length; 73 u32 length;
@@ -74,6 +80,8 @@ struct ehca_eq {
74 spinlock_t spinlock; 80 spinlock_t spinlock;
75 struct tasklet_struct interrupt_task; 81 struct tasklet_struct interrupt_task;
76 u32 ist; 82 u32 ist;
83 spinlock_t irq_spinlock;
84 struct ehca_eqe_cache_entry eqe_cache[EHCA_EQE_CACHE_SIZE];
77}; 85};
78 86
79struct ehca_sport { 87struct ehca_sport {
@@ -269,6 +277,7 @@ extern struct idr ehca_cq_idr;
269extern int ehca_static_rate; 277extern int ehca_static_rate;
270extern int ehca_port_act_time; 278extern int ehca_port_act_time;
271extern int ehca_use_hp_mr; 279extern int ehca_use_hp_mr;
280extern int ehca_scaling_code;
272 281
273struct ipzu_queue_resp { 282struct ipzu_queue_resp {
274 u32 qe_size; /* queue entry size */ 283 u32 qe_size; /* queue entry size */
diff --git a/drivers/infiniband/hw/ehca/ehca_eq.c b/drivers/infiniband/hw/ehca/ehca_eq.c
index 24ceab0bae4a..4961eb88827c 100644
--- a/drivers/infiniband/hw/ehca/ehca_eq.c
+++ b/drivers/infiniband/hw/ehca/ehca_eq.c
@@ -61,6 +61,7 @@ int ehca_create_eq(struct ehca_shca *shca,
61 struct ib_device *ib_dev = &shca->ib_device; 61 struct ib_device *ib_dev = &shca->ib_device;
62 62
63 spin_lock_init(&eq->spinlock); 63 spin_lock_init(&eq->spinlock);
64 spin_lock_init(&eq->irq_spinlock);
64 eq->is_initialized = 0; 65 eq->is_initialized = 0;
65 66
66 if (type != EHCA_EQ && type != EHCA_NEQ) { 67 if (type != EHCA_EQ && type != EHCA_NEQ) {
diff --git a/drivers/infiniband/hw/ehca/ehca_hca.c b/drivers/infiniband/hw/ehca/ehca_hca.c
index b7be950ab47c..30eb45df9f0b 100644
--- a/drivers/infiniband/hw/ehca/ehca_hca.c
+++ b/drivers/infiniband/hw/ehca/ehca_hca.c
@@ -162,6 +162,9 @@ int ehca_query_port(struct ib_device *ibdev,
162 props->active_width = IB_WIDTH_12X; 162 props->active_width = IB_WIDTH_12X;
163 props->active_speed = 0x1; 163 props->active_speed = 0x1;
164 164
165 /* at the moment (logical) link state is always LINK_UP */
166 props->phys_state = 0x5;
167
165query_port1: 168query_port1:
166 ehca_free_fw_ctrlblock(rblock); 169 ehca_free_fw_ctrlblock(rblock);
167 170
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.c b/drivers/infiniband/hw/ehca/ehca_irq.c
index 6c4f9f91b15d..3ec53c687d08 100644
--- a/drivers/infiniband/hw/ehca/ehca_irq.c
+++ b/drivers/infiniband/hw/ehca/ehca_irq.c
@@ -63,15 +63,11 @@
63#define ERROR_DATA_LENGTH EHCA_BMASK_IBM(52,63) 63#define ERROR_DATA_LENGTH EHCA_BMASK_IBM(52,63)
64#define ERROR_DATA_TYPE EHCA_BMASK_IBM(0,7) 64#define ERROR_DATA_TYPE EHCA_BMASK_IBM(0,7)
65 65
66#ifdef CONFIG_INFINIBAND_EHCA_SCALING
67
68static void queue_comp_task(struct ehca_cq *__cq); 66static void queue_comp_task(struct ehca_cq *__cq);
69 67
70static struct ehca_comp_pool* pool; 68static struct ehca_comp_pool* pool;
71static struct notifier_block comp_pool_callback_nb; 69static struct notifier_block comp_pool_callback_nb;
72 70
73#endif
74
75static inline void comp_event_callback(struct ehca_cq *cq) 71static inline void comp_event_callback(struct ehca_cq *cq)
76{ 72{
77 if (!cq->ib_cq.comp_handler) 73 if (!cq->ib_cq.comp_handler)
@@ -206,7 +202,7 @@ static void qp_event_callback(struct ehca_shca *shca,
206} 202}
207 203
208static void cq_event_callback(struct ehca_shca *shca, 204static void cq_event_callback(struct ehca_shca *shca,
209 u64 eqe) 205 u64 eqe)
210{ 206{
211 struct ehca_cq *cq; 207 struct ehca_cq *cq;
212 unsigned long flags; 208 unsigned long flags;
@@ -318,7 +314,7 @@ static void parse_ec(struct ehca_shca *shca, u64 eqe)
318 "disruptive port %x configuration change", port); 314 "disruptive port %x configuration change", port);
319 315
320 ehca_info(&shca->ib_device, 316 ehca_info(&shca->ib_device,
321 "port %x is inactive.", port); 317 "port %x is inactive.", port);
322 event.device = &shca->ib_device; 318 event.device = &shca->ib_device;
323 event.event = IB_EVENT_PORT_ERR; 319 event.event = IB_EVENT_PORT_ERR;
324 event.element.port_num = port; 320 event.element.port_num = port;
@@ -326,7 +322,7 @@ static void parse_ec(struct ehca_shca *shca, u64 eqe)
326 ib_dispatch_event(&event); 322 ib_dispatch_event(&event);
327 323
328 ehca_info(&shca->ib_device, 324 ehca_info(&shca->ib_device,
329 "port %x is active.", port); 325 "port %x is active.", port);
330 event.device = &shca->ib_device; 326 event.device = &shca->ib_device;
331 event.event = IB_EVENT_PORT_ACTIVE; 327 event.event = IB_EVENT_PORT_ACTIVE;
332 event.element.port_num = port; 328 event.element.port_num = port;
@@ -401,115 +397,170 @@ irqreturn_t ehca_interrupt_eq(int irq, void *dev_id)
401 return IRQ_HANDLED; 397 return IRQ_HANDLED;
402} 398}
403 399
404void ehca_tasklet_eq(unsigned long data)
405{
406 struct ehca_shca *shca = (struct ehca_shca*)data;
407 struct ehca_eqe *eqe;
408 int int_state;
409 int query_cnt = 0;
410 400
411 do { 401static inline void process_eqe(struct ehca_shca *shca, struct ehca_eqe *eqe)
412 eqe = (struct ehca_eqe *)ehca_poll_eq(shca, &shca->eq); 402{
403 u64 eqe_value;
404 u32 token;
405 unsigned long flags;
406 struct ehca_cq *cq;
407 eqe_value = eqe->entry;
408 ehca_dbg(&shca->ib_device, "eqe_value=%lx", eqe_value);
409 if (EHCA_BMASK_GET(EQE_COMPLETION_EVENT, eqe_value)) {
410 ehca_dbg(&shca->ib_device, "... completion event");
411 token = EHCA_BMASK_GET(EQE_CQ_TOKEN, eqe_value);
412 spin_lock_irqsave(&ehca_cq_idr_lock, flags);
413 cq = idr_find(&ehca_cq_idr, token);
414 if (cq == NULL) {
415 spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
416 ehca_err(&shca->ib_device,
417 "Invalid eqe for non-existing cq token=%x",
418 token);
419 return;
420 }
421 reset_eq_pending(cq);
422 if (ehca_scaling_code) {
423 queue_comp_task(cq);
424 spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
425 } else {
426 spin_unlock_irqrestore(&ehca_cq_idr_lock, flags);
427 comp_event_callback(cq);
428 }
429 } else {
430 ehca_dbg(&shca->ib_device,
431 "Got non completion event");
432 parse_identifier(shca, eqe_value);
433 }
434}
413 435
414 if ((shca->hw_level >= 2) && eqe) 436void ehca_process_eq(struct ehca_shca *shca, int is_irq)
415 int_state = 1; 437{
416 else 438 struct ehca_eq *eq = &shca->eq;
417 int_state = 0; 439 struct ehca_eqe_cache_entry *eqe_cache = eq->eqe_cache;
418 440 u64 eqe_value;
419 while ((int_state == 1) || eqe) { 441 unsigned long flags;
420 while (eqe) { 442 int eqe_cnt, i;
421 u64 eqe_value = eqe->entry; 443 int eq_empty = 0;
422 444
423 ehca_dbg(&shca->ib_device, 445 spin_lock_irqsave(&eq->irq_spinlock, flags);
424 "eqe_value=%lx", eqe_value); 446 if (is_irq) {
425 447 const int max_query_cnt = 100;
426 /* TODO: better structure */ 448 int query_cnt = 0;
427 if (EHCA_BMASK_GET(EQE_COMPLETION_EVENT, 449 int int_state = 1;
428 eqe_value)) { 450 do {
429 unsigned long flags; 451 int_state = hipz_h_query_int_state(
430 u32 token; 452 shca->ipz_hca_handle, eq->ist);
431 struct ehca_cq *cq; 453 query_cnt++;
432 454 iosync();
433 ehca_dbg(&shca->ib_device, 455 } while (int_state && query_cnt < max_query_cnt);
434 "... completion event"); 456 if (unlikely((query_cnt == max_query_cnt)))
435 token = 457 ehca_dbg(&shca->ib_device, "int_state=%x query_cnt=%x",
436 EHCA_BMASK_GET(EQE_CQ_TOKEN, 458 int_state, query_cnt);
437 eqe_value); 459 }
438 spin_lock_irqsave(&ehca_cq_idr_lock,
439 flags);
440 cq = idr_find(&ehca_cq_idr, token);
441
442 if (cq == NULL) {
443 spin_unlock_irqrestore(&ehca_cq_idr_lock,
444 flags);
445 break;
446 }
447
448 reset_eq_pending(cq);
449#ifdef CONFIG_INFINIBAND_EHCA_SCALING
450 queue_comp_task(cq);
451 spin_unlock_irqrestore(&ehca_cq_idr_lock,
452 flags);
453#else
454 spin_unlock_irqrestore(&ehca_cq_idr_lock,
455 flags);
456 comp_event_callback(cq);
457#endif
458 } else {
459 ehca_dbg(&shca->ib_device,
460 "... non completion event");
461 parse_identifier(shca, eqe_value);
462 }
463 eqe =
464 (struct ehca_eqe *)ehca_poll_eq(shca,
465 &shca->eq);
466 }
467 460
468 if (shca->hw_level >= 2) { 461 /* read out all eqes */
469 int_state = 462 eqe_cnt = 0;
470 hipz_h_query_int_state(shca->ipz_hca_handle, 463 do {
471 shca->eq.ist); 464 u32 token;
472 query_cnt++; 465 eqe_cache[eqe_cnt].eqe =
473 iosync(); 466 (struct ehca_eqe *)ehca_poll_eq(shca, eq);
474 if (query_cnt >= 100) { 467 if (!eqe_cache[eqe_cnt].eqe)
475 query_cnt = 0; 468 break;
476 int_state = 0; 469 eqe_value = eqe_cache[eqe_cnt].eqe->entry;
477 } 470 if (EHCA_BMASK_GET(EQE_COMPLETION_EVENT, eqe_value)) {
471 token = EHCA_BMASK_GET(EQE_CQ_TOKEN, eqe_value);
472 spin_lock(&ehca_cq_idr_lock);
473 eqe_cache[eqe_cnt].cq = idr_find(&ehca_cq_idr, token);
474 if (!eqe_cache[eqe_cnt].cq) {
475 spin_unlock(&ehca_cq_idr_lock);
476 ehca_err(&shca->ib_device,
477 "Invalid eqe for non-existing cq "
478 "token=%x", token);
479 continue;
478 } 480 }
479 eqe = (struct ehca_eqe *)ehca_poll_eq(shca, &shca->eq); 481 spin_unlock(&ehca_cq_idr_lock);
480 482 } else
483 eqe_cache[eqe_cnt].cq = NULL;
484 eqe_cnt++;
485 } while (eqe_cnt < EHCA_EQE_CACHE_SIZE);
486 if (!eqe_cnt) {
487 if (is_irq)
488 ehca_dbg(&shca->ib_device,
489 "No eqe found for irq event");
490 goto unlock_irq_spinlock;
491 } else if (!is_irq)
492 ehca_dbg(&shca->ib_device, "deadman found %x eqe", eqe_cnt);
493 if (unlikely(eqe_cnt == EHCA_EQE_CACHE_SIZE))
494 ehca_dbg(&shca->ib_device, "too many eqes for one irq event");
495 /* enable irq for new packets */
496 for (i = 0; i < eqe_cnt; i++) {
497 if (eq->eqe_cache[i].cq)
498 reset_eq_pending(eq->eqe_cache[i].cq);
499 }
500 /* check eq */
501 spin_lock(&eq->spinlock);
502 eq_empty = (!ipz_eqit_eq_peek_valid(&shca->eq.ipz_queue));
503 spin_unlock(&eq->spinlock);
504 /* call completion handler for cached eqes */
505 for (i = 0; i < eqe_cnt; i++)
506 if (eq->eqe_cache[i].cq) {
507 if (ehca_scaling_code) {
508 spin_lock(&ehca_cq_idr_lock);
509 queue_comp_task(eq->eqe_cache[i].cq);
510 spin_unlock(&ehca_cq_idr_lock);
511 } else
512 comp_event_callback(eq->eqe_cache[i].cq);
513 } else {
514 ehca_dbg(&shca->ib_device, "Got non completion event");
515 parse_identifier(shca, eq->eqe_cache[i].eqe->entry);
481 } 516 }
482 } while (int_state != 0); 517 /* poll eq if not empty */
483 518 if (eq_empty)
484 return; 519 goto unlock_irq_spinlock;
520 do {
521 struct ehca_eqe *eqe;
522 eqe = (struct ehca_eqe *)ehca_poll_eq(shca, &shca->eq);
523 if (!eqe)
524 break;
525 process_eqe(shca, eqe);
526 eqe_cnt++;
527 } while (1);
528
529unlock_irq_spinlock:
530 spin_unlock_irqrestore(&eq->irq_spinlock, flags);
485} 531}
486 532
487#ifdef CONFIG_INFINIBAND_EHCA_SCALING 533void ehca_tasklet_eq(unsigned long data)
534{
535 ehca_process_eq((struct ehca_shca*)data, 1);
536}
488 537
489static inline int find_next_online_cpu(struct ehca_comp_pool* pool) 538static inline int find_next_online_cpu(struct ehca_comp_pool* pool)
490{ 539{
491 unsigned long flags_last_cpu; 540 int cpu;
541 unsigned long flags;
492 542
543 WARN_ON_ONCE(!in_interrupt());
493 if (ehca_debug_level) 544 if (ehca_debug_level)
494 ehca_dmp(&cpu_online_map, sizeof(cpumask_t), ""); 545 ehca_dmp(&cpu_online_map, sizeof(cpumask_t), "");
495 546
496 spin_lock_irqsave(&pool->last_cpu_lock, flags_last_cpu); 547 spin_lock_irqsave(&pool->last_cpu_lock, flags);
497 pool->last_cpu = next_cpu(pool->last_cpu, cpu_online_map); 548 cpu = next_cpu(pool->last_cpu, cpu_online_map);
498 if (pool->last_cpu == NR_CPUS) 549 if (cpu == NR_CPUS)
499 pool->last_cpu = first_cpu(cpu_online_map); 550 cpu = first_cpu(cpu_online_map);
500 spin_unlock_irqrestore(&pool->last_cpu_lock, flags_last_cpu); 551 pool->last_cpu = cpu;
552 spin_unlock_irqrestore(&pool->last_cpu_lock, flags);
501 553
502 return pool->last_cpu; 554 return cpu;
503} 555}
504 556
505static void __queue_comp_task(struct ehca_cq *__cq, 557static void __queue_comp_task(struct ehca_cq *__cq,
506 struct ehca_cpu_comp_task *cct) 558 struct ehca_cpu_comp_task *cct)
507{ 559{
508 unsigned long flags_cct; 560 unsigned long flags;
509 unsigned long flags_cq;
510 561
511 spin_lock_irqsave(&cct->task_lock, flags_cct); 562 spin_lock_irqsave(&cct->task_lock, flags);
512 spin_lock_irqsave(&__cq->task_lock, flags_cq); 563 spin_lock(&__cq->task_lock);
513 564
514 if (__cq->nr_callbacks == 0) { 565 if (__cq->nr_callbacks == 0) {
515 __cq->nr_callbacks++; 566 __cq->nr_callbacks++;
@@ -520,8 +571,8 @@ static void __queue_comp_task(struct ehca_cq *__cq,
520 else 571 else
521 __cq->nr_callbacks++; 572 __cq->nr_callbacks++;
522 573
523 spin_unlock_irqrestore(&__cq->task_lock, flags_cq); 574 spin_unlock(&__cq->task_lock);
524 spin_unlock_irqrestore(&cct->task_lock, flags_cct); 575 spin_unlock_irqrestore(&cct->task_lock, flags);
525} 576}
526 577
527static void queue_comp_task(struct ehca_cq *__cq) 578static void queue_comp_task(struct ehca_cq *__cq)
@@ -532,69 +583,69 @@ static void queue_comp_task(struct ehca_cq *__cq)
532 583
533 cpu = get_cpu(); 584 cpu = get_cpu();
534 cpu_id = find_next_online_cpu(pool); 585 cpu_id = find_next_online_cpu(pool);
535
536 BUG_ON(!cpu_online(cpu_id)); 586 BUG_ON(!cpu_online(cpu_id));
537 587
538 cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu_id); 588 cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu_id);
589 BUG_ON(!cct);
539 590
540 if (cct->cq_jobs > 0) { 591 if (cct->cq_jobs > 0) {
541 cpu_id = find_next_online_cpu(pool); 592 cpu_id = find_next_online_cpu(pool);
542 cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu_id); 593 cct = per_cpu_ptr(pool->cpu_comp_tasks, cpu_id);
594 BUG_ON(!cct);
543 } 595 }
544 596
545 __queue_comp_task(__cq, cct); 597 __queue_comp_task(__cq, cct);
546
547 put_cpu();
548
549 return;
550} 598}
551 599
552static void run_comp_task(struct ehca_cpu_comp_task* cct) 600static void run_comp_task(struct ehca_cpu_comp_task* cct)
553{ 601{
554 struct ehca_cq *cq; 602 struct ehca_cq *cq;
555 unsigned long flags_cct; 603 unsigned long flags;
556 unsigned long flags_cq;
557 604
558 spin_lock_irqsave(&cct->task_lock, flags_cct); 605 spin_lock_irqsave(&cct->task_lock, flags);
559 606
560 while (!list_empty(&cct->cq_list)) { 607 while (!list_empty(&cct->cq_list)) {
561 cq = list_entry(cct->cq_list.next, struct ehca_cq, entry); 608 cq = list_entry(cct->cq_list.next, struct ehca_cq, entry);
562 spin_unlock_irqrestore(&cct->task_lock, flags_cct); 609 spin_unlock_irqrestore(&cct->task_lock, flags);
563 comp_event_callback(cq); 610 comp_event_callback(cq);
564 spin_lock_irqsave(&cct->task_lock, flags_cct); 611 spin_lock_irqsave(&cct->task_lock, flags);
565 612
566 spin_lock_irqsave(&cq->task_lock, flags_cq); 613 spin_lock(&cq->task_lock);
567 cq->nr_callbacks--; 614 cq->nr_callbacks--;
568 if (cq->nr_callbacks == 0) { 615 if (cq->nr_callbacks == 0) {
569 list_del_init(cct->cq_list.next); 616 list_del_init(cct->cq_list.next);
570 cct->cq_jobs--; 617 cct->cq_jobs--;
571 } 618 }
572 spin_unlock_irqrestore(&cq->task_lock, flags_cq); 619 spin_unlock(&cq->task_lock);
573
574 } 620 }
575 621
576 spin_unlock_irqrestore(&cct->task_lock, flags_cct); 622 spin_unlock_irqrestore(&cct->task_lock, flags);
577
578 return;
579} 623}
580 624
581static int comp_task(void *__cct) 625static int comp_task(void *__cct)
582{ 626{
583 struct ehca_cpu_comp_task* cct = __cct; 627 struct ehca_cpu_comp_task* cct = __cct;
628 int cql_empty;
584 DECLARE_WAITQUEUE(wait, current); 629 DECLARE_WAITQUEUE(wait, current);
585 630
586 set_current_state(TASK_INTERRUPTIBLE); 631 set_current_state(TASK_INTERRUPTIBLE);
587 while(!kthread_should_stop()) { 632 while(!kthread_should_stop()) {
588 add_wait_queue(&cct->wait_queue, &wait); 633 add_wait_queue(&cct->wait_queue, &wait);
589 634
590 if (list_empty(&cct->cq_list)) 635 spin_lock_irq(&cct->task_lock);
636 cql_empty = list_empty(&cct->cq_list);
637 spin_unlock_irq(&cct->task_lock);
638 if (cql_empty)
591 schedule(); 639 schedule();
592 else 640 else
593 __set_current_state(TASK_RUNNING); 641 __set_current_state(TASK_RUNNING);
594 642
595 remove_wait_queue(&cct->wait_queue, &wait); 643 remove_wait_queue(&cct->wait_queue, &wait);
596 644
597 if (!list_empty(&cct->cq_list)) 645 spin_lock_irq(&cct->task_lock);
646 cql_empty = list_empty(&cct->cq_list);
647 spin_unlock_irq(&cct->task_lock);
648 if (!cql_empty)
598 run_comp_task(__cct); 649 run_comp_task(__cct);
599 650
600 set_current_state(TASK_INTERRUPTIBLE); 651 set_current_state(TASK_INTERRUPTIBLE);
@@ -637,8 +688,6 @@ static void destroy_comp_task(struct ehca_comp_pool *pool,
637 688
638 if (task) 689 if (task)
639 kthread_stop(task); 690 kthread_stop(task);
640
641 return;
642} 691}
643 692
644static void take_over_work(struct ehca_comp_pool *pool, 693static void take_over_work(struct ehca_comp_pool *pool,
@@ -654,11 +703,11 @@ static void take_over_work(struct ehca_comp_pool *pool,
654 list_splice_init(&cct->cq_list, &list); 703 list_splice_init(&cct->cq_list, &list);
655 704
656 while(!list_empty(&list)) { 705 while(!list_empty(&list)) {
657 cq = list_entry(cct->cq_list.next, struct ehca_cq, entry); 706 cq = list_entry(cct->cq_list.next, struct ehca_cq, entry);
658 707
659 list_del(&cq->entry); 708 list_del(&cq->entry);
660 __queue_comp_task(cq, per_cpu_ptr(pool->cpu_comp_tasks, 709 __queue_comp_task(cq, per_cpu_ptr(pool->cpu_comp_tasks,
661 smp_processor_id())); 710 smp_processor_id()));
662 } 711 }
663 712
664 spin_unlock_irqrestore(&cct->task_lock, flags_cct); 713 spin_unlock_irqrestore(&cct->task_lock, flags_cct);
@@ -708,14 +757,14 @@ static int comp_pool_callback(struct notifier_block *nfb,
708 return NOTIFY_OK; 757 return NOTIFY_OK;
709} 758}
710 759
711#endif
712
713int ehca_create_comp_pool(void) 760int ehca_create_comp_pool(void)
714{ 761{
715#ifdef CONFIG_INFINIBAND_EHCA_SCALING
716 int cpu; 762 int cpu;
717 struct task_struct *task; 763 struct task_struct *task;
718 764
765 if (!ehca_scaling_code)
766 return 0;
767
719 pool = kzalloc(sizeof(struct ehca_comp_pool), GFP_KERNEL); 768 pool = kzalloc(sizeof(struct ehca_comp_pool), GFP_KERNEL);
720 if (pool == NULL) 769 if (pool == NULL)
721 return -ENOMEM; 770 return -ENOMEM;
@@ -740,16 +789,19 @@ int ehca_create_comp_pool(void)
740 comp_pool_callback_nb.notifier_call = comp_pool_callback; 789 comp_pool_callback_nb.notifier_call = comp_pool_callback;
741 comp_pool_callback_nb.priority =0; 790 comp_pool_callback_nb.priority =0;
742 register_cpu_notifier(&comp_pool_callback_nb); 791 register_cpu_notifier(&comp_pool_callback_nb);
743#endif 792
793 printk(KERN_INFO "eHCA scaling code enabled\n");
744 794
745 return 0; 795 return 0;
746} 796}
747 797
748void ehca_destroy_comp_pool(void) 798void ehca_destroy_comp_pool(void)
749{ 799{
750#ifdef CONFIG_INFINIBAND_EHCA_SCALING
751 int i; 800 int i;
752 801
802 if (!ehca_scaling_code)
803 return;
804
753 unregister_cpu_notifier(&comp_pool_callback_nb); 805 unregister_cpu_notifier(&comp_pool_callback_nb);
754 806
755 for (i = 0; i < NR_CPUS; i++) { 807 for (i = 0; i < NR_CPUS; i++) {
@@ -758,7 +810,4 @@ void ehca_destroy_comp_pool(void)
758 } 810 }
759 free_percpu(pool->cpu_comp_tasks); 811 free_percpu(pool->cpu_comp_tasks);
760 kfree(pool); 812 kfree(pool);
761#endif
762
763 return;
764} 813}
diff --git a/drivers/infiniband/hw/ehca/ehca_irq.h b/drivers/infiniband/hw/ehca/ehca_irq.h
index be579cc0adf6..6ed06ee033ed 100644
--- a/drivers/infiniband/hw/ehca/ehca_irq.h
+++ b/drivers/infiniband/hw/ehca/ehca_irq.h
@@ -56,6 +56,7 @@ void ehca_tasklet_neq(unsigned long data);
56 56
57irqreturn_t ehca_interrupt_eq(int irq, void *dev_id); 57irqreturn_t ehca_interrupt_eq(int irq, void *dev_id);
58void ehca_tasklet_eq(unsigned long data); 58void ehca_tasklet_eq(unsigned long data);
59void ehca_process_eq(struct ehca_shca *shca, int is_irq);
59 60
60struct ehca_cpu_comp_task { 61struct ehca_cpu_comp_task {
61 wait_queue_head_t wait_queue; 62 wait_queue_head_t wait_queue;
diff --git a/drivers/infiniband/hw/ehca/ehca_main.c b/drivers/infiniband/hw/ehca/ehca_main.c
index 1155bcf48212..c1835121a822 100644
--- a/drivers/infiniband/hw/ehca/ehca_main.c
+++ b/drivers/infiniband/hw/ehca/ehca_main.c
@@ -52,7 +52,7 @@
52MODULE_LICENSE("Dual BSD/GPL"); 52MODULE_LICENSE("Dual BSD/GPL");
53MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>"); 53MODULE_AUTHOR("Christoph Raisch <raisch@de.ibm.com>");
54MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver"); 54MODULE_DESCRIPTION("IBM eServer HCA InfiniBand Device Driver");
55MODULE_VERSION("SVNEHCA_0020"); 55MODULE_VERSION("SVNEHCA_0021");
56 56
57int ehca_open_aqp1 = 0; 57int ehca_open_aqp1 = 0;
58int ehca_debug_level = 0; 58int ehca_debug_level = 0;
@@ -62,6 +62,7 @@ int ehca_use_hp_mr = 0;
62int ehca_port_act_time = 30; 62int ehca_port_act_time = 30;
63int ehca_poll_all_eqs = 1; 63int ehca_poll_all_eqs = 1;
64int ehca_static_rate = -1; 64int ehca_static_rate = -1;
65int ehca_scaling_code = 1;
65 66
66module_param_named(open_aqp1, ehca_open_aqp1, int, 0); 67module_param_named(open_aqp1, ehca_open_aqp1, int, 0);
67module_param_named(debug_level, ehca_debug_level, int, 0); 68module_param_named(debug_level, ehca_debug_level, int, 0);
@@ -71,6 +72,7 @@ module_param_named(use_hp_mr, ehca_use_hp_mr, int, 0);
71module_param_named(port_act_time, ehca_port_act_time, int, 0); 72module_param_named(port_act_time, ehca_port_act_time, int, 0);
72module_param_named(poll_all_eqs, ehca_poll_all_eqs, int, 0); 73module_param_named(poll_all_eqs, ehca_poll_all_eqs, int, 0);
73module_param_named(static_rate, ehca_static_rate, int, 0); 74module_param_named(static_rate, ehca_static_rate, int, 0);
75module_param_named(scaling_code, ehca_scaling_code, int, 0);
74 76
75MODULE_PARM_DESC(open_aqp1, 77MODULE_PARM_DESC(open_aqp1,
76 "AQP1 on startup (0: no (default), 1: yes)"); 78 "AQP1 on startup (0: no (default), 1: yes)");
@@ -91,6 +93,8 @@ MODULE_PARM_DESC(poll_all_eqs,
91 " (0: no, 1: yes (default))"); 93 " (0: no, 1: yes (default))");
92MODULE_PARM_DESC(static_rate, 94MODULE_PARM_DESC(static_rate,
93 "set permanent static rate (default: disabled)"); 95 "set permanent static rate (default: disabled)");
96MODULE_PARM_DESC(scaling_code,
97 "set scaling code (0: disabled, 1: enabled/default)");
94 98
95spinlock_t ehca_qp_idr_lock; 99spinlock_t ehca_qp_idr_lock;
96spinlock_t ehca_cq_idr_lock; 100spinlock_t ehca_cq_idr_lock;
@@ -432,8 +436,8 @@ static int ehca_destroy_aqp1(struct ehca_sport *sport)
432 436
433static ssize_t ehca_show_debug_level(struct device_driver *ddp, char *buf) 437static ssize_t ehca_show_debug_level(struct device_driver *ddp, char *buf)
434{ 438{
435 return snprintf(buf, PAGE_SIZE, "%d\n", 439 return snprintf(buf, PAGE_SIZE, "%d\n",
436 ehca_debug_level); 440 ehca_debug_level);
437} 441}
438 442
439static ssize_t ehca_store_debug_level(struct device_driver *ddp, 443static ssize_t ehca_store_debug_level(struct device_driver *ddp,
@@ -778,8 +782,24 @@ void ehca_poll_eqs(unsigned long data)
778 782
779 spin_lock(&shca_list_lock); 783 spin_lock(&shca_list_lock);
780 list_for_each_entry(shca, &shca_list, shca_list) { 784 list_for_each_entry(shca, &shca_list, shca_list) {
781 if (shca->eq.is_initialized) 785 if (shca->eq.is_initialized) {
782 ehca_tasklet_eq((unsigned long)(void*)shca); 786 /* call deadman proc only if eq ptr does not change */
787 struct ehca_eq *eq = &shca->eq;
788 int max = 3;
789 volatile u64 q_ofs, q_ofs2;
790 u64 flags;
791 spin_lock_irqsave(&eq->spinlock, flags);
792 q_ofs = eq->ipz_queue.current_q_offset;
793 spin_unlock_irqrestore(&eq->spinlock, flags);
794 do {
795 spin_lock_irqsave(&eq->spinlock, flags);
796 q_ofs2 = eq->ipz_queue.current_q_offset;
797 spin_unlock_irqrestore(&eq->spinlock, flags);
798 max--;
799 } while (q_ofs == q_ofs2 && max > 0);
800 if (q_ofs == q_ofs2)
801 ehca_process_eq(shca, 0);
802 }
783 } 803 }
784 mod_timer(&poll_eqs_timer, jiffies + HZ); 804 mod_timer(&poll_eqs_timer, jiffies + HZ);
785 spin_unlock(&shca_list_lock); 805 spin_unlock(&shca_list_lock);
@@ -790,7 +810,7 @@ int __init ehca_module_init(void)
790 int ret; 810 int ret;
791 811
792 printk(KERN_INFO "eHCA Infiniband Device Driver " 812 printk(KERN_INFO "eHCA Infiniband Device Driver "
793 "(Rel.: SVNEHCA_0020)\n"); 813 "(Rel.: SVNEHCA_0021)\n");
794 idr_init(&ehca_qp_idr); 814 idr_init(&ehca_qp_idr);
795 idr_init(&ehca_cq_idr); 815 idr_init(&ehca_cq_idr);
796 spin_lock_init(&ehca_qp_idr_lock); 816 spin_lock_init(&ehca_qp_idr_lock);
diff --git a/drivers/infiniband/hw/ehca/ipz_pt_fn.h b/drivers/infiniband/hw/ehca/ipz_pt_fn.h
index dc3bda2634b7..8199c45768a3 100644
--- a/drivers/infiniband/hw/ehca/ipz_pt_fn.h
+++ b/drivers/infiniband/hw/ehca/ipz_pt_fn.h
@@ -79,7 +79,7 @@ static inline void *ipz_qeit_calc(struct ipz_queue *queue, u64 q_offset)
79 if (q_offset >= queue->queue_length) 79 if (q_offset >= queue->queue_length)
80 return NULL; 80 return NULL;
81 current_page = (queue->queue_pages)[q_offset >> EHCA_PAGESHIFT]; 81 current_page = (queue->queue_pages)[q_offset >> EHCA_PAGESHIFT];
82 return &current_page->entries[q_offset & (EHCA_PAGESIZE - 1)]; 82 return &current_page->entries[q_offset & (EHCA_PAGESIZE - 1)];
83} 83}
84 84
85/* 85/*
@@ -247,6 +247,15 @@ static inline void *ipz_eqit_eq_get_inc_valid(struct ipz_queue *queue)
247 return ret; 247 return ret;
248} 248}
249 249
250static inline void *ipz_eqit_eq_peek_valid(struct ipz_queue *queue)
251{
252 void *ret = ipz_qeit_get(queue);
253 u32 qe = *(u8 *) ret;
254 if ((qe >> 7) != (queue->toggle_state & 1))
255 return NULL;
256 return ret;
257}
258
250/* returns address (GX) of first queue entry */ 259/* returns address (GX) of first queue entry */
251static inline u64 ipz_qpt_get_firstpage(struct ipz_qpt *qpt) 260static inline u64 ipz_qpt_get_firstpage(struct ipz_qpt *qpt)
252{ 261{
diff --git a/drivers/infiniband/hw/ipath/ipath_dma.c b/drivers/infiniband/hw/ipath/ipath_dma.c
index 6e0f2b8918ce..f6f949040825 100644
--- a/drivers/infiniband/hw/ipath/ipath_dma.c
+++ b/drivers/infiniband/hw/ipath/ipath_dma.c
@@ -96,8 +96,8 @@ static void ipath_dma_unmap_page(struct ib_device *dev,
96 BUG_ON(!valid_dma_direction(direction)); 96 BUG_ON(!valid_dma_direction(direction));
97} 97}
98 98
99int ipath_map_sg(struct ib_device *dev, struct scatterlist *sg, int nents, 99static int ipath_map_sg(struct ib_device *dev, struct scatterlist *sg, int nents,
100 enum dma_data_direction direction) 100 enum dma_data_direction direction)
101{ 101{
102 u64 addr; 102 u64 addr;
103 int i; 103 int i;
diff --git a/drivers/infiniband/hw/mthca/mthca_memfree.c b/drivers/infiniband/hw/mthca/mthca_memfree.c
index 0b9d053a599d..48f7c65e9aed 100644
--- a/drivers/infiniband/hw/mthca/mthca_memfree.c
+++ b/drivers/infiniband/hw/mthca/mthca_memfree.c
@@ -175,7 +175,9 @@ struct mthca_icm *mthca_alloc_icm(struct mthca_dev *dev, int npages,
175 if (!ret) { 175 if (!ret) {
176 ++chunk->npages; 176 ++chunk->npages;
177 177
178 if (!coherent && chunk->npages == MTHCA_ICM_CHUNK_LEN) { 178 if (coherent)
179 ++chunk->nsg;
180 else if (chunk->npages == MTHCA_ICM_CHUNK_LEN) {
179 chunk->nsg = pci_map_sg(dev->pdev, chunk->mem, 181 chunk->nsg = pci_map_sg(dev->pdev, chunk->mem,
180 chunk->npages, 182 chunk->npages,
181 PCI_DMA_BIDIRECTIONAL); 183 PCI_DMA_BIDIRECTIONAL);
diff --git a/drivers/infiniband/hw/mthca/mthca_qp.c b/drivers/infiniband/hw/mthca/mthca_qp.c
index 224c93dd29eb..71dc84bd4254 100644
--- a/drivers/infiniband/hw/mthca/mthca_qp.c
+++ b/drivers/infiniband/hw/mthca/mthca_qp.c
@@ -573,6 +573,11 @@ int mthca_modify_qp(struct ib_qp *ibqp, struct ib_qp_attr *attr, int attr_mask,
573 goto out; 573 goto out;
574 } 574 }
575 575
576 if (cur_state == new_state && cur_state == IB_QPS_RESET) {
577 err = 0;
578 goto out;
579 }
580
576 if ((attr_mask & IB_QP_PKEY_INDEX) && 581 if ((attr_mask & IB_QP_PKEY_INDEX) &&
577 attr->pkey_index >= dev->limits.pkey_table_len) { 582 attr->pkey_index >= dev->limits.pkey_table_len) {
578 mthca_dbg(dev, "P_Key index (%u) too large. max is %d\n", 583 mthca_dbg(dev, "P_Key index (%u) too large. max is %d\n",
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_cm.c b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
index 2d483874a589..4d59682f7d4a 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_cm.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_cm.c
@@ -145,7 +145,7 @@ partial_error:
145 for (; i >= 0; --i) 145 for (; i >= 0; --i)
146 ib_dma_unmap_single(priv->ca, mapping[i + 1], PAGE_SIZE, DMA_FROM_DEVICE); 146 ib_dma_unmap_single(priv->ca, mapping[i + 1], PAGE_SIZE, DMA_FROM_DEVICE);
147 147
148 kfree_skb(skb); 148 dev_kfree_skb_any(skb);
149 return -ENOMEM; 149 return -ENOMEM;
150} 150}
151 151
@@ -1138,7 +1138,7 @@ static ssize_t set_mode(struct device *d, struct device_attribute *attr,
1138 return -EINVAL; 1138 return -EINVAL;
1139} 1139}
1140 1140
1141static DEVICE_ATTR(mode, S_IWUGO | S_IRUGO, show_mode, set_mode); 1141static DEVICE_ATTR(mode, S_IWUSR | S_IRUGO, show_mode, set_mode);
1142 1142
1143int ipoib_cm_add_mode_attr(struct net_device *dev) 1143int ipoib_cm_add_mode_attr(struct net_device *dev)
1144{ 1144{
diff --git a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
index fea737f520fd..b303ce6bc21e 100644
--- a/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
+++ b/drivers/infiniband/ulp/ipoib/ipoib_multicast.c
@@ -60,14 +60,11 @@ static DEFINE_MUTEX(mcast_mutex);
60/* Used for all multicast joins (broadcast, IPv4 mcast and IPv6 mcast) */ 60/* Used for all multicast joins (broadcast, IPv4 mcast and IPv6 mcast) */
61struct ipoib_mcast { 61struct ipoib_mcast {
62 struct ib_sa_mcmember_rec mcmember; 62 struct ib_sa_mcmember_rec mcmember;
63 struct ib_sa_multicast *mc;
63 struct ipoib_ah *ah; 64 struct ipoib_ah *ah;
64 65
65 struct rb_node rb_node; 66 struct rb_node rb_node;
66 struct list_head list; 67 struct list_head list;
67 struct completion done;
68
69 int query_id;
70 struct ib_sa_query *query;
71 68
72 unsigned long created; 69 unsigned long created;
73 unsigned long backoff; 70 unsigned long backoff;
@@ -299,18 +296,22 @@ static int ipoib_mcast_join_finish(struct ipoib_mcast *mcast,
299 return 0; 296 return 0;
300} 297}
301 298
302static void 299static int
303ipoib_mcast_sendonly_join_complete(int status, 300ipoib_mcast_sendonly_join_complete(int status,
304 struct ib_sa_mcmember_rec *mcmember, 301 struct ib_sa_multicast *multicast)
305 void *mcast_ptr)
306{ 302{
307 struct ipoib_mcast *mcast = mcast_ptr; 303 struct ipoib_mcast *mcast = multicast->context;
308 struct net_device *dev = mcast->dev; 304 struct net_device *dev = mcast->dev;
309 struct ipoib_dev_priv *priv = netdev_priv(dev); 305 struct ipoib_dev_priv *priv = netdev_priv(dev);
310 306
307 /* We trap for port events ourselves. */
308 if (status == -ENETRESET)
309 return 0;
310
311 if (!status) 311 if (!status)
312 ipoib_mcast_join_finish(mcast, mcmember); 312 status = ipoib_mcast_join_finish(mcast, &multicast->rec);
313 else { 313
314 if (status) {
314 if (mcast->logcount++ < 20) 315 if (mcast->logcount++ < 20)
315 ipoib_dbg_mcast(netdev_priv(dev), "multicast join failed for " 316 ipoib_dbg_mcast(netdev_priv(dev), "multicast join failed for "
316 IPOIB_GID_FMT ", status %d\n", 317 IPOIB_GID_FMT ", status %d\n",
@@ -325,11 +326,10 @@ ipoib_mcast_sendonly_join_complete(int status,
325 spin_unlock_irq(&priv->tx_lock); 326 spin_unlock_irq(&priv->tx_lock);
326 327
327 /* Clear the busy flag so we try again */ 328 /* Clear the busy flag so we try again */
328 clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags); 329 status = test_and_clear_bit(IPOIB_MCAST_FLAG_BUSY,
329 mcast->query = NULL; 330 &mcast->flags);
330 } 331 }
331 332 return status;
332 complete(&mcast->done);
333} 333}
334 334
335static int ipoib_mcast_sendonly_join(struct ipoib_mcast *mcast) 335static int ipoib_mcast_sendonly_join(struct ipoib_mcast *mcast)
@@ -359,35 +359,33 @@ static int ipoib_mcast_sendonly_join(struct ipoib_mcast *mcast)
359 rec.port_gid = priv->local_gid; 359 rec.port_gid = priv->local_gid;
360 rec.pkey = cpu_to_be16(priv->pkey); 360 rec.pkey = cpu_to_be16(priv->pkey);
361 361
362 init_completion(&mcast->done); 362 mcast->mc = ib_sa_join_multicast(&ipoib_sa_client, priv->ca,
363 363 priv->port, &rec,
364 ret = ib_sa_mcmember_rec_set(&ipoib_sa_client, priv->ca, priv->port, &rec, 364 IB_SA_MCMEMBER_REC_MGID |
365 IB_SA_MCMEMBER_REC_MGID | 365 IB_SA_MCMEMBER_REC_PORT_GID |
366 IB_SA_MCMEMBER_REC_PORT_GID | 366 IB_SA_MCMEMBER_REC_PKEY |
367 IB_SA_MCMEMBER_REC_PKEY | 367 IB_SA_MCMEMBER_REC_JOIN_STATE,
368 IB_SA_MCMEMBER_REC_JOIN_STATE, 368 GFP_ATOMIC,
369 1000, GFP_ATOMIC, 369 ipoib_mcast_sendonly_join_complete,
370 ipoib_mcast_sendonly_join_complete, 370 mcast);
371 mcast, &mcast->query); 371 if (IS_ERR(mcast->mc)) {
372 if (ret < 0) { 372 ret = PTR_ERR(mcast->mc);
373 ipoib_warn(priv, "ib_sa_mcmember_rec_set failed (ret = %d)\n", 373 clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
374 ipoib_warn(priv, "ib_sa_join_multicast failed (ret = %d)\n",
374 ret); 375 ret);
375 } else { 376 } else {
376 ipoib_dbg_mcast(priv, "no multicast record for " IPOIB_GID_FMT 377 ipoib_dbg_mcast(priv, "no multicast record for " IPOIB_GID_FMT
377 ", starting join\n", 378 ", starting join\n",
378 IPOIB_GID_ARG(mcast->mcmember.mgid)); 379 IPOIB_GID_ARG(mcast->mcmember.mgid));
379
380 mcast->query_id = ret;
381 } 380 }
382 381
383 return ret; 382 return ret;
384} 383}
385 384
386static void ipoib_mcast_join_complete(int status, 385static int ipoib_mcast_join_complete(int status,
387 struct ib_sa_mcmember_rec *mcmember, 386 struct ib_sa_multicast *multicast)
388 void *mcast_ptr)
389{ 387{
390 struct ipoib_mcast *mcast = mcast_ptr; 388 struct ipoib_mcast *mcast = multicast->context;
391 struct net_device *dev = mcast->dev; 389 struct net_device *dev = mcast->dev;
392 struct ipoib_dev_priv *priv = netdev_priv(dev); 390 struct ipoib_dev_priv *priv = netdev_priv(dev);
393 391
@@ -395,24 +393,25 @@ static void ipoib_mcast_join_complete(int status,
395 " (status %d)\n", 393 " (status %d)\n",
396 IPOIB_GID_ARG(mcast->mcmember.mgid), status); 394 IPOIB_GID_ARG(mcast->mcmember.mgid), status);
397 395
398 if (!status && !ipoib_mcast_join_finish(mcast, mcmember)) { 396 /* We trap for port events ourselves. */
397 if (status == -ENETRESET)
398 return 0;
399
400 if (!status)
401 status = ipoib_mcast_join_finish(mcast, &multicast->rec);
402
403 if (!status) {
399 mcast->backoff = 1; 404 mcast->backoff = 1;
400 mutex_lock(&mcast_mutex); 405 mutex_lock(&mcast_mutex);
401 if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) 406 if (test_bit(IPOIB_MCAST_RUN, &priv->flags))
402 queue_delayed_work(ipoib_workqueue, 407 queue_delayed_work(ipoib_workqueue,
403 &priv->mcast_task, 0); 408 &priv->mcast_task, 0);
404 mutex_unlock(&mcast_mutex); 409 mutex_unlock(&mcast_mutex);
405 complete(&mcast->done); 410 return 0;
406 return;
407 }
408
409 if (status == -EINTR) {
410 complete(&mcast->done);
411 return;
412 } 411 }
413 412
414 if (status && mcast->logcount++ < 20) { 413 if (mcast->logcount++ < 20) {
415 if (status == -ETIMEDOUT || status == -EINTR) { 414 if (status == -ETIMEDOUT) {
416 ipoib_dbg_mcast(priv, "multicast join failed for " IPOIB_GID_FMT 415 ipoib_dbg_mcast(priv, "multicast join failed for " IPOIB_GID_FMT
417 ", status %d\n", 416 ", status %d\n",
418 IPOIB_GID_ARG(mcast->mcmember.mgid), 417 IPOIB_GID_ARG(mcast->mcmember.mgid),
@@ -429,24 +428,18 @@ static void ipoib_mcast_join_complete(int status,
429 if (mcast->backoff > IPOIB_MAX_BACKOFF_SECONDS) 428 if (mcast->backoff > IPOIB_MAX_BACKOFF_SECONDS)
430 mcast->backoff = IPOIB_MAX_BACKOFF_SECONDS; 429 mcast->backoff = IPOIB_MAX_BACKOFF_SECONDS;
431 430
432 mutex_lock(&mcast_mutex); 431 /* Clear the busy flag so we try again */
432 status = test_and_clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
433 433
434 mutex_lock(&mcast_mutex);
434 spin_lock_irq(&priv->lock); 435 spin_lock_irq(&priv->lock);
435 mcast->query = NULL; 436 if (test_bit(IPOIB_MCAST_RUN, &priv->flags))
436 437 queue_delayed_work(ipoib_workqueue, &priv->mcast_task,
437 if (test_bit(IPOIB_MCAST_RUN, &priv->flags)) { 438 mcast->backoff * HZ);
438 if (status == -ETIMEDOUT)
439 queue_delayed_work(ipoib_workqueue, &priv->mcast_task,
440 0);
441 else
442 queue_delayed_work(ipoib_workqueue, &priv->mcast_task,
443 mcast->backoff * HZ);
444 } else
445 complete(&mcast->done);
446 spin_unlock_irq(&priv->lock); 439 spin_unlock_irq(&priv->lock);
447 mutex_unlock(&mcast_mutex); 440 mutex_unlock(&mcast_mutex);
448 441
449 return; 442 return status;
450} 443}
451 444
452static void ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast, 445static void ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast,
@@ -495,15 +488,14 @@ static void ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast,
495 rec.hop_limit = priv->broadcast->mcmember.hop_limit; 488 rec.hop_limit = priv->broadcast->mcmember.hop_limit;
496 } 489 }
497 490
498 init_completion(&mcast->done); 491 set_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
499 492 mcast->mc = ib_sa_join_multicast(&ipoib_sa_client, priv->ca, priv->port,
500 ret = ib_sa_mcmember_rec_set(&ipoib_sa_client, priv->ca, priv->port, 493 &rec, comp_mask, GFP_KERNEL,
501 &rec, comp_mask, mcast->backoff * 1000, 494 ipoib_mcast_join_complete, mcast);
502 GFP_ATOMIC, ipoib_mcast_join_complete, 495 if (IS_ERR(mcast->mc)) {
503 mcast, &mcast->query); 496 clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags);
504 497 ret = PTR_ERR(mcast->mc);
505 if (ret < 0) { 498 ipoib_warn(priv, "ib_sa_join_multicast failed, status %d\n", ret);
506 ipoib_warn(priv, "ib_sa_mcmember_rec_set failed, status %d\n", ret);
507 499
508 mcast->backoff *= 2; 500 mcast->backoff *= 2;
509 if (mcast->backoff > IPOIB_MAX_BACKOFF_SECONDS) 501 if (mcast->backoff > IPOIB_MAX_BACKOFF_SECONDS)
@@ -515,8 +507,7 @@ static void ipoib_mcast_join(struct net_device *dev, struct ipoib_mcast *mcast,
515 &priv->mcast_task, 507 &priv->mcast_task,
516 mcast->backoff * HZ); 508 mcast->backoff * HZ);
517 mutex_unlock(&mcast_mutex); 509 mutex_unlock(&mcast_mutex);
518 } else 510 }
519 mcast->query_id = ret;
520} 511}
521 512
522void ipoib_mcast_join_task(struct work_struct *work) 513void ipoib_mcast_join_task(struct work_struct *work)
@@ -541,7 +532,7 @@ void ipoib_mcast_join_task(struct work_struct *work)
541 priv->local_rate = attr.active_speed * 532 priv->local_rate = attr.active_speed *
542 ib_width_enum_to_int(attr.active_width); 533 ib_width_enum_to_int(attr.active_width);
543 } else 534 } else
544 ipoib_warn(priv, "ib_query_port failed\n"); 535 ipoib_warn(priv, "ib_query_port failed\n");
545 } 536 }
546 537
547 if (!priv->broadcast) { 538 if (!priv->broadcast) {
@@ -568,7 +559,8 @@ void ipoib_mcast_join_task(struct work_struct *work)
568 } 559 }
569 560
570 if (!test_bit(IPOIB_MCAST_FLAG_ATTACHED, &priv->broadcast->flags)) { 561 if (!test_bit(IPOIB_MCAST_FLAG_ATTACHED, &priv->broadcast->flags)) {
571 ipoib_mcast_join(dev, priv->broadcast, 0); 562 if (!test_bit(IPOIB_MCAST_FLAG_BUSY, &priv->broadcast->flags))
563 ipoib_mcast_join(dev, priv->broadcast, 0);
572 return; 564 return;
573 } 565 }
574 566
@@ -625,26 +617,9 @@ int ipoib_mcast_start_thread(struct net_device *dev)
625 return 0; 617 return 0;
626} 618}
627 619
628static void wait_for_mcast_join(struct ipoib_dev_priv *priv,
629 struct ipoib_mcast *mcast)
630{
631 spin_lock_irq(&priv->lock);
632 if (mcast && mcast->query) {
633 ib_sa_cancel_query(mcast->query_id, mcast->query);
634 mcast->query = NULL;
635 spin_unlock_irq(&priv->lock);
636 ipoib_dbg_mcast(priv, "waiting for MGID " IPOIB_GID_FMT "\n",
637 IPOIB_GID_ARG(mcast->mcmember.mgid));
638 wait_for_completion(&mcast->done);
639 }
640 else
641 spin_unlock_irq(&priv->lock);
642}
643
644int ipoib_mcast_stop_thread(struct net_device *dev, int flush) 620int ipoib_mcast_stop_thread(struct net_device *dev, int flush)
645{ 621{
646 struct ipoib_dev_priv *priv = netdev_priv(dev); 622 struct ipoib_dev_priv *priv = netdev_priv(dev);
647 struct ipoib_mcast *mcast;
648 623
649 ipoib_dbg_mcast(priv, "stopping multicast thread\n"); 624 ipoib_dbg_mcast(priv, "stopping multicast thread\n");
650 625
@@ -660,52 +635,27 @@ int ipoib_mcast_stop_thread(struct net_device *dev, int flush)
660 if (flush) 635 if (flush)
661 flush_workqueue(ipoib_workqueue); 636 flush_workqueue(ipoib_workqueue);
662 637
663 wait_for_mcast_join(priv, priv->broadcast);
664
665 list_for_each_entry(mcast, &priv->multicast_list, list)
666 wait_for_mcast_join(priv, mcast);
667
668 return 0; 638 return 0;
669} 639}
670 640
671static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast) 641static int ipoib_mcast_leave(struct net_device *dev, struct ipoib_mcast *mcast)
672{ 642{
673 struct ipoib_dev_priv *priv = netdev_priv(dev); 643 struct ipoib_dev_priv *priv = netdev_priv(dev);
674 struct ib_sa_mcmember_rec rec = {
675 .join_state = 1
676 };
677 int ret = 0; 644 int ret = 0;
678 645
679 if (!test_and_clear_bit(IPOIB_MCAST_FLAG_ATTACHED, &mcast->flags)) 646 if (test_and_clear_bit(IPOIB_MCAST_FLAG_ATTACHED, &mcast->flags)) {
680 return 0; 647 ipoib_dbg_mcast(priv, "leaving MGID " IPOIB_GID_FMT "\n",
681 648 IPOIB_GID_ARG(mcast->mcmember.mgid));
682 ipoib_dbg_mcast(priv, "leaving MGID " IPOIB_GID_FMT "\n",
683 IPOIB_GID_ARG(mcast->mcmember.mgid));
684
685 rec.mgid = mcast->mcmember.mgid;
686 rec.port_gid = priv->local_gid;
687 rec.pkey = cpu_to_be16(priv->pkey);
688 649
689 /* Remove ourselves from the multicast group */ 650 /* Remove ourselves from the multicast group */
690 ret = ipoib_mcast_detach(dev, be16_to_cpu(mcast->mcmember.mlid), 651 ret = ipoib_mcast_detach(dev, be16_to_cpu(mcast->mcmember.mlid),
691 &mcast->mcmember.mgid); 652 &mcast->mcmember.mgid);
692 if (ret) 653 if (ret)
693 ipoib_warn(priv, "ipoib_mcast_detach failed (result = %d)\n", ret); 654 ipoib_warn(priv, "ipoib_mcast_detach failed (result = %d)\n", ret);
655 }
694 656
695 /* 657 if (test_and_clear_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags))
696 * Just make one shot at leaving and don't wait for a reply; 658 ib_sa_free_multicast(mcast->mc);
697 * if we fail, too bad.
698 */
699 ret = ib_sa_mcmember_rec_delete(&ipoib_sa_client, priv->ca, priv->port, &rec,
700 IB_SA_MCMEMBER_REC_MGID |
701 IB_SA_MCMEMBER_REC_PORT_GID |
702 IB_SA_MCMEMBER_REC_PKEY |
703 IB_SA_MCMEMBER_REC_JOIN_STATE,
704 0, GFP_ATOMIC, NULL,
705 mcast, &mcast->query);
706 if (ret < 0)
707 ipoib_warn(priv, "ib_sa_mcmember_rec_delete failed "
708 "for leave (result = %d)\n", ret);
709 659
710 return 0; 660 return 0;
711} 661}
@@ -758,7 +708,7 @@ void ipoib_mcast_send(struct net_device *dev, void *mgid, struct sk_buff *skb)
758 dev_kfree_skb_any(skb); 708 dev_kfree_skb_any(skb);
759 } 709 }
760 710
761 if (mcast->query) 711 if (test_bit(IPOIB_MCAST_FLAG_BUSY, &mcast->flags))
762 ipoib_dbg_mcast(priv, "no address vector, " 712 ipoib_dbg_mcast(priv, "no address vector, "
763 "but multicast join already started\n"); 713 "but multicast join already started\n");
764 else if (test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags)) 714 else if (test_bit(IPOIB_MCAST_FLAG_SENDONLY, &mcast->flags))
@@ -916,7 +866,6 @@ void ipoib_mcast_restart_task(struct work_struct *work)
916 866
917 /* We have to cancel outside of the spinlock */ 867 /* We have to cancel outside of the spinlock */
918 list_for_each_entry_safe(mcast, tmcast, &remove_list, list) { 868 list_for_each_entry_safe(mcast, tmcast, &remove_list, list) {
919 wait_for_mcast_join(priv, mcast);
920 ipoib_mcast_leave(mcast->dev, mcast); 869 ipoib_mcast_leave(mcast->dev, mcast);
921 ipoib_mcast_free(mcast); 870 ipoib_mcast_free(mcast);
922 } 871 }
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index bedae4ad3f74..80b199fa0aa9 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -107,4 +107,19 @@ config MSI_LAPTOP
107 107
108 If you have an MSI S270 laptop, say Y or M here. 108 If you have an MSI S270 laptop, say Y or M here.
109 109
110config SONY_LAPTOP
111 tristate "Sony Laptop Extras"
112 depends on X86 && ACPI
113 select BACKLIGHT_CLASS_DEVICE
114 ---help---
115 This mini-driver drives the SNC device present in the ACPI BIOS of
116 the Sony Vaio laptops.
117
118 It gives access to some extra laptop functionalities. In its current
119 form, this driver let the user set or query the screen brightness
120 through the backlight subsystem and remove/apply power to some
121 devices.
122
123 Read <file:Documentation/sony-laptop.txt> for more information.
124
110endmenu 125endmenu
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 35da53c409c0..7793ccd79049 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_LKDTM) += lkdtm.o
11obj-$(CONFIG_TIFM_CORE) += tifm_core.o 11obj-$(CONFIG_TIFM_CORE) += tifm_core.o
12obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o 12obj-$(CONFIG_TIFM_7XX1) += tifm_7xx1.o
13obj-$(CONFIG_SGI_IOC4) += ioc4.o 13obj-$(CONFIG_SGI_IOC4) += ioc4.o
14obj-$(CONFIG_SONY_LAPTOP) += sony-laptop.o
diff --git a/drivers/misc/asus-laptop.c b/drivers/misc/asus-laptop.c
index 861c39935f99..e4e2b707a353 100644
--- a/drivers/misc/asus-laptop.c
+++ b/drivers/misc/asus-laptop.c
@@ -1088,11 +1088,6 @@ static int __init asus_laptop_init(void)
1088 if (acpi_disabled) 1088 if (acpi_disabled)
1089 return -ENODEV; 1089 return -ENODEV;
1090 1090
1091 if (!acpi_specific_hotkey_enabled) {
1092 printk(ASUS_ERR "Using generic hotkey driver\n");
1093 return -ENODEV;
1094 }
1095
1096 result = acpi_bus_register_driver(&asus_hotk_driver); 1091 result = acpi_bus_register_driver(&asus_hotk_driver);
1097 if (result < 0) 1092 if (result < 0)
1098 return result; 1093 return result;
diff --git a/drivers/misc/sony-laptop.c b/drivers/misc/sony-laptop.c
new file mode 100644
index 000000000000..cabbed0015e4
--- /dev/null
+++ b/drivers/misc/sony-laptop.c
@@ -0,0 +1,562 @@
1/*
2 * ACPI Sony Notebook Control Driver (SNC)
3 *
4 * Copyright (C) 2004-2005 Stelian Pop <stelian@popies.net>
5 * Copyright (C) 2007 Mattia Dongili <malattia@linux.it>
6 *
7 * Parts of this driver inspired from asus_acpi.c and ibm_acpi.c
8 * which are copyrighted by their respective authors.
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 of the License, or
13 * (at your option) 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
26#include <linux/kernel.h>
27#include <linux/module.h>
28#include <linux/moduleparam.h>
29#include <linux/init.h>
30#include <linux/types.h>
31#include <linux/backlight.h>
32#include <linux/platform_device.h>
33#include <linux/err.h>
34#include <acpi/acpi_drivers.h>
35#include <acpi/acpi_bus.h>
36#include <asm/uaccess.h>
37
38#define ACPI_SNC_CLASS "sony"
39#define ACPI_SNC_HID "SNY5001"
40#define ACPI_SNC_DRIVER_NAME "ACPI Sony Notebook Control Driver v0.4"
41
42/* the device uses 1-based values, while the backlight subsystem uses
43 0-based values */
44#define SONY_MAX_BRIGHTNESS 8
45
46#define LOG_PFX KERN_WARNING "sony-laptop: "
47
48MODULE_AUTHOR("Stelian Pop, Mattia Dongili");
49MODULE_DESCRIPTION(ACPI_SNC_DRIVER_NAME);
50MODULE_LICENSE("GPL");
51
52static int debug;
53module_param(debug, int, 0);
54MODULE_PARM_DESC(debug, "set this to 1 (and RTFM) if you want to help "
55 "the development of this driver");
56
57static ssize_t sony_acpi_show(struct device *, struct device_attribute *,
58 char *);
59static ssize_t sony_acpi_store(struct device *, struct device_attribute *,
60 const char *, size_t);
61static int boolean_validate(const int, const int);
62static int brightness_default_validate(const int, const int);
63
64#define SNC_VALIDATE_IN 0
65#define SNC_VALIDATE_OUT 1
66
67struct sony_acpi_value {
68 char *name; /* name of the entry */
69 char **acpiget; /* names of the ACPI get function */
70 char **acpiset; /* names of the ACPI set function */
71 int (*validate)(const int, const int); /* input/output validation */
72 int value; /* current setting */
73 int valid; /* Has ever been set */
74 int debug; /* active only in debug mode ? */
75 struct device_attribute devattr; /* sysfs atribute */
76};
77
78#define HANDLE_NAMES(_name, _values...) \
79 static char *snc_##_name[] = { _values, NULL }
80
81#define SONY_ACPI_VALUE(_name, _getters, _setters, _validate, _debug) \
82 { \
83 .name = __stringify(_name), \
84 .acpiget = _getters, \
85 .acpiset = _setters, \
86 .validate = _validate, \
87 .debug = _debug, \
88 .devattr = __ATTR(_name, 0, sony_acpi_show, sony_acpi_store), \
89 }
90
91#define SONY_ACPI_VALUE_NULL { .name = NULL }
92
93HANDLE_NAMES(fnkey_get, "GHKE");
94
95HANDLE_NAMES(brightness_def_get, "GPBR");
96HANDLE_NAMES(brightness_def_set, "SPBR");
97
98HANDLE_NAMES(cdpower_get, "GCDP");
99HANDLE_NAMES(cdpower_set, "SCDP", "CDPW");
100
101HANDLE_NAMES(audiopower_get, "GAZP");
102HANDLE_NAMES(audiopower_set, "AZPW");
103
104HANDLE_NAMES(lanpower_get, "GLNP");
105HANDLE_NAMES(lanpower_set, "LNPW");
106
107HANDLE_NAMES(PID_get, "GPID");
108
109HANDLE_NAMES(CTR_get, "GCTR");
110HANDLE_NAMES(CTR_set, "SCTR");
111
112HANDLE_NAMES(PCR_get, "GPCR");
113HANDLE_NAMES(PCR_set, "SPCR");
114
115HANDLE_NAMES(CMI_get, "GCMI");
116HANDLE_NAMES(CMI_set, "SCMI");
117
118static struct sony_acpi_value sony_acpi_values[] = {
119 SONY_ACPI_VALUE(brightness_default, snc_brightness_def_get,
120 snc_brightness_def_set, brightness_default_validate, 0),
121 SONY_ACPI_VALUE(fnkey, snc_fnkey_get, NULL, NULL, 0),
122 SONY_ACPI_VALUE(cdpower, snc_cdpower_get, snc_cdpower_set, boolean_validate, 0),
123 SONY_ACPI_VALUE(audiopower, snc_audiopower_get, snc_audiopower_set,
124 boolean_validate, 0),
125 SONY_ACPI_VALUE(lanpower, snc_lanpower_get, snc_lanpower_set,
126 boolean_validate, 1),
127 /* unknown methods */
128 SONY_ACPI_VALUE(PID, snc_PID_get, NULL, NULL, 1),
129 SONY_ACPI_VALUE(CTR, snc_CTR_get, snc_CTR_set, NULL, 1),
130 SONY_ACPI_VALUE(PCR, snc_PCR_get, snc_PCR_set, NULL, 1),
131 SONY_ACPI_VALUE(CMI, snc_CMI_get, snc_CMI_set, NULL, 1),
132 SONY_ACPI_VALUE_NULL
133};
134
135static acpi_handle sony_acpi_handle;
136static struct acpi_device *sony_acpi_acpi_device = NULL;
137
138/*
139 * acpi_evaluate_object wrappers
140 */
141static int acpi_callgetfunc(acpi_handle handle, char *name, int *result)
142{
143 struct acpi_buffer output;
144 union acpi_object out_obj;
145 acpi_status status;
146
147 output.length = sizeof(out_obj);
148 output.pointer = &out_obj;
149
150 status = acpi_evaluate_object(handle, name, NULL, &output);
151 if ((status == AE_OK) && (out_obj.type == ACPI_TYPE_INTEGER)) {
152 *result = out_obj.integer.value;
153 return 0;
154 }
155
156 printk(LOG_PFX "acpi_callreadfunc failed\n");
157
158 return -1;
159}
160
161static int acpi_callsetfunc(acpi_handle handle, char *name, int value,
162 int *result)
163{
164 struct acpi_object_list params;
165 union acpi_object in_obj;
166 struct acpi_buffer output;
167 union acpi_object out_obj;
168 acpi_status status;
169
170 params.count = 1;
171 params.pointer = &in_obj;
172 in_obj.type = ACPI_TYPE_INTEGER;
173 in_obj.integer.value = value;
174
175 output.length = sizeof(out_obj);
176 output.pointer = &out_obj;
177
178 status = acpi_evaluate_object(handle, name, &params, &output);
179 if (status == AE_OK) {
180 if (result != NULL) {
181 if (out_obj.type != ACPI_TYPE_INTEGER) {
182 printk(LOG_PFX "acpi_evaluate_object bad "
183 "return type\n");
184 return -1;
185 }
186 *result = out_obj.integer.value;
187 }
188 return 0;
189 }
190
191 printk(LOG_PFX "acpi_evaluate_object failed\n");
192
193 return -1;
194}
195
196/*
197 * sony_acpi_values input/output validate functions
198 */
199
200/* brightness_default_validate:
201 *
202 * manipulate input output values to keep consistency with the
203 * backlight framework for which brightness values are 0-based.
204 */
205static int brightness_default_validate(const int direction, const int value)
206{
207 switch (direction) {
208 case SNC_VALIDATE_OUT:
209 return value - 1;
210 case SNC_VALIDATE_IN:
211 if (value >= 0 && value < SONY_MAX_BRIGHTNESS)
212 return value + 1;
213 }
214 return -EINVAL;
215}
216
217/* boolean_validate:
218 *
219 * on input validate boolean values 0/1, on output just pass the
220 * received value.
221 */
222static int boolean_validate(const int direction, const int value)
223{
224 if (direction == SNC_VALIDATE_IN) {
225 if (value != 0 && value != 1)
226 return -EINVAL;
227 }
228 return value;
229}
230
231/*
232 * Sysfs show/store common to all sony_acpi_values
233 */
234static ssize_t sony_acpi_show(struct device *dev, struct device_attribute *attr,
235 char *buffer)
236{
237 int value;
238 struct sony_acpi_value *item =
239 container_of(attr, struct sony_acpi_value, devattr);
240
241 if (!*item->acpiget)
242 return -EIO;
243
244 if (acpi_callgetfunc(sony_acpi_handle, *item->acpiget, &value) < 0)
245 return -EIO;
246
247 if (item->validate)
248 value = item->validate(SNC_VALIDATE_OUT, value);
249
250 return snprintf(buffer, PAGE_SIZE, "%d\n", value);
251}
252
253static ssize_t sony_acpi_store(struct device *dev,
254 struct device_attribute *attr,
255 const char *buffer, size_t count)
256{
257 int value;
258 struct sony_acpi_value *item =
259 container_of(attr, struct sony_acpi_value, devattr);
260
261 if (!item->acpiset)
262 return -EIO;
263
264 if (count > 31)
265 return -EINVAL;
266
267 value = simple_strtoul(buffer, NULL, 10);
268
269 if (item->validate)
270 value = item->validate(SNC_VALIDATE_IN, value);
271
272 if (value < 0)
273 return value;
274
275 if (acpi_callsetfunc(sony_acpi_handle, *item->acpiset, value, NULL) < 0)
276 return -EIO;
277 item->value = value;
278 item->valid = 1;
279 return count;
280}
281
282/*
283 * Platform device
284 */
285static struct platform_driver sncpf_driver = {
286 .driver = {
287 .name = "sony-laptop",
288 .owner = THIS_MODULE,
289 }
290};
291static struct platform_device *sncpf_device;
292
293static int sony_snc_pf_add(void)
294{
295 acpi_handle handle;
296 struct sony_acpi_value *item;
297 int ret = 0;
298
299 ret = platform_driver_register(&sncpf_driver);
300 if (ret)
301 goto out;
302
303 sncpf_device = platform_device_alloc("sony-laptop", -1);
304 if (!sncpf_device) {
305 ret = -ENOMEM;
306 goto out_platform_registered;
307 }
308
309 ret = platform_device_add(sncpf_device);
310 if (ret)
311 goto out_platform_alloced;
312
313 for (item = sony_acpi_values; item->name; ++item) {
314
315 if (!debug && item->debug)
316 continue;
317
318 /* find the available acpiget as described in the DSDT */
319 for (; item->acpiget && *item->acpiget; ++item->acpiget) {
320 if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle,
321 *item->acpiget,
322 &handle))) {
323 if (debug)
324 printk(LOG_PFX "Found %s getter: %s\n",
325 item->name, *item->acpiget);
326 item->devattr.attr.mode |= S_IRUGO;
327 break;
328 }
329 }
330
331 /* find the available acpiset as described in the DSDT */
332 for (; item->acpiset && *item->acpiset; ++item->acpiset) {
333 if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle,
334 *item->acpiset,
335 &handle))) {
336 if (debug)
337 printk(LOG_PFX "Found %s setter: %s\n",
338 item->name, *item->acpiset);
339 item->devattr.attr.mode |= S_IWUSR;
340 break;
341 }
342 }
343
344 if (item->devattr.attr.mode != 0) {
345 ret =
346 device_create_file(&sncpf_device->dev,
347 &item->devattr);
348 if (ret)
349 goto out_sysfs;
350 }
351 }
352
353 return 0;
354
355 out_sysfs:
356 for (item = sony_acpi_values; item->name; ++item) {
357 device_remove_file(&sncpf_device->dev, &item->devattr);
358 }
359 platform_device_del(sncpf_device);
360 out_platform_alloced:
361 platform_device_put(sncpf_device);
362 out_platform_registered:
363 platform_driver_unregister(&sncpf_driver);
364 out:
365 return ret;
366}
367
368static void sony_snc_pf_remove(void)
369{
370 struct sony_acpi_value *item;
371
372 for (item = sony_acpi_values; item->name; ++item) {
373 device_remove_file(&sncpf_device->dev, &item->devattr);
374 }
375
376 platform_device_del(sncpf_device);
377 platform_device_put(sncpf_device);
378 platform_driver_unregister(&sncpf_driver);
379}
380
381/*
382 * Backlight device
383 */
384static int sony_backlight_update_status(struct backlight_device *bd)
385{
386 return acpi_callsetfunc(sony_acpi_handle, "SBRT",
387 bd->props->brightness + 1, NULL);
388}
389
390static int sony_backlight_get_brightness(struct backlight_device *bd)
391{
392 int value;
393
394 if (acpi_callgetfunc(sony_acpi_handle, "GBRT", &value))
395 return 0;
396 /* brightness levels are 1-based, while backlight ones are 0-based */
397 return value - 1;
398}
399
400static struct backlight_device *sony_backlight_device;
401static struct backlight_properties sony_backlight_properties = {
402 .owner = THIS_MODULE,
403 .update_status = sony_backlight_update_status,
404 .get_brightness = sony_backlight_get_brightness,
405 .max_brightness = SONY_MAX_BRIGHTNESS - 1,
406};
407
408/*
409 * ACPI callbacks
410 */
411static void sony_acpi_notify(acpi_handle handle, u32 event, void *data)
412{
413 if (debug)
414 printk(LOG_PFX "sony_acpi_notify, event: %d\n", event);
415 acpi_bus_generate_event(sony_acpi_acpi_device, 1, event);
416}
417
418static acpi_status sony_walk_callback(acpi_handle handle, u32 level,
419 void *context, void **return_value)
420{
421 struct acpi_namespace_node *node;
422 union acpi_operand_object *operand;
423
424 node = (struct acpi_namespace_node *)handle;
425 operand = (union acpi_operand_object *)node->object;
426
427 printk(LOG_PFX "method: name: %4.4s, args %X\n", node->name.ascii,
428 (u32) operand->method.param_count);
429
430 return AE_OK;
431}
432
433/*
434 * ACPI device
435 */
436static int sony_acpi_resume(struct acpi_device *device)
437{
438 struct sony_acpi_value *item;
439
440 for (item = sony_acpi_values; item->name; item++) {
441 int ret;
442
443 if (!item->valid)
444 continue;
445 ret = acpi_callsetfunc(sony_acpi_handle, *item->acpiset,
446 item->value, NULL);
447 if (ret < 0) {
448 printk("%s: %d\n", __FUNCTION__, ret);
449 break;
450 }
451 }
452 return 0;
453}
454
455static int sony_acpi_add(struct acpi_device *device)
456{
457 acpi_status status;
458 int result;
459 acpi_handle handle;
460
461 sony_acpi_acpi_device = device;
462
463 sony_acpi_handle = device->handle;
464
465 if (debug) {
466 status = acpi_walk_namespace(ACPI_TYPE_METHOD, sony_acpi_handle,
467 1, sony_walk_callback, NULL, NULL);
468 if (ACPI_FAILURE(status)) {
469 printk(LOG_PFX "unable to walk acpi resources\n");
470 result = -ENODEV;
471 goto outwalk;
472 }
473 }
474
475 status = acpi_install_notify_handler(sony_acpi_handle,
476 ACPI_DEVICE_NOTIFY,
477 sony_acpi_notify, NULL);
478 if (ACPI_FAILURE(status)) {
479 printk(LOG_PFX "unable to install notify handler\n");
480 result = -ENODEV;
481 goto outwalk;
482 }
483
484 if (ACPI_SUCCESS(acpi_get_handle(sony_acpi_handle, "GBRT", &handle))) {
485 sony_backlight_device = backlight_device_register("sony", NULL,
486 NULL,
487 &sony_backlight_properties);
488
489 if (IS_ERR(sony_backlight_device)) {
490 printk(LOG_PFX "unable to register backlight device\n");
491 sony_backlight_device = NULL;
492 } else
493 sony_backlight_properties.brightness =
494 sony_backlight_get_brightness
495 (sony_backlight_device);
496 }
497
498 if (sony_snc_pf_add())
499 goto outbacklight;
500
501 printk(KERN_INFO ACPI_SNC_DRIVER_NAME " successfully installed\n");
502
503 return 0;
504
505 outbacklight:
506 if (sony_backlight_device)
507 backlight_device_unregister(sony_backlight_device);
508
509 status = acpi_remove_notify_handler(sony_acpi_handle,
510 ACPI_DEVICE_NOTIFY,
511 sony_acpi_notify);
512 if (ACPI_FAILURE(status))
513 printk(LOG_PFX "unable to remove notify handler\n");
514 outwalk:
515 return result;
516}
517
518static int sony_acpi_remove(struct acpi_device *device, int type)
519{
520 acpi_status status;
521
522 if (sony_backlight_device)
523 backlight_device_unregister(sony_backlight_device);
524
525 sony_acpi_acpi_device = NULL;
526
527 status = acpi_remove_notify_handler(sony_acpi_handle,
528 ACPI_DEVICE_NOTIFY,
529 sony_acpi_notify);
530 if (ACPI_FAILURE(status))
531 printk(LOG_PFX "unable to remove notify handler\n");
532
533 sony_snc_pf_remove();
534
535 printk(KERN_INFO ACPI_SNC_DRIVER_NAME " successfully removed\n");
536
537 return 0;
538}
539
540static struct acpi_driver sony_acpi_driver = {
541 .name = ACPI_SNC_DRIVER_NAME,
542 .class = ACPI_SNC_CLASS,
543 .ids = ACPI_SNC_HID,
544 .ops = {
545 .add = sony_acpi_add,
546 .remove = sony_acpi_remove,
547 .resume = sony_acpi_resume,
548 },
549};
550
551static int __init sony_acpi_init(void)
552{
553 return acpi_bus_register_driver(&sony_acpi_driver);
554}
555
556static void __exit sony_acpi_exit(void)
557{
558 acpi_bus_unregister_driver(&sony_acpi_driver);
559}
560
561module_init(sony_acpi_init);
562module_exit(sony_acpi_exit);
diff --git a/drivers/mmc/at91_mci.c b/drivers/mmc/at91_mci.c
index 2ce50f38e3c7..459f4b4feded 100644
--- a/drivers/mmc/at91_mci.c
+++ b/drivers/mmc/at91_mci.c
@@ -64,6 +64,7 @@
64#include <linux/err.h> 64#include <linux/err.h>
65#include <linux/dma-mapping.h> 65#include <linux/dma-mapping.h>
66#include <linux/clk.h> 66#include <linux/clk.h>
67#include <linux/atmel_pdc.h>
67 68
68#include <linux/mmc/host.h> 69#include <linux/mmc/host.h>
69#include <linux/mmc/protocol.h> 70#include <linux/mmc/protocol.h>
@@ -75,7 +76,6 @@
75#include <asm/arch/cpu.h> 76#include <asm/arch/cpu.h>
76#include <asm/arch/gpio.h> 77#include <asm/arch/gpio.h>
77#include <asm/arch/at91_mci.h> 78#include <asm/arch/at91_mci.h>
78#include <asm/arch/at91_pdc.h>
79 79
80#define DRIVER_NAME "at91_mci" 80#define DRIVER_NAME "at91_mci"
81 81
@@ -211,13 +211,13 @@ static void at91mci_pre_dma_read(struct at91mci_host *host)
211 211
212 /* Check to see if this needs filling */ 212 /* Check to see if this needs filling */
213 if (i == 0) { 213 if (i == 0) {
214 if (at91_mci_read(host, AT91_PDC_RCR) != 0) { 214 if (at91_mci_read(host, ATMEL_PDC_RCR) != 0) {
215 pr_debug("Transfer active in current\n"); 215 pr_debug("Transfer active in current\n");
216 continue; 216 continue;
217 } 217 }
218 } 218 }
219 else { 219 else {
220 if (at91_mci_read(host, AT91_PDC_RNCR) != 0) { 220 if (at91_mci_read(host, ATMEL_PDC_RNCR) != 0) {
221 pr_debug("Transfer active in next\n"); 221 pr_debug("Transfer active in next\n");
222 continue; 222 continue;
223 } 223 }
@@ -234,12 +234,12 @@ static void at91mci_pre_dma_read(struct at91mci_host *host)
234 pr_debug("dma address = %08X, length = %d\n", sg->dma_address, sg->length); 234 pr_debug("dma address = %08X, length = %d\n", sg->dma_address, sg->length);
235 235
236 if (i == 0) { 236 if (i == 0) {
237 at91_mci_write(host, AT91_PDC_RPR, sg->dma_address); 237 at91_mci_write(host, ATMEL_PDC_RPR, sg->dma_address);
238 at91_mci_write(host, AT91_PDC_RCR, sg->length / 4); 238 at91_mci_write(host, ATMEL_PDC_RCR, sg->length / 4);
239 } 239 }
240 else { 240 else {
241 at91_mci_write(host, AT91_PDC_RNPR, sg->dma_address); 241 at91_mci_write(host, ATMEL_PDC_RNPR, sg->dma_address);
242 at91_mci_write(host, AT91_PDC_RNCR, sg->length / 4); 242 at91_mci_write(host, ATMEL_PDC_RNCR, sg->length / 4);
243 } 243 }
244 } 244 }
245 245
@@ -303,7 +303,7 @@ static void at91mci_post_dma_read(struct at91mci_host *host)
303 at91mci_pre_dma_read(host); 303 at91mci_pre_dma_read(host);
304 else { 304 else {
305 at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF); 305 at91_mci_write(host, AT91_MCI_IER, AT91_MCI_RXBUFF);
306 at91_mci_write(host, AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS); 306 at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
307 } 307 }
308 308
309 pr_debug("post dma read done\n"); 309 pr_debug("post dma read done\n");
@@ -320,7 +320,7 @@ static void at91_mci_handle_transmitted(struct at91mci_host *host)
320 pr_debug("Handling the transmit\n"); 320 pr_debug("Handling the transmit\n");
321 321
322 /* Disable the transfer */ 322 /* Disable the transfer */
323 at91_mci_write(host, AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS); 323 at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
324 324
325 /* Now wait for cmd ready */ 325 /* Now wait for cmd ready */
326 at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_TXBUFE); 326 at91_mci_write(host, AT91_MCI_IDR, AT91_MCI_TXBUFE);
@@ -431,15 +431,15 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_
431 cmd->opcode, cmdr, cmd->arg, blocks, block_length, at91_mci_read(host, AT91_MCI_MR)); 431 cmd->opcode, cmdr, cmd->arg, blocks, block_length, at91_mci_read(host, AT91_MCI_MR));
432 432
433 if (!data) { 433 if (!data) {
434 at91_mci_write(host, AT91_PDC_PTCR, AT91_PDC_TXTDIS | AT91_PDC_RXTDIS); 434 at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTDIS | ATMEL_PDC_RXTDIS);
435 at91_mci_write(host, AT91_PDC_RPR, 0); 435 at91_mci_write(host, ATMEL_PDC_RPR, 0);
436 at91_mci_write(host, AT91_PDC_RCR, 0); 436 at91_mci_write(host, ATMEL_PDC_RCR, 0);
437 at91_mci_write(host, AT91_PDC_RNPR, 0); 437 at91_mci_write(host, ATMEL_PDC_RNPR, 0);
438 at91_mci_write(host, AT91_PDC_RNCR, 0); 438 at91_mci_write(host, ATMEL_PDC_RNCR, 0);
439 at91_mci_write(host, AT91_PDC_TPR, 0); 439 at91_mci_write(host, ATMEL_PDC_TPR, 0);
440 at91_mci_write(host, AT91_PDC_TCR, 0); 440 at91_mci_write(host, ATMEL_PDC_TCR, 0);
441 at91_mci_write(host, AT91_PDC_TNPR, 0); 441 at91_mci_write(host, ATMEL_PDC_TNPR, 0);
442 at91_mci_write(host, AT91_PDC_TNCR, 0); 442 at91_mci_write(host, ATMEL_PDC_TNCR, 0);
443 443
444 at91_mci_write(host, AT91_MCI_ARGR, cmd->arg); 444 at91_mci_write(host, AT91_MCI_ARGR, cmd->arg);
445 at91_mci_write(host, AT91_MCI_CMDR, cmdr); 445 at91_mci_write(host, AT91_MCI_CMDR, cmdr);
@@ -452,7 +452,7 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_
452 /* 452 /*
453 * Disable the PDC controller 453 * Disable the PDC controller
454 */ 454 */
455 at91_mci_write(host, AT91_PDC_PTCR, AT91_PDC_RXTDIS | AT91_PDC_TXTDIS); 455 at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTDIS | ATMEL_PDC_TXTDIS);
456 456
457 if (cmdr & AT91_MCI_TRCMD_START) { 457 if (cmdr & AT91_MCI_TRCMD_START) {
458 data->bytes_xfered = 0; 458 data->bytes_xfered = 0;
@@ -481,8 +481,8 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_
481 481
482 pr_debug("Transmitting %d bytes\n", host->total_length); 482 pr_debug("Transmitting %d bytes\n", host->total_length);
483 483
484 at91_mci_write(host, AT91_PDC_TPR, host->physical_address); 484 at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address);
485 at91_mci_write(host, AT91_PDC_TCR, host->total_length / 4); 485 at91_mci_write(host, ATMEL_PDC_TCR, host->total_length / 4);
486 ier = AT91_MCI_TXBUFE; 486 ier = AT91_MCI_TXBUFE;
487 } 487 }
488 } 488 }
@@ -497,9 +497,9 @@ static unsigned int at91_mci_send_command(struct at91mci_host *host, struct mmc_
497 497
498 if (cmdr & AT91_MCI_TRCMD_START) { 498 if (cmdr & AT91_MCI_TRCMD_START) {
499 if (cmdr & AT91_MCI_TRDIR) 499 if (cmdr & AT91_MCI_TRDIR)
500 at91_mci_write(host, AT91_PDC_PTCR, AT91_PDC_RXTEN); 500 at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_RXTEN);
501 else 501 else
502 at91_mci_write(host, AT91_PDC_PTCR, AT91_PDC_TXTEN); 502 at91_mci_write(host, ATMEL_PDC_PTCR, ATMEL_PDC_TXTEN);
503 } 503 }
504 return ier; 504 return ier;
505} 505}
diff --git a/drivers/pci/pci-driver.c b/drivers/pci/pci-driver.c
index 4438ae1ede4f..a3c1755b2f28 100644
--- a/drivers/pci/pci-driver.c
+++ b/drivers/pci/pci-driver.c
@@ -415,6 +415,7 @@ static struct kobj_type pci_driver_kobj_type = {
415 * __pci_register_driver - register a new pci driver 415 * __pci_register_driver - register a new pci driver
416 * @drv: the driver structure to register 416 * @drv: the driver structure to register
417 * @owner: owner module of drv 417 * @owner: owner module of drv
418 * @mod_name: module name string
418 * 419 *
419 * Adds the driver structure to the list of registered drivers. 420 * Adds the driver structure to the list of registered drivers.
420 * Returns a negative value on error, otherwise 0. 421 * Returns a negative value on error, otherwise 0.
diff --git a/drivers/pci/pci-sysfs.c b/drivers/pci/pci-sysfs.c
index 7a94076752d0..cd913a2a416f 100644
--- a/drivers/pci/pci-sysfs.c
+++ b/drivers/pci/pci-sysfs.c
@@ -143,6 +143,14 @@ static ssize_t is_enabled_show(struct device *dev,
143 return sprintf (buf, "%u\n", atomic_read(&pdev->enable_cnt)); 143 return sprintf (buf, "%u\n", atomic_read(&pdev->enable_cnt));
144} 144}
145 145
146#ifdef CONFIG_NUMA
147static ssize_t
148numa_node_show(struct device *dev, struct device_attribute *attr, char *buf)
149{
150 return sprintf (buf, "%d\n", dev->numa_node);
151}
152#endif
153
146static ssize_t 154static ssize_t
147msi_bus_show(struct device *dev, struct device_attribute *attr, char *buf) 155msi_bus_show(struct device *dev, struct device_attribute *attr, char *buf)
148{ 156{
@@ -194,6 +202,9 @@ struct device_attribute pci_dev_attrs[] = {
194 __ATTR_RO(irq), 202 __ATTR_RO(irq),
195 __ATTR_RO(local_cpus), 203 __ATTR_RO(local_cpus),
196 __ATTR_RO(modalias), 204 __ATTR_RO(modalias),
205#ifdef CONFIG_NUMA
206 __ATTR_RO(numa_node),
207#endif
197 __ATTR(enable, 0600, is_enabled_show, is_enabled_store), 208 __ATTR(enable, 0600, is_enabled_show, is_enabled_store),
198 __ATTR(broken_parity_status,(S_IRUGO|S_IWUSR), 209 __ATTR(broken_parity_status,(S_IRUGO|S_IWUSR),
199 broken_parity_status_show,broken_parity_status_store), 210 broken_parity_status_show,broken_parity_status_store),
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index 8b44cff2c176..1e74e1ee8bd8 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -21,6 +21,12 @@
21 21
22unsigned int pci_pm_d3_delay = 10; 22unsigned int pci_pm_d3_delay = 10;
23 23
24#define DEFAULT_CARDBUS_IO_SIZE (256)
25#define DEFAULT_CARDBUS_MEM_SIZE (64*1024*1024)
26/* pci=cbmemsize=nnM,cbiosize=nn can override this */
27unsigned long pci_cardbus_io_size = DEFAULT_CARDBUS_IO_SIZE;
28unsigned long pci_cardbus_mem_size = DEFAULT_CARDBUS_MEM_SIZE;
29
24/** 30/**
25 * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children 31 * pci_bus_max_busnr - returns maximum PCI bus number of given bus' children
26 * @bus: pointer to PCI bus structure to search 32 * @bus: pointer to PCI bus structure to search
@@ -1300,7 +1306,7 @@ pci_set_consistent_dma_mask(struct pci_dev *dev, u64 mask)
1300 1306
1301/** 1307/**
1302 * pci_select_bars - Make BAR mask from the type of resource 1308 * pci_select_bars - Make BAR mask from the type of resource
1303 * @pdev: the PCI device for which BAR mask is made 1309 * @dev: the PCI device for which BAR mask is made
1304 * @flags: resource type mask to be selected 1310 * @flags: resource type mask to be selected
1305 * 1311 *
1306 * This helper routine makes bar mask from the type of resource. 1312 * This helper routine makes bar mask from the type of resource.
@@ -1333,6 +1339,10 @@ static int __devinit pci_setup(char *str)
1333 if (*str && (str = pcibios_setup(str)) && *str) { 1339 if (*str && (str = pcibios_setup(str)) && *str) {
1334 if (!strcmp(str, "nomsi")) { 1340 if (!strcmp(str, "nomsi")) {
1335 pci_no_msi(); 1341 pci_no_msi();
1342 } else if (!strncmp(str, "cbiosize=", 9)) {
1343 pci_cardbus_io_size = memparse(str + 9, &str);
1344 } else if (!strncmp(str, "cbmemsize=", 10)) {
1345 pci_cardbus_mem_size = memparse(str + 10, &str);
1336 } else { 1346 } else {
1337 printk(KERN_ERR "PCI: Unknown option `%s'\n", 1347 printk(KERN_ERR "PCI: Unknown option `%s'\n",
1338 str); 1348 str);
diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c
index 89f3036f0de8..3554f3948814 100644
--- a/drivers/pci/setup-bus.c
+++ b/drivers/pci/setup-bus.c
@@ -36,13 +36,6 @@
36 36
37#define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1)) 37#define ROUND_UP(x, a) (((x) + (a) - 1) & ~((a) - 1))
38 38
39/*
40 * FIXME: IO should be max 256 bytes. However, since we may
41 * have a P2P bridge below a cardbus bridge, we need 4K.
42 */
43#define CARDBUS_IO_SIZE (256)
44#define CARDBUS_MEM_SIZE (64*1024*1024)
45
46static void __devinit 39static void __devinit
47pbus_assign_resources_sorted(struct pci_bus *bus) 40pbus_assign_resources_sorted(struct pci_bus *bus)
48{ 41{
@@ -415,12 +408,12 @@ pci_bus_size_cardbus(struct pci_bus *bus)
415 * Reserve some resources for CardBus. We reserve 408 * Reserve some resources for CardBus. We reserve
416 * a fixed amount of bus space for CardBus bridges. 409 * a fixed amount of bus space for CardBus bridges.
417 */ 410 */
418 b_res[0].start = CARDBUS_IO_SIZE; 411 b_res[0].start = pci_cardbus_io_size;
419 b_res[0].end = b_res[0].start + CARDBUS_IO_SIZE - 1; 412 b_res[0].end = b_res[0].start + pci_cardbus_io_size - 1;
420 b_res[0].flags |= IORESOURCE_IO; 413 b_res[0].flags |= IORESOURCE_IO;
421 414
422 b_res[1].start = CARDBUS_IO_SIZE; 415 b_res[1].start = pci_cardbus_io_size;
423 b_res[1].end = b_res[1].start + CARDBUS_IO_SIZE - 1; 416 b_res[1].end = b_res[1].start + pci_cardbus_io_size - 1;
424 b_res[1].flags |= IORESOURCE_IO; 417 b_res[1].flags |= IORESOURCE_IO;
425 418
426 /* 419 /*
@@ -440,16 +433,16 @@ pci_bus_size_cardbus(struct pci_bus *bus)
440 * twice the size. 433 * twice the size.
441 */ 434 */
442 if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) { 435 if (ctrl & PCI_CB_BRIDGE_CTL_PREFETCH_MEM0) {
443 b_res[2].start = CARDBUS_MEM_SIZE; 436 b_res[2].start = pci_cardbus_mem_size;
444 b_res[2].end = b_res[2].start + CARDBUS_MEM_SIZE - 1; 437 b_res[2].end = b_res[2].start + pci_cardbus_mem_size - 1;
445 b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH; 438 b_res[2].flags |= IORESOURCE_MEM | IORESOURCE_PREFETCH;
446 439
447 b_res[3].start = CARDBUS_MEM_SIZE; 440 b_res[3].start = pci_cardbus_mem_size;
448 b_res[3].end = b_res[3].start + CARDBUS_MEM_SIZE - 1; 441 b_res[3].end = b_res[3].start + pci_cardbus_mem_size - 1;
449 b_res[3].flags |= IORESOURCE_MEM; 442 b_res[3].flags |= IORESOURCE_MEM;
450 } else { 443 } else {
451 b_res[3].start = CARDBUS_MEM_SIZE * 2; 444 b_res[3].start = pci_cardbus_mem_size * 2;
452 b_res[3].end = b_res[3].start + CARDBUS_MEM_SIZE * 2 - 1; 445 b_res[3].end = b_res[3].start + pci_cardbus_mem_size * 2 - 1;
453 b_res[3].flags |= IORESOURCE_MEM; 446 b_res[3].flags |= IORESOURCE_MEM;
454 } 447 }
455} 448}
diff --git a/drivers/pci/setup-irq.c b/drivers/pci/setup-irq.c
index a251289c9958..568f1877315c 100644
--- a/drivers/pci/setup-irq.c
+++ b/drivers/pci/setup-irq.c
@@ -24,7 +24,7 @@ pdev_fixup_irq(struct pci_dev *dev,
24 int (*map_irq)(struct pci_dev *, u8, u8)) 24 int (*map_irq)(struct pci_dev *, u8, u8))
25{ 25{
26 u8 pin, slot; 26 u8 pin, slot;
27 int irq; 27 int irq = 0;
28 28
29 /* If this device is not on the primary bus, we need to figure out 29 /* If this device is not on the primary bus, we need to figure out
30 which interrupt pin it will come in on. We know which slot it 30 which interrupt pin it will come in on. We know which slot it
@@ -33,16 +33,18 @@ pdev_fixup_irq(struct pci_dev *dev,
33 apply the swizzle function. */ 33 apply the swizzle function. */
34 34
35 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); 35 pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin);
36 /* Cope with 0 and illegal. */ 36 /* Cope with illegal. */
37 if (pin == 0 || pin > 4) 37 if (pin > 4)
38 pin = 1; 38 pin = 1;
39 39
40 /* Follow the chain of bridges, swizzling as we go. */ 40 if (pin != 0) {
41 slot = (*swizzle)(dev, &pin); 41 /* Follow the chain of bridges, swizzling as we go. */
42 slot = (*swizzle)(dev, &pin);
42 43
43 irq = (*map_irq)(dev, slot, pin); 44 irq = (*map_irq)(dev, slot, pin);
44 if (irq == -1) 45 if (irq == -1)
45 irq = 0; 46 irq = 0;
47 }
46 dev->irq = irq; 48 dev->irq = irq;
47 49
48 pr_debug("PCI: fixup irq: (%s) got %d\n", 50 pr_debug("PCI: fixup irq: (%s) got %d\n",
diff --git a/drivers/pcmcia/at91_cf.c b/drivers/pcmcia/at91_cf.c
index b31862837534..99baabc23599 100644
--- a/drivers/pcmcia/at91_cf.c
+++ b/drivers/pcmcia/at91_cf.c
@@ -277,7 +277,7 @@ static int __init at91_cf_probe(struct platform_device *pdev)
277 board->det_pin, board->irq_pin); 277 board->det_pin, board->irq_pin);
278 278
279 cf->socket.owner = THIS_MODULE; 279 cf->socket.owner = THIS_MODULE;
280 cf->socket.dev.dev = &pdev->dev; 280 cf->socket.dev.parent = &pdev->dev;
281 cf->socket.ops = &at91_cf_ops; 281 cf->socket.ops = &at91_cf_ops;
282 cf->socket.resource_ops = &pccard_static_ops; 282 cf->socket.resource_ops = &pccard_static_ops;
283 cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP 283 cf->socket.features = SS_CAP_PCCARD | SS_CAP_STATIC_MAP
diff --git a/drivers/pcmcia/soc_common.c b/drivers/pcmcia/soc_common.c
index d2a3bea55de2..aa7779d89752 100644
--- a/drivers/pcmcia/soc_common.c
+++ b/drivers/pcmcia/soc_common.c
@@ -478,7 +478,7 @@ dump_bits(char **p, const char *prefix, unsigned int val, struct bittbl *bits, i
478 * 478 *
479 * Returns: the number of characters added to the buffer 479 * Returns: the number of characters added to the buffer
480 */ 480 */
481static ssize_t show_status(struct device *dev, char *buf) 481static ssize_t show_status(struct device *dev, struct device_attribute *attr, char *buf)
482{ 482{
483 struct soc_pcmcia_socket *skt = 483 struct soc_pcmcia_socket *skt =
484 container_of(dev, struct soc_pcmcia_socket, socket.dev); 484 container_of(dev, struct soc_pcmcia_socket, socket.dev);
@@ -501,7 +501,7 @@ static ssize_t show_status(struct device *dev, char *buf)
501 501
502 return p-buf; 502 return p-buf;
503} 503}
504static CLASS_DEVICE_ATTR(status, S_IRUGO, show_status, NULL); 504static DEVICE_ATTR(status, S_IRUGO, show_status, NULL);
505 505
506 506
507static struct pccard_operations soc_common_pcmcia_operations = { 507static struct pccard_operations soc_common_pcmcia_operations = {
@@ -660,7 +660,7 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
660 660
661 skt->socket.ops = &soc_common_pcmcia_operations; 661 skt->socket.ops = &soc_common_pcmcia_operations;
662 skt->socket.owner = ops->owner; 662 skt->socket.owner = ops->owner;
663 skt->socket.dev.dev = dev; 663 skt->socket.dev.parent = dev;
664 664
665 init_timer(&skt->poll_timer); 665 init_timer(&skt->poll_timer);
666 skt->poll_timer.function = soc_common_pcmcia_poll_event; 666 skt->poll_timer.function = soc_common_pcmcia_poll_event;
@@ -747,7 +747,7 @@ int soc_common_drv_pcmcia_probe(struct device *dev, struct pcmcia_low_level *ops
747 747
748 add_timer(&skt->poll_timer); 748 add_timer(&skt->poll_timer);
749 749
750 device_create_file(&skt->socket.dev, &device_attr_status); 750 device_create_file(&skt->socket.dev, &dev_attr_status);
751 } 751 }
752 752
753 dev_set_drvdata(dev, sinfo); 753 dev_set_drvdata(dev, sinfo);
diff --git a/drivers/pnp/pnpacpi/Kconfig b/drivers/pnp/pnpacpi/Kconfig
index ad27e5e0101f..b04767ce273e 100644
--- a/drivers/pnp/pnpacpi/Kconfig
+++ b/drivers/pnp/pnpacpi/Kconfig
@@ -2,17 +2,5 @@
2# Plug and Play ACPI configuration 2# Plug and Play ACPI configuration
3# 3#
4config PNPACPI 4config PNPACPI
5 bool "Plug and Play ACPI support" 5 bool
6 depends on PNP && ACPI 6 default (PNP && ACPI)
7 default y
8 ---help---
9 Linux uses the PNPACPI to autodetect built-in
10 mainboard resources (e.g. parallel port resources).
11
12 Some features (e.g. real hotplug) are not currently
13 implemented.
14
15 If you would like the kernel to detect and allocate resources to
16 your mainboard devices (on some systems they are disabled by the
17 BIOS) say Y here. Also the PNPACPI can help prevent resource
18 conflicts between mainboard devices and other bus devices.
diff --git a/drivers/ps3/Makefile b/drivers/ps3/Makefile
index 96958c03cf61..e251d1c1171c 100644
--- a/drivers/ps3/Makefile
+++ b/drivers/ps3/Makefile
@@ -1,2 +1,3 @@
1obj-$(CONFIG_PS3_VUART) += vuart.o 1obj-$(CONFIG_PS3_VUART) += vuart.o
2obj-$(CONFIG_PS3_PS3AV) += ps3av.o ps3av_cmd.o 2obj-$(CONFIG_PS3_PS3AV) += ps3av.o ps3av_cmd.o
3obj-$(CONFIG_PS3_SYS_MANAGER) += sys-manager.o
diff --git a/drivers/ps3/sys-manager.c b/drivers/ps3/sys-manager.c
new file mode 100644
index 000000000000..0fc30be8b81e
--- /dev/null
+++ b/drivers/ps3/sys-manager.c
@@ -0,0 +1,604 @@
1/*
2 * PS3 System Manager.
3 *
4 * Copyright (C) 2007 Sony Computer Entertainment Inc.
5 * Copyright 2007 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/workqueue.h>
24#include <linux/reboot.h>
25#include <asm/ps3.h>
26#include "vuart.h"
27
28MODULE_AUTHOR("Sony Corporation");
29MODULE_LICENSE("GPL v2");
30MODULE_DESCRIPTION("PS3 System Manager");
31
32/**
33 * ps3_sys_manager - PS3 system manager driver.
34 *
35 * The system manager provides an asyncronous system event notification
36 * mechanism for reporting events like thermal alert and button presses to
37 * guests. It also provides support to control system shutdown and startup.
38 *
39 * The actual system manager is implemented as an application running in the
40 * system policy module in lpar_1. Guests communicate with the system manager
41 * through port 2 of the vuart using a simple packet message protocol.
42 * Messages are comprised of a fixed field header followed by a message
43 * specific payload.
44 */
45
46/**
47 * struct ps3_sys_manager_header - System manager message header.
48 * @version: Header version, currently 1.
49 * @size: Header size in bytes, curently 16.
50 * @payload_size: Message payload size in bytes.
51 * @service_id: Message type, one of enum ps3_sys_manager_service_id.
52 */
53
54struct ps3_sys_manager_header {
55 /* version 1 */
56 u8 version;
57 u8 size;
58 u16 reserved_1;
59 u32 payload_size;
60 u16 service_id;
61 u16 reserved_2[3];
62};
63
64/**
65 * @PS3_SM_RX_MSG_LEN - System manager received message length.
66 *
67 * Currently all messages received from the system manager are the same length
68 * (16 bytes header + 16 bytes payload = 32 bytes). This knowlege is used to
69 * simplify the logic.
70 */
71
72enum {
73 PS3_SM_RX_MSG_LEN = 32,
74};
75
76/**
77 * enum ps3_sys_manager_service_id - Message header service_id.
78 * @PS3_SM_SERVICE_ID_REQUEST: guest --> sys_manager.
79 * @PS3_SM_SERVICE_ID_COMMAND: guest <-- sys_manager.
80 * @PS3_SM_SERVICE_ID_RESPONSE: guest --> sys_manager.
81 * @PS3_SM_SERVICE_ID_SET_ATTR: guest --> sys_manager.
82 * @PS3_SM_SERVICE_ID_EXTERN_EVENT: guest <-- sys_manager.
83 * @PS3_SM_SERVICE_ID_SET_NEXT_OP: guest --> sys_manager.
84 */
85
86enum ps3_sys_manager_service_id {
87 /* version 1 */
88 PS3_SM_SERVICE_ID_REQUEST = 1,
89 PS3_SM_SERVICE_ID_RESPONSE = 2,
90 PS3_SM_SERVICE_ID_COMMAND = 3,
91 PS3_SM_SERVICE_ID_EXTERN_EVENT = 4,
92 PS3_SM_SERVICE_ID_SET_NEXT_OP = 5,
93 PS3_SM_SERVICE_ID_SET_ATTR = 8,
94};
95
96/**
97 * enum ps3_sys_manager_attr - Notification attribute (bit position mask).
98 * @PS3_SM_ATTR_POWER: Power button.
99 * @PS3_SM_ATTR_RESET: Reset button, not available on retail console.
100 * @PS3_SM_ATTR_THERMAL: Sytem thermal alert.
101 * @PS3_SM_ATTR_CONTROLLER: Remote controller event.
102 * @PS3_SM_ATTR_ALL: Logical OR of all.
103 *
104 * The guest tells the system manager which events it is interested in receiving
105 * notice of by sending the system manager a logical OR of notification
106 * attributes via the ps3_sys_manager_send_attr() routine.
107 */
108
109enum ps3_sys_manager_attr {
110 /* version 1 */
111 PS3_SM_ATTR_POWER = 1,
112 PS3_SM_ATTR_RESET = 2,
113 PS3_SM_ATTR_THERMAL = 4,
114 PS3_SM_ATTR_CONTROLLER = 8, /* bogus? */
115 PS3_SM_ATTR_ALL = 0x0f,
116};
117
118/**
119 * enum ps3_sys_manager_event - External event type, reported by system manager.
120 * @PS3_SM_EVENT_POWER_PRESSED: payload.value not used.
121 * @PS3_SM_EVENT_POWER_RELEASED: payload.value = time pressed in millisec.
122 * @PS3_SM_EVENT_RESET_PRESSED: payload.value not used.
123 * @PS3_SM_EVENT_RESET_RELEASED: payload.value = time pressed in millisec.
124 * @PS3_SM_EVENT_THERMAL_ALERT: payload.value = thermal zone id.
125 * @PS3_SM_EVENT_THERMAL_CLEARED: payload.value = thermal zone id.
126 */
127
128enum ps3_sys_manager_event {
129 /* version 1 */
130 PS3_SM_EVENT_POWER_PRESSED = 3,
131 PS3_SM_EVENT_POWER_RELEASED = 4,
132 PS3_SM_EVENT_RESET_PRESSED = 5,
133 PS3_SM_EVENT_RESET_RELEASED = 6,
134 PS3_SM_EVENT_THERMAL_ALERT = 7,
135 PS3_SM_EVENT_THERMAL_CLEARED = 8,
136 /* no info on controller events */
137};
138
139/**
140 * enum ps3_sys_manager_next_op - Operation to perform after lpar is destroyed.
141 */
142
143enum ps3_sys_manager_next_op {
144 /* version 3 */
145 PS3_SM_NEXT_OP_SYS_SHUTDOWN = 1,
146 PS3_SM_NEXT_OP_SYS_REBOOT = 2,
147 PS3_SM_NEXT_OP_LPAR_REBOOT = 0x82,
148};
149
150/**
151 * enum ps3_sys_manager_wake_source - Next-op wakeup source (bit position mask).
152 * @PS3_SM_WAKE_DEFAULT: Disk insert, power button, eject button, IR
153 * controller, and bluetooth controller.
154 * @PS3_SM_WAKE_RTC:
155 * @PS3_SM_WAKE_RTC_ERROR:
156 * @PS3_SM_WAKE_P_O_R: Power on reset.
157 *
158 * Additional wakeup sources when specifying PS3_SM_NEXT_OP_SYS_SHUTDOWN.
159 * System will always wake from the PS3_SM_WAKE_DEFAULT sources.
160 */
161
162enum ps3_sys_manager_wake_source {
163 /* version 3 */
164 PS3_SM_WAKE_DEFAULT = 0,
165 PS3_SM_WAKE_RTC = 0x00000040,
166 PS3_SM_WAKE_RTC_ERROR = 0x00000080,
167 PS3_SM_WAKE_P_O_R = 0x10000000,
168};
169
170/**
171 * enum ps3_sys_manager_cmd - Command from system manager to guest.
172 *
173 * The guest completes the actions needed, then acks or naks the command via
174 * ps3_sys_manager_send_response(). In the case of @PS3_SM_CMD_SHUTDOWN,
175 * the guest must be fully prepared for a system poweroff prior to acking the
176 * command.
177 */
178
179enum ps3_sys_manager_cmd {
180 /* version 1 */
181 PS3_SM_CMD_SHUTDOWN = 1, /* shutdown guest OS */
182};
183
184/**
185 * ps3_sys_manager_write - Helper to write a two part message to the vuart.
186 *
187 */
188
189static int ps3_sys_manager_write(struct ps3_vuart_port_device *dev,
190 const struct ps3_sys_manager_header *header, const void *payload)
191{
192 int result;
193
194 BUG_ON(header->version != 1);
195 BUG_ON(header->size != 16);
196 BUG_ON(header->payload_size != 8 && header->payload_size != 16);
197 BUG_ON(header->service_id > 8);
198
199 result = ps3_vuart_write(dev, header,
200 sizeof(struct ps3_sys_manager_header));
201
202 if (!result)
203 result = ps3_vuart_write(dev, payload, header->payload_size);
204
205 return result;
206}
207
208/**
209 * ps3_sys_manager_send_attr - Send a 'set attribute' to the system manager.
210 *
211 */
212
213static int ps3_sys_manager_send_attr(struct ps3_vuart_port_device *dev,
214 enum ps3_sys_manager_attr attr)
215{
216 static const struct ps3_sys_manager_header header = {
217 .version = 1,
218 .size = 16,
219 .payload_size = 16,
220 .service_id = PS3_SM_SERVICE_ID_SET_ATTR,
221 };
222 struct {
223 u8 version;
224 u8 reserved_1[3];
225 u32 attribute;
226 } payload;
227
228 BUILD_BUG_ON(sizeof(payload) != 8);
229
230 dev_dbg(&dev->core, "%s:%d: %xh\n", __func__, __LINE__, attr);
231
232 memset(&payload, 0, sizeof(payload));
233 payload.version = 1;
234 payload.attribute = attr;
235
236 return ps3_sys_manager_write(dev, &header, &payload);
237}
238
239/**
240 * ps3_sys_manager_send_next_op - Send a 'set next op' to the system manager.
241 *
242 * Tell the system manager what to do after this lpar is destroyed.
243 */
244
245static int ps3_sys_manager_send_next_op(struct ps3_vuart_port_device *dev,
246 enum ps3_sys_manager_next_op op,
247 enum ps3_sys_manager_wake_source wake_source)
248{
249 static const struct ps3_sys_manager_header header = {
250 .version = 1,
251 .size = 16,
252 .payload_size = 16,
253 .service_id = PS3_SM_SERVICE_ID_SET_NEXT_OP,
254 };
255 struct {
256 u8 version;
257 u8 type;
258 u8 gos_id;
259 u8 reserved_1;
260 u32 wake_source;
261 u8 reserved_2[8];
262 } payload;
263
264 BUILD_BUG_ON(sizeof(payload) != 16);
265
266 dev_dbg(&dev->core, "%s:%d: (%xh)\n", __func__, __LINE__, op);
267
268 memset(&payload, 0, sizeof(payload));
269 payload.version = 3;
270 payload.type = op;
271 payload.gos_id = 3; /* other os */
272 payload.wake_source = wake_source;
273
274 return ps3_sys_manager_write(dev, &header, &payload);
275}
276
277/**
278 * ps3_sys_manager_send_request_shutdown - Send 'request' to the system manager.
279 *
280 * The guest sends this message to request an operation or action of the system
281 * manager. The reply is a command message from the system manager. In the
282 * command handler the guest performs the requested operation. The result of
283 * the command is then communicated back to the system manager with a response
284 * message.
285 *
286 * Currently, the only supported request it the 'shutdown self' request.
287 */
288
289static int ps3_sys_manager_send_request_shutdown(struct ps3_vuart_port_device *dev)
290{
291 static const struct ps3_sys_manager_header header = {
292 .version = 1,
293 .size = 16,
294 .payload_size = 16,
295 .service_id = PS3_SM_SERVICE_ID_REQUEST,
296 };
297 struct {
298 u8 version;
299 u8 type;
300 u8 gos_id;
301 u8 reserved_1[13];
302 } static const payload = {
303 .version = 1,
304 .type = 1, /* shutdown */
305 .gos_id = 0, /* self */
306 };
307
308 BUILD_BUG_ON(sizeof(payload) != 16);
309
310 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
311
312 return ps3_sys_manager_write(dev, &header, &payload);
313}
314
315/**
316 * ps3_sys_manager_send_response - Send a 'response' to the system manager.
317 * @status: zero = success, others fail.
318 *
319 * The guest sends this message to the system manager to acnowledge success or
320 * failure of a command sent by the system manager.
321 */
322
323static int ps3_sys_manager_send_response(struct ps3_vuart_port_device *dev,
324 u64 status)
325{
326 static const struct ps3_sys_manager_header header = {
327 .version = 1,
328 .size = 16,
329 .payload_size = 16,
330 .service_id = PS3_SM_SERVICE_ID_RESPONSE,
331 };
332 struct {
333 u8 version;
334 u8 reserved_1[3];
335 u8 status;
336 u8 reserved_2[11];
337 } payload;
338
339 BUILD_BUG_ON(sizeof(payload) != 16);
340
341 dev_dbg(&dev->core, "%s:%d: (%s)\n", __func__, __LINE__,
342 (status ? "nak" : "ack"));
343
344 memset(&payload, 0, sizeof(payload));
345 payload.version = 1;
346 payload.status = status;
347
348 return ps3_sys_manager_write(dev, &header, &payload);
349}
350
351/**
352 * ps3_sys_manager_handle_event - Second stage event msg handler.
353 *
354 */
355
356static int ps3_sys_manager_handle_event(struct ps3_vuart_port_device *dev)
357{
358 int result;
359 struct {
360 u8 version;
361 u8 type;
362 u8 reserved_1[2];
363 u32 value;
364 u8 reserved_2[8];
365 } event;
366
367 BUILD_BUG_ON(sizeof(event) != 16);
368
369 result = ps3_vuart_read(dev, &event, sizeof(event));
370 BUG_ON(result);
371
372 if (event.version != 1) {
373 dev_dbg(&dev->core, "%s:%d: unsupported event version (%u)\n",
374 __func__, __LINE__, event.version);
375 return -EIO;
376 }
377
378 switch (event.type) {
379 case PS3_SM_EVENT_POWER_PRESSED:
380 dev_dbg(&dev->core, "%s:%d: POWER_PRESSED\n",
381 __func__, __LINE__);
382 break;
383 case PS3_SM_EVENT_POWER_RELEASED:
384 dev_dbg(&dev->core, "%s:%d: POWER_RELEASED (%u ms)\n",
385 __func__, __LINE__, event.value);
386 kill_cad_pid(SIGINT, 1);
387 break;
388 case PS3_SM_EVENT_THERMAL_ALERT:
389 dev_dbg(&dev->core, "%s:%d: THERMAL_ALERT (zone %u)\n",
390 __func__, __LINE__, event.value);
391 printk(KERN_INFO "PS3 Thermal Alert Zone %u\n", event.value);
392 break;
393 case PS3_SM_EVENT_THERMAL_CLEARED:
394 dev_dbg(&dev->core, "%s:%d: THERMAL_CLEARED (zone %u)\n",
395 __func__, __LINE__, event.value);
396 break;
397 default:
398 dev_dbg(&dev->core, "%s:%d: unknown event (%u)\n",
399 __func__, __LINE__, event.type);
400 return -EIO;
401 }
402
403 return 0;
404}
405/**
406 * ps3_sys_manager_handle_cmd - Second stage command msg handler.
407 *
408 * The system manager sends this in reply to a 'request' message from the guest.
409 */
410
411static int ps3_sys_manager_handle_cmd(struct ps3_vuart_port_device *dev)
412{
413 int result;
414 struct {
415 u8 version;
416 u8 type;
417 u8 reserved_1[14];
418 } cmd;
419
420 BUILD_BUG_ON(sizeof(cmd) != 16);
421
422 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
423
424 result = ps3_vuart_read(dev, &cmd, sizeof(cmd));
425
426 if(result)
427 return result;
428
429 if (cmd.version != 1) {
430 dev_dbg(&dev->core, "%s:%d: unsupported cmd version (%u)\n",
431 __func__, __LINE__, cmd.version);
432 return -EIO;
433 }
434
435 if (cmd.type != PS3_SM_CMD_SHUTDOWN) {
436 dev_dbg(&dev->core, "%s:%d: unknown cmd (%u)\n",
437 __func__, __LINE__, cmd.type);
438 return -EIO;
439 }
440
441 ps3_sys_manager_send_response(dev, 0);
442 return 0;
443}
444
445/**
446 * ps3_sys_manager_handle_msg - First stage msg handler.
447 *
448 */
449
450static int ps3_sys_manager_handle_msg(struct ps3_vuart_port_device *dev)
451{
452 int result;
453 struct ps3_sys_manager_header header;
454
455 result = ps3_vuart_read(dev, &header,
456 sizeof(struct ps3_sys_manager_header));
457
458 if(result)
459 return result;
460
461 if (header.version != 1) {
462 dev_dbg(&dev->core, "%s:%d: unsupported header version (%u)\n",
463 __func__, __LINE__, header.version);
464 goto fail_header;
465 }
466
467 BUILD_BUG_ON(sizeof(header) != 16);
468 BUG_ON(header.size != 16);
469 BUG_ON(header.payload_size != 16);
470
471 switch (header.service_id) {
472 case PS3_SM_SERVICE_ID_EXTERN_EVENT:
473 dev_dbg(&dev->core, "%s:%d: EVENT\n", __func__, __LINE__);
474 return ps3_sys_manager_handle_event(dev);
475 case PS3_SM_SERVICE_ID_COMMAND:
476 dev_dbg(&dev->core, "%s:%d: COMMAND\n", __func__, __LINE__);
477 return ps3_sys_manager_handle_cmd(dev);
478 default:
479 dev_dbg(&dev->core, "%s:%d: unknown service_id (%u)\n",
480 __func__, __LINE__, header.service_id);
481 break;
482 }
483 goto fail_id;
484
485fail_header:
486 ps3_vuart_clear_rx_bytes(dev, 0);
487 return -EIO;
488fail_id:
489 ps3_vuart_clear_rx_bytes(dev, header.payload_size);
490 return -EIO;
491}
492
493/**
494 * ps3_sys_manager_work - Asyncronous read handler.
495 *
496 * Signaled when a complete message arrives at the vuart port.
497 */
498
499static void ps3_sys_manager_work(struct work_struct *work)
500{
501 struct ps3_vuart_port_device *dev = ps3_vuart_work_to_port_device(work);
502
503 ps3_sys_manager_handle_msg(dev);
504 ps3_vuart_read_async(dev, ps3_sys_manager_work, PS3_SM_RX_MSG_LEN);
505}
506
507struct {
508 struct ps3_vuart_port_device *dev;
509} static drv_priv;
510
511/**
512 * ps3_sys_manager_restart - The final platform machine_restart routine.
513 *
514 * This routine never returns. The routine disables asyncronous vuart reads
515 * then spins calling ps3_sys_manager_handle_msg() to receive and acknowledge
516 * the shutdown command sent from the system manager. Soon after the
517 * acknowledgement is sent the lpar is destroyed by the HV. This routine
518 * should only be called from ps3_restart().
519 */
520
521void ps3_sys_manager_restart(void)
522{
523 struct ps3_vuart_port_device *dev = drv_priv.dev;
524
525 BUG_ON(!drv_priv.dev);
526
527 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
528
529 ps3_vuart_cancel_async(dev);
530
531 ps3_sys_manager_send_attr(dev, 0);
532 ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_LPAR_REBOOT,
533 PS3_SM_WAKE_DEFAULT);
534 ps3_sys_manager_send_request_shutdown(dev);
535
536 printk(KERN_EMERG "System Halted, OK to turn off power\n");
537
538 while(1)
539 ps3_sys_manager_handle_msg(dev);
540}
541
542/**
543 * ps3_sys_manager_power_off - The final platform machine_power_off routine.
544 *
545 * This routine never returns. The routine disables asyncronous vuart reads
546 * then spins calling ps3_sys_manager_handle_msg() to receive and acknowledge
547 * the shutdown command sent from the system manager. Soon after the
548 * acknowledgement is sent the lpar is destroyed by the HV. This routine
549 * should only be called from ps3_power_off().
550 */
551
552void ps3_sys_manager_power_off(void)
553{
554 struct ps3_vuart_port_device *dev = drv_priv.dev;
555
556 BUG_ON(!drv_priv.dev);
557
558 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
559
560 ps3_vuart_cancel_async(dev);
561
562 ps3_sys_manager_send_next_op(dev, PS3_SM_NEXT_OP_SYS_SHUTDOWN,
563 PS3_SM_WAKE_DEFAULT);
564 ps3_sys_manager_send_request_shutdown(dev);
565
566 printk(KERN_EMERG "System Halted, OK to turn off power\n");
567
568 while(1)
569 ps3_sys_manager_handle_msg(dev);
570}
571
572static int ps3_sys_manager_probe(struct ps3_vuart_port_device *dev)
573{
574 int result;
575
576 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
577
578 BUG_ON(drv_priv.dev);
579 drv_priv.dev = dev;
580
581 result = ps3_sys_manager_send_attr(dev, PS3_SM_ATTR_ALL);
582 BUG_ON(result);
583
584 result = ps3_vuart_read_async(dev, ps3_sys_manager_work,
585 PS3_SM_RX_MSG_LEN);
586 BUG_ON(result);
587
588 return result;
589}
590
591static struct ps3_vuart_port_driver ps3_sys_manager = {
592 .match_id = PS3_MATCH_ID_SYSTEM_MANAGER,
593 .core = {
594 .name = "ps3_sys_manager",
595 },
596 .probe = ps3_sys_manager_probe,
597};
598
599static int __init ps3_sys_manager_init(void)
600{
601 return ps3_vuart_port_driver_register(&ps3_sys_manager);
602}
603
604module_init(ps3_sys_manager_init);
diff --git a/drivers/ps3/vuart.c b/drivers/ps3/vuart.c
index ef8fd4c30875..746298107d6f 100644
--- a/drivers/ps3/vuart.c
+++ b/drivers/ps3/vuart.c
@@ -21,8 +21,10 @@
21#include <linux/kernel.h> 21#include <linux/kernel.h>
22#include <linux/module.h> 22#include <linux/module.h>
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/workqueue.h>
24#include <asm/ps3.h> 25#include <asm/ps3.h>
25 26
27#include <asm/firmware.h>
26#include <asm/lv1call.h> 28#include <asm/lv1call.h>
27#include <asm/bitops.h> 29#include <asm/bitops.h>
28 30
@@ -30,7 +32,7 @@
30 32
31MODULE_AUTHOR("Sony Corporation"); 33MODULE_AUTHOR("Sony Corporation");
32MODULE_LICENSE("GPL v2"); 34MODULE_LICENSE("GPL v2");
33MODULE_DESCRIPTION("ps3 vuart"); 35MODULE_DESCRIPTION("PS3 vuart");
34 36
35/** 37/**
36 * vuart - An inter-partition data link service. 38 * vuart - An inter-partition data link service.
@@ -157,7 +159,7 @@ int ps3_vuart_get_triggers(struct ps3_vuart_port_device *dev,
157 unsigned long size; 159 unsigned long size;
158 unsigned long val; 160 unsigned long val;
159 161
160 result = lv1_get_virtual_uart_param(dev->port_number, 162 result = lv1_get_virtual_uart_param(dev->priv->port_number,
161 PARAM_TX_TRIGGER, &trig->tx); 163 PARAM_TX_TRIGGER, &trig->tx);
162 164
163 if (result) { 165 if (result) {
@@ -166,7 +168,7 @@ int ps3_vuart_get_triggers(struct ps3_vuart_port_device *dev,
166 return result; 168 return result;
167 } 169 }
168 170
169 result = lv1_get_virtual_uart_param(dev->port_number, 171 result = lv1_get_virtual_uart_param(dev->priv->port_number,
170 PARAM_RX_BUF_SIZE, &size); 172 PARAM_RX_BUF_SIZE, &size);
171 173
172 if (result) { 174 if (result) {
@@ -175,7 +177,7 @@ int ps3_vuart_get_triggers(struct ps3_vuart_port_device *dev,
175 return result; 177 return result;
176 } 178 }
177 179
178 result = lv1_get_virtual_uart_param(dev->port_number, 180 result = lv1_get_virtual_uart_param(dev->priv->port_number,
179 PARAM_RX_TRIGGER, &val); 181 PARAM_RX_TRIGGER, &val);
180 182
181 if (result) { 183 if (result) {
@@ -198,7 +200,7 @@ int ps3_vuart_set_triggers(struct ps3_vuart_port_device *dev, unsigned int tx,
198 int result; 200 int result;
199 unsigned long size; 201 unsigned long size;
200 202
201 result = lv1_set_virtual_uart_param(dev->port_number, 203 result = lv1_set_virtual_uart_param(dev->priv->port_number,
202 PARAM_TX_TRIGGER, tx); 204 PARAM_TX_TRIGGER, tx);
203 205
204 if (result) { 206 if (result) {
@@ -207,7 +209,7 @@ int ps3_vuart_set_triggers(struct ps3_vuart_port_device *dev, unsigned int tx,
207 return result; 209 return result;
208 } 210 }
209 211
210 result = lv1_get_virtual_uart_param(dev->port_number, 212 result = lv1_get_virtual_uart_param(dev->priv->port_number,
211 PARAM_RX_BUF_SIZE, &size); 213 PARAM_RX_BUF_SIZE, &size);
212 214
213 if (result) { 215 if (result) {
@@ -216,7 +218,7 @@ int ps3_vuart_set_triggers(struct ps3_vuart_port_device *dev, unsigned int tx,
216 return result; 218 return result;
217 } 219 }
218 220
219 result = lv1_set_virtual_uart_param(dev->port_number, 221 result = lv1_set_virtual_uart_param(dev->priv->port_number,
220 PARAM_RX_TRIGGER, size - rx); 222 PARAM_RX_TRIGGER, size - rx);
221 223
222 if (result) { 224 if (result) {
@@ -232,9 +234,9 @@ int ps3_vuart_set_triggers(struct ps3_vuart_port_device *dev, unsigned int tx,
232} 234}
233 235
234static int ps3_vuart_get_rx_bytes_waiting(struct ps3_vuart_port_device *dev, 236static int ps3_vuart_get_rx_bytes_waiting(struct ps3_vuart_port_device *dev,
235 unsigned long *bytes_waiting) 237 u64 *bytes_waiting)
236{ 238{
237 int result = lv1_get_virtual_uart_param(dev->port_number, 239 int result = lv1_get_virtual_uart_param(dev->priv->port_number,
238 PARAM_RX_BYTES, bytes_waiting); 240 PARAM_RX_BYTES, bytes_waiting);
239 241
240 if (result) 242 if (result)
@@ -253,10 +255,10 @@ static int ps3_vuart_set_interrupt_mask(struct ps3_vuart_port_device *dev,
253 255
254 dev_dbg(&dev->core, "%s:%d: %lxh\n", __func__, __LINE__, mask); 256 dev_dbg(&dev->core, "%s:%d: %lxh\n", __func__, __LINE__, mask);
255 257
256 dev->interrupt_mask = mask; 258 dev->priv->interrupt_mask = mask;
257 259
258 result = lv1_set_virtual_uart_param(dev->port_number, 260 result = lv1_set_virtual_uart_param(dev->priv->port_number,
259 PARAM_INTERRUPT_MASK, dev->interrupt_mask); 261 PARAM_INTERRUPT_MASK, dev->priv->interrupt_mask);
260 262
261 if (result) 263 if (result)
262 dev_dbg(&dev->core, "%s:%d: interrupt_mask failed: %s\n", 264 dev_dbg(&dev->core, "%s:%d: interrupt_mask failed: %s\n",
@@ -265,62 +267,64 @@ static int ps3_vuart_set_interrupt_mask(struct ps3_vuart_port_device *dev,
265 return result; 267 return result;
266} 268}
267 269
268static int ps3_vuart_get_interrupt_mask(struct ps3_vuart_port_device *dev, 270static int ps3_vuart_get_interrupt_status(struct ps3_vuart_port_device *dev,
269 unsigned long *status) 271 unsigned long *status)
270{ 272{
271 int result = lv1_get_virtual_uart_param(dev->port_number, 273 u64 tmp;
272 PARAM_INTERRUPT_STATUS, status); 274 int result = lv1_get_virtual_uart_param(dev->priv->port_number,
275 PARAM_INTERRUPT_STATUS, &tmp);
273 276
274 if (result) 277 if (result)
275 dev_dbg(&dev->core, "%s:%d: interrupt_status failed: %s\n", 278 dev_dbg(&dev->core, "%s:%d: interrupt_status failed: %s\n",
276 __func__, __LINE__, ps3_result(result)); 279 __func__, __LINE__, ps3_result(result));
277 280
281 *status = tmp & dev->priv->interrupt_mask;
282
278 dev_dbg(&dev->core, "%s:%d: m %lxh, s %lxh, m&s %lxh\n", 283 dev_dbg(&dev->core, "%s:%d: m %lxh, s %lxh, m&s %lxh\n",
279 __func__, __LINE__, dev->interrupt_mask, *status, 284 __func__, __LINE__, dev->priv->interrupt_mask, tmp, *status);
280 dev->interrupt_mask & *status);
281 285
282 return result; 286 return result;
283} 287}
284 288
285int ps3_vuart_enable_interrupt_tx(struct ps3_vuart_port_device *dev) 289int ps3_vuart_enable_interrupt_tx(struct ps3_vuart_port_device *dev)
286{ 290{
287 return (dev->interrupt_mask & INTERRUPT_MASK_TX) ? 0 291 return (dev->priv->interrupt_mask & INTERRUPT_MASK_TX) ? 0
288 : ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask 292 : ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
289 | INTERRUPT_MASK_TX); 293 | INTERRUPT_MASK_TX);
290} 294}
291 295
292int ps3_vuart_enable_interrupt_rx(struct ps3_vuart_port_device *dev) 296int ps3_vuart_enable_interrupt_rx(struct ps3_vuart_port_device *dev)
293{ 297{
294 return (dev->interrupt_mask & INTERRUPT_MASK_RX) ? 0 298 return (dev->priv->interrupt_mask & INTERRUPT_MASK_RX) ? 0
295 : ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask 299 : ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
296 | INTERRUPT_MASK_RX); 300 | INTERRUPT_MASK_RX);
297} 301}
298 302
299int ps3_vuart_enable_interrupt_disconnect(struct ps3_vuart_port_device *dev) 303int ps3_vuart_enable_interrupt_disconnect(struct ps3_vuart_port_device *dev)
300{ 304{
301 return (dev->interrupt_mask & INTERRUPT_MASK_DISCONNECT) ? 0 305 return (dev->priv->interrupt_mask & INTERRUPT_MASK_DISCONNECT) ? 0
302 : ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask 306 : ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
303 | INTERRUPT_MASK_DISCONNECT); 307 | INTERRUPT_MASK_DISCONNECT);
304} 308}
305 309
306int ps3_vuart_disable_interrupt_tx(struct ps3_vuart_port_device *dev) 310int ps3_vuart_disable_interrupt_tx(struct ps3_vuart_port_device *dev)
307{ 311{
308 return (dev->interrupt_mask & INTERRUPT_MASK_TX) 312 return (dev->priv->interrupt_mask & INTERRUPT_MASK_TX)
309 ? ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask 313 ? ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
310 & ~INTERRUPT_MASK_TX) : 0; 314 & ~INTERRUPT_MASK_TX) : 0;
311} 315}
312 316
313int ps3_vuart_disable_interrupt_rx(struct ps3_vuart_port_device *dev) 317int ps3_vuart_disable_interrupt_rx(struct ps3_vuart_port_device *dev)
314{ 318{
315 return (dev->interrupt_mask & INTERRUPT_MASK_RX) 319 return (dev->priv->interrupt_mask & INTERRUPT_MASK_RX)
316 ? ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask 320 ? ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
317 & ~INTERRUPT_MASK_RX) : 0; 321 & ~INTERRUPT_MASK_RX) : 0;
318} 322}
319 323
320int ps3_vuart_disable_interrupt_disconnect(struct ps3_vuart_port_device *dev) 324int ps3_vuart_disable_interrupt_disconnect(struct ps3_vuart_port_device *dev)
321{ 325{
322 return (dev->interrupt_mask & INTERRUPT_MASK_DISCONNECT) 326 return (dev->priv->interrupt_mask & INTERRUPT_MASK_DISCONNECT)
323 ? ps3_vuart_set_interrupt_mask(dev, dev->interrupt_mask 327 ? ps3_vuart_set_interrupt_mask(dev, dev->priv->interrupt_mask
324 & ~INTERRUPT_MASK_DISCONNECT) : 0; 328 & ~INTERRUPT_MASK_DISCONNECT) : 0;
325} 329}
326 330
@@ -335,9 +339,7 @@ static int ps3_vuart_raw_write(struct ps3_vuart_port_device *dev,
335{ 339{
336 int result; 340 int result;
337 341
338 dev_dbg(&dev->core, "%s:%d: %xh\n", __func__, __LINE__, bytes); 342 result = lv1_write_virtual_uart(dev->priv->port_number,
339
340 result = lv1_write_virtual_uart(dev->port_number,
341 ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_written); 343 ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_written);
342 344
343 if (result) { 345 if (result) {
@@ -346,10 +348,10 @@ static int ps3_vuart_raw_write(struct ps3_vuart_port_device *dev,
346 return result; 348 return result;
347 } 349 }
348 350
349 dev->stats.bytes_written += *bytes_written; 351 dev->priv->stats.bytes_written += *bytes_written;
350 352
351 dev_dbg(&dev->core, "%s:%d: wrote %lxh/%xh=>%lxh\n", __func__, 353 dev_dbg(&dev->core, "%s:%d: wrote %lxh/%xh=>%lxh\n", __func__, __LINE__,
352 __LINE__, *bytes_written, bytes, dev->stats.bytes_written); 354 *bytes_written, bytes, dev->priv->stats.bytes_written);
353 355
354 return result; 356 return result;
355} 357}
@@ -367,7 +369,7 @@ static int ps3_vuart_raw_read(struct ps3_vuart_port_device *dev, void* buf,
367 369
368 dev_dbg(&dev->core, "%s:%d: %xh\n", __func__, __LINE__, bytes); 370 dev_dbg(&dev->core, "%s:%d: %xh\n", __func__, __LINE__, bytes);
369 371
370 result = lv1_read_virtual_uart(dev->port_number, 372 result = lv1_read_virtual_uart(dev->priv->port_number,
371 ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_read); 373 ps3_mm_phys_to_lpar(__pa(buf)), bytes, bytes_read);
372 374
373 if (result) { 375 if (result) {
@@ -376,15 +378,58 @@ static int ps3_vuart_raw_read(struct ps3_vuart_port_device *dev, void* buf,
376 return result; 378 return result;
377 } 379 }
378 380
379 dev->stats.bytes_read += *bytes_read; 381 dev->priv->stats.bytes_read += *bytes_read;
380 382
381 dev_dbg(&dev->core, "%s:%d: read %lxh/%xh=>%lxh\n", __func__, __LINE__, 383 dev_dbg(&dev->core, "%s:%d: read %lxh/%xh=>%lxh\n", __func__, __LINE__,
382 *bytes_read, bytes, dev->stats.bytes_read); 384 *bytes_read, bytes, dev->priv->stats.bytes_read);
383 385
384 return result; 386 return result;
385} 387}
386 388
387/** 389/**
390 * ps3_vuart_clear_rx_bytes - Discard bytes received.
391 * @bytes: Max byte count to discard, zero = all pending.
392 *
393 * Used to clear pending rx interrupt source. Will not block.
394 */
395
396void ps3_vuart_clear_rx_bytes(struct ps3_vuart_port_device *dev,
397 unsigned int bytes)
398{
399 int result;
400 u64 bytes_waiting;
401 void* tmp;
402
403 result = ps3_vuart_get_rx_bytes_waiting(dev, &bytes_waiting);
404
405 BUG_ON(result);
406
407 bytes = bytes ? min(bytes, (unsigned int)bytes_waiting) : bytes_waiting;
408
409 dev_dbg(&dev->core, "%s:%d: %u\n", __func__, __LINE__, bytes);
410
411 if (!bytes)
412 return;
413
414 /* Add some extra space for recently arrived data. */
415
416 bytes += 128;
417
418 tmp = kmalloc(bytes, GFP_KERNEL);
419
420 if (!tmp)
421 return;
422
423 ps3_vuart_raw_read(dev, tmp, bytes, &bytes_waiting);
424
425 kfree(tmp);
426
427 /* Don't include these bytes in the stats. */
428
429 dev->priv->stats.bytes_read -= bytes_waiting;
430}
431
432/**
388 * struct list_buffer - An element for a port device fifo buffer list. 433 * struct list_buffer - An element for a port device fifo buffer list.
389 */ 434 */
390 435
@@ -416,14 +461,14 @@ int ps3_vuart_write(struct ps3_vuart_port_device *dev, const void* buf,
416 dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__, 461 dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__,
417 bytes, bytes); 462 bytes, bytes);
418 463
419 spin_lock_irqsave(&dev->tx_list.lock, flags); 464 spin_lock_irqsave(&dev->priv->tx_list.lock, flags);
420 465
421 if (list_empty(&dev->tx_list.head)) { 466 if (list_empty(&dev->priv->tx_list.head)) {
422 unsigned long bytes_written; 467 unsigned long bytes_written;
423 468
424 result = ps3_vuart_raw_write(dev, buf, bytes, &bytes_written); 469 result = ps3_vuart_raw_write(dev, buf, bytes, &bytes_written);
425 470
426 spin_unlock_irqrestore(&dev->tx_list.lock, flags); 471 spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags);
427 472
428 if (result) { 473 if (result) {
429 dev_dbg(&dev->core, 474 dev_dbg(&dev->core,
@@ -441,7 +486,7 @@ int ps3_vuart_write(struct ps3_vuart_port_device *dev, const void* buf,
441 bytes -= bytes_written; 486 bytes -= bytes_written;
442 buf += bytes_written; 487 buf += bytes_written;
443 } else 488 } else
444 spin_unlock_irqrestore(&dev->tx_list.lock, flags); 489 spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags);
445 490
446 lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_KERNEL); 491 lb = kmalloc(sizeof(struct list_buffer) + bytes, GFP_KERNEL);
447 492
@@ -454,10 +499,10 @@ int ps3_vuart_write(struct ps3_vuart_port_device *dev, const void* buf,
454 lb->tail = lb->data + bytes; 499 lb->tail = lb->data + bytes;
455 lb->dbg_number = ++dbg_number; 500 lb->dbg_number = ++dbg_number;
456 501
457 spin_lock_irqsave(&dev->tx_list.lock, flags); 502 spin_lock_irqsave(&dev->priv->tx_list.lock, flags);
458 list_add_tail(&lb->link, &dev->tx_list.head); 503 list_add_tail(&lb->link, &dev->priv->tx_list.head);
459 ps3_vuart_enable_interrupt_tx(dev); 504 ps3_vuart_enable_interrupt_tx(dev);
460 spin_unlock_irqrestore(&dev->tx_list.lock, flags); 505 spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags);
461 506
462 dev_dbg(&dev->core, "%s:%d: queued buf_%lu, %xh bytes\n", 507 dev_dbg(&dev->core, "%s:%d: queued buf_%lu, %xh bytes\n",
463 __func__, __LINE__, lb->dbg_number, bytes); 508 __func__, __LINE__, lb->dbg_number, bytes);
@@ -484,47 +529,83 @@ int ps3_vuart_read(struct ps3_vuart_port_device *dev, void* buf,
484 dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__, 529 dev_dbg(&dev->core, "%s:%d: %u(%xh) bytes\n", __func__, __LINE__,
485 bytes, bytes); 530 bytes, bytes);
486 531
487 spin_lock_irqsave(&dev->rx_list.lock, flags); 532 spin_lock_irqsave(&dev->priv->rx_list.lock, flags);
488 533
489 if (dev->rx_list.bytes_held < bytes) { 534 if (dev->priv->rx_list.bytes_held < bytes) {
490 spin_unlock_irqrestore(&dev->rx_list.lock, flags); 535 spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags);
491 dev_dbg(&dev->core, "%s:%d: starved for %lxh bytes\n", 536 dev_dbg(&dev->core, "%s:%d: starved for %lxh bytes\n",
492 __func__, __LINE__, bytes - dev->rx_list.bytes_held); 537 __func__, __LINE__,
538 bytes - dev->priv->rx_list.bytes_held);
493 return -EAGAIN; 539 return -EAGAIN;
494 } 540 }
495 541
496 list_for_each_entry_safe(lb, n, &dev->rx_list.head, link) { 542 list_for_each_entry_safe(lb, n, &dev->priv->rx_list.head, link) {
497 bytes_read = min((unsigned int)(lb->tail - lb->head), bytes); 543 bytes_read = min((unsigned int)(lb->tail - lb->head), bytes);
498 544
499 memcpy(buf, lb->head, bytes_read); 545 memcpy(buf, lb->head, bytes_read);
500 buf += bytes_read; 546 buf += bytes_read;
501 bytes -= bytes_read; 547 bytes -= bytes_read;
502 dev->rx_list.bytes_held -= bytes_read; 548 dev->priv->rx_list.bytes_held -= bytes_read;
503 549
504 if (bytes_read < lb->tail - lb->head) { 550 if (bytes_read < lb->tail - lb->head) {
505 lb->head += bytes_read; 551 lb->head += bytes_read;
506 spin_unlock_irqrestore(&dev->rx_list.lock, flags); 552 dev_dbg(&dev->core, "%s:%d: buf_%lu: dequeued %lxh "
507 553 "bytes\n", __func__, __LINE__, lb->dbg_number,
508 dev_dbg(&dev->core, 554 bytes_read);
509 "%s:%d: dequeued buf_%lu, %lxh bytes\n", 555 spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags);
510 __func__, __LINE__, lb->dbg_number, bytes_read);
511 return 0; 556 return 0;
512 } 557 }
513 558
514 dev_dbg(&dev->core, "%s:%d free buf_%lu\n", __func__, __LINE__, 559 dev_dbg(&dev->core, "%s:%d: buf_%lu: free, dequeued %lxh "
515 lb->dbg_number); 560 "bytes\n", __func__, __LINE__, lb->dbg_number,
561 bytes_read);
516 562
517 list_del(&lb->link); 563 list_del(&lb->link);
518 kfree(lb); 564 kfree(lb);
519 } 565 }
520 spin_unlock_irqrestore(&dev->rx_list.lock, flags);
521 566
522 dev_dbg(&dev->core, "%s:%d: dequeued buf_%lu, %xh bytes\n", 567 spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags);
523 __func__, __LINE__, lb->dbg_number, bytes); 568 return 0;
569}
570
571int ps3_vuart_read_async(struct ps3_vuart_port_device *dev, work_func_t func,
572 unsigned int bytes)
573{
574 unsigned long flags;
575
576 if(dev->priv->work.trigger) {
577 dev_dbg(&dev->core, "%s:%d: warning, multiple calls\n",
578 __func__, __LINE__);
579 return -EAGAIN;
580 }
581
582 BUG_ON(!bytes);
583
584 PREPARE_WORK(&dev->priv->work.work, func);
585
586 spin_lock_irqsave(&dev->priv->work.lock, flags);
587 if(dev->priv->rx_list.bytes_held >= bytes) {
588 dev_dbg(&dev->core, "%s:%d: schedule_work %xh bytes\n",
589 __func__, __LINE__, bytes);
590 schedule_work(&dev->priv->work.work);
591 spin_unlock_irqrestore(&dev->priv->work.lock, flags);
592 return 0;
593 }
594
595 dev->priv->work.trigger = bytes;
596 spin_unlock_irqrestore(&dev->priv->work.lock, flags);
597
598 dev_dbg(&dev->core, "%s:%d: waiting for %u(%xh) bytes\n", __func__,
599 __LINE__, bytes, bytes);
524 600
525 return 0; 601 return 0;
526} 602}
527 603
604void ps3_vuart_cancel_async(struct ps3_vuart_port_device *dev)
605{
606 dev->priv->work.trigger = 0;
607}
608
528/** 609/**
529 * ps3_vuart_handle_interrupt_tx - third stage transmit interrupt handler 610 * ps3_vuart_handle_interrupt_tx - third stage transmit interrupt handler
530 * 611 *
@@ -542,9 +623,9 @@ static int ps3_vuart_handle_interrupt_tx(struct ps3_vuart_port_device *dev)
542 623
543 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__); 624 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
544 625
545 spin_lock_irqsave(&dev->tx_list.lock, flags); 626 spin_lock_irqsave(&dev->priv->tx_list.lock, flags);
546 627
547 list_for_each_entry_safe(lb, n, &dev->tx_list.head, link) { 628 list_for_each_entry_safe(lb, n, &dev->priv->tx_list.head, link) {
548 629
549 unsigned long bytes_written; 630 unsigned long bytes_written;
550 631
@@ -578,7 +659,7 @@ static int ps3_vuart_handle_interrupt_tx(struct ps3_vuart_port_device *dev)
578 659
579 ps3_vuart_disable_interrupt_tx(dev); 660 ps3_vuart_disable_interrupt_tx(dev);
580port_full: 661port_full:
581 spin_unlock_irqrestore(&dev->tx_list.lock, flags); 662 spin_unlock_irqrestore(&dev->priv->tx_list.lock, flags);
582 dev_dbg(&dev->core, "%s:%d wrote %lxh bytes total\n", 663 dev_dbg(&dev->core, "%s:%d wrote %lxh bytes total\n",
583 __func__, __LINE__, bytes_total); 664 __func__, __LINE__, bytes_total);
584 return result; 665 return result;
@@ -609,7 +690,7 @@ static int ps3_vuart_handle_interrupt_rx(struct ps3_vuart_port_device *dev)
609 690
610 BUG_ON(!bytes); 691 BUG_ON(!bytes);
611 692
612 /* add some extra space for recently arrived data */ 693 /* Add some extra space for recently arrived data. */
613 694
614 bytes += 128; 695 bytes += 128;
615 696
@@ -624,14 +705,23 @@ static int ps3_vuart_handle_interrupt_rx(struct ps3_vuart_port_device *dev)
624 lb->tail = lb->data + bytes; 705 lb->tail = lb->data + bytes;
625 lb->dbg_number = ++dbg_number; 706 lb->dbg_number = ++dbg_number;
626 707
627 spin_lock_irqsave(&dev->rx_list.lock, flags); 708 spin_lock_irqsave(&dev->priv->rx_list.lock, flags);
628 list_add_tail(&lb->link, &dev->rx_list.head); 709 list_add_tail(&lb->link, &dev->priv->rx_list.head);
629 dev->rx_list.bytes_held += bytes; 710 dev->priv->rx_list.bytes_held += bytes;
630 spin_unlock_irqrestore(&dev->rx_list.lock, flags); 711 spin_unlock_irqrestore(&dev->priv->rx_list.lock, flags);
631 712
632 dev_dbg(&dev->core, "%s:%d: queued buf_%lu, %lxh bytes\n", 713 dev_dbg(&dev->core, "%s:%d: buf_%lu: queued %lxh bytes\n",
633 __func__, __LINE__, lb->dbg_number, bytes); 714 __func__, __LINE__, lb->dbg_number, bytes);
634 715
716 spin_lock_irqsave(&dev->priv->work.lock, flags);
717 if(dev->priv->work.trigger
718 && dev->priv->rx_list.bytes_held >= dev->priv->work.trigger) {
719 dev_dbg(&dev->core, "%s:%d: schedule_work %lxh bytes\n",
720 __func__, __LINE__, dev->priv->work.trigger);
721 dev->priv->work.trigger = 0;
722 schedule_work(&dev->priv->work.work);
723 }
724 spin_unlock_irqrestore(&dev->priv->work.lock, flags);
635 return 0; 725 return 0;
636} 726}
637 727
@@ -656,7 +746,7 @@ static int ps3_vuart_handle_port_interrupt(struct ps3_vuart_port_device *dev)
656 int result; 746 int result;
657 unsigned long status; 747 unsigned long status;
658 748
659 result = ps3_vuart_get_interrupt_mask(dev, &status); 749 result = ps3_vuart_get_interrupt_status(dev, &status);
660 750
661 if (result) 751 if (result)
662 return result; 752 return result;
@@ -665,21 +755,21 @@ static int ps3_vuart_handle_port_interrupt(struct ps3_vuart_port_device *dev)
665 status); 755 status);
666 756
667 if (status & INTERRUPT_MASK_DISCONNECT) { 757 if (status & INTERRUPT_MASK_DISCONNECT) {
668 dev->stats.disconnect_interrupts++; 758 dev->priv->stats.disconnect_interrupts++;
669 result = ps3_vuart_handle_interrupt_disconnect(dev); 759 result = ps3_vuart_handle_interrupt_disconnect(dev);
670 if (result) 760 if (result)
671 ps3_vuart_disable_interrupt_disconnect(dev); 761 ps3_vuart_disable_interrupt_disconnect(dev);
672 } 762 }
673 763
674 if (status & INTERRUPT_MASK_TX) { 764 if (status & INTERRUPT_MASK_TX) {
675 dev->stats.tx_interrupts++; 765 dev->priv->stats.tx_interrupts++;
676 result = ps3_vuart_handle_interrupt_tx(dev); 766 result = ps3_vuart_handle_interrupt_tx(dev);
677 if (result) 767 if (result)
678 ps3_vuart_disable_interrupt_tx(dev); 768 ps3_vuart_disable_interrupt_tx(dev);
679 } 769 }
680 770
681 if (status & INTERRUPT_MASK_RX) { 771 if (status & INTERRUPT_MASK_RX) {
682 dev->stats.rx_interrupts++; 772 dev->priv->stats.rx_interrupts++;
683 result = ps3_vuart_handle_interrupt_rx(dev); 773 result = ps3_vuart_handle_interrupt_rx(dev);
684 if (result) 774 if (result)
685 ps3_vuart_disable_interrupt_rx(dev); 775 ps3_vuart_disable_interrupt_rx(dev);
@@ -688,12 +778,13 @@ static int ps3_vuart_handle_port_interrupt(struct ps3_vuart_port_device *dev)
688 return 0; 778 return 0;
689} 779}
690 780
691struct vuart_private { 781struct vuart_bus_priv {
692 unsigned int in_use; 782 const struct ports_bmp bmp;
693 unsigned int virq; 783 unsigned int virq;
784 struct semaphore probe_mutex;
785 int use_count;
694 struct ps3_vuart_port_device *devices[PORT_COUNT]; 786 struct ps3_vuart_port_device *devices[PORT_COUNT];
695 const struct ports_bmp bmp; 787} static vuart_bus_priv;
696};
697 788
698/** 789/**
699 * ps3_vuart_irq_handler - first stage interrupt handler 790 * ps3_vuart_irq_handler - first stage interrupt handler
@@ -705,25 +796,25 @@ struct vuart_private {
705 796
706static irqreturn_t ps3_vuart_irq_handler(int irq, void *_private) 797static irqreturn_t ps3_vuart_irq_handler(int irq, void *_private)
707{ 798{
708 struct vuart_private *private; 799 struct vuart_bus_priv *bus_priv;
709 800
710 BUG_ON(!_private); 801 BUG_ON(!_private);
711 private = (struct vuart_private *)_private; 802 bus_priv = (struct vuart_bus_priv *)_private;
712 803
713 while (1) { 804 while (1) {
714 unsigned int port; 805 unsigned int port;
715 806
716 dump_ports_bmp(&private->bmp); 807 dump_ports_bmp(&bus_priv->bmp);
717 808
718 port = (BITS_PER_LONG - 1) - __ilog2(private->bmp.status); 809 port = (BITS_PER_LONG - 1) - __ilog2(bus_priv->bmp.status);
719 810
720 if (port == BITS_PER_LONG) 811 if (port == BITS_PER_LONG)
721 break; 812 break;
722 813
723 BUG_ON(port >= PORT_COUNT); 814 BUG_ON(port >= PORT_COUNT);
724 BUG_ON(!private->devices[port]); 815 BUG_ON(!bus_priv->devices[port]);
725 816
726 ps3_vuart_handle_port_interrupt(private->devices[port]); 817 ps3_vuart_handle_port_interrupt(bus_priv->devices[port]);
727 } 818 }
728 819
729 return IRQ_HANDLED; 820 return IRQ_HANDLED;
@@ -744,12 +835,10 @@ static int ps3_vuart_match(struct device *_dev, struct device_driver *_drv)
744 return result; 835 return result;
745} 836}
746 837
747static struct vuart_private vuart_private;
748
749static int ps3_vuart_probe(struct device *_dev) 838static int ps3_vuart_probe(struct device *_dev)
750{ 839{
751 int result; 840 int result;
752 unsigned long tmp; 841 unsigned int port_number;
753 struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev); 842 struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev);
754 struct ps3_vuart_port_driver *drv = 843 struct ps3_vuart_port_driver *drv =
755 to_ps3_vuart_port_driver(_dev->driver); 844 to_ps3_vuart_port_driver(_dev->driver);
@@ -758,7 +847,12 @@ static int ps3_vuart_probe(struct device *_dev)
758 847
759 BUG_ON(!drv); 848 BUG_ON(!drv);
760 849
761 result = ps3_vuart_match_id_to_port(dev->match_id, &dev->port_number); 850 down(&vuart_bus_priv.probe_mutex);
851
852 /* Setup vuart_bus_priv.devices[]. */
853
854 result = ps3_vuart_match_id_to_port(dev->match_id,
855 &port_number);
762 856
763 if (result) { 857 if (result) {
764 dev_dbg(&dev->core, "%s:%d: unknown match_id (%d)\n", 858 dev_dbg(&dev->core, "%s:%d: unknown match_id (%d)\n",
@@ -767,24 +861,41 @@ static int ps3_vuart_probe(struct device *_dev)
767 goto fail_match; 861 goto fail_match;
768 } 862 }
769 863
770 if (vuart_private.devices[dev->port_number]) { 864 if (vuart_bus_priv.devices[port_number]) {
771 dev_dbg(&dev->core, "%s:%d: port busy (%d)\n", __func__, 865 dev_dbg(&dev->core, "%s:%d: port busy (%d)\n", __func__,
772 __LINE__, dev->port_number); 866 __LINE__, port_number);
773 result = -EBUSY; 867 result = -EBUSY;
774 goto fail_match; 868 goto fail_match;
775 } 869 }
776 870
777 vuart_private.devices[dev->port_number] = dev; 871 vuart_bus_priv.devices[port_number] = dev;
872
873 /* Setup dev->priv. */
874
875 dev->priv = kzalloc(sizeof(struct ps3_vuart_port_priv), GFP_KERNEL);
876
877 if (!dev->priv) {
878 result = -ENOMEM;
879 goto fail_alloc;
880 }
778 881
779 INIT_LIST_HEAD(&dev->tx_list.head); 882 dev->priv->port_number = port_number;
780 spin_lock_init(&dev->tx_list.lock); 883
781 INIT_LIST_HEAD(&dev->rx_list.head); 884 INIT_LIST_HEAD(&dev->priv->tx_list.head);
782 spin_lock_init(&dev->rx_list.lock); 885 spin_lock_init(&dev->priv->tx_list.lock);
886
887 INIT_LIST_HEAD(&dev->priv->rx_list.head);
888 spin_lock_init(&dev->priv->rx_list.lock);
889
890 INIT_WORK(&dev->priv->work.work, NULL);
891 spin_lock_init(&dev->priv->work.lock);
892 dev->priv->work.trigger = 0;
893 dev->priv->work.dev = dev;
894
895 if (++vuart_bus_priv.use_count == 1) {
783 896
784 vuart_private.in_use++;
785 if (vuart_private.in_use == 1) {
786 result = ps3_alloc_vuart_irq(PS3_BINDING_CPU_ANY, 897 result = ps3_alloc_vuart_irq(PS3_BINDING_CPU_ANY,
787 (void*)&vuart_private.bmp.status, &vuart_private.virq); 898 (void*)&vuart_bus_priv.bmp.status, &vuart_bus_priv.virq);
788 899
789 if (result) { 900 if (result) {
790 dev_dbg(&dev->core, 901 dev_dbg(&dev->core,
@@ -794,8 +905,8 @@ static int ps3_vuart_probe(struct device *_dev)
794 goto fail_alloc_irq; 905 goto fail_alloc_irq;
795 } 906 }
796 907
797 result = request_irq(vuart_private.virq, ps3_vuart_irq_handler, 908 result = request_irq(vuart_bus_priv.virq, ps3_vuart_irq_handler,
798 IRQF_DISABLED, "vuart", &vuart_private); 909 IRQF_DISABLED, "vuart", &vuart_bus_priv);
799 910
800 if (result) { 911 if (result) {
801 dev_info(&dev->core, "%s:%d: request_irq failed (%d)\n", 912 dev_info(&dev->core, "%s:%d: request_irq failed (%d)\n",
@@ -804,10 +915,11 @@ static int ps3_vuart_probe(struct device *_dev)
804 } 915 }
805 } 916 }
806 917
807 ps3_vuart_set_interrupt_mask(dev, INTERRUPT_MASK_RX);
808
809 /* clear stale pending interrupts */ 918 /* clear stale pending interrupts */
810 ps3_vuart_get_interrupt_mask(dev, &tmp); 919
920 ps3_vuart_clear_rx_bytes(dev, 0);
921
922 ps3_vuart_set_interrupt_mask(dev, INTERRUPT_MASK_RX);
811 923
812 ps3_vuart_set_triggers(dev, 1, 1); 924 ps3_vuart_set_triggers(dev, 1, 1);
813 925
@@ -822,20 +934,27 @@ static int ps3_vuart_probe(struct device *_dev)
822 if (result) { 934 if (result) {
823 dev_dbg(&dev->core, "%s:%d: drv->probe failed\n", 935 dev_dbg(&dev->core, "%s:%d: drv->probe failed\n",
824 __func__, __LINE__); 936 __func__, __LINE__);
937 down(&vuart_bus_priv.probe_mutex);
825 goto fail_probe; 938 goto fail_probe;
826 } 939 }
827 940
941 up(&vuart_bus_priv.probe_mutex);
942
828 return result; 943 return result;
829 944
830fail_probe: 945fail_probe:
946 ps3_vuart_set_interrupt_mask(dev, 0);
831fail_request_irq: 947fail_request_irq:
832 vuart_private.in_use--; 948 ps3_free_vuart_irq(vuart_bus_priv.virq);
833 if (!vuart_private.in_use) { 949 vuart_bus_priv.virq = NO_IRQ;
834 ps3_free_vuart_irq(vuart_private.virq);
835 vuart_private.virq = NO_IRQ;
836 }
837fail_alloc_irq: 950fail_alloc_irq:
951 --vuart_bus_priv.use_count;
952 kfree(dev->priv);
953 dev->priv = NULL;
954fail_alloc:
955 vuart_bus_priv.devices[port_number] = 0;
838fail_match: 956fail_match:
957 up(&vuart_bus_priv.probe_mutex);
839 dev_dbg(&dev->core, "%s:%d failed\n", __func__, __LINE__); 958 dev_dbg(&dev->core, "%s:%d failed\n", __func__, __LINE__);
840 return result; 959 return result;
841} 960}
@@ -846,10 +965,12 @@ static int ps3_vuart_remove(struct device *_dev)
846 struct ps3_vuart_port_driver *drv = 965 struct ps3_vuart_port_driver *drv =
847 to_ps3_vuart_port_driver(_dev->driver); 966 to_ps3_vuart_port_driver(_dev->driver);
848 967
968 down(&vuart_bus_priv.probe_mutex);
969
849 dev_dbg(&dev->core, "%s:%d: %s\n", __func__, __LINE__, 970 dev_dbg(&dev->core, "%s:%d: %s\n", __func__, __LINE__,
850 dev->core.bus_id); 971 dev->core.bus_id);
851 972
852 BUG_ON(vuart_private.in_use < 1); 973 BUG_ON(vuart_bus_priv.use_count < 1);
853 974
854 if (drv->remove) 975 if (drv->remove)
855 drv->remove(dev); 976 drv->remove(dev);
@@ -857,13 +978,19 @@ static int ps3_vuart_remove(struct device *_dev)
857 dev_dbg(&dev->core, "%s:%d: %s no remove method\n", __func__, 978 dev_dbg(&dev->core, "%s:%d: %s no remove method\n", __func__,
858 __LINE__, dev->core.bus_id); 979 __LINE__, dev->core.bus_id);
859 980
860 vuart_private.in_use--; 981 vuart_bus_priv.devices[dev->priv->port_number] = 0;
861 982
862 if (!vuart_private.in_use) { 983 if (--vuart_bus_priv.use_count == 0) {
863 free_irq(vuart_private.virq, &vuart_private); 984 BUG();
864 ps3_free_vuart_irq(vuart_private.virq); 985 free_irq(vuart_bus_priv.virq, &vuart_bus_priv);
865 vuart_private.virq = NO_IRQ; 986 ps3_free_vuart_irq(vuart_bus_priv.virq);
987 vuart_bus_priv.virq = NO_IRQ;
866 } 988 }
989
990 kfree(dev->priv);
991 dev->priv = NULL;
992
993 up(&vuart_bus_priv.probe_mutex);
867 return 0; 994 return 0;
868} 995}
869 996
@@ -884,12 +1011,12 @@ static void ps3_vuart_shutdown(struct device *_dev)
884} 1011}
885 1012
886/** 1013/**
887 * ps3_vuart - The vuart instance. 1014 * ps3_vuart_bus - The vuart bus instance.
888 * 1015 *
889 * The vuart is managed as a bus that port devices connect to. 1016 * The vuart is managed as a bus that port devices connect to.
890 */ 1017 */
891 1018
892struct bus_type ps3_vuart = { 1019struct bus_type ps3_vuart_bus = {
893 .name = "ps3_vuart", 1020 .name = "ps3_vuart",
894 .match = ps3_vuart_match, 1021 .match = ps3_vuart_match,
895 .probe = ps3_vuart_probe, 1022 .probe = ps3_vuart_probe,
@@ -897,24 +1024,30 @@ struct bus_type ps3_vuart = {
897 .shutdown = ps3_vuart_shutdown, 1024 .shutdown = ps3_vuart_shutdown,
898}; 1025};
899 1026
900int __init ps3_vuart_init(void) 1027int __init ps3_vuart_bus_init(void)
901{ 1028{
902 int result; 1029 int result;
903 1030
904 pr_debug("%s:%d:\n", __func__, __LINE__); 1031 pr_debug("%s:%d:\n", __func__, __LINE__);
905 result = bus_register(&ps3_vuart); 1032
1033 if (!firmware_has_feature(FW_FEATURE_PS3_LV1))
1034 return 0;
1035
1036 init_MUTEX(&vuart_bus_priv.probe_mutex);
1037 result = bus_register(&ps3_vuart_bus);
906 BUG_ON(result); 1038 BUG_ON(result);
1039
907 return result; 1040 return result;
908} 1041}
909 1042
910void __exit ps3_vuart_exit(void) 1043void __exit ps3_vuart_bus_exit(void)
911{ 1044{
912 pr_debug("%s:%d:\n", __func__, __LINE__); 1045 pr_debug("%s:%d:\n", __func__, __LINE__);
913 bus_unregister(&ps3_vuart); 1046 bus_unregister(&ps3_vuart_bus);
914} 1047}
915 1048
916core_initcall(ps3_vuart_init); 1049core_initcall(ps3_vuart_bus_init);
917module_exit(ps3_vuart_exit); 1050module_exit(ps3_vuart_bus_exit);
918 1051
919/** 1052/**
920 * ps3_vuart_port_release_device - Remove a vuart port device. 1053 * ps3_vuart_port_release_device - Remove a vuart port device.
@@ -922,11 +1055,14 @@ module_exit(ps3_vuart_exit);
922 1055
923static void ps3_vuart_port_release_device(struct device *_dev) 1056static void ps3_vuart_port_release_device(struct device *_dev)
924{ 1057{
925 struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev);
926#if defined(DEBUG) 1058#if defined(DEBUG)
927 memset(dev, 0xad, sizeof(struct ps3_vuart_port_device)); 1059 struct ps3_vuart_port_device *dev = to_ps3_vuart_port_device(_dev);
1060
1061 dev_dbg(&dev->core, "%s:%d\n", __func__, __LINE__);
1062
1063 BUG_ON(dev->priv && "forgot to free");
1064 memset(&dev->core, 0, sizeof(dev->core));
928#endif 1065#endif
929 kfree(dev);
930} 1066}
931 1067
932/** 1068/**
@@ -935,11 +1071,12 @@ static void ps3_vuart_port_release_device(struct device *_dev)
935 1071
936int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev) 1072int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev)
937{ 1073{
938 int result;
939 static unsigned int dev_count = 1; 1074 static unsigned int dev_count = 1;
940 1075
1076 BUG_ON(dev->priv && "forgot to free");
1077
941 dev->core.parent = NULL; 1078 dev->core.parent = NULL;
942 dev->core.bus = &ps3_vuart; 1079 dev->core.bus = &ps3_vuart_bus;
943 dev->core.release = ps3_vuart_port_release_device; 1080 dev->core.release = ps3_vuart_port_release_device;
944 1081
945 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), "vuart_%02x", 1082 snprintf(dev->core.bus_id, sizeof(dev->core.bus_id), "vuart_%02x",
@@ -947,9 +1084,7 @@ int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev)
947 1084
948 dev_dbg(&dev->core, "%s:%d register\n", __func__, __LINE__); 1085 dev_dbg(&dev->core, "%s:%d register\n", __func__, __LINE__);
949 1086
950 result = device_register(&dev->core); 1087 return device_register(&dev->core);
951
952 return result;
953} 1088}
954 1089
955EXPORT_SYMBOL_GPL(ps3_vuart_port_device_register); 1090EXPORT_SYMBOL_GPL(ps3_vuart_port_device_register);
@@ -963,7 +1098,7 @@ int ps3_vuart_port_driver_register(struct ps3_vuart_port_driver *drv)
963 int result; 1098 int result;
964 1099
965 pr_debug("%s:%d: (%s)\n", __func__, __LINE__, drv->core.name); 1100 pr_debug("%s:%d: (%s)\n", __func__, __LINE__, drv->core.name);
966 drv->core.bus = &ps3_vuart; 1101 drv->core.bus = &ps3_vuart_bus;
967 result = driver_register(&drv->core); 1102 result = driver_register(&drv->core);
968 return result; 1103 return result;
969} 1104}
@@ -976,6 +1111,7 @@ EXPORT_SYMBOL_GPL(ps3_vuart_port_driver_register);
976 1111
977void ps3_vuart_port_driver_unregister(struct ps3_vuart_port_driver *drv) 1112void ps3_vuart_port_driver_unregister(struct ps3_vuart_port_driver *drv)
978{ 1113{
1114 pr_debug("%s:%d: (%s)\n", __func__, __LINE__, drv->core.name);
979 driver_unregister(&drv->core); 1115 driver_unregister(&drv->core);
980} 1116}
981 1117
diff --git a/drivers/ps3/vuart.h b/drivers/ps3/vuart.h
index 2cbf728a3a0b..1be992d568c8 100644
--- a/drivers/ps3/vuart.h
+++ b/drivers/ps3/vuart.h
@@ -21,6 +21,44 @@
21#if !defined(_PS3_VUART_H) 21#if !defined(_PS3_VUART_H)
22#define _PS3_VUART_H 22#define _PS3_VUART_H
23 23
24#include <asm/ps3.h>
25
26struct ps3_vuart_stats {
27 unsigned long bytes_written;
28 unsigned long bytes_read;
29 unsigned long tx_interrupts;
30 unsigned long rx_interrupts;
31 unsigned long disconnect_interrupts;
32};
33
34struct ps3_vuart_work {
35 struct work_struct work;
36 unsigned long trigger;
37 spinlock_t lock;
38 struct ps3_vuart_port_device* dev; /* to convert work to device */
39};
40
41/**
42 * struct ps3_vuart_port_priv - private vuart device data.
43 */
44
45struct ps3_vuart_port_priv {
46 unsigned int port_number;
47 u64 interrupt_mask;
48
49 struct {
50 spinlock_t lock;
51 struct list_head head;
52 } tx_list;
53 struct {
54 unsigned long bytes_held;
55 spinlock_t lock;
56 struct list_head head;
57 } rx_list;
58 struct ps3_vuart_stats stats;
59 struct ps3_vuart_work work;
60};
61
24/** 62/**
25 * struct ps3_vuart_port_driver - a driver for a device on a vuart port 63 * struct ps3_vuart_port_driver - a driver for a device on a vuart port
26 */ 64 */
@@ -41,10 +79,6 @@ struct ps3_vuart_port_driver {
41int ps3_vuart_port_driver_register(struct ps3_vuart_port_driver *drv); 79int ps3_vuart_port_driver_register(struct ps3_vuart_port_driver *drv);
42void ps3_vuart_port_driver_unregister(struct ps3_vuart_port_driver *drv); 80void ps3_vuart_port_driver_unregister(struct ps3_vuart_port_driver *drv);
43 81
44int ps3_vuart_write(struct ps3_vuart_port_device *dev,
45 const void* buf, unsigned int bytes);
46int ps3_vuart_read(struct ps3_vuart_port_device *dev, void* buf,
47 unsigned int bytes);
48static inline struct ps3_vuart_port_driver *to_ps3_vuart_port_driver( 82static inline struct ps3_vuart_port_driver *to_ps3_vuart_port_driver(
49 struct device_driver *_drv) 83 struct device_driver *_drv)
50{ 84{
@@ -55,5 +89,22 @@ static inline struct ps3_vuart_port_device *to_ps3_vuart_port_device(
55{ 89{
56 return container_of(_dev, struct ps3_vuart_port_device, core); 90 return container_of(_dev, struct ps3_vuart_port_device, core);
57} 91}
92static inline struct ps3_vuart_port_device *ps3_vuart_work_to_port_device(
93 struct work_struct *_work)
94{
95 struct ps3_vuart_work *vw = container_of(_work, struct ps3_vuart_work,
96 work);
97 return vw->dev;
98}
99
100int ps3_vuart_write(struct ps3_vuart_port_device *dev, const void* buf,
101 unsigned int bytes);
102int ps3_vuart_read(struct ps3_vuart_port_device *dev, void* buf,
103 unsigned int bytes);
104int ps3_vuart_read_async(struct ps3_vuart_port_device *dev, work_func_t func,
105 unsigned int bytes);
106void ps3_vuart_cancel_async(struct ps3_vuart_port_device *dev);
107void ps3_vuart_clear_rx_bytes(struct ps3_vuart_port_device *dev,
108 unsigned int bytes);
58 109
59#endif 110#endif
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index 8f6b5bf580f6..2b5b8a93bc10 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -801,15 +801,10 @@ static int idescsi_ide_open(struct inode *inode, struct file *filp)
801{ 801{
802 struct gendisk *disk = inode->i_bdev->bd_disk; 802 struct gendisk *disk = inode->i_bdev->bd_disk;
803 struct ide_scsi_obj *scsi; 803 struct ide_scsi_obj *scsi;
804 ide_drive_t *drive;
805 804
806 if (!(scsi = ide_scsi_get(disk))) 805 if (!(scsi = ide_scsi_get(disk)))
807 return -ENXIO; 806 return -ENXIO;
808 807
809 drive = scsi->drive;
810
811 drive->usage++;
812
813 return 0; 808 return 0;
814} 809}
815 810
@@ -817,9 +812,6 @@ static int idescsi_ide_release(struct inode *inode, struct file *filp)
817{ 812{
818 struct gendisk *disk = inode->i_bdev->bd_disk; 813 struct gendisk *disk = inode->i_bdev->bd_disk;
819 struct ide_scsi_obj *scsi = ide_scsi_g(disk); 814 struct ide_scsi_obj *scsi = ide_scsi_g(disk);
820 ide_drive_t *drive = scsi->drive;
821
822 drive->usage--;
823 815
824 ide_scsi_put(scsi); 816 ide_scsi_put(scsi);
825 817
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 3f048bd6326d..5a8f55fea5ff 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -1269,9 +1269,18 @@ repeat:
1269 1269
1270 /* Some devices return the total number of sectors, not the 1270 /* Some devices return the total number of sectors, not the
1271 * highest sector number. Make the necessary adjustment. */ 1271 * highest sector number. Make the necessary adjustment. */
1272 if (sdp->fix_capacity) 1272 if (sdp->fix_capacity) {
1273 --sdkp->capacity; 1273 --sdkp->capacity;
1274 1274
1275 /* Some devices have version which report the correct sizes
1276 * and others which do not. We guess size according to a heuristic
1277 * and err on the side of lowering the capacity. */
1278 } else {
1279 if (sdp->guess_capacity)
1280 if (sdkp->capacity & 0x01) /* odd sizes are odd */
1281 --sdkp->capacity;
1282 }
1283
1275got_data: 1284got_data:
1276 if (sector_size == 0) { 1285 if (sector_size == 0) {
1277 sector_size = 512; 1286 sector_size = 512;
diff --git a/drivers/serial/Kconfig b/drivers/serial/Kconfig
index e8dd71df9165..ad9f321968e1 100644
--- a/drivers/serial/Kconfig
+++ b/drivers/serial/Kconfig
@@ -262,7 +262,8 @@ config SERIAL_AMBA_PL010
262 select SERIAL_CORE 262 select SERIAL_CORE
263 help 263 help
264 This selects the ARM(R) AMBA(R) PrimeCell PL010 UART. If you have 264 This selects the ARM(R) AMBA(R) PrimeCell PL010 UART. If you have
265 an Integrator/AP or Integrator/PP2 platform, say Y or M here. 265 an Integrator/AP or Integrator/PP2 platform, or if you have a
266 Cirrus Logic EP93xx CPU, say Y or M here.
266 267
267 If unsure, say N. 268 If unsure, say N.
268 269
diff --git a/drivers/serial/atmel_serial.c b/drivers/serial/atmel_serial.c
index df45a7ac773f..935f48fa501d 100644
--- a/drivers/serial/atmel_serial.c
+++ b/drivers/serial/atmel_serial.c
@@ -33,12 +33,13 @@
33#include <linux/sysrq.h> 33#include <linux/sysrq.h>
34#include <linux/tty_flip.h> 34#include <linux/tty_flip.h>
35#include <linux/platform_device.h> 35#include <linux/platform_device.h>
36#include <linux/atmel_pdc.h>
36 37
37#include <asm/io.h> 38#include <asm/io.h>
38 39
39#include <asm/mach/serial_at91.h> 40#include <asm/mach/serial_at91.h>
40#include <asm/arch/board.h> 41#include <asm/arch/board.h>
41#include <asm/arch/at91_pdc.h> 42
42#ifdef CONFIG_ARM 43#ifdef CONFIG_ARM
43#include <asm/arch/cpu.h> 44#include <asm/arch/cpu.h>
44#include <asm/arch/gpio.h> 45#include <asm/arch/gpio.h>
diff --git a/drivers/serial/cpm_uart/cpm_uart_cpm2.c b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
index 787a8f134677..fa455996ad8f 100644
--- a/drivers/serial/cpm_uart/cpm_uart_cpm2.c
+++ b/drivers/serial/cpm_uart/cpm_uart_cpm2.c
@@ -285,7 +285,7 @@ void cpm_uart_freebuf(struct uart_cpm_port *pinfo)
285int __init 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 u16 *addr;
289#endif 289#endif
290 pr_debug("CPM uart[-]:init portdesc\n"); 290 pr_debug("CPM uart[-]:init portdesc\n");
291 291
diff --git a/drivers/serial/imx.c b/drivers/serial/imx.c
index e216dcf29376..04cc88cc528c 100644
--- a/drivers/serial/imx.c
+++ b/drivers/serial/imx.c
@@ -154,7 +154,7 @@ static inline void imx_transmit_buffer(struct imx_port *sport)
154{ 154{
155 struct circ_buf *xmit = &sport->port.info->xmit; 155 struct circ_buf *xmit = &sport->port.info->xmit;
156 156
157 do { 157 while (!(UTS((u32)sport->port.membase) & UTS_TXFULL)) {
158 /* send xmit->buf[xmit->tail] 158 /* send xmit->buf[xmit->tail]
159 * out the port here */ 159 * out the port here */
160 URTX0((u32)sport->port.membase) = xmit->buf[xmit->tail]; 160 URTX0((u32)sport->port.membase) = xmit->buf[xmit->tail];
@@ -163,7 +163,7 @@ static inline void imx_transmit_buffer(struct imx_port *sport)
163 sport->port.icount.tx++; 163 sport->port.icount.tx++;
164 if (uart_circ_empty(xmit)) 164 if (uart_circ_empty(xmit))
165 break; 165 break;
166 } while (!(UTS((u32)sport->port.membase) & UTS_TXFULL)); 166 }
167 167
168 if (uart_circ_empty(xmit)) 168 if (uart_circ_empty(xmit))
169 imx_stop_tx(&sport->port); 169 imx_stop_tx(&sport->port);
@@ -178,8 +178,7 @@ static void imx_start_tx(struct uart_port *port)
178 178
179 UCR1((u32)sport->port.membase) |= UCR1_TXMPTYEN; 179 UCR1((u32)sport->port.membase) |= UCR1_TXMPTYEN;
180 180
181 if(UTS((u32)sport->port.membase) & UTS_TXEMPTY) 181 imx_transmit_buffer(sport);
182 imx_transmit_buffer(sport);
183} 182}
184 183
185static irqreturn_t imx_rtsint(int irq, void *dev_id) 184static irqreturn_t imx_rtsint(int irq, void *dev_id)
@@ -404,7 +403,8 @@ static int imx_startup(struct uart_port *port)
404 if (retval) goto error_out2; 403 if (retval) goto error_out2;
405 404
406 retval = request_irq(sport->rtsirq, imx_rtsint, 405 retval = request_irq(sport->rtsirq, imx_rtsint,
407 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING, 406 (sport->rtsirq < IMX_IRQS) ? 0 :
407 IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
408 DRIVER_NAME, sport); 408 DRIVER_NAME, sport);
409 if (retval) goto error_out3; 409 if (retval) goto error_out3;
410 410
@@ -678,7 +678,7 @@ static struct imx_port imx_ports[] = {
678 .mapbase = IMX_UART1_BASE, /* FIXME */ 678 .mapbase = IMX_UART1_BASE, /* FIXME */
679 .irq = UART1_MINT_RX, 679 .irq = UART1_MINT_RX,
680 .uartclk = 16000000, 680 .uartclk = 16000000,
681 .fifosize = 8, 681 .fifosize = 32,
682 .flags = UPF_BOOT_AUTOCONF, 682 .flags = UPF_BOOT_AUTOCONF,
683 .ops = &imx_pops, 683 .ops = &imx_pops,
684 .line = 0, 684 .line = 0,
@@ -694,7 +694,7 @@ static struct imx_port imx_ports[] = {
694 .mapbase = IMX_UART2_BASE, /* FIXME */ 694 .mapbase = IMX_UART2_BASE, /* FIXME */
695 .irq = UART2_MINT_RX, 695 .irq = UART2_MINT_RX,
696 .uartclk = 16000000, 696 .uartclk = 16000000,
697 .fifosize = 8, 697 .fifosize = 32,
698 .flags = UPF_BOOT_AUTOCONF, 698 .flags = UPF_BOOT_AUTOCONF,
699 .ops = &imx_pops, 699 .ops = &imx_pops,
700 .line = 1, 700 .line = 1,
diff --git a/drivers/serial/mpc52xx_uart.c b/drivers/serial/mpc52xx_uart.c
index 955bbd653e22..8d24cd521056 100644
--- a/drivers/serial/mpc52xx_uart.c
+++ b/drivers/serial/mpc52xx_uart.c
@@ -995,8 +995,10 @@ mpc52xx_uart_of_remove(struct of_device *op)
995 struct uart_port *port = dev_get_drvdata(&op->dev); 995 struct uart_port *port = dev_get_drvdata(&op->dev);
996 dev_set_drvdata(&op->dev, NULL); 996 dev_set_drvdata(&op->dev, NULL);
997 997
998 if (port) 998 if (port) {
999 uart_remove_one_port(&mpc52xx_uart_driver, port); 999 uart_remove_one_port(&mpc52xx_uart_driver, port);
1000 irq_dispose_mapping(port->irq);
1001 }
1000 1002
1001 return 0; 1003 return 0;
1002} 1004}
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index c2f1012449da..6b76babc7fbf 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -248,6 +248,10 @@ static const struct serial_quirk quirks[] = {
248 .multi = 2, 248 .multi = 2,
249 }, { 249 }, {
250 .manfid = MANFID_QUATECH, 250 .manfid = MANFID_QUATECH,
251 .prodid = PRODID_QUATECH_DUAL_RS232_G,
252 .multi = 2,
253 }, {
254 .manfid = MANFID_QUATECH,
251 .prodid = PRODID_QUATECH_QUAD_RS232, 255 .prodid = PRODID_QUATECH_QUAD_RS232,
252 .multi = 4, 256 .multi = 4,
253 }, { 257 }, {
@@ -891,6 +895,7 @@ static struct pcmcia_device_id serial_ids[] = {
891 PCMCIA_DEVICE_PROD_ID12("OEM ", "C288MX ", 0xb572d360, 0xd2385b7a), 895 PCMCIA_DEVICE_PROD_ID12("OEM ", "C288MX ", 0xb572d360, 0xd2385b7a),
892 PCMCIA_DEVICE_PROD_ID12("PCMCIA ", "C336MX ", 0x99bcafe9, 0xaa25bcab), 896 PCMCIA_DEVICE_PROD_ID12("PCMCIA ", "C336MX ", 0x99bcafe9, 0xaa25bcab),
893 PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f), 897 PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "PCMCIA Dual RS-232 Serial Port Card", 0xc4420b35, 0x92abc92f),
898 PCMCIA_DEVICE_PROD_ID12("Quatech Inc", "Dual RS-232 Serial Port PC Card", 0xc4420b35, 0x031a380d),
894 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "PCMLM28.cis"), 899 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "EN2218-LAN/MODEM", 0x281f1c5d, 0x570f348e, "PCMLM28.cis"),
895 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "PCMLM28.cis"), 900 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "PCMCIA", "UE2218-LAN/MODEM", 0x281f1c5d, 0x6fdcacee, "PCMLM28.cis"),
896 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "PCMLM28.cis"), 901 PCMCIA_PFC_DEVICE_CIS_PROD_ID12(1, "Psion Dacom", "Gold Card V34 Ethernet", 0xf5f025c2, 0x338e8155, "PCMLM28.cis"),
diff --git a/drivers/usb/Makefile b/drivers/usb/Makefile
index 825bf884537a..8b7ff467d262 100644
--- a/drivers/usb/Makefile
+++ b/drivers/usb/Makefile
@@ -51,6 +51,7 @@ obj-$(CONFIG_USB_SERIAL) += serial/
51obj-$(CONFIG_USB_ADUTUX) += misc/ 51obj-$(CONFIG_USB_ADUTUX) += misc/
52obj-$(CONFIG_USB_APPLEDISPLAY) += misc/ 52obj-$(CONFIG_USB_APPLEDISPLAY) += misc/
53obj-$(CONFIG_USB_AUERSWALD) += misc/ 53obj-$(CONFIG_USB_AUERSWALD) += misc/
54obj-$(CONFIG_USB_BERRY_CHARGE) += misc/
54obj-$(CONFIG_USB_CYPRESS_CY7C63)+= misc/ 55obj-$(CONFIG_USB_CYPRESS_CY7C63)+= misc/
55obj-$(CONFIG_USB_CYTHERM) += misc/ 56obj-$(CONFIG_USB_CYTHERM) += misc/
56obj-$(CONFIG_USB_EMI26) += misc/ 57obj-$(CONFIG_USB_EMI26) += misc/
diff --git a/drivers/usb/atm/ueagle-atm.c b/drivers/usb/atm/ueagle-atm.c
index dae4ef1e8fe5..4973e147bc79 100644
--- a/drivers/usb/atm/ueagle-atm.c
+++ b/drivers/usb/atm/ueagle-atm.c
@@ -61,6 +61,7 @@
61#include <linux/usb.h> 61#include <linux/usb.h>
62#include <linux/firmware.h> 62#include <linux/firmware.h>
63#include <linux/ctype.h> 63#include <linux/ctype.h>
64#include <linux/sched.h>
64#include <linux/kthread.h> 65#include <linux/kthread.h>
65#include <linux/version.h> 66#include <linux/version.h>
66#include <linux/mutex.h> 67#include <linux/mutex.h>
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 98199628e394..d38a25f36ea5 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -326,10 +326,16 @@ static void acm_rx_tasklet(unsigned long _acm)
326 struct tty_struct *tty = acm->tty; 326 struct tty_struct *tty = acm->tty;
327 struct acm_ru *rcv; 327 struct acm_ru *rcv;
328 unsigned long flags; 328 unsigned long flags;
329 int i = 0; 329 unsigned char throttled;
330 dbg("Entering acm_rx_tasklet"); 330 dbg("Entering acm_rx_tasklet");
331 331
332 if (!ACM_READY(acm) || acm->throttle) 332 if (!ACM_READY(acm))
333 return;
334
335 spin_lock(&acm->throttle_lock);
336 throttled = acm->throttle;
337 spin_unlock(&acm->throttle_lock);
338 if (throttled)
333 return; 339 return;
334 340
335next_buffer: 341next_buffer:
@@ -346,22 +352,20 @@ next_buffer:
346 dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d", buf, buf->size); 352 dbg("acm_rx_tasklet: procesing buf 0x%p, size = %d", buf, buf->size);
347 353
348 tty_buffer_request_room(tty, buf->size); 354 tty_buffer_request_room(tty, buf->size);
349 if (!acm->throttle) 355 spin_lock(&acm->throttle_lock);
356 throttled = acm->throttle;
357 spin_unlock(&acm->throttle_lock);
358 if (!throttled)
350 tty_insert_flip_string(tty, buf->base, buf->size); 359 tty_insert_flip_string(tty, buf->base, buf->size);
351 tty_flip_buffer_push(tty); 360 tty_flip_buffer_push(tty);
352 361
353 spin_lock(&acm->throttle_lock); 362 if (throttled) {
354 if (acm->throttle) { 363 dbg("Throttling noticed");
355 dbg("Throtteling noticed");
356 memmove(buf->base, buf->base + i, buf->size - i);
357 buf->size -= i;
358 spin_unlock(&acm->throttle_lock);
359 spin_lock_irqsave(&acm->read_lock, flags); 364 spin_lock_irqsave(&acm->read_lock, flags);
360 list_add(&buf->list, &acm->filled_read_bufs); 365 list_add(&buf->list, &acm->filled_read_bufs);
361 spin_unlock_irqrestore(&acm->read_lock, flags); 366 spin_unlock_irqrestore(&acm->read_lock, flags);
362 return; 367 return;
363 } 368 }
364 spin_unlock(&acm->throttle_lock);
365 369
366 spin_lock_irqsave(&acm->read_lock, flags); 370 spin_lock_irqsave(&acm->read_lock, flags);
367 list_add(&buf->list, &acm->spare_read_bufs); 371 list_add(&buf->list, &acm->spare_read_bufs);
@@ -467,7 +471,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
467 goto bail_out; 471 goto bail_out;
468 } 472 }
469 473
470 if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS)) 474 if (0 > acm_set_control(acm, acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS) &&
475 (acm->ctrl_caps & USB_CDC_CAP_LINE))
471 goto full_bailout; 476 goto full_bailout;
472 477
473 INIT_LIST_HEAD(&acm->spare_read_urbs); 478 INIT_LIST_HEAD(&acm->spare_read_urbs);
@@ -480,6 +485,8 @@ static int acm_tty_open(struct tty_struct *tty, struct file *filp)
480 list_add(&(acm->rb[i].list), &acm->spare_read_bufs); 485 list_add(&(acm->rb[i].list), &acm->spare_read_bufs);
481 } 486 }
482 487
488 acm->throttle = 0;
489
483 tasklet_schedule(&acm->urb_task); 490 tasklet_schedule(&acm->urb_task);
484 491
485done: 492done:
@@ -1092,6 +1099,10 @@ static struct usb_device_id acm_ids[] = {
1092 { USB_DEVICE(0x0ace, 0x1611), /* ZyDAS 56K USB MODEM - new version */ 1099 { USB_DEVICE(0x0ace, 0x1611), /* ZyDAS 56K USB MODEM - new version */
1093 .driver_info = SINGLE_RX_URB, /* firmware bug */ 1100 .driver_info = SINGLE_RX_URB, /* firmware bug */
1094 }, 1101 },
1102 { USB_DEVICE(0x22b8, 0x7000), /* Motorola Q Phone */
1103 .driver_info = NO_UNION_NORMAL, /* has no union descriptor */
1104 },
1105
1095 /* control interfaces with various AT-command sets */ 1106 /* control interfaces with various AT-command sets */
1096 { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM, 1107 { USB_INTERFACE_INFO(USB_CLASS_COMM, USB_CDC_SUBCLASS_ACM,
1097 USB_CDC_ACM_PROTO_AT_V25TER) }, 1108 USB_CDC_ACM_PROTO_AT_V25TER) },
diff --git a/drivers/usb/core/devices.c b/drivers/usb/core/devices.c
index a47c30b2d764..aefc7987120d 100644
--- a/drivers/usb/core/devices.c
+++ b/drivers/usb/core/devices.c
@@ -604,10 +604,6 @@ static unsigned int usb_device_poll(struct file *file, struct poll_table_struct
604 lock_kernel(); 604 lock_kernel();
605 if (!st) { 605 if (!st) {
606 st = kmalloc(sizeof(struct usb_device_status), GFP_KERNEL); 606 st = kmalloc(sizeof(struct usb_device_status), GFP_KERNEL);
607 if (!st) {
608 unlock_kernel();
609 return POLLIN;
610 }
611 607
612 /* we may have dropped BKL - need to check for having lost the race */ 608 /* we may have dropped BKL - need to check for having lost the race */
613 if (file->private_data) { 609 if (file->private_data) {
@@ -615,6 +611,11 @@ static unsigned int usb_device_poll(struct file *file, struct poll_table_struct
615 st = file->private_data; 611 st = file->private_data;
616 goto lost_race; 612 goto lost_race;
617 } 613 }
614 /* we haven't lost - check for allocation failure now */
615 if (!st) {
616 unlock_kernel();
617 return POLLIN;
618 }
618 619
619 /* 620 /*
620 * need to prevent the module from being unloaded, since 621 * need to prevent the module from being unloaded, since
diff --git a/drivers/usb/core/devio.c b/drivers/usb/core/devio.c
index 2087766f9e88..274f14f1633e 100644
--- a/drivers/usb/core/devio.c
+++ b/drivers/usb/core/devio.c
@@ -857,11 +857,11 @@ static int proc_setintf(struct dev_state *ps, void __user *arg)
857 857
858static int proc_setconfig(struct dev_state *ps, void __user *arg) 858static int proc_setconfig(struct dev_state *ps, void __user *arg)
859{ 859{
860 unsigned int u; 860 int u;
861 int status = 0; 861 int status = 0;
862 struct usb_host_config *actconfig; 862 struct usb_host_config *actconfig;
863 863
864 if (get_user(u, (unsigned int __user *)arg)) 864 if (get_user(u, (int __user *)arg))
865 return -EFAULT; 865 return -EFAULT;
866 866
867 actconfig = ps->dev->actconfig; 867 actconfig = ps->dev->actconfig;
diff --git a/drivers/usb/core/driver.c b/drivers/usb/core/driver.c
index 600d1bc8272a..2aded261f42c 100644
--- a/drivers/usb/core/driver.c
+++ b/drivers/usb/core/driver.c
@@ -743,6 +743,7 @@ EXPORT_SYMBOL_GPL(usb_deregister_device_driver);
743 * usb_register_driver - register a USB interface driver 743 * usb_register_driver - register a USB interface driver
744 * @new_driver: USB operations for the interface driver 744 * @new_driver: USB operations for the interface driver
745 * @owner: module owner of this driver. 745 * @owner: module owner of this driver.
746 * @mod_name: module name string
746 * 747 *
747 * Registers a USB interface driver with the USB core. The list of 748 * Registers a USB interface driver with the USB core. The list of
748 * unattached interfaces will be rescanned whenever a new driver is 749 * unattached interfaces will be rescanned whenever a new driver is
diff --git a/drivers/usb/core/endpoint.c b/drivers/usb/core/endpoint.c
index 5e628ae3aec7..e0ec7045e865 100644
--- a/drivers/usb/core/endpoint.c
+++ b/drivers/usb/core/endpoint.c
@@ -229,7 +229,7 @@ static int init_endpoint_class(void)
229 kref_init(&ep_class->kref); 229 kref_init(&ep_class->kref);
230 ep_class->class = class_create(THIS_MODULE, "usb_endpoint"); 230 ep_class->class = class_create(THIS_MODULE, "usb_endpoint");
231 if (IS_ERR(ep_class->class)) { 231 if (IS_ERR(ep_class->class)) {
232 result = IS_ERR(ep_class->class); 232 result = PTR_ERR(ep_class->class);
233 goto class_create_error; 233 goto class_create_error;
234 } 234 }
235 235
diff --git a/drivers/usb/core/generic.c b/drivers/usb/core/generic.c
index b531a4fd30c2..9bbcb20e2d94 100644
--- a/drivers/usb/core/generic.c
+++ b/drivers/usb/core/generic.c
@@ -184,7 +184,7 @@ static void generic_disconnect(struct usb_device *udev)
184 /* if this is only an unbind, not a physical disconnect, then 184 /* if this is only an unbind, not a physical disconnect, then
185 * unconfigure the device */ 185 * unconfigure the device */
186 if (udev->actconfig) 186 if (udev->actconfig)
187 usb_set_configuration(udev, 0); 187 usb_set_configuration(udev, -1);
188 188
189 usb_remove_sysfs_dev_files(udev); 189 usb_remove_sysfs_dev_files(udev);
190} 190}
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index 590ec82d0515..50c0db15304a 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -44,6 +44,7 @@ struct usb_hub {
44 struct usb_hub_status hub; 44 struct usb_hub_status hub;
45 struct usb_port_status port; 45 struct usb_port_status port;
46 } *status; /* buffer for status reports */ 46 } *status; /* buffer for status reports */
47 struct mutex status_mutex; /* for the status buffer */
47 48
48 int error; /* last reported error */ 49 int error; /* last reported error */
49 int nerrors; /* track consecutive errors */ 50 int nerrors; /* track consecutive errors */
@@ -535,6 +536,7 @@ static int hub_hub_status(struct usb_hub *hub,
535{ 536{
536 int ret; 537 int ret;
537 538
539 mutex_lock(&hub->status_mutex);
538 ret = get_hub_status(hub->hdev, &hub->status->hub); 540 ret = get_hub_status(hub->hdev, &hub->status->hub);
539 if (ret < 0) 541 if (ret < 0)
540 dev_err (hub->intfdev, 542 dev_err (hub->intfdev,
@@ -544,6 +546,7 @@ static int hub_hub_status(struct usb_hub *hub,
544 *change = le16_to_cpu(hub->status->hub.wHubChange); 546 *change = le16_to_cpu(hub->status->hub.wHubChange);
545 ret = 0; 547 ret = 0;
546 } 548 }
549 mutex_unlock(&hub->status_mutex);
547 return ret; 550 return ret;
548} 551}
549 552
@@ -617,6 +620,7 @@ static int hub_configure(struct usb_hub *hub,
617 ret = -ENOMEM; 620 ret = -ENOMEM;
618 goto fail; 621 goto fail;
619 } 622 }
623 mutex_init(&hub->status_mutex);
620 624
621 hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL); 625 hub->descriptor = kmalloc(sizeof(*hub->descriptor), GFP_KERNEL);
622 if (!hub->descriptor) { 626 if (!hub->descriptor) {
@@ -1396,6 +1400,7 @@ static int hub_port_status(struct usb_hub *hub, int port1,
1396{ 1400{
1397 int ret; 1401 int ret;
1398 1402
1403 mutex_lock(&hub->status_mutex);
1399 ret = get_port_status(hub->hdev, port1, &hub->status->port); 1404 ret = get_port_status(hub->hdev, port1, &hub->status->port);
1400 if (ret < 4) { 1405 if (ret < 4) {
1401 dev_err (hub->intfdev, 1406 dev_err (hub->intfdev,
@@ -1407,6 +1412,7 @@ static int hub_port_status(struct usb_hub *hub, int port1,
1407 *change = le16_to_cpu(hub->status->port.wPortChange); 1412 *change = le16_to_cpu(hub->status->port.wPortChange);
1408 ret = 0; 1413 ret = 0;
1409 } 1414 }
1415 mutex_unlock(&hub->status_mutex);
1410 return ret; 1416 return ret;
1411} 1417}
1412 1418
@@ -1904,6 +1910,7 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
1904 struct usb_hub *hub = usb_get_intfdata (intf); 1910 struct usb_hub *hub = usb_get_intfdata (intf);
1905 struct usb_device *hdev = hub->hdev; 1911 struct usb_device *hdev = hub->hdev;
1906 unsigned port1; 1912 unsigned port1;
1913 int status = 0;
1907 1914
1908 /* fail if children aren't already suspended */ 1915 /* fail if children aren't already suspended */
1909 for (port1 = 1; port1 <= hdev->maxchild; port1++) { 1916 for (port1 = 1; port1 <= hdev->maxchild; port1++) {
@@ -1927,24 +1934,18 @@ static int hub_suspend(struct usb_interface *intf, pm_message_t msg)
1927 1934
1928 dev_dbg(&intf->dev, "%s\n", __FUNCTION__); 1935 dev_dbg(&intf->dev, "%s\n", __FUNCTION__);
1929 1936
1937 /* stop khubd and related activity */
1938 hub_quiesce(hub);
1939
1930 /* "global suspend" of the downstream HC-to-USB interface */ 1940 /* "global suspend" of the downstream HC-to-USB interface */
1931 if (!hdev->parent) { 1941 if (!hdev->parent) {
1932 struct usb_bus *bus = hdev->bus; 1942 status = hcd_bus_suspend(hdev->bus);
1933 if (bus) { 1943 if (status != 0) {
1934 int status = hcd_bus_suspend (bus); 1944 dev_dbg(&hdev->dev, "'global' suspend %d\n", status);
1935 1945 hub_activate(hub);
1936 if (status != 0) { 1946 }
1937 dev_dbg(&hdev->dev, "'global' suspend %d\n",
1938 status);
1939 return status;
1940 }
1941 } else
1942 return -EOPNOTSUPP;
1943 } 1947 }
1944 1948 return status;
1945 /* stop khubd and related activity */
1946 hub_quiesce(hub);
1947 return 0;
1948} 1949}
1949 1950
1950static int hub_resume(struct usb_interface *intf) 1951static int hub_resume(struct usb_interface *intf)
diff --git a/drivers/usb/core/message.c b/drivers/usb/core/message.c
index 8aca3574c2b5..74edaea5665d 100644
--- a/drivers/usb/core/message.c
+++ b/drivers/usb/core/message.c
@@ -1316,6 +1316,14 @@ static void release_interface(struct device *dev)
1316 * use this kind of configurability; many devices only have one 1316 * use this kind of configurability; many devices only have one
1317 * configuration. 1317 * configuration.
1318 * 1318 *
1319 * @configuration is the value of the configuration to be installed.
1320 * According to the USB spec (e.g. section 9.1.1.5), configuration values
1321 * must be non-zero; a value of zero indicates that the device in
1322 * unconfigured. However some devices erroneously use 0 as one of their
1323 * configuration values. To help manage such devices, this routine will
1324 * accept @configuration = -1 as indicating the device should be put in
1325 * an unconfigured state.
1326 *
1319 * USB device configurations may affect Linux interoperability, 1327 * USB device configurations may affect Linux interoperability,
1320 * power consumption and the functionality available. For example, 1328 * power consumption and the functionality available. For example,
1321 * the default configuration is limited to using 100mA of bus power, 1329 * the default configuration is limited to using 100mA of bus power,
@@ -1347,10 +1355,15 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
1347 struct usb_interface **new_interfaces = NULL; 1355 struct usb_interface **new_interfaces = NULL;
1348 int n, nintf; 1356 int n, nintf;
1349 1357
1350 for (i = 0; i < dev->descriptor.bNumConfigurations; i++) { 1358 if (configuration == -1)
1351 if (dev->config[i].desc.bConfigurationValue == configuration) { 1359 configuration = 0;
1352 cp = &dev->config[i]; 1360 else {
1353 break; 1361 for (i = 0; i < dev->descriptor.bNumConfigurations; i++) {
1362 if (dev->config[i].desc.bConfigurationValue ==
1363 configuration) {
1364 cp = &dev->config[i];
1365 break;
1366 }
1354 } 1367 }
1355 } 1368 }
1356 if ((!cp && configuration != 0)) 1369 if ((!cp && configuration != 0))
@@ -1359,6 +1372,7 @@ int usb_set_configuration(struct usb_device *dev, int configuration)
1359 /* The USB spec says configuration 0 means unconfigured. 1372 /* The USB spec says configuration 0 means unconfigured.
1360 * But if a device includes a configuration numbered 0, 1373 * But if a device includes a configuration numbered 0,
1361 * we will accept it as a correctly configured state. 1374 * we will accept it as a correctly configured state.
1375 * Use -1 if you really want to unconfigure the device.
1362 */ 1376 */
1363 if (cp && configuration == 0) 1377 if (cp && configuration == 0)
1364 dev_warn(&dev->dev, "config 0 descriptor??\n"); 1378 dev_warn(&dev->dev, "config 0 descriptor??\n");
diff --git a/drivers/usb/core/otg_whitelist.h b/drivers/usb/core/otg_whitelist.h
index 627a5a2fc9cf..7f31a495a25d 100644
--- a/drivers/usb/core/otg_whitelist.h
+++ b/drivers/usb/core/otg_whitelist.h
@@ -31,7 +31,7 @@ static struct usb_device_id whitelist_table [] = {
31{ USB_DEVICE_INFO(7, 1, 3) }, 31{ USB_DEVICE_INFO(7, 1, 3) },
32#endif 32#endif
33 33
34#ifdef CONFIG_USB_CDCETHER 34#ifdef CONFIG_USB_NET_CDCETHER
35/* Linux-USB CDC Ethernet gadget */ 35/* Linux-USB CDC Ethernet gadget */
36{ USB_DEVICE(0x0525, 0xa4a1), }, 36{ USB_DEVICE(0x0525, 0xa4a1), },
37/* Linux-USB CDC Ethernet + RNDIS gadget */ 37/* Linux-USB CDC Ethernet + RNDIS gadget */
diff --git a/drivers/usb/core/sysfs.c b/drivers/usb/core/sysfs.c
index 4eaa0ee8e72f..0edfbafd702c 100644
--- a/drivers/usb/core/sysfs.c
+++ b/drivers/usb/core/sysfs.c
@@ -63,7 +63,7 @@ set_bConfigurationValue(struct device *dev, struct device_attribute *attr,
63 struct usb_device *udev = to_usb_device(dev); 63 struct usb_device *udev = to_usb_device(dev);
64 int config, value; 64 int config, value;
65 65
66 if (sscanf(buf, "%u", &config) != 1 || config > 255) 66 if (sscanf(buf, "%d", &config) != 1 || config < -1 || config > 255)
67 return -EINVAL; 67 return -EINVAL;
68 usb_lock_device(udev); 68 usb_lock_device(udev);
69 value = usb_set_configuration(udev, config); 69 value = usb_set_configuration(udev, config);
diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c
index 36b36e0175fc..a4677802fb20 100644
--- a/drivers/usb/gadget/at91_udc.c
+++ b/drivers/usb/gadget/at91_udc.c
@@ -784,7 +784,7 @@ static int at91_ep_set_halt(struct usb_ep *_ep, int value)
784 return status; 784 return status;
785} 785}
786 786
787static struct usb_ep_ops at91_ep_ops = { 787static const struct usb_ep_ops at91_ep_ops = {
788 .enable = at91_ep_enable, 788 .enable = at91_ep_enable,
789 .disable = at91_ep_disable, 789 .disable = at91_ep_disable,
790 .alloc_request = at91_ep_alloc_request, 790 .alloc_request = at91_ep_alloc_request,
@@ -912,7 +912,7 @@ static void pullup(struct at91_udc *udc, int is_on)
912 at91_udp_write(udc, AT91_UDP_TXVC, 0); 912 at91_udp_write(udc, AT91_UDP_TXVC, 0);
913 if (cpu_is_at91rm9200()) 913 if (cpu_is_at91rm9200())
914 at91_set_gpio_value(udc->board.pullup_pin, 1); 914 at91_set_gpio_value(udc->board.pullup_pin, 1);
915 else if (cpu_is_at91sam9260()) { 915 else if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) {
916 u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC); 916 u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC);
917 917
918 txvc |= AT91_UDP_TXVC_PUON; 918 txvc |= AT91_UDP_TXVC_PUON;
@@ -929,7 +929,7 @@ static void pullup(struct at91_udc *udc, int is_on)
929 at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS); 929 at91_udp_write(udc, AT91_UDP_TXVC, AT91_UDP_TXVC_TXVDIS);
930 if (cpu_is_at91rm9200()) 930 if (cpu_is_at91rm9200())
931 at91_set_gpio_value(udc->board.pullup_pin, 0); 931 at91_set_gpio_value(udc->board.pullup_pin, 0);
932 else if (cpu_is_at91sam9260()) { 932 else if (cpu_is_at91sam9260() || cpu_is_at91sam9263()) {
933 u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC); 933 u32 txvc = at91_udp_read(udc, AT91_UDP_TXVC);
934 934
935 txvc &= ~AT91_UDP_TXVC_PUON; 935 txvc &= ~AT91_UDP_TXVC_PUON;
@@ -1651,7 +1651,7 @@ static void at91udc_shutdown(struct platform_device *dev)
1651 pullup(platform_get_drvdata(dev), 0); 1651 pullup(platform_get_drvdata(dev), 0);
1652} 1652}
1653 1653
1654static int __devinit at91udc_probe(struct platform_device *pdev) 1654static int __init at91udc_probe(struct platform_device *pdev)
1655{ 1655{
1656 struct device *dev = &pdev->dev; 1656 struct device *dev = &pdev->dev;
1657 struct at91_udc *udc; 1657 struct at91_udc *udc;
@@ -1762,7 +1762,7 @@ fail0:
1762 return retval; 1762 return retval;
1763} 1763}
1764 1764
1765static int __devexit at91udc_remove(struct platform_device *pdev) 1765static int __exit at91udc_remove(struct platform_device *pdev)
1766{ 1766{
1767 struct at91_udc *udc = platform_get_drvdata(pdev); 1767 struct at91_udc *udc = platform_get_drvdata(pdev);
1768 struct resource *res; 1768 struct resource *res;
@@ -1836,8 +1836,7 @@ static int at91udc_resume(struct platform_device *pdev)
1836#endif 1836#endif
1837 1837
1838static struct platform_driver at91_udc = { 1838static struct platform_driver at91_udc = {
1839 .probe = at91udc_probe, 1839 .remove = __exit_p(at91udc_remove),
1840 .remove = __devexit_p(at91udc_remove),
1841 .shutdown = at91udc_shutdown, 1840 .shutdown = at91udc_shutdown,
1842 .suspend = at91udc_suspend, 1841 .suspend = at91udc_suspend,
1843 .resume = at91udc_resume, 1842 .resume = at91udc_resume,
@@ -1847,13 +1846,13 @@ static struct platform_driver at91_udc = {
1847 }, 1846 },
1848}; 1847};
1849 1848
1850static int __devinit udc_init_module(void) 1849static int __init udc_init_module(void)
1851{ 1850{
1852 return platform_driver_register(&at91_udc); 1851 return platform_driver_probe(&at91_udc, at91udc_probe);
1853} 1852}
1854module_init(udc_init_module); 1853module_init(udc_init_module);
1855 1854
1856static void __devexit udc_exit_module(void) 1855static void __exit udc_exit_module(void)
1857{ 1856{
1858 platform_driver_unregister(&at91_udc); 1857 platform_driver_unregister(&at91_udc);
1859} 1858}
diff --git a/drivers/usb/gadget/pxa2xx_udc.c b/drivers/usb/gadget/pxa2xx_udc.c
index 27904a56494b..f01890dc8751 100644
--- a/drivers/usb/gadget/pxa2xx_udc.c
+++ b/drivers/usb/gadget/pxa2xx_udc.c
@@ -155,7 +155,7 @@ static int is_vbus_present(void)
155 struct pxa2xx_udc_mach_info *mach = the_controller->mach; 155 struct pxa2xx_udc_mach_info *mach = the_controller->mach;
156 156
157 if (mach->gpio_vbus) 157 if (mach->gpio_vbus)
158 return pxa_gpio_get(mach->gpio_vbus); 158 return udc_gpio_get(mach->gpio_vbus);
159 if (mach->udc_is_connected) 159 if (mach->udc_is_connected)
160 return mach->udc_is_connected(); 160 return mach->udc_is_connected();
161 return 1; 161 return 1;
@@ -167,7 +167,7 @@ static void pullup_off(void)
167 struct pxa2xx_udc_mach_info *mach = the_controller->mach; 167 struct pxa2xx_udc_mach_info *mach = the_controller->mach;
168 168
169 if (mach->gpio_pullup) 169 if (mach->gpio_pullup)
170 pxa_gpio_set(mach->gpio_pullup, 0); 170 udc_gpio_set(mach->gpio_pullup, 0);
171 else if (mach->udc_command) 171 else if (mach->udc_command)
172 mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT); 172 mach->udc_command(PXA2XX_UDC_CMD_DISCONNECT);
173} 173}
@@ -177,7 +177,7 @@ static void pullup_on(void)
177 struct pxa2xx_udc_mach_info *mach = the_controller->mach; 177 struct pxa2xx_udc_mach_info *mach = the_controller->mach;
178 178
179 if (mach->gpio_pullup) 179 if (mach->gpio_pullup)
180 pxa_gpio_set(mach->gpio_pullup, 1); 180 udc_gpio_set(mach->gpio_pullup, 1);
181 else if (mach->udc_command) 181 else if (mach->udc_command)
182 mach->udc_command(PXA2XX_UDC_CMD_CONNECT); 182 mach->udc_command(PXA2XX_UDC_CMD_CONNECT);
183} 183}
@@ -1755,7 +1755,7 @@ lubbock_vbus_irq(int irq, void *_dev)
1755static irqreturn_t udc_vbus_irq(int irq, void *_dev) 1755static irqreturn_t udc_vbus_irq(int irq, void *_dev)
1756{ 1756{
1757 struct pxa2xx_udc *dev = _dev; 1757 struct pxa2xx_udc *dev = _dev;
1758 int vbus = pxa_gpio_get(dev->mach->gpio_vbus); 1758 int vbus = udc_gpio_get(dev->mach->gpio_vbus);
1759 1759
1760 pxa2xx_udc_vbus_session(&dev->gadget, vbus); 1760 pxa2xx_udc_vbus_session(&dev->gadget, vbus);
1761 return IRQ_HANDLED; 1761 return IRQ_HANDLED;
@@ -2545,15 +2545,13 @@ static int __init pxa2xx_udc_probe(struct platform_device *pdev)
2545 dev->dev = &pdev->dev; 2545 dev->dev = &pdev->dev;
2546 dev->mach = pdev->dev.platform_data; 2546 dev->mach = pdev->dev.platform_data;
2547 if (dev->mach->gpio_vbus) { 2547 if (dev->mach->gpio_vbus) {
2548 vbus_irq = IRQ_GPIO(dev->mach->gpio_vbus & GPIO_MD_MASK_NR); 2548 udc_gpio_init_vbus(dev->mach->gpio_vbus);
2549 pxa_gpio_mode((dev->mach->gpio_vbus & GPIO_MD_MASK_NR) 2549 vbus_irq = udc_gpio_to_irq(dev->mach->gpio_vbus);
2550 | GPIO_IN);
2551 set_irq_type(vbus_irq, IRQT_BOTHEDGE); 2550 set_irq_type(vbus_irq, IRQT_BOTHEDGE);
2552 } else 2551 } else
2553 vbus_irq = 0; 2552 vbus_irq = 0;
2554 if (dev->mach->gpio_pullup) 2553 if (dev->mach->gpio_pullup)
2555 pxa_gpio_mode((dev->mach->gpio_pullup & GPIO_MD_MASK_NR) 2554 udc_gpio_init_pullup(dev->mach->gpio_pullup);
2556 | GPIO_OUT | GPIO_DFLT_LOW);
2557 2555
2558 init_timer(&dev->timer); 2556 init_timer(&dev->timer);
2559 dev->timer.function = udc_watchdog; 2557 dev->timer.function = udc_watchdog;
diff --git a/drivers/usb/gadget/pxa2xx_udc.h b/drivers/usb/gadget/pxa2xx_udc.h
index 8e598c8bf4e3..773e549aff3f 100644
--- a/drivers/usb/gadget/pxa2xx_udc.h
+++ b/drivers/usb/gadget/pxa2xx_udc.h
@@ -177,21 +177,6 @@ struct pxa2xx_udc {
177 177
178static struct pxa2xx_udc *the_controller; 178static struct pxa2xx_udc *the_controller;
179 179
180static inline int pxa_gpio_get(unsigned gpio)
181{
182 return (GPLR(gpio) & GPIO_bit(gpio)) != 0;
183}
184
185static inline void pxa_gpio_set(unsigned gpio, int is_on)
186{
187 int mask = GPIO_bit(gpio);
188
189 if (is_on)
190 GPSR(gpio) = mask;
191 else
192 GPCR(gpio) = mask;
193}
194
195/*-------------------------------------------------------------------------*/ 180/*-------------------------------------------------------------------------*/
196 181
197/* 182/*
diff --git a/drivers/usb/gadget/serial.c b/drivers/usb/gadget/serial.c
index e6c19aa4bef3..e552668d36b3 100644
--- a/drivers/usb/gadget/serial.c
+++ b/drivers/usb/gadget/serial.c
@@ -1699,6 +1699,7 @@ static int gs_setup_class(struct usb_gadget *gadget,
1699 memcpy(&port->port_line_coding, req->buf, ret); 1699 memcpy(&port->port_line_coding, req->buf, ret);
1700 spin_unlock(&port->port_lock); 1700 spin_unlock(&port->port_lock);
1701 } 1701 }
1702 ret = 0;
1702 break; 1703 break;
1703 1704
1704 case USB_CDC_REQ_GET_LINE_CODING: 1705 case USB_CDC_REQ_GET_LINE_CODING:
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 185721dba42b..a74056488234 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -42,6 +42,9 @@
42#include <asm/irq.h> 42#include <asm/irq.h>
43#include <asm/system.h> 43#include <asm/system.h>
44#include <asm/unaligned.h> 44#include <asm/unaligned.h>
45#ifdef CONFIG_PPC_PS3
46#include <asm/firmware.h>
47#endif
45 48
46 49
47/*-------------------------------------------------------------------------*/ 50/*-------------------------------------------------------------------------*/
@@ -299,6 +302,19 @@ static void ehci_watchdog (unsigned long param)
299 spin_unlock_irqrestore (&ehci->lock, flags); 302 spin_unlock_irqrestore (&ehci->lock, flags);
300} 303}
301 304
305/* On some systems, leaving remote wakeup enabled prevents system shutdown.
306 * The firmware seems to think that powering off is a wakeup event!
307 * This routine turns off remote wakeup and everything else, on all ports.
308 */
309static void ehci_turn_off_all_ports(struct ehci_hcd *ehci)
310{
311 int port = HCS_N_PORTS(ehci->hcs_params);
312
313 while (port--)
314 ehci_writel(ehci, PORT_RWC_BITS,
315 &ehci->regs->port_status[port]);
316}
317
302/* ehci_shutdown kick in for silicon on any bus (not just pci, etc). 318/* ehci_shutdown kick in for silicon on any bus (not just pci, etc).
303 * This forcibly disables dma and IRQs, helping kexec and other cases 319 * This forcibly disables dma and IRQs, helping kexec and other cases
304 * where the next system software may expect clean state. 320 * where the next system software may expect clean state.
@@ -310,9 +326,13 @@ ehci_shutdown (struct usb_hcd *hcd)
310 326
311 ehci = hcd_to_ehci (hcd); 327 ehci = hcd_to_ehci (hcd);
312 (void) ehci_halt (ehci); 328 (void) ehci_halt (ehci);
329 ehci_turn_off_all_ports(ehci);
313 330
314 /* make BIOS/etc use companion controller during reboot */ 331 /* make BIOS/etc use companion controller during reboot */
315 ehci_writel(ehci, 0, &ehci->regs->configured_flag); 332 ehci_writel(ehci, 0, &ehci->regs->configured_flag);
333
334 /* unblock posted writes */
335 ehci_readl(ehci, &ehci->regs->configured_flag);
316} 336}
317 337
318static void ehci_port_power (struct ehci_hcd *ehci, int is_on) 338static void ehci_port_power (struct ehci_hcd *ehci, int is_on)
@@ -951,15 +971,18 @@ static int __init ehci_hcd_init(void)
951#endif 971#endif
952 972
953#ifdef PS3_SYSTEM_BUS_DRIVER 973#ifdef PS3_SYSTEM_BUS_DRIVER
954 retval = ps3_system_bus_driver_register(&PS3_SYSTEM_BUS_DRIVER); 974 if (firmware_has_feature(FW_FEATURE_PS3_LV1)) {
955 if (retval < 0) { 975 retval = ps3_system_bus_driver_register(
976 &PS3_SYSTEM_BUS_DRIVER);
977 if (retval < 0) {
956#ifdef PLATFORM_DRIVER 978#ifdef PLATFORM_DRIVER
957 platform_driver_unregister(&PLATFORM_DRIVER); 979 platform_driver_unregister(&PLATFORM_DRIVER);
958#endif 980#endif
959#ifdef PCI_DRIVER 981#ifdef PCI_DRIVER
960 pci_unregister_driver(&PCI_DRIVER); 982 pci_unregister_driver(&PCI_DRIVER);
961#endif 983#endif
962 return retval; 984 return retval;
985 }
963 } 986 }
964#endif 987#endif
965 988
@@ -976,7 +999,8 @@ static void __exit ehci_hcd_cleanup(void)
976 pci_unregister_driver(&PCI_DRIVER); 999 pci_unregister_driver(&PCI_DRIVER);
977#endif 1000#endif
978#ifdef PS3_SYSTEM_BUS_DRIVER 1001#ifdef PS3_SYSTEM_BUS_DRIVER
979 ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); 1002 if (firmware_has_feature(FW_FEATURE_PS3_LV1))
1003 ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
980#endif 1004#endif
981} 1005}
982module_exit(ehci_hcd_cleanup); 1006module_exit(ehci_hcd_cleanup);
diff --git a/drivers/usb/host/ehci-hub.c b/drivers/usb/host/ehci-hub.c
index 0d83c6df1a3b..9af529d22b3e 100644
--- a/drivers/usb/host/ehci-hub.c
+++ b/drivers/usb/host/ehci-hub.c
@@ -36,6 +36,8 @@ static int ehci_bus_suspend (struct usb_hcd *hcd)
36 int port; 36 int port;
37 int mask; 37 int mask;
38 38
39 ehci_dbg(ehci, "suspend root hub\n");
40
39 if (time_before (jiffies, ehci->next_statechange)) 41 if (time_before (jiffies, ehci->next_statechange))
40 msleep(5); 42 msleep(5);
41 43
diff --git a/drivers/usb/host/isp116x-hcd.c b/drivers/usb/host/isp116x-hcd.c
index 2718b5dc4ec1..46873f2534b5 100644
--- a/drivers/usb/host/isp116x-hcd.c
+++ b/drivers/usb/host/isp116x-hcd.c
@@ -1577,7 +1577,7 @@ static int isp116x_remove(struct platform_device *pdev)
1577 1577
1578#define resource_len(r) (((r)->end - (r)->start) + 1) 1578#define resource_len(r) (((r)->end - (r)->start) + 1)
1579 1579
1580static int __init isp116x_probe(struct platform_device *pdev) 1580static int __devinit isp116x_probe(struct platform_device *pdev)
1581{ 1581{
1582 struct usb_hcd *hcd; 1582 struct usb_hcd *hcd;
1583 struct isp116x *isp116x; 1583 struct isp116x *isp116x;
diff --git a/drivers/usb/host/ohci-at91.c b/drivers/usb/host/ohci-at91.c
index 930346487278..d849c809acbd 100644
--- a/drivers/usb/host/ohci-at91.c
+++ b/drivers/usb/host/ohci-at91.c
@@ -18,19 +18,38 @@
18#include <asm/mach-types.h> 18#include <asm/mach-types.h>
19#include <asm/hardware.h> 19#include <asm/hardware.h>
20#include <asm/arch/board.h> 20#include <asm/arch/board.h>
21#include <asm/arch/cpu.h>
21 22
22#ifndef CONFIG_ARCH_AT91 23#ifndef CONFIG_ARCH_AT91
23#error "CONFIG_ARCH_AT91 must be defined." 24#error "CONFIG_ARCH_AT91 must be defined."
24#endif 25#endif
25 26
26/* interface and function clocks */ 27/* interface and function clocks; sometimes also an AHB clock */
27static struct clk *iclk, *fclk; 28static struct clk *iclk, *fclk, *hclk;
28static int clocked; 29static int clocked;
29 30
30extern int usb_disabled(void); 31extern int usb_disabled(void);
31 32
32/*-------------------------------------------------------------------------*/ 33/*-------------------------------------------------------------------------*/
33 34
35static void at91_start_clock(void)
36{
37 if (cpu_is_at91sam9261())
38 clk_enable(hclk);
39 clk_enable(iclk);
40 clk_enable(fclk);
41 clocked = 1;
42}
43
44static void at91_stop_clock(void)
45{
46 clk_disable(fclk);
47 clk_disable(iclk);
48 if (cpu_is_at91sam9261())
49 clk_disable(hclk);
50 clocked = 0;
51}
52
34static void at91_start_hc(struct platform_device *pdev) 53static void at91_start_hc(struct platform_device *pdev)
35{ 54{
36 struct usb_hcd *hcd = platform_get_drvdata(pdev); 55 struct usb_hcd *hcd = platform_get_drvdata(pdev);
@@ -41,9 +60,7 @@ static void at91_start_hc(struct platform_device *pdev)
41 /* 60 /*
42 * Start the USB clocks. 61 * Start the USB clocks.
43 */ 62 */
44 clk_enable(iclk); 63 at91_start_clock();
45 clk_enable(fclk);
46 clocked = 1;
47 64
48 /* 65 /*
49 * The USB host controller must remain in reset. 66 * The USB host controller must remain in reset.
@@ -66,9 +83,7 @@ static void at91_stop_hc(struct platform_device *pdev)
66 /* 83 /*
67 * Stop the USB clocks. 84 * Stop the USB clocks.
68 */ 85 */
69 clk_disable(fclk); 86 at91_stop_clock();
70 clk_disable(iclk);
71 clocked = 0;
72} 87}
73 88
74 89
@@ -126,6 +141,8 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
126 141
127 iclk = clk_get(&pdev->dev, "ohci_clk"); 142 iclk = clk_get(&pdev->dev, "ohci_clk");
128 fclk = clk_get(&pdev->dev, "uhpck"); 143 fclk = clk_get(&pdev->dev, "uhpck");
144 if (cpu_is_at91sam9261())
145 hclk = clk_get(&pdev->dev, "hck0");
129 146
130 at91_start_hc(pdev); 147 at91_start_hc(pdev);
131 ohci_hcd_init(hcd_to_ohci(hcd)); 148 ohci_hcd_init(hcd_to_ohci(hcd));
@@ -137,6 +154,8 @@ static int usb_hcd_at91_probe(const struct hc_driver *driver,
137 /* Error handling */ 154 /* Error handling */
138 at91_stop_hc(pdev); 155 at91_stop_hc(pdev);
139 156
157 if (cpu_is_at91sam9261())
158 clk_put(hclk);
140 clk_put(fclk); 159 clk_put(fclk);
141 clk_put(iclk); 160 clk_put(iclk);
142 161
@@ -171,9 +190,11 @@ static int usb_hcd_at91_remove(struct usb_hcd *hcd,
171 iounmap(hcd->regs); 190 iounmap(hcd->regs);
172 release_mem_region(hcd->rsrc_start, hcd->rsrc_len); 191 release_mem_region(hcd->rsrc_start, hcd->rsrc_len);
173 192
193 if (cpu_is_at91sam9261())
194 clk_put(hclk);
174 clk_put(fclk); 195 clk_put(fclk);
175 clk_put(iclk); 196 clk_put(iclk);
176 fclk = iclk = NULL; 197 fclk = iclk = hclk = NULL;
177 198
178 dev_set_drvdata(&pdev->dev, NULL); 199 dev_set_drvdata(&pdev->dev, NULL);
179 return 0; 200 return 0;
@@ -280,9 +301,7 @@ ohci_hcd_at91_drv_suspend(struct platform_device *pdev, pm_message_t mesg)
280 */ 301 */
281 if (at91_suspend_entering_slow_clock()) { 302 if (at91_suspend_entering_slow_clock()) {
282 ohci_usb_reset (ohci); 303 ohci_usb_reset (ohci);
283 clk_disable(fclk); 304 at91_stop_clock();
284 clk_disable(iclk);
285 clocked = 0;
286 } 305 }
287 306
288 return 0; 307 return 0;
@@ -295,11 +314,8 @@ static int ohci_hcd_at91_drv_resume(struct platform_device *pdev)
295 if (device_may_wakeup(&pdev->dev)) 314 if (device_may_wakeup(&pdev->dev))
296 disable_irq_wake(hcd->irq); 315 disable_irq_wake(hcd->irq);
297 316
298 if (!clocked) { 317 if (!clocked)
299 clk_enable(iclk); 318 at91_start_clock();
300 clk_enable(fclk);
301 clocked = 1;
302 }
303 319
304 return 0; 320 return 0;
305} 321}
diff --git a/drivers/usb/host/ohci-hcd.c b/drivers/usb/host/ohci-hcd.c
index fa6a7ceaa0db..f0d29eda3c6d 100644
--- a/drivers/usb/host/ohci-hcd.c
+++ b/drivers/usb/host/ohci-hcd.c
@@ -42,6 +42,9 @@
42#include <asm/system.h> 42#include <asm/system.h>
43#include <asm/unaligned.h> 43#include <asm/unaligned.h>
44#include <asm/byteorder.h> 44#include <asm/byteorder.h>
45#ifdef CONFIG_PPC_PS3
46#include <asm/firmware.h>
47#endif
45 48
46#include "../core/hcd.h" 49#include "../core/hcd.h"
47 50
@@ -944,9 +947,12 @@ static int __init ohci_hcd_mod_init(void)
944 sizeof (struct ed), sizeof (struct td)); 947 sizeof (struct ed), sizeof (struct td));
945 948
946#ifdef PS3_SYSTEM_BUS_DRIVER 949#ifdef PS3_SYSTEM_BUS_DRIVER
947 retval = ps3_system_bus_driver_register(&PS3_SYSTEM_BUS_DRIVER); 950 if (firmware_has_feature(FW_FEATURE_PS3_LV1)) {
948 if (retval < 0) 951 retval = ps3_system_bus_driver_register(
949 goto error_ps3; 952 &PS3_SYSTEM_BUS_DRIVER);
953 if (retval < 0)
954 goto error_ps3;
955 }
950#endif 956#endif
951 957
952#ifdef PLATFORM_DRIVER 958#ifdef PLATFORM_DRIVER
@@ -992,7 +998,8 @@ static int __init ohci_hcd_mod_init(void)
992 error_platform: 998 error_platform:
993#endif 999#endif
994#ifdef PS3_SYSTEM_BUS_DRIVER 1000#ifdef PS3_SYSTEM_BUS_DRIVER
995 ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); 1001 if (firmware_has_feature(FW_FEATURE_PS3_LV1))
1002 ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
996 error_ps3: 1003 error_ps3:
997#endif 1004#endif
998 return retval; 1005 return retval;
@@ -1014,7 +1021,8 @@ static void __exit ohci_hcd_mod_exit(void)
1014 platform_driver_unregister(&PLATFORM_DRIVER); 1021 platform_driver_unregister(&PLATFORM_DRIVER);
1015#endif 1022#endif
1016#ifdef PS3_SYSTEM_BUS_DRIVER 1023#ifdef PS3_SYSTEM_BUS_DRIVER
1017 ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER); 1024 if (firmware_has_feature(FW_FEATURE_PS3_LV1))
1025 ps3_system_bus_driver_unregister(&PS3_SYSTEM_BUS_DRIVER);
1018#endif 1026#endif
1019} 1027}
1020module_exit(ohci_hcd_mod_exit); 1028module_exit(ohci_hcd_mod_exit);
diff --git a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
index 4d8ed3d71a15..ef09952f2039 100644
--- a/drivers/usb/input/hid-core.c
+++ b/drivers/usb/input/hid-core.c
@@ -515,6 +515,7 @@ void usbhid_close(struct hid_device *hid)
515 515
516#define USB_VENDOR_ID_TURBOX 0x062a 516#define USB_VENDOR_ID_TURBOX 0x062a
517#define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201 517#define USB_DEVICE_ID_TURBOX_KEYBOARD 0x0201
518#define USB_VENDOR_ID_CIDC 0x1677
518 519
519/* 520/*
520 * Initialize all reports 521 * Initialize all reports
@@ -548,7 +549,6 @@ void usbhid_init_reports(struct hid_device *hid)
548} 549}
549 550
550#define USB_VENDOR_ID_GTCO 0x078c 551#define USB_VENDOR_ID_GTCO 0x078c
551#define USB_VENDOR_ID_GTCO_IPANEL_2 0x5543
552#define USB_DEVICE_ID_GTCO_90 0x0090 552#define USB_DEVICE_ID_GTCO_90 0x0090
553#define USB_DEVICE_ID_GTCO_100 0x0100 553#define USB_DEVICE_ID_GTCO_100 0x0100
554#define USB_DEVICE_ID_GTCO_101 0x0101 554#define USB_DEVICE_ID_GTCO_101 0x0101
@@ -594,8 +594,6 @@ void usbhid_init_reports(struct hid_device *hid)
594#define USB_DEVICE_ID_GTCO_1004 0x1004 594#define USB_DEVICE_ID_GTCO_1004 0x1004
595#define USB_DEVICE_ID_GTCO_1005 0x1005 595#define USB_DEVICE_ID_GTCO_1005 0x1005
596#define USB_DEVICE_ID_GTCO_1006 0x1006 596#define USB_DEVICE_ID_GTCO_1006 0x1006
597#define USB_DEVICE_ID_GTCO_8 0x0008
598#define USB_DEVICE_ID_GTCO_d 0x000d
599 597
600#define USB_VENDOR_ID_WACOM 0x056a 598#define USB_VENDOR_ID_WACOM 0x056a
601 599
@@ -854,8 +852,6 @@ static const struct hid_blacklist {
854 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1004, HID_QUIRK_IGNORE }, 852 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1004, HID_QUIRK_IGNORE },
855 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1005, HID_QUIRK_IGNORE }, 853 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1005, HID_QUIRK_IGNORE },
856 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006, HID_QUIRK_IGNORE }, 854 { USB_VENDOR_ID_GTCO, USB_DEVICE_ID_GTCO_1006, HID_QUIRK_IGNORE },
857 { USB_VENDOR_ID_GTCO_IPANEL_2, USB_DEVICE_ID_GTCO_8, HID_QUIRK_IGNORE },
858 { USB_VENDOR_ID_GTCO_IPANEL_2, USB_DEVICE_ID_GTCO_d, HID_QUIRK_IGNORE },
859 { USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA, HID_QUIRK_IGNORE }, 855 { USB_VENDOR_ID_IMATION, USB_DEVICE_ID_DISC_STAKKA, HID_QUIRK_IGNORE },
860 { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE }, 856 { USB_VENDOR_ID_KBGEAR, USB_DEVICE_ID_KBGEAR_JAMSTUDIO, HID_QUIRK_IGNORE },
861 { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY, HID_QUIRK_IGNORE }, 857 { USB_VENDOR_ID_LD, USB_DEVICE_ID_LD_CASSY, HID_QUIRK_IGNORE },
@@ -953,6 +949,8 @@ static const struct hid_blacklist {
953 949
954 { USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER, HID_QUIRK_SONY_PS3_CONTROLLER }, 950 { USB_VENDOR_ID_SONY, USB_DEVICE_ID_SONY_PS3_CONTROLLER, HID_QUIRK_SONY_PS3_CONTROLLER },
955 951
952 { USB_VENDOR_ID_CIDC, 0x0103, HID_QUIRK_IGNORE },
953
956 { 0, 0 } 954 { 0, 0 }
957}; 955};
958 956
diff --git a/drivers/usb/misc/Kconfig b/drivers/usb/misc/Kconfig
index a74bf8617e7f..4907e8b80070 100644
--- a/drivers/usb/misc/Kconfig
+++ b/drivers/usb/misc/Kconfig
@@ -88,6 +88,17 @@ config USB_LCD
88 To compile this driver as a module, choose M here: the 88 To compile this driver as a module, choose M here: the
89 module will be called usblcd. 89 module will be called usblcd.
90 90
91config USB_BERRY_CHARGE
92 tristate "USB BlackBerry recharge support"
93 depends on USB
94 help
95 Say Y here if you want to connect a BlackBerry device to your
96 computer's USB port and have it automatically switch to "recharge"
97 mode.
98
99 To compile this driver as a module, choose M here: the
100 module will be called berry_charge.
101
91config USB_LED 102config USB_LED
92 tristate "USB LED driver support" 103 tristate "USB LED driver support"
93 depends on USB 104 depends on USB
diff --git a/drivers/usb/misc/Makefile b/drivers/usb/misc/Makefile
index 2cba07d31971..dac2d5b71566 100644
--- a/drivers/usb/misc/Makefile
+++ b/drivers/usb/misc/Makefile
@@ -6,6 +6,7 @@
6obj-$(CONFIG_USB_ADUTUX) += adutux.o 6obj-$(CONFIG_USB_ADUTUX) += adutux.o
7obj-$(CONFIG_USB_APPLEDISPLAY) += appledisplay.o 7obj-$(CONFIG_USB_APPLEDISPLAY) += appledisplay.o
8obj-$(CONFIG_USB_AUERSWALD) += auerswald.o 8obj-$(CONFIG_USB_AUERSWALD) += auerswald.o
9obj-$(CONFIG_USB_BERRY_CHARGE) += berry_charge.o
9obj-$(CONFIG_USB_CYPRESS_CY7C63)+= cypress_cy7c63.o 10obj-$(CONFIG_USB_CYPRESS_CY7C63)+= cypress_cy7c63.o
10obj-$(CONFIG_USB_CYTHERM) += cytherm.o 11obj-$(CONFIG_USB_CYTHERM) += cytherm.o
11obj-$(CONFIG_USB_EMI26) += emi26.o 12obj-$(CONFIG_USB_EMI26) += emi26.o
diff --git a/drivers/usb/misc/appledisplay.c b/drivers/usb/misc/appledisplay.c
index 32f0e3a5b022..e573c8ba9785 100644
--- a/drivers/usb/misc/appledisplay.c
+++ b/drivers/usb/misc/appledisplay.c
@@ -281,8 +281,8 @@ static int appledisplay_probe(struct usb_interface *iface,
281 /* Register backlight device */ 281 /* Register backlight device */
282 snprintf(bl_name, sizeof(bl_name), "appledisplay%d", 282 snprintf(bl_name, sizeof(bl_name), "appledisplay%d",
283 atomic_inc_return(&count_displays) - 1); 283 atomic_inc_return(&count_displays) - 1);
284 pdata->bd = backlight_device_register(bl_name, NULL, 284 pdata->bd = backlight_device_register(bl_name, NULL, pdata,
285 pdata, &appledisplay_bl_data); 285 &appledisplay_bl_data);
286 if (IS_ERR(pdata->bd)) { 286 if (IS_ERR(pdata->bd)) {
287 err("appledisplay: Backlight registration failed"); 287 err("appledisplay: Backlight registration failed");
288 goto error; 288 goto error;
diff --git a/drivers/usb/misc/berry_charge.c b/drivers/usb/misc/berry_charge.c
new file mode 100644
index 000000000000..60893c6c8221
--- /dev/null
+++ b/drivers/usb/misc/berry_charge.c
@@ -0,0 +1,140 @@
1/*
2 * USB BlackBerry charging module
3 *
4 * Copyright (C) 2007 Greg Kroah-Hartman <gregkh@suse.de>
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 as
8 * published by the Free Software Foundation, version 2.
9 *
10 * Information on how to switch configs was taken by the bcharge.cc file
11 * created by the barry.sf.net project.
12 *
13 * bcharge.cc has the following copyright:
14 * Copyright (C) 2006, Net Direct Inc. (http://www.netdirect.ca/)
15 * and is released under the GPLv2.
16 *
17 *
18 */
19
20#include <linux/kernel.h>
21#include <linux/errno.h>
22#include <linux/init.h>
23#include <linux/slab.h>
24#include <linux/module.h>
25#include <linux/usb.h>
26
27#define RIM_VENDOR 0x0fca
28#define BLACKBERRY 0x0001
29
30static int debug;
31
32#ifdef dbg
33#undef dbg
34#endif
35#define dbg(dev, format, arg...) \
36 if (debug) \
37 dev_printk(KERN_DEBUG , dev , format , ## arg)
38
39static struct usb_device_id id_table [] = {
40 { USB_DEVICE(RIM_VENDOR, BLACKBERRY) },
41 { }, /* Terminating entry */
42};
43MODULE_DEVICE_TABLE(usb, id_table);
44
45static int magic_charge(struct usb_device *udev)
46{
47 char *dummy_buffer = kzalloc(2, GFP_KERNEL);
48 int retval;
49
50 if (!dummy_buffer)
51 return -ENOMEM;
52
53 /* send two magic commands and then set the configuration. The device
54 * will then reset itself with the new power usage and should start
55 * charging. */
56
57 /* Note, with testing, it only seems that the first message is really
58 * needed (at least for the 8700c), but to be safe, we emulate what
59 * other operating systems seem to be sending to their device. We
60 * really need to get some specs for this device to be sure about what
61 * is going on here.
62 */
63 dbg(&udev->dev, "Sending first magic command\n");
64 retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
65 0xa5, 0xc0, 0, 1, dummy_buffer, 2, 100);
66 if (retval != 2) {
67 dev_err(&udev->dev, "First magic command failed: %d.\n",
68 retval);
69 return retval;
70 }
71
72 dbg(&udev->dev, "Sending first magic command\n");
73 retval = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
74 0xa2, 0x40, 0, 1, dummy_buffer, 0, 100);
75 if (retval != 0) {
76 dev_err(&udev->dev, "Second magic command failed: %d.\n",
77 retval);
78 return retval;
79 }
80
81 dbg(&udev->dev, "Calling set_configuration\n");
82 retval = usb_driver_set_configuration(udev, 1);
83 if (retval)
84 dev_err(&udev->dev, "Set Configuration failed :%d.\n", retval);
85
86 return retval;
87}
88
89static int berry_probe(struct usb_interface *intf,
90 const struct usb_device_id *id)
91{
92 struct usb_device *udev = interface_to_usbdev(intf);
93
94 dbg(&udev->dev, "Power is set to %dmA\n",
95 udev->actconfig->desc.bMaxPower * 2);
96
97 /* check the power usage so we don't try to enable something that is
98 * already enabled */
99 if ((udev->actconfig->desc.bMaxPower * 2) == 500) {
100 dbg(&udev->dev, "device is already charging, power is "
101 "set to %dmA\n", udev->actconfig->desc.bMaxPower * 2);
102 return -ENODEV;
103 }
104
105 /* turn the power on */
106 magic_charge(udev);
107
108 /* we don't really want to bind to the device, userspace programs can
109 * handle the syncing just fine, so get outta here. */
110 return -ENODEV;
111}
112
113static void berry_disconnect(struct usb_interface *intf)
114{
115}
116
117static struct usb_driver berry_driver = {
118 .name = "berry_charge",
119 .probe = berry_probe,
120 .disconnect = berry_disconnect,
121 .id_table = id_table,
122};
123
124static int __init berry_init(void)
125{
126 return usb_register(&berry_driver);
127}
128
129static void __exit berry_exit(void)
130{
131 usb_deregister(&berry_driver);
132}
133
134module_init(berry_init);
135module_exit(berry_exit);
136
137MODULE_LICENSE("GPL");
138MODULE_AUTHOR("Greg Kroah-Hartman <gregkh@suse.de>");
139module_param(debug, bool, S_IRUGO | S_IWUSR);
140MODULE_PARM_DESC(debug, "Debug enabled or not");
diff --git a/drivers/usb/net/Kconfig b/drivers/usb/net/Kconfig
index a2b94ef512bc..0f3d7dbb537f 100644
--- a/drivers/usb/net/Kconfig
+++ b/drivers/usb/net/Kconfig
@@ -84,6 +84,7 @@ config USB_PEGASUS
84config USB_RTL8150 84config USB_RTL8150
85 tristate "USB RTL8150 based ethernet device support (EXPERIMENTAL)" 85 tristate "USB RTL8150 based ethernet device support (EXPERIMENTAL)"
86 depends on EXPERIMENTAL 86 depends on EXPERIMENTAL
87 select MII
87 help 88 help
88 Say Y here if you have RTL8150 based usb-ethernet adapter. 89 Say Y here if you have RTL8150 based usb-ethernet adapter.
89 Send me <petkan@users.sourceforge.net> any comments you may have. 90 Send me <petkan@users.sourceforge.net> any comments you may have.
@@ -98,7 +99,7 @@ config USB_USBNET_MII
98 99
99config USB_USBNET 100config USB_USBNET
100 tristate "Multi-purpose USB Networking Framework" 101 tristate "Multi-purpose USB Networking Framework"
101 select MII if USBNET_MII != n 102 select MII if USB_USBNET_MII != n
102 ---help--- 103 ---help---
103 This driver supports several kinds of network links over USB, 104 This driver supports several kinds of network links over USB,
104 with "minidrivers" built around a common network driver core 105 with "minidrivers" built around a common network driver core
@@ -239,6 +240,7 @@ config USB_NET_RNDIS_HOST
239config USB_NET_CDC_SUBSET 240config USB_NET_CDC_SUBSET
240 tristate "Simple USB Network Links (CDC Ethernet subset)" 241 tristate "Simple USB Network Links (CDC Ethernet subset)"
241 depends on USB_USBNET 242 depends on USB_USBNET
243 default y
242 help 244 help
243 This driver module supports USB network devices that can work 245 This driver module supports USB network devices that can work
244 without any device-specific information. Select it if you have 246 without any device-specific information. Select it if you have
@@ -298,6 +300,13 @@ config USB_EPSON2888
298 Choose this option to support the usb networking links used 300 Choose this option to support the usb networking links used
299 by some sample firmware from Epson. 301 by some sample firmware from Epson.
300 302
303config USB_KC2190
304 boolean "KT Technology KC2190 based cables (InstaNet)"
305 depends on USB_NET_CDC_SUBSET && EXPERIMENTAL
306 help
307  Choose this option if you're using a host-to-host cable
308  with one of these chips.
309
301config USB_NET_ZAURUS 310config USB_NET_ZAURUS
302 tristate "Sharp Zaurus (stock ROMs) and compatible" 311 tristate "Sharp Zaurus (stock ROMs) and compatible"
303 depends on USB_USBNET 312 depends on USB_USBNET
diff --git a/drivers/usb/net/asix.c b/drivers/usb/net/asix.c
index bd357e178e55..7ef2e4b5e39b 100644
--- a/drivers/usb/net/asix.c
+++ b/drivers/usb/net/asix.c
@@ -351,9 +351,11 @@ static struct sk_buff *asix_tx_fixup(struct usbnet *dev, struct sk_buff *skb,
351 351
352 skb_push(skb, 4); 352 skb_push(skb, 4);
353 packet_len = (((skb->len - 4) ^ 0x0000ffff) << 16) + (skb->len - 4); 353 packet_len = (((skb->len - 4) ^ 0x0000ffff) << 16) + (skb->len - 4);
354 cpu_to_le32s(&packet_len);
354 memcpy(skb->data, &packet_len, sizeof(packet_len)); 355 memcpy(skb->data, &packet_len, sizeof(packet_len));
355 356
356 if ((skb->len % 512) == 0) { 357 if ((skb->len % 512) == 0) {
358 cpu_to_le32s(&padbytes);
357 memcpy( skb->tail, &padbytes, sizeof(padbytes)); 359 memcpy( skb->tail, &padbytes, sizeof(padbytes));
358 skb_put(skb, sizeof(padbytes)); 360 skb_put(skb, sizeof(padbytes));
359 } 361 }
diff --git a/drivers/usb/net/cdc_subset.c b/drivers/usb/net/cdc_subset.c
index ae8fb06cf38e..bc62b012602b 100644
--- a/drivers/usb/net/cdc_subset.c
+++ b/drivers/usb/net/cdc_subset.c
@@ -79,13 +79,19 @@ static int always_connected (struct usbnet *dev)
79 * 79 *
80 * ALi M5632 driver ... does high speed 80 * ALi M5632 driver ... does high speed
81 * 81 *
82 * NOTE that the MS-Windows drivers for this chip use some funky and
83 * (naturally) undocumented 7-byte prefix to each packet, so this is a
84 * case where we don't currently interoperate. Also, once you unplug
85 * one end of the cable, you need to replug the other end too ... since
86 * chip docs are unavailable, there's no way to reset the relevant state
87 * short of a power cycle.
88 *
82 *-------------------------------------------------------------------------*/ 89 *-------------------------------------------------------------------------*/
83 90
84static const struct driver_info ali_m5632_info = { 91static const struct driver_info ali_m5632_info = {
85 .description = "ALi M5632", 92 .description = "ALi M5632",
86}; 93};
87 94
88
89#endif 95#endif
90 96
91 97
@@ -159,6 +165,11 @@ static const struct driver_info epson2888_info = {
159#endif /* CONFIG_USB_EPSON2888 */ 165#endif /* CONFIG_USB_EPSON2888 */
160 166
161 167
168/*-------------------------------------------------------------------------
169 *
170 * info from Jonathan McDowell <noodles@earth.li>
171 *
172 *-------------------------------------------------------------------------*/
162#ifdef CONFIG_USB_KC2190 173#ifdef CONFIG_USB_KC2190
163#define HAVE_HARDWARE 174#define HAVE_HARDWARE
164static const struct driver_info kc2190_info = { 175static const struct driver_info kc2190_info = {
@@ -223,6 +234,10 @@ static const struct usb_device_id products [] = {
223 USB_DEVICE (0x0402, 0x5632), // ALi defaults 234 USB_DEVICE (0x0402, 0x5632), // ALi defaults
224 .driver_info = (unsigned long) &ali_m5632_info, 235 .driver_info = (unsigned long) &ali_m5632_info,
225}, 236},
237{
238 USB_DEVICE (0x182d,0x207c), // SiteCom CN-124
239 .driver_info = (unsigned long) &ali_m5632_info,
240},
226#endif 241#endif
227 242
228#ifdef CONFIG_USB_AN2720 243#ifdef CONFIG_USB_AN2720
@@ -314,13 +329,13 @@ static struct usb_driver cdc_subset_driver = {
314 329
315static int __init cdc_subset_init(void) 330static int __init cdc_subset_init(void)
316{ 331{
317 return usb_register(&cdc_subset_driver); 332 return usb_register(&cdc_subset_driver);
318} 333}
319module_init(cdc_subset_init); 334module_init(cdc_subset_init);
320 335
321static void __exit cdc_subset_exit(void) 336static void __exit cdc_subset_exit(void)
322{ 337{
323 usb_deregister(&cdc_subset_driver); 338 usb_deregister(&cdc_subset_driver);
324} 339}
325module_exit(cdc_subset_exit); 340module_exit(cdc_subset_exit);
326 341
diff --git a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
index 43ba61abfcc5..de69b183bd2f 100644
--- a/drivers/usb/net/usbnet.c
+++ b/drivers/usb/net/usbnet.c
@@ -147,7 +147,7 @@ int usbnet_get_endpoints(struct usbnet *dev, struct usb_interface *intf)
147 if (tmp < 0) 147 if (tmp < 0)
148 return tmp; 148 return tmp;
149 } 149 }
150 150
151 dev->in = usb_rcvbulkpipe (dev->udev, 151 dev->in = usb_rcvbulkpipe (dev->udev,
152 in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK); 152 in->desc.bEndpointAddress & USB_ENDPOINT_NUMBER_MASK);
153 dev->out = usb_sndbulkpipe (dev->udev, 153 dev->out = usb_sndbulkpipe (dev->udev,
@@ -327,7 +327,7 @@ static void rx_submit (struct usbnet *dev, struct urb *urb, gfp_t flags)
327 if (netif_running (dev->net) 327 if (netif_running (dev->net)
328 && netif_device_present (dev->net) 328 && netif_device_present (dev->net)
329 && !test_bit (EVENT_RX_HALT, &dev->flags)) { 329 && !test_bit (EVENT_RX_HALT, &dev->flags)) {
330 switch (retval = usb_submit_urb (urb, GFP_ATOMIC)){ 330 switch (retval = usb_submit_urb (urb, GFP_ATOMIC)){
331 case -EPIPE: 331 case -EPIPE:
332 usbnet_defer_kevent (dev, EVENT_RX_HALT); 332 usbnet_defer_kevent (dev, EVENT_RX_HALT);
333 break; 333 break;
@@ -443,7 +443,7 @@ block:
443 case -EOVERFLOW: 443 case -EOVERFLOW:
444 dev->stats.rx_over_errors++; 444 dev->stats.rx_over_errors++;
445 // FALLTHROUGH 445 // FALLTHROUGH
446 446
447 default: 447 default:
448 entry->state = rx_cleanup; 448 entry->state = rx_cleanup;
449 dev->stats.rx_errors++; 449 dev->stats.rx_errors++;
@@ -560,7 +560,7 @@ static int usbnet_stop (struct net_device *net)
560 560
561 if (netif_msg_ifdown (dev)) 561 if (netif_msg_ifdown (dev))
562 devinfo (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld", 562 devinfo (dev, "stop stats: rx/tx %ld/%ld, errs %ld/%ld",
563 dev->stats.rx_packets, dev->stats.tx_packets, 563 dev->stats.rx_packets, dev->stats.tx_packets,
564 dev->stats.rx_errors, dev->stats.tx_errors 564 dev->stats.rx_errors, dev->stats.tx_errors
565 ); 565 );
566 566
@@ -578,7 +578,7 @@ static int usbnet_stop (struct net_device *net)
578 devdbg (dev, "waited for %d urb completions", temp); 578 devdbg (dev, "waited for %d urb completions", temp);
579 } 579 }
580 dev->wait = NULL; 580 dev->wait = NULL;
581 remove_wait_queue (&unlink_wakeup, &wait); 581 remove_wait_queue (&unlink_wakeup, &wait);
582 582
583 usb_kill_urb(dev->interrupt); 583 usb_kill_urb(dev->interrupt);
584 584
@@ -834,7 +834,7 @@ kevent (struct work_struct *work)
834 } 834 }
835 835
836 if (test_bit (EVENT_LINK_RESET, &dev->flags)) { 836 if (test_bit (EVENT_LINK_RESET, &dev->flags)) {
837 struct driver_info *info = dev->driver_info; 837 struct driver_info *info = dev->driver_info;
838 int retval = 0; 838 int retval = 0;
839 839
840 clear_bit (EVENT_LINK_RESET, &dev->flags); 840 clear_bit (EVENT_LINK_RESET, &dev->flags);
@@ -1066,7 +1066,7 @@ static void usbnet_bh (unsigned long param)
1066 * USB Device Driver support 1066 * USB Device Driver support
1067 * 1067 *
1068 *-------------------------------------------------------------------------*/ 1068 *-------------------------------------------------------------------------*/
1069 1069
1070// precondition: never called in_interrupt 1070// precondition: never called in_interrupt
1071 1071
1072void usbnet_disconnect (struct usb_interface *intf) 1072void usbnet_disconnect (struct usb_interface *intf)
@@ -1087,7 +1087,7 @@ void usbnet_disconnect (struct usb_interface *intf)
1087 intf->dev.driver->name, 1087 intf->dev.driver->name,
1088 xdev->bus->bus_name, xdev->devpath, 1088 xdev->bus->bus_name, xdev->devpath,
1089 dev->driver_info->description); 1089 dev->driver_info->description);
1090 1090
1091 net = dev->net; 1091 net = dev->net;
1092 unregister_netdev (net); 1092 unregister_netdev (net);
1093 1093
@@ -1111,7 +1111,7 @@ int
1111usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod) 1111usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
1112{ 1112{
1113 struct usbnet *dev; 1113 struct usbnet *dev;
1114 struct net_device *net; 1114 struct net_device *net;
1115 struct usb_host_interface *interface; 1115 struct usb_host_interface *interface;
1116 struct driver_info *info; 1116 struct driver_info *info;
1117 struct usb_device *xdev; 1117 struct usb_device *xdev;
@@ -1181,6 +1181,9 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
1181 // NOTE net->name still not usable ... 1181 // NOTE net->name still not usable ...
1182 if (info->bind) { 1182 if (info->bind) {
1183 status = info->bind (dev, udev); 1183 status = info->bind (dev, udev);
1184 if (status < 0)
1185 goto out1;
1186
1184 // heuristic: "usb%d" for links we know are two-host, 1187 // heuristic: "usb%d" for links we know are two-host,
1185 // else "eth%d" when there's reasonable doubt. userspace 1188 // else "eth%d" when there's reasonable doubt. userspace
1186 // can rename the link if it knows better. 1189 // can rename the link if it knows better.
@@ -1207,12 +1210,12 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)
1207 if (status == 0 && dev->status) 1210 if (status == 0 && dev->status)
1208 status = init_status (dev, udev); 1211 status = init_status (dev, udev);
1209 if (status < 0) 1212 if (status < 0)
1210 goto out1; 1213 goto out3;
1211 1214
1212 if (!dev->rx_urb_size) 1215 if (!dev->rx_urb_size)
1213 dev->rx_urb_size = dev->hard_mtu; 1216 dev->rx_urb_size = dev->hard_mtu;
1214 dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1); 1217 dev->maxpacket = usb_maxpacket (dev->udev, dev->out, 1);
1215 1218
1216 SET_NETDEV_DEV(net, &udev->dev); 1219 SET_NETDEV_DEV(net, &udev->dev);
1217 status = register_netdev (net); 1220 status = register_netdev (net);
1218 if (status) 1221 if (status)
@@ -1255,7 +1258,7 @@ EXPORT_SYMBOL_GPL(usbnet_probe);
1255int usbnet_suspend (struct usb_interface *intf, pm_message_t message) 1258int usbnet_suspend (struct usb_interface *intf, pm_message_t message)
1256{ 1259{
1257 struct usbnet *dev = usb_get_intfdata(intf); 1260 struct usbnet *dev = usb_get_intfdata(intf);
1258 1261
1259 /* accelerate emptying of the rx and queues, to avoid 1262 /* accelerate emptying of the rx and queues, to avoid
1260 * having everything error out. 1263 * having everything error out.
1261 */ 1264 */
@@ -1286,7 +1289,7 @@ static int __init usbnet_init(void)
1286 < sizeof (struct skb_data)); 1289 < sizeof (struct skb_data));
1287 1290
1288 random_ether_addr(node_id); 1291 random_ether_addr(node_id);
1289 return 0; 1292 return 0;
1290} 1293}
1291module_init(usbnet_init); 1294module_init(usbnet_init);
1292 1295
diff --git a/drivers/usb/serial/airprime.c b/drivers/usb/serial/airprime.c
index 0af42e32fa0a..18816bf96a4d 100644
--- a/drivers/usb/serial/airprime.c
+++ b/drivers/usb/serial/airprime.c
@@ -58,11 +58,6 @@ static void airprime_read_bulk_callback(struct urb *urb)
58 if (urb->status) { 58 if (urb->status) {
59 dbg("%s - nonzero read bulk status received: %d", 59 dbg("%s - nonzero read bulk status received: %d",
60 __FUNCTION__, urb->status); 60 __FUNCTION__, urb->status);
61 /* something happened, so free up the memory for this urb */
62 if (urb->transfer_buffer) {
63 kfree (urb->transfer_buffer);
64 urb->transfer_buffer = NULL;
65 }
66 return; 61 return;
67 } 62 }
68 usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data); 63 usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
@@ -146,6 +141,8 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp)
146 airprime_read_bulk_callback, port); 141 airprime_read_bulk_callback, port);
147 result = usb_submit_urb(urb, GFP_KERNEL); 142 result = usb_submit_urb(urb, GFP_KERNEL);
148 if (result) { 143 if (result) {
144 usb_free_urb(urb);
145 kfree(buffer);
149 dev_err(&port->dev, 146 dev_err(&port->dev,
150 "%s - failed submitting read urb %d for port %d, error %d\n", 147 "%s - failed submitting read urb %d for port %d, error %d\n",
151 __FUNCTION__, i, port->number, result); 148 __FUNCTION__, i, port->number, result);
@@ -160,27 +157,12 @@ static int airprime_open(struct usb_serial_port *port, struct file *filp)
160 /* some error happened, cancel any submitted urbs and clean up anything that 157 /* some error happened, cancel any submitted urbs and clean up anything that
161 got allocated successfully */ 158 got allocated successfully */
162 159
163 for ( ; i >= 0; --i) { 160 while (i-- != 0) {
164 urb = priv->read_urbp[i]; 161 urb = priv->read_urbp[i];
165 if (urb) { 162 buffer = urb->transfer_buffer;
166 /* This urb was submitted successfully. So we have to 163 usb_kill_urb (urb);
167 cancel it. 164 usb_free_urb (urb);
168 Unlinking the urb will invoke read_bulk_callback() 165 kfree (buffer);
169 with an error status, so its transfer buffer will
170 be freed there */
171 if (usb_unlink_urb (urb) != -EINPROGRESS) {
172 /* comments in drivers/usb/core/urb.c say this
173 can only happen if the urb was never submitted,
174 or has completed already.
175 Either way we may have to free the transfer
176 buffer here. */
177 if (urb->transfer_buffer) {
178 kfree (urb->transfer_buffer);
179 urb->transfer_buffer = NULL;
180 }
181 }
182 usb_free_urb (urb);
183 }
184 } 166 }
185 167
186 out: 168 out:
@@ -194,10 +176,9 @@ static void airprime_close(struct usb_serial_port *port, struct file * filp)
194 176
195 dbg("%s - port %d", __FUNCTION__, port->number); 177 dbg("%s - port %d", __FUNCTION__, port->number);
196 178
197 /* killing the urb will invoke read_bulk_callback() with an error status,
198 so the transfer buffer will be freed there */
199 for (i = 0; i < NUM_READ_URBS; ++i) { 179 for (i = 0; i < NUM_READ_URBS; ++i) {
200 usb_kill_urb (priv->read_urbp[i]); 180 usb_kill_urb (priv->read_urbp[i]);
181 kfree (priv->read_urbp[i]->transfer_buffer);
201 usb_free_urb (priv->read_urbp[i]); 182 usb_free_urb (priv->read_urbp[i]);
202 } 183 }
203 184
diff --git a/drivers/usb/serial/cp2101.c b/drivers/usb/serial/cp2101.c
index 3ec24870bca9..db623e754899 100644
--- a/drivers/usb/serial/cp2101.c
+++ b/drivers/usb/serial/cp2101.c
@@ -69,6 +69,7 @@ static struct usb_device_id id_table [] = {
69 { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */ 69 { USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
70 { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */ 70 { USB_DEVICE(0x10C4, 0xEA60) }, /* Silicon Labs factory default */
71 { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */ 71 { USB_DEVICE(0x10C4, 0xEA61) }, /* Silicon Labs factory default */
72 { USB_DEVICE(0x10C5, 0xEA61) }, /* Silicon Labs MobiData GPRS USB Modem */
72 { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */ 73 { USB_DEVICE(0x13AD, 0x9999) }, /* Baltech card reader */
73 { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */ 74 { USB_DEVICE(0x16D6, 0x0001) }, /* Jablotron serial interface */
74 { } /* Terminating Entry */ 75 { } /* Terminating Entry */
diff --git a/drivers/usb/serial/generic.c b/drivers/usb/serial/generic.c
index 601e0648dec6..53baeec8f265 100644
--- a/drivers/usb/serial/generic.c
+++ b/drivers/usb/serial/generic.c
@@ -66,6 +66,8 @@ struct usb_serial_driver usb_serial_generic_device = {
66 .num_bulk_out = NUM_DONT_CARE, 66 .num_bulk_out = NUM_DONT_CARE,
67 .num_ports = 1, 67 .num_ports = 1,
68 .shutdown = usb_serial_generic_shutdown, 68 .shutdown = usb_serial_generic_shutdown,
69 .throttle = usb_serial_generic_throttle,
70 .unthrottle = usb_serial_generic_unthrottle,
69}; 71};
70 72
71static int generic_probe(struct usb_interface *interface, 73static int generic_probe(struct usb_interface *interface,
@@ -115,6 +117,7 @@ int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp)
115{ 117{
116 struct usb_serial *serial = port->serial; 118 struct usb_serial *serial = port->serial;
117 int result = 0; 119 int result = 0;
120 unsigned long flags;
118 121
119 dbg("%s - port %d", __FUNCTION__, port->number); 122 dbg("%s - port %d", __FUNCTION__, port->number);
120 123
@@ -124,7 +127,13 @@ int usb_serial_generic_open (struct usb_serial_port *port, struct file *filp)
124 if (port->tty) 127 if (port->tty)
125 port->tty->low_latency = 1; 128 port->tty->low_latency = 1;
126 129
127 /* if we have a bulk interrupt, start reading from it */ 130 /* clear the throttle flags */
131 spin_lock_irqsave(&port->lock, flags);
132 port->throttled = 0;
133 port->throttle_req = 0;
134 spin_unlock_irqrestore(&port->lock, flags);
135
136 /* if we have a bulk endpoint, start reading from it */
128 if (serial->num_bulk_in) { 137 if (serial->num_bulk_in) {
129 /* Start reading from the device */ 138 /* Start reading from the device */
130 usb_fill_bulk_urb (port->read_urb, serial->dev, 139 usb_fill_bulk_urb (port->read_urb, serial->dev,
@@ -253,31 +262,22 @@ int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port)
253 return (chars); 262 return (chars);
254} 263}
255 264
256void usb_serial_generic_read_bulk_callback (struct urb *urb) 265/* Push data to tty layer and resubmit the bulk read URB */
266static void flush_and_resubmit_read_urb (struct usb_serial_port *port)
257{ 267{
258 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
259 struct usb_serial *serial = port->serial; 268 struct usb_serial *serial = port->serial;
260 struct tty_struct *tty; 269 struct urb *urb = port->read_urb;
261 unsigned char *data = urb->transfer_buffer; 270 struct tty_struct *tty = port->tty;
262 int result; 271 int result;
263 272
264 dbg("%s - port %d", __FUNCTION__, port->number); 273 /* Push data to tty */
265
266 if (urb->status) {
267 dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
268 return;
269 }
270
271 usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
272
273 tty = port->tty;
274 if (tty && urb->actual_length) { 274 if (tty && urb->actual_length) {
275 tty_buffer_request_room(tty, urb->actual_length); 275 tty_buffer_request_room(tty, urb->actual_length);
276 tty_insert_flip_string(tty, data, urb->actual_length); 276 tty_insert_flip_string(tty, urb->transfer_buffer, urb->actual_length);
277 tty_flip_buffer_push(tty); 277 tty_flip_buffer_push(tty); /* is this allowed from an URB callback ? */
278 } 278 }
279 279
280 /* Continue trying to always read */ 280 /* Continue reading from device */
281 usb_fill_bulk_urb (port->read_urb, serial->dev, 281 usb_fill_bulk_urb (port->read_urb, serial->dev,
282 usb_rcvbulkpipe (serial->dev, 282 usb_rcvbulkpipe (serial->dev,
283 port->bulk_in_endpointAddress), 283 port->bulk_in_endpointAddress),
@@ -290,6 +290,40 @@ void usb_serial_generic_read_bulk_callback (struct urb *urb)
290 if (result) 290 if (result)
291 dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result); 291 dev_err(&port->dev, "%s - failed resubmitting read urb, error %d\n", __FUNCTION__, result);
292} 292}
293
294void usb_serial_generic_read_bulk_callback (struct urb *urb)
295{
296 struct usb_serial_port *port = (struct usb_serial_port *)urb->context;
297 unsigned char *data = urb->transfer_buffer;
298 int is_throttled;
299 unsigned long flags;
300
301 dbg("%s - port %d", __FUNCTION__, port->number);
302
303 if (urb->status) {
304 dbg("%s - nonzero read bulk status received: %d", __FUNCTION__, urb->status);
305 return;
306 }
307
308 usb_serial_debug_data(debug, &port->dev, __FUNCTION__, urb->actual_length, data);
309
310 /* Throttle the device if requested by tty */
311 if (urb->actual_length) {
312 spin_lock_irqsave(&port->lock, flags);
313 is_throttled = port->throttled = port->throttle_req;
314 spin_unlock_irqrestore(&port->lock, flags);
315 if (is_throttled) {
316 /* Let the received data linger in the read URB;
317 * usb_serial_generic_unthrottle() will pick it
318 * up later. */
319 dbg("%s - throttling device", __FUNCTION__);
320 return;
321 }
322 }
323
324 /* Handle data and continue reading from device */
325 flush_and_resubmit_read_urb(port);
326}
293EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback); 327EXPORT_SYMBOL_GPL(usb_serial_generic_read_bulk_callback);
294 328
295void usb_serial_generic_write_bulk_callback (struct urb *urb) 329void usb_serial_generic_write_bulk_callback (struct urb *urb)
@@ -308,6 +342,38 @@ void usb_serial_generic_write_bulk_callback (struct urb *urb)
308} 342}
309EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback); 343EXPORT_SYMBOL_GPL(usb_serial_generic_write_bulk_callback);
310 344
345void usb_serial_generic_throttle (struct usb_serial_port *port)
346{
347 unsigned long flags;
348
349 dbg("%s - port %d", __FUNCTION__, port->number);
350
351 /* Set the throttle request flag. It will be picked up
352 * by usb_serial_generic_read_bulk_callback(). */
353 spin_lock_irqsave(&port->lock, flags);
354 port->throttle_req = 1;
355 spin_unlock_irqrestore(&port->lock, flags);
356}
357
358void usb_serial_generic_unthrottle (struct usb_serial_port *port)
359{
360 int was_throttled;
361 unsigned long flags;
362
363 dbg("%s - port %d", __FUNCTION__, port->number);
364
365 /* Clear the throttle flags */
366 spin_lock_irqsave(&port->lock, flags);
367 was_throttled = port->throttled;
368 port->throttled = port->throttle_req = 0;
369 spin_unlock_irqrestore(&port->lock, flags);
370
371 if (was_throttled) {
372 /* Handle pending data and resume reading from device */
373 flush_and_resubmit_read_urb(port);
374 }
375}
376
311void usb_serial_generic_shutdown (struct usb_serial *serial) 377void usb_serial_generic_shutdown (struct usb_serial *serial)
312{ 378{
313 int i; 379 int i;
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index ced9f32b29d9..9963a8b75840 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -69,7 +69,6 @@ static int option_send_setup(struct usb_serial_port *port);
69/* Vendor and product IDs */ 69/* Vendor and product IDs */
70#define OPTION_VENDOR_ID 0x0AF0 70#define OPTION_VENDOR_ID 0x0AF0
71#define HUAWEI_VENDOR_ID 0x12D1 71#define HUAWEI_VENDOR_ID 0x12D1
72#define AUDIOVOX_VENDOR_ID 0x0F3D
73#define NOVATELWIRELESS_VENDOR_ID 0x1410 72#define NOVATELWIRELESS_VENDOR_ID 0x1410
74#define ANYDATA_VENDOR_ID 0x16d5 73#define ANYDATA_VENDOR_ID 0x16d5
75 74
@@ -81,7 +80,6 @@ static int option_send_setup(struct usb_serial_port *port);
81#define OPTION_PRODUCT_GTMAX36 0x6701 80#define OPTION_PRODUCT_GTMAX36 0x6701
82#define HUAWEI_PRODUCT_E600 0x1001 81#define HUAWEI_PRODUCT_E600 0x1001
83#define HUAWEI_PRODUCT_E220 0x1003 82#define HUAWEI_PRODUCT_E220 0x1003
84#define AUDIOVOX_PRODUCT_AIRCARD 0x0112
85#define NOVATELWIRELESS_PRODUCT_U740 0x1400 83#define NOVATELWIRELESS_PRODUCT_U740 0x1400
86#define ANYDATA_PRODUCT_ID 0x6501 84#define ANYDATA_PRODUCT_ID 0x6501
87 85
@@ -94,7 +92,6 @@ static struct usb_device_id option_ids[] = {
94 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTMAX36) }, 92 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTMAX36) },
95 { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, 93 { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
96 { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) }, 94 { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) },
97 { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
98 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, 95 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
99 { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) }, 96 { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
100 { } /* Terminating entry */ 97 { } /* Terminating entry */
@@ -109,7 +106,6 @@ static struct usb_device_id option_ids1[] = {
109 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTMAX36) }, 106 { USB_DEVICE(OPTION_VENDOR_ID, OPTION_PRODUCT_GTMAX36) },
110 { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) }, 107 { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E600) },
111 { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) }, 108 { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_E220) },
112 { USB_DEVICE(AUDIOVOX_VENDOR_ID, AUDIOVOX_PRODUCT_AIRCARD) },
113 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) }, 109 { USB_DEVICE(NOVATELWIRELESS_VENDOR_ID,NOVATELWIRELESS_PRODUCT_U740) },
114 { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) }, 110 { USB_DEVICE(ANYDATA_VENDOR_ID, ANYDATA_PRODUCT_ID) },
115 { } /* Terminating entry */ 111 { } /* Terminating entry */
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 6c083d4e2c9b..83dfae93a45d 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -83,6 +83,7 @@ static struct usb_device_id id_table [] = {
83 { USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) }, 83 { USB_DEVICE(BELKIN_VENDOR_ID, BELKIN_PRODUCT_ID) },
84 { USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) }, 84 { USB_DEVICE(ALCOR_VENDOR_ID, ALCOR_PRODUCT_ID) },
85 { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ID) }, 85 { USB_DEVICE(HUAWEI_VENDOR_ID, HUAWEI_PRODUCT_ID) },
86 { USB_DEVICE(WS002IN_VENDOR_ID, WS002IN_PRODUCT_ID) },
86 { } /* Terminating entry */ 87 { } /* Terminating entry */
87}; 88};
88 89
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
index 65a5039665e7..f9a71d0c102e 100644
--- a/drivers/usb/serial/pl2303.h
+++ b/drivers/usb/serial/pl2303.h
@@ -97,3 +97,8 @@
97/* Huawei E620 UMTS/HSDPA card (ID: 12d1:1001) */ 97/* Huawei E620 UMTS/HSDPA card (ID: 12d1:1001) */
98#define HUAWEI_VENDOR_ID 0x12d1 98#define HUAWEI_VENDOR_ID 0x12d1
99#define HUAWEI_PRODUCT_ID 0x1001 99#define HUAWEI_PRODUCT_ID 0x1001
100
101/* Willcom WS002IN Data Driver (by NetIndex Inc.) */
102#define WS002IN_VENDOR_ID 0x11f6
103#define WS002IN_PRODUCT_ID 0x2001
104
diff --git a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
index 70234f5dbeeb..e227f64d5641 100644
--- a/drivers/usb/storage/scsiglue.c
+++ b/drivers/usb/storage/scsiglue.c
@@ -153,6 +153,12 @@ static int slave_configure(struct scsi_device *sdev)
153 if (us->flags & US_FL_FIX_CAPACITY) 153 if (us->flags & US_FL_FIX_CAPACITY)
154 sdev->fix_capacity = 1; 154 sdev->fix_capacity = 1;
155 155
156 /* A few disks have two indistinguishable version, one of
157 * which reports the correct capacity and the other does not.
158 * The sd driver has to guess which is the case. */
159 if (us->flags & US_FL_CAPACITY_HEURISTICS)
160 sdev->guess_capacity = 1;
161
156 /* Some devices report a SCSI revision level above 2 but are 162 /* Some devices report a SCSI revision level above 2 but are
157 * unable to handle the REPORT LUNS command (for which 163 * unable to handle the REPORT LUNS command (for which
158 * support is mandatory at level 3). Since we already have 164 * support is mandatory at level 3). Since we already have
diff --git a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
index f49a62fc32d2..9644a8ea4aa7 100644
--- a/drivers/usb/storage/unusual_devs.h
+++ b/drivers/usb/storage/unusual_devs.h
@@ -1101,6 +1101,15 @@ UNUSUAL_DEV( 0x08bd, 0x1100, 0x0000, 0x0000,
1101 US_SC_DEVICE, US_PR_DEVICE, NULL, 1101 US_SC_DEVICE, US_PR_DEVICE, NULL,
1102 US_FL_SINGLE_LUN), 1102 US_FL_SINGLE_LUN),
1103 1103
1104/* Submitted by Dylan Taft <d13f00l@gmail.com>
1105 * US_FL_IGNORE_RESIDUE Needed
1106 */
1107UNUSUAL_DEV( 0x08ca, 0x3103, 0x0100, 0x0100,
1108 "AIPTEK",
1109 "Aiptek USB Keychain MP3 Player",
1110 US_SC_DEVICE, US_PR_DEVICE, NULL,
1111 US_FL_IGNORE_RESIDUE),
1112
1104/* Entry needed for flags. Moreover, all devices with this ID use 1113/* Entry needed for flags. Moreover, all devices with this ID use
1105 * bulk-only transport, but _some_ falsely report Control/Bulk instead. 1114 * bulk-only transport, but _some_ falsely report Control/Bulk instead.
1106 * One example is "Trumpion Digital Research MYMP3". 1115 * One example is "Trumpion Digital Research MYMP3".
@@ -1311,12 +1320,13 @@ UNUSUAL_DEV( 0x0fce, 0xd008, 0x0000, 0x0000,
1311 US_SC_DEVICE, US_PR_DEVICE, NULL, 1320 US_SC_DEVICE, US_PR_DEVICE, NULL,
1312 US_FL_NO_WP_DETECT ), 1321 US_FL_NO_WP_DETECT ),
1313 1322
1314/* Reported by Jan Mate <mate@fiit.stuba.sk> */ 1323/* Reported by Jan Mate <mate@fiit.stuba.sk>
1324 * and by Soeren Sonnenburg <kernel@nn7.de> */
1315UNUSUAL_DEV( 0x0fce, 0xe030, 0x0000, 0x0000, 1325UNUSUAL_DEV( 0x0fce, 0xe030, 0x0000, 0x0000,
1316 "Sony Ericsson", 1326 "Sony Ericsson",
1317 "P990i", 1327 "P990i",
1318 US_SC_DEVICE, US_PR_DEVICE, NULL, 1328 US_SC_DEVICE, US_PR_DEVICE, NULL,
1319 US_FL_FIX_CAPACITY ), 1329 US_FL_FIX_CAPACITY | US_FL_IGNORE_RESIDUE ),
1320 1330
1321/* Reported by Emmanuel Vasilakis <evas@forthnet.gr> */ 1331/* Reported by Emmanuel Vasilakis <evas@forthnet.gr> */
1322UNUSUAL_DEV( 0x0fce, 0xe031, 0x0000, 0x0000, 1332UNUSUAL_DEV( 0x0fce, 0xe031, 0x0000, 0x0000,
@@ -1385,6 +1395,16 @@ UNUSUAL_DEV( 0x1652, 0x6600, 0x0201, 0x0201,
1385 US_SC_DEVICE, US_PR_DEVICE, NULL, 1395 US_SC_DEVICE, US_PR_DEVICE, NULL,
1386 US_FL_IGNORE_RESIDUE ), 1396 US_FL_IGNORE_RESIDUE ),
1387 1397
1398/* Reported by Thomas Baechler <thomas@archlinux.org>
1399 * Fixes I/O errors with Teac HD-35PU devices
1400 */
1401
1402UNUSUAL_DEV( 0x1652, 0x6600, 0x0201, 0x0201,
1403 "Super Top",
1404 "USB 2.0 IDE DEVICE",
1405 US_SC_DEVICE, US_PR_DEVICE, NULL,
1406 US_FL_IGNORE_RESIDUE),
1407
1388/* patch submitted by Davide Perini <perini.davide@dpsoftware.org> 1408/* patch submitted by Davide Perini <perini.davide@dpsoftware.org>
1389 * and Renato Perini <rperini@email.it> 1409 * and Renato Perini <rperini@email.it>
1390 */ 1410 */
@@ -1423,7 +1443,7 @@ UNUSUAL_DEV( 0xed06, 0x4500, 0x0001, 0x0001,
1423 "DataStor", 1443 "DataStor",
1424 "USB4500 FW1.04", 1444 "USB4500 FW1.04",
1425 US_SC_DEVICE, US_PR_DEVICE, NULL, 1445 US_SC_DEVICE, US_PR_DEVICE, NULL,
1426 US_FL_FIX_CAPACITY), 1446 US_FL_CAPACITY_HEURISTICS),
1427 1447
1428/* Control/Bulk transport for all SubClass values */ 1448/* Control/Bulk transport for all SubClass values */
1429USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR), 1449USUAL_DEV(US_SC_RBC, US_PR_CB, USB_US_TYPE_STOR),
diff --git a/drivers/usb/usb-skeleton.c b/drivers/usb/usb-skeleton.c
index 296b091cf168..46929a1b6f24 100644
--- a/drivers/usb/usb-skeleton.c
+++ b/drivers/usb/usb-skeleton.c
@@ -90,13 +90,15 @@ static int skel_open(struct inode *inode, struct file *file)
90 goto exit; 90 goto exit;
91 } 91 }
92 92
93 /* increment our usage count for the device */
94 kref_get(&dev->kref);
95
93 /* prevent the device from being autosuspended */ 96 /* prevent the device from being autosuspended */
94 retval = usb_autopm_get_interface(interface); 97 retval = usb_autopm_get_interface(interface);
95 if (retval) 98 if (retval) {
99 kref_put(&dev->kref, skel_delete);
96 goto exit; 100 goto exit;
97 101 }
98 /* increment our usage count for the device */
99 kref_get(&dev->kref);
100 102
101 /* save our object in the file's private structure */ 103 /* save our object in the file's private structure */
102 file->private_data = dev; 104 file->private_data = dev;
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index 8d130cc85322..682f928b7f4d 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -16,6 +16,7 @@
16#include <linux/module.h> 16#include <linux/module.h>
17#include <linux/fs.h> 17#include <linux/fs.h>
18#include <linux/pagemap.h> 18#include <linux/pagemap.h>
19#include <linux/namei.h>
19#include <linux/debugfs.h> 20#include <linux/debugfs.h>
20 21
21static ssize_t default_read_file(struct file *file, char __user *buf, 22static ssize_t default_read_file(struct file *file, char __user *buf,
@@ -44,6 +45,17 @@ const struct file_operations debugfs_file_operations = {
44 .open = default_open, 45 .open = default_open,
45}; 46};
46 47
48static void *debugfs_follow_link(struct dentry *dentry, struct nameidata *nd)
49{
50 nd_set_link(nd, dentry->d_inode->i_private);
51 return NULL;
52}
53
54const struct inode_operations debugfs_link_operations = {
55 .readlink = generic_readlink,
56 .follow_link = debugfs_follow_link,
57};
58
47static void debugfs_u8_set(void *data, u64 val) 59static void debugfs_u8_set(void *data, u64 val)
48{ 60{
49 *(u8 *)data = val; 61 *(u8 *)data = val;
diff --git a/fs/debugfs/inode.c b/fs/debugfs/inode.c
index c692487346ea..7b324cfebcb1 100644
--- a/fs/debugfs/inode.c
+++ b/fs/debugfs/inode.c
@@ -25,11 +25,13 @@
25#include <linux/namei.h> 25#include <linux/namei.h>
26#include <linux/debugfs.h> 26#include <linux/debugfs.h>
27#include <linux/fsnotify.h> 27#include <linux/fsnotify.h>
28#include <linux/string.h>
28 29
29#define DEBUGFS_MAGIC 0x64626720 30#define DEBUGFS_MAGIC 0x64626720
30 31
31/* declared over in file.c */ 32/* declared over in file.c */
32extern struct file_operations debugfs_file_operations; 33extern struct file_operations debugfs_file_operations;
34extern struct inode_operations debugfs_link_operations;
33 35
34static struct vfsmount *debugfs_mount; 36static struct vfsmount *debugfs_mount;
35static int debugfs_mount_count; 37static int debugfs_mount_count;
@@ -51,6 +53,9 @@ static struct inode *debugfs_get_inode(struct super_block *sb, int mode, dev_t d
51 case S_IFREG: 53 case S_IFREG:
52 inode->i_fop = &debugfs_file_operations; 54 inode->i_fop = &debugfs_file_operations;
53 break; 55 break;
56 case S_IFLNK:
57 inode->i_op = &debugfs_link_operations;
58 break;
54 case S_IFDIR: 59 case S_IFDIR:
55 inode->i_op = &simple_dir_inode_operations; 60 inode->i_op = &simple_dir_inode_operations;
56 inode->i_fop = &simple_dir_operations; 61 inode->i_fop = &simple_dir_operations;
@@ -96,6 +101,12 @@ static int debugfs_mkdir(struct inode *dir, struct dentry *dentry, int mode)
96 return res; 101 return res;
97} 102}
98 103
104static int debugfs_link(struct inode *dir, struct dentry *dentry, int mode)
105{
106 mode = (mode & S_IALLUGO) | S_IFLNK;
107 return debugfs_mknod(dir, dentry, mode, 0);
108}
109
99static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode) 110static int debugfs_create(struct inode *dir, struct dentry *dentry, int mode)
100{ 111{
101 int res; 112 int res;
@@ -158,10 +169,17 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
158 mutex_lock(&parent->d_inode->i_mutex); 169 mutex_lock(&parent->d_inode->i_mutex);
159 *dentry = lookup_one_len(name, parent, strlen(name)); 170 *dentry = lookup_one_len(name, parent, strlen(name));
160 if (!IS_ERR(*dentry)) { 171 if (!IS_ERR(*dentry)) {
161 if ((mode & S_IFMT) == S_IFDIR) 172 switch (mode & S_IFMT) {
173 case S_IFDIR:
162 error = debugfs_mkdir(parent->d_inode, *dentry, mode); 174 error = debugfs_mkdir(parent->d_inode, *dentry, mode);
163 else 175 break;
176 case S_IFLNK:
177 error = debugfs_link(parent->d_inode, *dentry, mode);
178 break;
179 default:
164 error = debugfs_create(parent->d_inode, *dentry, mode); 180 error = debugfs_create(parent->d_inode, *dentry, mode);
181 break;
182 }
165 dput(*dentry); 183 dput(*dentry);
166 } else 184 } else
167 error = PTR_ERR(*dentry); 185 error = PTR_ERR(*dentry);
@@ -194,9 +212,7 @@ static int debugfs_create_by_name(const char *name, mode_t mode,
194 * you are responsible here.) If an error occurs, %NULL will be returned. 212 * you are responsible here.) If an error occurs, %NULL will be returned.
195 * 213 *
196 * If debugfs is not enabled in the kernel, the value -%ENODEV will be 214 * If debugfs is not enabled in the kernel, the value -%ENODEV will be
197 * returned. It is not wise to check for this value, but rather, check for 215 * returned.
198 * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
199 * code.
200 */ 216 */
201struct dentry *debugfs_create_file(const char *name, mode_t mode, 217struct dentry *debugfs_create_file(const char *name, mode_t mode,
202 struct dentry *parent, void *data, 218 struct dentry *parent, void *data,
@@ -246,9 +262,7 @@ EXPORT_SYMBOL_GPL(debugfs_create_file);
246 * you are responsible here.) If an error occurs, %NULL will be returned. 262 * you are responsible here.) If an error occurs, %NULL will be returned.
247 * 263 *
248 * If debugfs is not enabled in the kernel, the value -%ENODEV will be 264 * If debugfs is not enabled in the kernel, the value -%ENODEV will be
249 * returned. It is not wise to check for this value, but rather, check for 265 * returned.
250 * %NULL or !%NULL instead as to eliminate the need for #ifdef in the calling
251 * code.
252 */ 266 */
253struct dentry *debugfs_create_dir(const char *name, struct dentry *parent) 267struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
254{ 268{
@@ -259,6 +273,47 @@ struct dentry *debugfs_create_dir(const char *name, struct dentry *parent)
259EXPORT_SYMBOL_GPL(debugfs_create_dir); 273EXPORT_SYMBOL_GPL(debugfs_create_dir);
260 274
261/** 275/**
276 * debugfs_create_symlink- create a symbolic link in the debugfs filesystem
277 * @name: a pointer to a string containing the name of the symbolic link to
278 * create.
279 * @parent: a pointer to the parent dentry for this symbolic link. This
280 * should be a directory dentry if set. If this paramater is NULL,
281 * then the symbolic link will be created in the root of the debugfs
282 * filesystem.
283 * @target: a pointer to a string containing the path to the target of the
284 * symbolic link.
285 *
286 * This function creates a symbolic link with the given name in debugfs that
287 * links to the given target path.
288 *
289 * This function will return a pointer to a dentry if it succeeds. This
290 * pointer must be passed to the debugfs_remove() function when the symbolic
291 * link is to be removed (no automatic cleanup happens if your module is
292 * unloaded, you are responsible here.) If an error occurs, %NULL will be
293 * returned.
294 *
295 * If debugfs is not enabled in the kernel, the value -%ENODEV will be
296 * returned.
297 */
298struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
299 const char *target)
300{
301 struct dentry *result;
302 char *link;
303
304 link = kstrdup(target, GFP_KERNEL);
305 if (!link)
306 return NULL;
307
308 result = debugfs_create_file(name, S_IFLNK | S_IRWXUGO, parent, link,
309 NULL);
310 if (!result)
311 kfree(link);
312 return result;
313}
314EXPORT_SYMBOL_GPL(debugfs_create_symlink);
315
316/**
262 * debugfs_remove - removes a file or directory from the debugfs filesystem 317 * debugfs_remove - removes a file or directory from the debugfs filesystem
263 * @dentry: a pointer to a the dentry of the file or directory to be 318 * @dentry: a pointer to a the dentry of the file or directory to be
264 * removed. 319 * removed.
@@ -287,15 +342,22 @@ void debugfs_remove(struct dentry *dentry)
287 if (debugfs_positive(dentry)) { 342 if (debugfs_positive(dentry)) {
288 if (dentry->d_inode) { 343 if (dentry->d_inode) {
289 dget(dentry); 344 dget(dentry);
290 if (S_ISDIR(dentry->d_inode->i_mode)) { 345 switch (dentry->d_inode->i_mode & S_IFMT) {
346 case S_IFDIR:
291 ret = simple_rmdir(parent->d_inode, dentry); 347 ret = simple_rmdir(parent->d_inode, dentry);
292 if (ret) 348 if (ret)
293 printk(KERN_ERR 349 printk(KERN_ERR
294 "DebugFS rmdir on %s failed : " 350 "DebugFS rmdir on %s failed : "
295 "directory not empty.\n", 351 "directory not empty.\n",
296 dentry->d_name.name); 352 dentry->d_name.name);
297 } else 353 break;
354 case S_IFLNK:
355 kfree(dentry->d_inode->i_private);
356 /* fall through */
357 default:
298 simple_unlink(parent->d_inode, dentry); 358 simple_unlink(parent->d_inode, dentry);
359 break;
360 }
299 if (!ret) 361 if (!ret)
300 d_delete(dentry); 362 d_delete(dentry);
301 dput(dentry); 363 dput(dentry);
diff --git a/fs/partitions/check.c b/fs/partitions/check.c
index ac32a2e8540c..22d38ffc9ef0 100644
--- a/fs/partitions/check.c
+++ b/fs/partitions/check.c
@@ -358,8 +358,7 @@ void delete_partition(struct gendisk *disk, int part)
358 p->ios[0] = p->ios[1] = 0; 358 p->ios[0] = p->ios[1] = 0;
359 p->sectors[0] = p->sectors[1] = 0; 359 p->sectors[0] = p->sectors[1] = 0;
360 sysfs_remove_link(&p->kobj, "subsystem"); 360 sysfs_remove_link(&p->kobj, "subsystem");
361 if (p->holder_dir) 361 kobject_unregister(p->holder_dir);
362 kobject_unregister(p->holder_dir);
363 kobject_uevent(&p->kobj, KOBJ_REMOVE); 362 kobject_uevent(&p->kobj, KOBJ_REMOVE);
364 kobject_del(&p->kobj); 363 kobject_del(&p->kobj);
365 kobject_put(&p->kobj); 364 kobject_put(&p->kobj);
@@ -603,10 +602,8 @@ void del_gendisk(struct gendisk *disk)
603 disk->stamp = 0; 602 disk->stamp = 0;
604 603
605 kobject_uevent(&disk->kobj, KOBJ_REMOVE); 604 kobject_uevent(&disk->kobj, KOBJ_REMOVE);
606 if (disk->holder_dir) 605 kobject_unregister(disk->holder_dir);
607 kobject_unregister(disk->holder_dir); 606 kobject_unregister(disk->slave_dir);
608 if (disk->slave_dir)
609 kobject_unregister(disk->slave_dir);
610 if (disk->driverfs_dev) { 607 if (disk->driverfs_dev) {
611 char *disk_name = make_block_name(disk); 608 char *disk_name = make_block_name(disk);
612 sysfs_remove_link(&disk->kobj, "device"); 609 sysfs_remove_link(&disk->kobj, "device");
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index c0e117649a4d..98b0910ad80c 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -54,7 +54,7 @@ static struct sysfs_ops subsys_sysfs_ops = {
54/** 54/**
55 * add_to_collection - add buffer to a collection 55 * add_to_collection - add buffer to a collection
56 * @buffer: buffer to be added 56 * @buffer: buffer to be added
57 * @node inode of set to add to 57 * @node: inode of set to add to
58 */ 58 */
59 59
60static inline void 60static inline void
diff --git a/include/acpi/acinterp.h b/include/acpi/acinterp.h
index ce7c9d653910..73967c8152d3 100644
--- a/include/acpi/acinterp.h
+++ b/include/acpi/acinterp.h
@@ -253,7 +253,8 @@ acpi_ex_release_mutex(union acpi_operand_object *obj_desc,
253 253
254void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread); 254void acpi_ex_release_all_mutexes(struct acpi_thread_state *thread);
255 255
256void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc); 256void acpi_ex_unlink_mutex(union acpi_operand_object *obj_desc,
257 struct acpi_thread_state *thread);
257 258
258/* 259/*
259 * exprep - ACPI AML execution - prep utilities 260 * exprep - ACPI AML execution - prep utilities
diff --git a/include/acpi/acobject.h b/include/acpi/acobject.h
index 04e9735a6742..5206d61d74a6 100644
--- a/include/acpi/acobject.h
+++ b/include/acpi/acobject.h
@@ -155,7 +155,7 @@ struct acpi_object_event {
155struct acpi_object_mutex { 155struct acpi_object_mutex {
156 ACPI_OBJECT_COMMON_HEADER u8 sync_level; /* 0-15, specified in Mutex() call */ 156 ACPI_OBJECT_COMMON_HEADER u8 sync_level; /* 0-15, specified in Mutex() call */
157 u16 acquisition_depth; /* Allow multiple Acquires, same thread */ 157 u16 acquisition_depth; /* Allow multiple Acquires, same thread */
158 struct acpi_thread_state *owner_thread; /* Current owner of the mutex */ 158 acpi_thread_id owner_thread_id; /* Current owner of the mutex */
159 acpi_mutex os_mutex; /* Actual OS synchronization object */ 159 acpi_mutex os_mutex; /* Actual OS synchronization object */
160 union acpi_operand_object *prev; /* Link for list of acquired mutexes */ 160 union acpi_operand_object *prev; /* Link for list of acquired mutexes */
161 union acpi_operand_object *next; /* Link for list of acquired mutexes */ 161 union acpi_operand_object *next; /* Link for list of acquired mutexes */
diff --git a/include/acpi/acpi_drivers.h b/include/acpi/acpi_drivers.h
index 4dc8a5043ef0..f6275b0e66dd 100644
--- a/include/acpi/acpi_drivers.h
+++ b/include/acpi/acpi_drivers.h
@@ -105,12 +105,6 @@ int acpi_ec_ecdt_probe(void);
105 105
106int acpi_processor_set_thermal_limit(acpi_handle handle, int type); 106int acpi_processor_set_thermal_limit(acpi_handle handle, int type);
107 107
108/* --------------------------------------------------------------------------
109 Hot Keys
110 -------------------------------------------------------------------------- */
111
112extern int acpi_specific_hotkey_enabled;
113
114/*-------------------------------------------------------------------------- 108/*--------------------------------------------------------------------------
115 Dock Station 109 Dock Station
116 -------------------------------------------------------------------------- */ 110 -------------------------------------------------------------------------- */
@@ -122,10 +116,34 @@ extern int register_hotplug_dock_device(acpi_handle handle,
122 acpi_notify_handler handler, void *context); 116 acpi_notify_handler handler, void *context);
123extern void unregister_hotplug_dock_device(acpi_handle handle); 117extern void unregister_hotplug_dock_device(acpi_handle handle);
124#else 118#else
125#define is_dock_device(h) (0) 119static inline int is_dock_device(acpi_handle handle)
126#define register_dock_notifier(nb) (-ENODEV) 120{
127#define unregister_dock_notifier(nb) do { } while(0) 121 return 0;
128#define register_hotplug_dock_device(h1, h2, c) (-ENODEV) 122}
129#define unregister_hotplug_dock_device(h) do { } while(0) 123static inline int register_dock_notifier(struct notifier_block *nb)
124{
125 return -ENODEV;
126}
127static inline void unregister_dock_notifier(struct notifier_block *nb)
128{
129}
130static inline int register_hotplug_dock_device(acpi_handle handle,
131 acpi_notify_handler handler, void *context)
132{
133 return -ENODEV;
134}
135static inline void unregister_hotplug_dock_device(acpi_handle handle)
136{
137}
138#endif
139
140/*--------------------------------------------------------------------------
141 Suspend/Resume
142 -------------------------------------------------------------------------- */
143#ifdef CONFIG_ACPI_SLEEP
144extern int acpi_sleep_init(void);
145#else
146#define acpi_sleep_init() do {} while (0)
130#endif 147#endif
148
131#endif /*__ACPI_DRIVERS_H__*/ 149#endif /*__ACPI_DRIVERS_H__*/
diff --git a/include/acpi/acpiosxf.h b/include/acpi/acpiosxf.h
index 781394b9efe0..2785058c82ab 100644
--- a/include/acpi/acpiosxf.h
+++ b/include/acpi/acpiosxf.h
@@ -240,12 +240,6 @@ acpi_status
240acpi_os_validate_address(u8 space_id, 240acpi_os_validate_address(u8 space_id,
241 acpi_physical_address address, acpi_size length); 241 acpi_physical_address address, acpi_size length);
242 242
243u8 acpi_os_readable(void *pointer, acpi_size length);
244
245#ifdef ACPI_FUTURE_USAGE
246u8 acpi_os_writable(void *pointer, acpi_size length);
247#endif
248
249u64 acpi_os_get_timer(void); 243u64 acpi_os_get_timer(void);
250 244
251acpi_status acpi_os_signal(u32 function, void *info); 245acpi_status acpi_os_signal(u32 function, void *info);
diff --git a/include/asm-arm/.gitignore b/include/asm-arm/.gitignore
new file mode 100644
index 000000000000..e02c15d158fc
--- /dev/null
+++ b/include/asm-arm/.gitignore
@@ -0,0 +1,2 @@
1arch
2mach-types.h
diff --git a/include/asm-arm/arch-at91rm9200/at91_aic.h b/include/asm-arm/arch-at91/at91_aic.h
index 267e69812e26..df44c12a12d4 100644
--- a/include/asm-arm/arch-at91rm9200/at91_aic.h
+++ b/include/asm-arm/arch-at91/at91_aic.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91_aic.h 2 * include/asm-arm/arch-at91/at91_aic.h
3 * 3 *
4 * Copyright (C) 2005 Ivan Kokshaysky 4 * Copyright (C) 2005 Ivan Kokshaysky
5 * Copyright (C) SAN People 5 * Copyright (C) SAN People
diff --git a/include/asm-arm/arch-at91rm9200/at91_dbgu.h b/include/asm-arm/arch-at91/at91_dbgu.h
index e4b8b27acfca..b0369e176f7b 100644
--- a/include/asm-arm/arch-at91rm9200/at91_dbgu.h
+++ b/include/asm-arm/arch-at91/at91_dbgu.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91_dbgu.h 2 * include/asm-arm/arch-at91/at91_dbgu.h
3 * 3 *
4 * Copyright (C) 2005 Ivan Kokshaysky 4 * Copyright (C) 2005 Ivan Kokshaysky
5 * Copyright (C) SAN People 5 * Copyright (C) SAN People
@@ -35,6 +35,20 @@
35#define AT91_CIDR_NVPSIZ (0xf << 8) /* Nonvolatile Program Memory Size */ 35#define AT91_CIDR_NVPSIZ (0xf << 8) /* Nonvolatile Program Memory Size */
36#define AT91_CIDR_NVPSIZ2 (0xf << 12) /* Second Nonvolatile Program Memory Size */ 36#define AT91_CIDR_NVPSIZ2 (0xf << 12) /* Second Nonvolatile Program Memory Size */
37#define AT91_CIDR_SRAMSIZ (0xf << 16) /* Internal SRAM Size */ 37#define AT91_CIDR_SRAMSIZ (0xf << 16) /* Internal SRAM Size */
38#define AT91_CIDR_SRAMSIZ_1K (1 << 16)
39#define AT91_CIDR_SRAMSIZ_2K (2 << 16)
40#define AT91_CIDR_SRAMSIZ_112K (4 << 16)
41#define AT91_CIDR_SRAMSIZ_4K (5 << 16)
42#define AT91_CIDR_SRAMSIZ_80K (6 << 16)
43#define AT91_CIDR_SRAMSIZ_160K (7 << 16)
44#define AT91_CIDR_SRAMSIZ_8K (8 << 16)
45#define AT91_CIDR_SRAMSIZ_16K (9 << 16)
46#define AT91_CIDR_SRAMSIZ_32K (10 << 16)
47#define AT91_CIDR_SRAMSIZ_64K (11 << 16)
48#define AT91_CIDR_SRAMSIZ_128K (12 << 16)
49#define AT91_CIDR_SRAMSIZ_256K (13 << 16)
50#define AT91_CIDR_SRAMSIZ_96K (14 << 16)
51#define AT91_CIDR_SRAMSIZ_512K (15 << 16)
38#define AT91_CIDR_ARCH (0xff << 20) /* Architecture Identifier */ 52#define AT91_CIDR_ARCH (0xff << 20) /* Architecture Identifier */
39#define AT91_CIDR_NVPTYP (7 << 28) /* Nonvolatile Program Memory Type */ 53#define AT91_CIDR_NVPTYP (7 << 28) /* Nonvolatile Program Memory Type */
40#define AT91_CIDR_EXT (1 << 31) /* Extension Flag */ 54#define AT91_CIDR_EXT (1 << 31) /* Extension Flag */
diff --git a/include/asm-arm/arch-at91rm9200/at91_ecc.h b/include/asm-arm/arch-at91/at91_ecc.h
index 5c564ede5c5d..ff93df516d6d 100644
--- a/include/asm-arm/arch-at91rm9200/at91_ecc.h
+++ b/include/asm-arm/arch-at91/at91_ecc.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91_ecc.h 2 * include/asm-arm/arch-at91/at91_ecc.h
3 * 3 *
4 * Error Corrected Code Controller (ECC) - System peripherals regsters. 4 * Error Corrected Code Controller (ECC) - System peripherals regsters.
5 * Based on AT91SAM9260 datasheet revision B. 5 * Based on AT91SAM9260 datasheet revision B.
diff --git a/include/asm-arm/arch-at91rm9200/at91_lcdc.h b/include/asm-arm/arch-at91/at91_lcdc.h
index 9cbfcdd3c471..ab040a40d37b 100644
--- a/include/asm-arm/arch-at91rm9200/at91_lcdc.h
+++ b/include/asm-arm/arch-at91/at91_lcdc.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91_lcdc.h 2 * include/asm-arm/arch-at91/at91_lcdc.h
3 * 3 *
4 * LCD Controller (LCDC). 4 * LCD Controller (LCDC).
5 * Based on AT91SAM9261 datasheet revision E. 5 * Based on AT91SAM9261 datasheet revision E.
diff --git a/include/asm-arm/arch-at91rm9200/at91_mci.h b/include/asm-arm/arch-at91/at91_mci.h
index 9a552cb743c0..40a9876b661a 100644
--- a/include/asm-arm/arch-at91rm9200/at91_mci.h
+++ b/include/asm-arm/arch-at91/at91_mci.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91_mci.h 2 * include/asm-arm/arch-at91/at91_mci.h
3 * 3 *
4 * Copyright (C) 2005 Ivan Kokshaysky 4 * Copyright (C) 2005 Ivan Kokshaysky
5 * Copyright (C) SAN People 5 * Copyright (C) SAN People
diff --git a/include/asm-arm/arch-at91rm9200/at91_pio.h b/include/asm-arm/arch-at91/at91_pio.h
index 680eaa1f5915..84c3866d309f 100644
--- a/include/asm-arm/arch-at91rm9200/at91_pio.h
+++ b/include/asm-arm/arch-at91/at91_pio.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91_pio.h 2 * include/asm-arm/arch-at91/at91_pio.h
3 * 3 *
4 * Copyright (C) 2005 Ivan Kokshaysky 4 * Copyright (C) 2005 Ivan Kokshaysky
5 * Copyright (C) SAN People 5 * Copyright (C) SAN People
diff --git a/include/asm-arm/arch-at91rm9200/at91_pit.h b/include/asm-arm/arch-at91/at91_pit.h
index 4a30d009c588..5026325a5ae4 100644
--- a/include/asm-arm/arch-at91rm9200/at91_pit.h
+++ b/include/asm-arm/arch-at91/at91_pit.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91_pit.h 2 * include/asm-arm/arch-at91/at91_pit.h
3 * 3 *
4 * Periodic Interval Timer (PIT) - System peripherals regsters. 4 * Periodic Interval Timer (PIT) - System peripherals regsters.
5 * Based on AT91SAM9261 datasheet revision D. 5 * Based on AT91SAM9261 datasheet revision D.
diff --git a/include/asm-arm/arch-at91rm9200/at91_pmc.h b/include/asm-arm/arch-at91/at91_pmc.h
index c3b489d09b6c..33ff5b6798ee 100644
--- a/include/asm-arm/arch-at91rm9200/at91_pmc.h
+++ b/include/asm-arm/arch-at91/at91_pmc.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91_pmc.h 2 * include/asm-arm/arch-at91/at91_pmc.h
3 * 3 *
4 * Copyright (C) 2005 Ivan Kokshaysky 4 * Copyright (C) 2005 Ivan Kokshaysky
5 * Copyright (C) SAN People 5 * Copyright (C) SAN People
diff --git a/include/asm-arm/arch-at91rm9200/at91_rstc.h b/include/asm-arm/arch-at91/at91_rstc.h
index 237d3c40b318..fb8d1618a231 100644
--- a/include/asm-arm/arch-at91rm9200/at91_rstc.h
+++ b/include/asm-arm/arch-at91/at91_rstc.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91_rstc.h 2 * include/asm-arm/arch-at91/at91_rstc.h
3 * 3 *
4 * Reset Controller (RSTC) - System peripherals regsters. 4 * Reset Controller (RSTC) - System peripherals regsters.
5 * Based on AT91SAM9261 datasheet revision D. 5 * Based on AT91SAM9261 datasheet revision D.
@@ -17,7 +17,7 @@
17#define AT91_RSTC_PROCRST (1 << 0) /* Processor Reset */ 17#define AT91_RSTC_PROCRST (1 << 0) /* Processor Reset */
18#define AT91_RSTC_PERRST (1 << 2) /* Peripheral Reset */ 18#define AT91_RSTC_PERRST (1 << 2) /* Peripheral Reset */
19#define AT91_RSTC_EXTRST (1 << 3) /* External Reset */ 19#define AT91_RSTC_EXTRST (1 << 3) /* External Reset */
20#define AT91_RSTC_KEY (0xff << 24) /* KEY Password */ 20#define AT91_RSTC_KEY (0xa5 << 24) /* KEY Password */
21 21
22#define AT91_RSTC_SR (AT91_RSTC + 0x04) /* Reset Controller Status Register */ 22#define AT91_RSTC_SR (AT91_RSTC + 0x04) /* Reset Controller Status Register */
23#define AT91_RSTC_URSTS (1 << 0) /* User Reset Status */ 23#define AT91_RSTC_URSTS (1 << 0) /* User Reset Status */
@@ -34,6 +34,5 @@
34#define AT91_RSTC_URSTEN (1 << 0) /* User Reset Enable */ 34#define AT91_RSTC_URSTEN (1 << 0) /* User Reset Enable */
35#define AT91_RSTC_URSTIEN (1 << 4) /* User Reset Interrupt Enable */ 35#define AT91_RSTC_URSTIEN (1 << 4) /* User Reset Interrupt Enable */
36#define AT91_RSTC_ERSTL (0xf << 8) /* External Reset Length */ 36#define AT91_RSTC_ERSTL (0xf << 8) /* External Reset Length */
37#define AT91_RSTC_KEY (0xff << 24) /* KEY Password */
38 37
39#endif 38#endif
diff --git a/include/asm-arm/arch-at91rm9200/at91_rtc.h b/include/asm-arm/arch-at91/at91_rtc.h
index 095fe0883102..af9bd28174c0 100644
--- a/include/asm-arm/arch-at91rm9200/at91_rtc.h
+++ b/include/asm-arm/arch-at91/at91_rtc.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91_rtc.h 2 * include/asm-arm/arch-at91/at91_rtc.h
3 * 3 *
4 * Copyright (C) 2005 Ivan Kokshaysky 4 * Copyright (C) 2005 Ivan Kokshaysky
5 * Copyright (C) SAN People 5 * Copyright (C) SAN People
diff --git a/include/asm-arm/arch-at91rm9200/at91_rtt.h b/include/asm-arm/arch-at91/at91_rtt.h
index c6751ba3cccc..bae1103fbbb2 100644
--- a/include/asm-arm/arch-at91rm9200/at91_rtt.h
+++ b/include/asm-arm/arch-at91/at91_rtt.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91_rtt.h 2 * include/asm-arm/arch-at91/at91_rtt.h
3 * 3 *
4 * Real-time Timer (RTT) - System peripherals regsters. 4 * Real-time Timer (RTT) - System peripherals regsters.
5 * Based on AT91SAM9261 datasheet revision D. 5 * Based on AT91SAM9261 datasheet revision D.
diff --git a/include/asm-arm/arch-at91rm9200/at91_shdwc.h b/include/asm-arm/arch-at91/at91_shdwc.h
index 0439250553c9..795fcc266228 100644
--- a/include/asm-arm/arch-at91rm9200/at91_shdwc.h
+++ b/include/asm-arm/arch-at91/at91_shdwc.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91_shdwc.h 2 * include/asm-arm/arch-at91/at91_shdwc.h
3 * 3 *
4 * Shutdown Controller (SHDWC) - System peripherals regsters. 4 * Shutdown Controller (SHDWC) - System peripherals regsters.
5 * Based on AT91SAM9261 datasheet revision D. 5 * Based on AT91SAM9261 datasheet revision D.
diff --git a/include/asm-arm/arch-at91rm9200/at91_spi.h b/include/asm-arm/arch-at91/at91_spi.h
index bec48ca89bba..f9b9a8464997 100644
--- a/include/asm-arm/arch-at91rm9200/at91_spi.h
+++ b/include/asm-arm/arch-at91/at91_spi.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91_spi.h 2 * include/asm-arm/arch-at91/at91_spi.h
3 * 3 *
4 * Copyright (C) 2005 Ivan Kokshaysky 4 * Copyright (C) 2005 Ivan Kokshaysky
5 * Copyright (C) SAN People 5 * Copyright (C) SAN People
diff --git a/include/asm-arm/arch-at91rm9200/at91_ssc.h b/include/asm-arm/arch-at91/at91_ssc.h
index 694bcaa8f7c2..0ecc73460b50 100644
--- a/include/asm-arm/arch-at91rm9200/at91_ssc.h
+++ b/include/asm-arm/arch-at91/at91_ssc.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91_ssc.h 2 * include/asm-arm/arch-at91/at91_ssc.h
3 * 3 *
4 * Copyright (C) SAN People 4 * Copyright (C) SAN People
5 * 5 *
diff --git a/include/asm-arm/arch-at91rm9200/at91_st.h b/include/asm-arm/arch-at91/at91_st.h
index 2432ddfc6c47..30446e2ea772 100644
--- a/include/asm-arm/arch-at91rm9200/at91_st.h
+++ b/include/asm-arm/arch-at91/at91_st.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91_st.h 2 * include/asm-arm/arch-at91/at91_st.h
3 * 3 *
4 * Copyright (C) 2005 Ivan Kokshaysky 4 * Copyright (C) 2005 Ivan Kokshaysky
5 * Copyright (C) SAN People 5 * Copyright (C) SAN People
diff --git a/include/asm-arm/arch-at91rm9200/at91_tc.h b/include/asm-arm/arch-at91/at91_tc.h
index 8d06eb078e1d..b85d3faeef5c 100644
--- a/include/asm-arm/arch-at91rm9200/at91_tc.h
+++ b/include/asm-arm/arch-at91/at91_tc.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91_tc.h 2 * include/asm-arm/arch-at91/at91_tc.h
3 * 3 *
4 * Copyright (C) SAN People 4 * Copyright (C) SAN People
5 * 5 *
diff --git a/include/asm-arm/arch-at91rm9200/at91_twi.h b/include/asm-arm/arch-at91/at91_twi.h
index cda914f1e740..ca9a90733456 100644
--- a/include/asm-arm/arch-at91rm9200/at91_twi.h
+++ b/include/asm-arm/arch-at91/at91_twi.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91_twi.h 2 * include/asm-arm/arch-at91/at91_twi.h
3 * 3 *
4 * Copyright (C) 2005 Ivan Kokshaysky 4 * Copyright (C) 2005 Ivan Kokshaysky
5 * Copyright (C) SAN People 5 * Copyright (C) SAN People
diff --git a/include/asm-arm/arch-at91rm9200/at91_wdt.h b/include/asm-arm/arch-at91/at91_wdt.h
index ac63e775772c..7251a344c740 100644
--- a/include/asm-arm/arch-at91rm9200/at91_wdt.h
+++ b/include/asm-arm/arch-at91/at91_wdt.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91_wdt.h 2 * include/asm-arm/arch-at91/at91_wdt.h
3 * 3 *
4 * Watchdog Timer (WDT) - System peripherals regsters. 4 * Watchdog Timer (WDT) - System peripherals regsters.
5 * Based on AT91SAM9261 datasheet revision D. 5 * Based on AT91SAM9261 datasheet revision D.
diff --git a/include/asm-arm/arch-at91rm9200/at91rm9200.h b/include/asm-arm/arch-at91/at91rm9200.h
index c569b6a21a42..a12ac8ab2ad0 100644
--- a/include/asm-arm/arch-at91rm9200/at91rm9200.h
+++ b/include/asm-arm/arch-at91/at91rm9200.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91rm9200.h 2 * include/asm-arm/arch-at91/at91rm9200.h
3 * 3 *
4 * Copyright (C) 2005 Ivan Kokshaysky 4 * Copyright (C) 2005 Ivan Kokshaysky
5 * Copyright (C) SAN People 5 * Copyright (C) SAN People
diff --git a/include/asm-arm/arch-at91rm9200/at91rm9200_emac.h b/include/asm-arm/arch-at91/at91rm9200_emac.h
index fbc091e61e2f..0c417af5fe7f 100644
--- a/include/asm-arm/arch-at91rm9200/at91rm9200_emac.h
+++ b/include/asm-arm/arch-at91/at91rm9200_emac.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91rm9200_emac.h 2 * include/asm-arm/arch-at91/at91rm9200_emac.h
3 * 3 *
4 * Copyright (C) 2005 Ivan Kokshaysky 4 * Copyright (C) 2005 Ivan Kokshaysky
5 * Copyright (C) SAN People 5 * Copyright (C) SAN People
diff --git a/include/asm-arm/arch-at91rm9200/at91rm9200_mc.h b/include/asm-arm/arch-at91/at91rm9200_mc.h
index 0c0d81480b3a..24d012939cc4 100644
--- a/include/asm-arm/arch-at91rm9200/at91rm9200_mc.h
+++ b/include/asm-arm/arch-at91/at91rm9200_mc.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91rm9200_mc.h 2 * include/asm-arm/arch-at91/at91rm9200_mc.h
3 * 3 *
4 * Copyright (C) 2005 Ivan Kokshaysky 4 * Copyright (C) 2005 Ivan Kokshaysky
5 * Copyright (C) SAN People 5 * Copyright (C) SAN People
diff --git a/include/asm-arm/arch-at91rm9200/at91sam9260.h b/include/asm-arm/arch-at91/at91sam9260.h
index 46f4dd65c035..2cadebc36af7 100644
--- a/include/asm-arm/arch-at91rm9200/at91sam9260.h
+++ b/include/asm-arm/arch-at91/at91sam9260.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91sam9260.h 2 * include/asm-arm/arch-at91/at91sam9260.h
3 * 3 *
4 * (C) 2006 Andrew Victor 4 * (C) 2006 Andrew Victor
5 * 5 *
@@ -113,6 +113,10 @@
113 113
114#define AT91SAM9260_UHP_BASE 0x00500000 /* USB Host controller */ 114#define AT91SAM9260_UHP_BASE 0x00500000 /* USB Host controller */
115 115
116#define AT91SAM9XE_FLASH_BASE 0x00200000 /* Internal FLASH base address */
117#define AT91SAM9XE_SRAM_BASE 0x00300000 /* Internal SRAM base address */
118
119
116#if 0 120#if 0
117/* 121/*
118 * PIO pin definitions (peripheral A/B multiplexing). 122 * PIO pin definitions (peripheral A/B multiplexing).
diff --git a/include/asm-arm/arch-at91rm9200/at91sam9260_matrix.h b/include/asm-arm/arch-at91/at91sam9260_matrix.h
index 78f6b4917b8b..aacb1e976422 100644
--- a/include/asm-arm/arch-at91rm9200/at91sam9260_matrix.h
+++ b/include/asm-arm/arch-at91/at91sam9260_matrix.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91sam9260_matrix.h 2 * include/asm-arm/arch-at91/at91sam9260_matrix.h
3 * 3 *
4 * Memory Controllers (MATRIX, EBI) - System peripherals registers. 4 * Memory Controllers (MATRIX, EBI) - System peripherals registers.
5 * Based on AT91SAM9260 datasheet revision B. 5 * Based on AT91SAM9260 datasheet revision B.
@@ -18,7 +18,7 @@
18#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */ 18#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */
19#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */ 19#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */
20#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */ 20#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */
21#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x04) /* Master Configuration Register 5 */ 21#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */
22#define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */ 22#define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */
23#define AT91_MATRIX_ULBT_INFINITE (0 << 0) 23#define AT91_MATRIX_ULBT_INFINITE (0 << 0)
24#define AT91_MATRIX_ULBT_SINGLE (1 << 0) 24#define AT91_MATRIX_ULBT_SINGLE (1 << 0)
diff --git a/include/asm-arm/arch-at91rm9200/at91sam9261.h b/include/asm-arm/arch-at91/at91sam9261.h
index 8d39672d5b82..01b58ffe2e27 100644
--- a/include/asm-arm/arch-at91rm9200/at91sam9261.h
+++ b/include/asm-arm/arch-at91/at91sam9261.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91sam9261.h 2 * include/asm-arm/arch-at91/at91sam9261.h
3 * 3 *
4 * Copyright (C) SAN People 4 * Copyright (C) SAN People
5 * 5 *
diff --git a/include/asm-arm/arch-at91rm9200/at91sam9261_matrix.h b/include/asm-arm/arch-at91/at91sam9261_matrix.h
index ec88efabbe6c..6f072421be5b 100644
--- a/include/asm-arm/arch-at91rm9200/at91sam9261_matrix.h
+++ b/include/asm-arm/arch-at91/at91sam9261_matrix.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91sam9261_matrix.h 2 * include/asm-arm/arch-at91/at91sam9261_matrix.h
3 * 3 *
4 * Memory Controllers (MATRIX, EBI) - System peripherals registers. 4 * Memory Controllers (MATRIX, EBI) - System peripherals registers.
5 * Based on AT91SAM9261 datasheet revision D. 5 * Based on AT91SAM9261 datasheet revision D.
diff --git a/include/asm-arm/arch-at91/at91sam9263.h b/include/asm-arm/arch-at91/at91sam9263.h
new file mode 100644
index 000000000000..f4af68ae0ea9
--- /dev/null
+++ b/include/asm-arm/arch-at91/at91sam9263.h
@@ -0,0 +1,131 @@
1/*
2 * include/asm-arm/arch-at91/at91sam9263.h
3 *
4 * (C) 2007 Atmel Corporation.
5 *
6 * Common definitions.
7 * Based on AT91SAM9263 datasheet revision B (Preliminary).
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
15#ifndef AT91SAM9263_H
16#define AT91SAM9263_H
17
18/*
19 * Peripheral identifiers/interrupts.
20 */
21#define AT91_ID_FIQ 0 /* Advanced Interrupt Controller (FIQ) */
22#define AT91_ID_SYS 1 /* System Peripherals */
23#define AT91SAM9263_ID_PIOA 2 /* Parallel IO Controller A */
24#define AT91SAM9263_ID_PIOB 3 /* Parallel IO Controller B */
25#define AT91SAM9263_ID_PIOCDE 4 /* Parallel IO Controller C, D and E */
26#define AT91SAM9263_ID_US0 7 /* USART 0 */
27#define AT91SAM9263_ID_US1 8 /* USART 1 */
28#define AT91SAM9263_ID_US2 9 /* USART 2 */
29#define AT91SAM9263_ID_MCI0 10 /* Multimedia Card Interface 0 */
30#define AT91SAM9263_ID_MCI1 11 /* Multimedia Card Interface 1 */
31#define AT91SAM9263_ID_CAN 12 /* CAN */
32#define AT91SAM9263_ID_TWI 13 /* Two-Wire Interface */
33#define AT91SAM9263_ID_SPI0 14 /* Serial Peripheral Interface 0 */
34#define AT91SAM9263_ID_SPI1 15 /* Serial Peripheral Interface 1 */
35#define AT91SAM9263_ID_SSC0 16 /* Serial Synchronous Controller 0 */
36#define AT91SAM9263_ID_SSC1 17 /* Serial Synchronous Controller 1 */
37#define AT91SAM9263_ID_AC97C 18 /* AC97 Controller */
38#define AT91SAM9263_ID_TCB 19 /* Timer Counter 0, 1 and 2 */
39#define AT91SAM9263_ID_PWMC 20 /* Pulse Width Modulation Controller */
40#define AT91SAM9263_ID_EMAC 21 /* Ethernet */
41#define AT91SAM9263_ID_2DGE 23 /* 2D Graphic Engine */
42#define AT91SAM9263_ID_UDP 24 /* USB Device Port */
43#define AT91SAM9263_ID_ISI 25 /* Image Sensor Interface */
44#define AT91SAM9263_ID_LCDC 26 /* LCD Controller */
45#define AT91SAM9263_ID_DMA 27 /* DMA Controller */
46#define AT91SAM9263_ID_UHP 29 /* USB Host port */
47#define AT91SAM9263_ID_IRQ0 30 /* Advanced Interrupt Controller (IRQ0) */
48#define AT91SAM9263_ID_IRQ1 31 /* Advanced Interrupt Controller (IRQ1) */
49
50
51/*
52 * User Peripheral physical base addresses.
53 */
54#define AT91SAM9263_BASE_UDP 0xfff78000
55#define AT91SAM9263_BASE_TCB0 0xfff7c000
56#define AT91SAM9263_BASE_TC0 0xfff7c000
57#define AT91SAM9263_BASE_TC1 0xfff7c040
58#define AT91SAM9263_BASE_TC2 0xfff7c080
59#define AT91SAM9263_BASE_MCI0 0xfff80000
60#define AT91SAM9263_BASE_MCI1 0xfff84000
61#define AT91SAM9263_BASE_TWI 0xfff88000
62#define AT91SAM9263_BASE_US0 0xfff8c000
63#define AT91SAM9263_BASE_US1 0xfff90000
64#define AT91SAM9263_BASE_US2 0xfff94000
65#define AT91SAM9263_BASE_SSC0 0xfff98000
66#define AT91SAM9263_BASE_SSC1 0xfff9c000
67#define AT91SAM9263_BASE_AC97C 0xfffa0000
68#define AT91SAM9263_BASE_SPI0 0xfffa4000
69#define AT91SAM9263_BASE_SPI1 0xfffa8000
70#define AT91SAM9263_BASE_CAN 0xfffac000
71#define AT91SAM9263_BASE_PWMC 0xfffb8000
72#define AT91SAM9263_BASE_EMAC 0xfffbc000
73#define AT91SAM9263_BASE_ISI 0xfffc4000
74#define AT91SAM9263_BASE_2DGE 0xfffc8000
75#define AT91_BASE_SYS 0xffffe000
76
77/*
78 * System Peripherals (offset from AT91_BASE_SYS)
79 */
80#define AT91_ECC0 (0xffffe000 - AT91_BASE_SYS)
81#define AT91_SDRAMC0 (0xffffe200 - AT91_BASE_SYS)
82#define AT91_SMC0 (0xffffe400 - AT91_BASE_SYS)
83#define AT91_ECC1 (0xffffe600 - AT91_BASE_SYS)
84#define AT91_SDRAMC1 (0xffffe800 - AT91_BASE_SYS)
85#define AT91_SMC1 (0xffffea00 - AT91_BASE_SYS)
86#define AT91_MATRIX (0xffffec00 - AT91_BASE_SYS)
87#define AT91_CCFG (0xffffed10 - AT91_BASE_SYS)
88#define AT91_DBGU (0xffffee00 - AT91_BASE_SYS)
89#define AT91_AIC (0xfffff000 - AT91_BASE_SYS)
90#define AT91_PIOA (0xfffff200 - AT91_BASE_SYS)
91#define AT91_PIOB (0xfffff400 - AT91_BASE_SYS)
92#define AT91_PIOC (0xfffff600 - AT91_BASE_SYS)
93#define AT91_PIOD (0xfffff800 - AT91_BASE_SYS)
94#define AT91_PIOE (0xfffffa00 - AT91_BASE_SYS)
95#define AT91_PMC (0xfffffc00 - AT91_BASE_SYS)
96#define AT91_RSTC (0xfffffd00 - AT91_BASE_SYS)
97#define AT91_SHDWC (0xfffffd10 - AT91_BASE_SYS)
98#define AT91_RTT0 (0xfffffd20 - AT91_BASE_SYS)
99#define AT91_PIT (0xfffffd30 - AT91_BASE_SYS)
100#define AT91_WDT (0xfffffd40 - AT91_BASE_SYS)
101#define AT91_RTT1 (0xfffffd50 - AT91_BASE_SYS)
102#define AT91_GPBR (0xfffffd60 - AT91_BASE_SYS)
103
104#define AT91_SMC AT91_SMC0
105
106/*
107 * Internal Memory.
108 */
109#define AT91SAM9263_SRAM0_BASE 0x00300000 /* Internal SRAM 0 base address */
110#define AT91SAM9263_SRAM0_SIZE (80 * SZ_1K) /* Internal SRAM 0 size (80Kb) */
111
112#define AT91SAM9263_ROM_BASE 0x00400000 /* Internal ROM base address */
113#define AT91SAM9263_ROM_SIZE SZ_128K /* Internal ROM size (128Kb) */
114
115#define AT91SAM9263_SRAM1_BASE 0x00500000 /* Internal SRAM 1 base address */
116#define AT91SAM9263_SRAM1_SIZE SZ_16K /* Internal SRAM 1 size (16Kb) */
117
118#define AT91SAM9263_LCDC_BASE 0x00700000 /* LCD Controller */
119#define AT91SAM9263_DMAC_BASE 0x00800000 /* DMA Controller */
120#define AT91SAM9263_UHP_BASE 0x00a00000 /* USB Host controller */
121
122#if 0
123/*
124 * PIO pin definitions (peripheral A/B multiplexing).
125 */
126
127// TODO: Add
128
129#endif
130
131#endif
diff --git a/include/asm-arm/arch-at91/at91sam9263_matrix.h b/include/asm-arm/arch-at91/at91sam9263_matrix.h
new file mode 100644
index 000000000000..6fc6e4be624e
--- /dev/null
+++ b/include/asm-arm/arch-at91/at91sam9263_matrix.h
@@ -0,0 +1,129 @@
1/*
2 * include/asm-arm/arch-at91/at91sam9263_matrix.h
3 *
4 * Copyright (C) 2006 Atmel Corporation.
5 *
6 * Memory Controllers (MATRIX, EBI) - System peripherals registers.
7 * Based on AT91SAM9263 datasheet revision B (Preliminary).
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
15#ifndef AT91SAM9263_MATRIX_H
16#define AT91SAM9263_MATRIX_H
17
18#define AT91_MATRIX_MCFG0 (AT91_MATRIX + 0x00) /* Master Configuration Register 0 */
19#define AT91_MATRIX_MCFG1 (AT91_MATRIX + 0x04) /* Master Configuration Register 1 */
20#define AT91_MATRIX_MCFG2 (AT91_MATRIX + 0x08) /* Master Configuration Register 2 */
21#define AT91_MATRIX_MCFG3 (AT91_MATRIX + 0x0C) /* Master Configuration Register 3 */
22#define AT91_MATRIX_MCFG4 (AT91_MATRIX + 0x10) /* Master Configuration Register 4 */
23#define AT91_MATRIX_MCFG5 (AT91_MATRIX + 0x14) /* Master Configuration Register 5 */
24#define AT91_MATRIX_MCFG6 (AT91_MATRIX + 0x18) /* Master Configuration Register 6 */
25#define AT91_MATRIX_MCFG7 (AT91_MATRIX + 0x1C) /* Master Configuration Register 7 */
26#define AT91_MATRIX_MCFG8 (AT91_MATRIX + 0x20) /* Master Configuration Register 8 */
27#define AT91_MATRIX_ULBT (7 << 0) /* Undefined Length Burst Type */
28#define AT91_MATRIX_ULBT_INFINITE (0 << 0)
29#define AT91_MATRIX_ULBT_SINGLE (1 << 0)
30#define AT91_MATRIX_ULBT_FOUR (2 << 0)
31#define AT91_MATRIX_ULBT_EIGHT (3 << 0)
32#define AT91_MATRIX_ULBT_SIXTEEN (4 << 0)
33
34#define AT91_MATRIX_SCFG0 (AT91_MATRIX + 0x40) /* Slave Configuration Register 0 */
35#define AT91_MATRIX_SCFG1 (AT91_MATRIX + 0x44) /* Slave Configuration Register 1 */
36#define AT91_MATRIX_SCFG2 (AT91_MATRIX + 0x48) /* Slave Configuration Register 2 */
37#define AT91_MATRIX_SCFG3 (AT91_MATRIX + 0x4C) /* Slave Configuration Register 3 */
38#define AT91_MATRIX_SCFG4 (AT91_MATRIX + 0x50) /* Slave Configuration Register 4 */
39#define AT91_MATRIX_SCFG5 (AT91_MATRIX + 0x54) /* Slave Configuration Register 5 */
40#define AT91_MATRIX_SCFG6 (AT91_MATRIX + 0x58) /* Slave Configuration Register 6 */
41#define AT91_MATRIX_SCFG7 (AT91_MATRIX + 0x5C) /* Slave Configuration Register 7 */
42#define AT91_MATRIX_SLOT_CYCLE (0xff << 0) /* Maximum Number of Allowed Cycles for a Burst */
43#define AT91_MATRIX_DEFMSTR_TYPE (3 << 16) /* Default Master Type */
44#define AT91_MATRIX_DEFMSTR_TYPE_NONE (0 << 16)
45#define AT91_MATRIX_DEFMSTR_TYPE_LAST (1 << 16)
46#define AT91_MATRIX_DEFMSTR_TYPE_FIXED (2 << 16)
47#define AT91_MATRIX_FIXED_DEFMSTR (7 << 18) /* Fixed Index of Default Master */
48#define AT91_MATRIX_ARBT (3 << 24) /* Arbitration Type */
49#define AT91_MATRIX_ARBT_ROUND_ROBIN (0 << 24)
50#define AT91_MATRIX_ARBT_FIXED_PRIORITY (1 << 24)
51
52#define AT91_MATRIX_PRAS0 (AT91_MATRIX + 0x80) /* Priority Register A for Slave 0 */
53#define AT91_MATRIX_PRBS0 (AT91_MATRIX + 0x84) /* Priority Register B for Slave 0 */
54#define AT91_MATRIX_PRAS1 (AT91_MATRIX + 0x88) /* Priority Register A for Slave 1 */
55#define AT91_MATRIX_PRBS1 (AT91_MATRIX + 0x8C) /* Priority Register B for Slave 1 */
56#define AT91_MATRIX_PRAS2 (AT91_MATRIX + 0x90) /* Priority Register A for Slave 2 */
57#define AT91_MATRIX_PRBS2 (AT91_MATRIX + 0x94) /* Priority Register B for Slave 2 */
58#define AT91_MATRIX_PRAS3 (AT91_MATRIX + 0x98) /* Priority Register A for Slave 3 */
59#define AT91_MATRIX_PRBS3 (AT91_MATRIX + 0x9C) /* Priority Register B for Slave 3 */
60#define AT91_MATRIX_PRAS4 (AT91_MATRIX + 0xA0) /* Priority Register A for Slave 4 */
61#define AT91_MATRIX_PRBS4 (AT91_MATRIX + 0xA4) /* Priority Register B for Slave 4 */
62#define AT91_MATRIX_PRAS5 (AT91_MATRIX + 0xA8) /* Priority Register A for Slave 5 */
63#define AT91_MATRIX_PRBS5 (AT91_MATRIX + 0xAC) /* Priority Register B for Slave 5 */
64#define AT91_MATRIX_PRAS6 (AT91_MATRIX + 0xB0) /* Priority Register A for Slave 6 */
65#define AT91_MATRIX_PRBS6 (AT91_MATRIX + 0xB4) /* Priority Register B for Slave 6 */
66#define AT91_MATRIX_PRAS7 (AT91_MATRIX + 0xB8) /* Priority Register A for Slave 7 */
67#define AT91_MATRIX_PRBS7 (AT91_MATRIX + 0xBC) /* Priority Register B for Slave 7 */
68#define AT91_MATRIX_M0PR (3 << 0) /* Master 0 Priority */
69#define AT91_MATRIX_M1PR (3 << 4) /* Master 1 Priority */
70#define AT91_MATRIX_M2PR (3 << 8) /* Master 2 Priority */
71#define AT91_MATRIX_M3PR (3 << 12) /* Master 3 Priority */
72#define AT91_MATRIX_M4PR (3 << 16) /* Master 4 Priority */
73#define AT91_MATRIX_M5PR (3 << 20) /* Master 5 Priority */
74#define AT91_MATRIX_M6PR (3 << 24) /* Master 6 Priority */
75#define AT91_MATRIX_M7PR (3 << 28) /* Master 7 Priority */
76#define AT91_MATRIX_M8PR (3 << 0) /* Master 8 Priority (in Register B) */
77
78#define AT91_MATRIX_MRCR (AT91_MATRIX + 0x100) /* Master Remap Control Register */
79#define AT91_MATRIX_RCB0 (1 << 0) /* Remap Command for AHB Master 0 (ARM926EJ-S Instruction Master) */
80#define AT91_MATRIX_RCB1 (1 << 1) /* Remap Command for AHB Master 1 (ARM926EJ-S Data Master) */
81#define AT91_MATRIX_RCB2 (1 << 2)
82#define AT91_MATRIX_RCB3 (1 << 3)
83#define AT91_MATRIX_RCB4 (1 << 4)
84#define AT91_MATRIX_RCB5 (1 << 5)
85#define AT91_MATRIX_RCB6 (1 << 6)
86#define AT91_MATRIX_RCB7 (1 << 7)
87#define AT91_MATRIX_RCB8 (1 << 8)
88
89#define AT91_MATRIX_TCMR (AT91_MATRIX + 0x114) /* TCM Configuration Register */
90#define AT91_MATRIX_ITCM_SIZE (0xf << 0) /* Size of ITCM enabled memory block */
91#define AT91_MATRIX_ITCM_0 (0 << 0)
92#define AT91_MATRIX_ITCM_16 (5 << 0)
93#define AT91_MATRIX_ITCM_32 (6 << 0)
94#define AT91_MATRIX_DTCM_SIZE (0xf << 4) /* Size of DTCM enabled memory block */
95#define AT91_MATRIX_DTCM_0 (0 << 4)
96#define AT91_MATRIX_DTCM_16 (5 << 4)
97#define AT91_MATRIX_DTCM_32 (6 << 4)
98
99#define AT91_MATRIX_EBI0CSA (AT91_MATRIX + 0x120) /* EBI0 Chip Select Assignment Register */
100#define AT91_MATRIX_EBI0_CS1A (1 << 1) /* Chip Select 1 Assignment */
101#define AT91_MATRIX_EBI0_CS1A_SMC (0 << 1)
102#define AT91_MATRIX_EBI0_CS1A_SDRAMC (1 << 1)
103#define AT91_MATRIX_EBI0_CS3A (1 << 3) /* Chip Select 3 Assignment */
104#define AT91_MATRIX_EBI0_CS3A_SMC (0 << 3)
105#define AT91_MATRIX_EBI0_CS3A_SMC_SMARTMEDIA (1 << 3)
106#define AT91_MATRIX_EBI0_CS4A (1 << 4) /* Chip Select 4 Assignment */
107#define AT91_MATRIX_EBI0_CS4A_SMC (0 << 4)
108#define AT91_MATRIX_EBI0_CS4A_SMC_CF1 (1 << 4)
109#define AT91_MATRIX_EBI0_CS5A (1 << 5) /* Chip Select 5 Assignment */
110#define AT91_MATRIX_EBI0_CS5A_SMC (0 << 5)
111#define AT91_MATRIX_EBI0_CS5A_SMC_CF2 (1 << 5)
112#define AT91_MATRIX_EBI0_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */
113#define AT91_MATRIX_EBI0_VDDIOMSEL (1 << 16) /* Memory voltage selection */
114#define AT91_MATRIX_EBI0_VDDIOMSEL_1_8V (0 << 16)
115#define AT91_MATRIX_EBI0_VDDIOMSEL_3_3V (1 << 16)
116
117#define AT91_MATRIX_EBI1CSA (AT91_MATRIX + 0x124) /* EBI1 Chip Select Assignment Register */
118#define AT91_MATRIX_EBI1_CS1A (1 << 1) /* Chip Select 1 Assignment */
119#define AT91_MATRIX_EBI1_CS1A_SMC (0 << 1)
120#define AT91_MATRIX_EBI1_CS1A_SDRAMC (1 << 1)
121#define AT91_MATRIX_EBI1_CS2A (1 << 3) /* Chip Select 3 Assignment */
122#define AT91_MATRIX_EBI1_CS2A_SMC (0 << 3)
123#define AT91_MATRIX_EBI1_CS2A_SMC_SMARTMEDIA (1 << 3)
124#define AT91_MATRIX_EBI1_DBPUC (1 << 8) /* Data Bus Pull-up Configuration */
125#define AT91_MATRIX_EBI1_VDDIOMSEL (1 << 16) /* Memory voltage selection */
126#define AT91_MATRIX_EBI1_VDDIOMSEL_1_8V (0 << 16)
127#define AT91_MATRIX_EBI1_VDDIOMSEL_3_3V (1 << 16)
128
129#endif
diff --git a/include/asm-arm/arch-at91rm9200/at91sam926x_mc.h b/include/asm-arm/arch-at91/at91sam926x_mc.h
index 972e7531c7f4..d82631c251f1 100644
--- a/include/asm-arm/arch-at91rm9200/at91sam926x_mc.h
+++ b/include/asm-arm/arch-at91/at91sam926x_mc.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/at91sam926x_mc.h 2 * include/asm-arm/arch-at91/at91sam926x_mc.h
3 * 3 *
4 * Memory Controllers (SMC, SDRAMC) - System peripherals registers. 4 * Memory Controllers (SMC, SDRAMC) - System peripherals registers.
5 * Based on AT91SAM9261 datasheet revision D. 5 * Based on AT91SAM9261 datasheet revision D.
@@ -131,4 +131,11 @@
131#define AT91_SMC_PS_16 (2 << 28) 131#define AT91_SMC_PS_16 (2 << 28)
132#define AT91_SMC_PS_32 (3 << 28) 132#define AT91_SMC_PS_32 (3 << 28)
133 133
134#if defined(AT91_SMC1) /* The AT91SAM9263 has 2 Static Memory contollers */
135#define AT91_SMC1_SETUP(n) (AT91_SMC1 + 0x00 + ((n)*0x10)) /* Setup Register for CS n */
136#define AT91_SMC1_PULSE(n) (AT91_SMC1 + 0x04 + ((n)*0x10)) /* Pulse Register for CS n */
137#define AT91_SMC1_CYCLE(n) (AT91_SMC1 + 0x08 + ((n)*0x10)) /* Cycle Register for CS n */
138#define AT91_SMC1_MODE(n) (AT91_SMC1 + 0x0c + ((n)*0x10)) /* Mode Register for CS n */
139#endif
140
134#endif 141#endif
diff --git a/include/asm-arm/arch-at91rm9200/board.h b/include/asm-arm/arch-at91/board.h
index 768e0fc6aa2f..7b9903c2c447 100644
--- a/include/asm-arm/arch-at91rm9200/board.h
+++ b/include/asm-arm/arch-at91/board.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/board.h 2 * include/asm-arm/arch-at91/board.h
3 * 3 *
4 * Copyright (C) 2005 HP Labs 4 * Copyright (C) 2005 HP Labs
5 * 5 *
@@ -60,7 +60,7 @@ struct at91_mmc_data {
60 u8 wp_pin; /* (SD) writeprotect detect */ 60 u8 wp_pin; /* (SD) writeprotect detect */
61 u8 vcc_pin; /* power switching (high == on) */ 61 u8 vcc_pin; /* power switching (high == on) */
62}; 62};
63extern void __init at91_add_device_mmc(struct at91_mmc_data *data); 63extern void __init at91_add_device_mmc(short mmc_id, struct at91_mmc_data *data);
64 64
65 /* Ethernet */ 65 /* Ethernet */
66struct at91_eth_data { 66struct at91_eth_data {
@@ -69,9 +69,14 @@ struct at91_eth_data {
69}; 69};
70extern void __init at91_add_device_eth(struct at91_eth_data *data); 70extern void __init at91_add_device_eth(struct at91_eth_data *data);
71 71
72#if defined(CONFIG_ARCH_AT91SAM9260) || defined(CONFIG_ARCH_AT91SAM9263)
73#define eth_platform_data at91_eth_data
74#endif
75
72 /* USB Host */ 76 /* USB Host */
73struct at91_usbh_data { 77struct at91_usbh_data {
74 u8 ports; /* number of ports on root hub */ 78 u8 ports; /* number of ports on root hub */
79 u8 vbus_pin[]; /* port power-control pin */
75}; 80};
76extern void __init at91_add_device_usbh(struct at91_usbh_data *data); 81extern void __init at91_add_device_usbh(struct at91_usbh_data *data);
77 82
diff --git a/include/asm-arm/arch-at91rm9200/cpu.h b/include/asm-arm/arch-at91/cpu.h
index 6f8d09b08692..d464ca58cdbc 100644
--- a/include/asm-arm/arch-at91rm9200/cpu.h
+++ b/include/asm-arm/arch-at91/cpu.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/cpu.h 2 * include/asm-arm/arch-at91/cpu.h
3 * 3 *
4 * Copyright (C) 2006 SAN People 4 * Copyright (C) 2006 SAN People
5 * 5 *
@@ -20,7 +20,11 @@
20#define ARCH_ID_AT91RM9200 0x09290780 20#define ARCH_ID_AT91RM9200 0x09290780
21#define ARCH_ID_AT91SAM9260 0x019803a0 21#define ARCH_ID_AT91SAM9260 0x019803a0
22#define ARCH_ID_AT91SAM9261 0x019703a0 22#define ARCH_ID_AT91SAM9261 0x019703a0
23#define ARCH_ID_AT91SAM9263 0x019607a0
23 24
25#define ARCH_ID_AT91SAM9XE128 0x329973a0
26#define ARCH_ID_AT91SAM9XE256 0x329a93a0
27#define ARCH_ID_AT91SAM9XE512 0x329aa3a0
24 28
25static inline unsigned long at91_cpu_identify(void) 29static inline unsigned long at91_cpu_identify(void)
26{ 30{
@@ -28,6 +32,16 @@ static inline unsigned long at91_cpu_identify(void)
28} 32}
29 33
30 34
35#define ARCH_FAMILY_AT91X92 0x09200000
36#define ARCH_FAMILY_AT91SAM9 0x01900000
37#define ARCH_FAMILY_AT91SAM9XE 0x02900000
38
39static inline unsigned long at91_arch_identify(void)
40{
41 return (at91_sys_read(AT91_DBGU_CIDR) & AT91_CIDR_ARCH);
42}
43
44
31#ifdef CONFIG_ARCH_AT91RM9200 45#ifdef CONFIG_ARCH_AT91RM9200
32#define cpu_is_at91rm9200() (at91_cpu_identify() == ARCH_ID_AT91RM9200) 46#define cpu_is_at91rm9200() (at91_cpu_identify() == ARCH_ID_AT91RM9200)
33#else 47#else
@@ -35,8 +49,10 @@ static inline unsigned long at91_cpu_identify(void)
35#endif 49#endif
36 50
37#ifdef CONFIG_ARCH_AT91SAM9260 51#ifdef CONFIG_ARCH_AT91SAM9260
38#define cpu_is_at91sam9260() (at91_cpu_identify() == ARCH_ID_AT91SAM9260) 52#define cpu_is_at91sam9xe() (at91_arch_identify() == ARCH_FAMILY_AT91SAM9XE)
53#define cpu_is_at91sam9260() ((at91_cpu_identify() == ARCH_ID_AT91SAM9260) || cpu_is_at91sam9xe())
39#else 54#else
55#define cpu_is_at91sam9xe() (0)
40#define cpu_is_at91sam9260() (0) 56#define cpu_is_at91sam9260() (0)
41#endif 57#endif
42 58
@@ -46,4 +62,10 @@ static inline unsigned long at91_cpu_identify(void)
46#define cpu_is_at91sam9261() (0) 62#define cpu_is_at91sam9261() (0)
47#endif 63#endif
48 64
65#ifdef CONFIG_ARCH_AT91SAM9263
66#define cpu_is_at91sam9263() (at91_cpu_identify() == ARCH_ID_AT91SAM9263)
67#else
68#define cpu_is_at91sam9263() (0)
69#endif
70
49#endif 71#endif
diff --git a/include/asm-arm/arch-at91/debug-macro.S b/include/asm-arm/arch-at91/debug-macro.S
new file mode 100644
index 000000000000..13e9f5e1d4ff
--- /dev/null
+++ b/include/asm-arm/arch-at91/debug-macro.S
@@ -0,0 +1,39 @@
1/*
2 * include/asm-arm/arch-at91/debug-macro.S
3 *
4 * Copyright (C) 2003-2005 SAN People
5 *
6 * Debugging macro include header
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 version 2 as
10 * published by the Free Software Foundation.
11 *
12*/
13
14#include <asm/hardware.h>
15#include <asm/arch/at91_dbgu.h>
16
17 .macro addruart,rx
18 mrc p15, 0, \rx, c1, c0
19 tst \rx, #1 @ MMU enabled?
20 ldreq \rx, =(AT91_BASE_SYS + AT91_DBGU) @ System peripherals (phys address)
21 ldrne \rx, =(AT91_VA_BASE_SYS + AT91_DBGU) @ System peripherals (virt address)
22 .endm
23
24 .macro senduart,rd,rx
25 strb \rd, [\rx, #(AT91_DBGU_THR - AT91_DBGU)] @ Write to Transmitter Holding Register
26 .endm
27
28 .macro waituart,rd,rx
291001: ldr \rd, [\rx, #(AT91_DBGU_SR - AT91_DBGU)] @ Read Status Register
30 tst \rd, #AT91_DBGU_TXRDY @ DBGU_TXRDY = 1 when ready to transmit
31 beq 1001b
32 .endm
33
34 .macro busyuart,rd,rx
351001: ldr \rd, [\rx, #(AT91_DBGU_SR - AT91_DBGU)] @ Read Status Register
36 tst \rd, #AT91_DBGU_TXEMPTY @ DBGU_TXEMPTY = 1 when transmission complete
37 beq 1001b
38 .endm
39
diff --git a/include/asm-arm/arch-at91rm9200/dma.h b/include/asm-arm/arch-at91/dma.h
index 22c1dfdd8da3..774565412beb 100644
--- a/include/asm-arm/arch-at91rm9200/dma.h
+++ b/include/asm-arm/arch-at91/dma.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/dma.h 2 * include/asm-arm/arch-at91/dma.h
3 * 3 *
4 * Copyright (C) 2003 SAN People 4 * Copyright (C) 2003 SAN People
5 * 5 *
diff --git a/include/asm-arm/arch-at91/entry-macro.S b/include/asm-arm/arch-at91/entry-macro.S
new file mode 100644
index 000000000000..76c8cccf73aa
--- /dev/null
+++ b/include/asm-arm/arch-at91/entry-macro.S
@@ -0,0 +1,26 @@
1/*
2 * include/asm-arm/arch-at91/entry-macro.S
3 *
4 * Copyright (C) 2003-2005 SAN People
5 *
6 * Low-level IRQ helper macros for AT91RM9200 platforms
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13#include <asm/hardware.h>
14#include <asm/arch/at91_aic.h>
15
16 .macro disable_fiq
17 .endm
18
19 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
20 ldr \base, =(AT91_VA_BASE_SYS + AT91_AIC) @ base virtual address of AIC peripheral
21 ldr \irqnr, [\base, #(AT91_AIC_IVR - AT91_AIC)] @ read IRQ vector register: de-asserts nIRQ to processor (and clears interrupt)
22 ldr \irqstat, [\base, #(AT91_AIC_ISR - AT91_AIC)] @ read interrupt source number
23 teq \irqstat, #0 @ ISR is 0 when no current interrupt, or spurious interrupt
24 streq \tmp, [\base, #(AT91_AIC_EOICR - AT91_AIC)] @ not going to be handled further, then ACK it now.
25 .endm
26
diff --git a/include/asm-arm/arch-at91rm9200/gpio.h b/include/asm-arm/arch-at91/gpio.h
index e09d6528fadf..98ad2114f43a 100644
--- a/include/asm-arm/arch-at91rm9200/gpio.h
+++ b/include/asm-arm/arch-at91/gpio.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/gpio.h 2 * include/asm-arm/arch-at91/gpio.h
3 * 3 *
4 * Copyright (C) 2005 HP Labs 4 * Copyright (C) 2005 HP Labs
5 * 5 *
@@ -17,7 +17,7 @@
17 17
18#define PIN_BASE NR_AIC_IRQS 18#define PIN_BASE NR_AIC_IRQS
19 19
20#define MAX_GPIO_BANKS 4 20#define MAX_GPIO_BANKS 5
21 21
22/* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */ 22/* these pin numbers double as IRQ numbers, like AT91xxx_ID_* values */
23 23
@@ -26,37 +26,31 @@
26#define AT91_PIN_PA2 (PIN_BASE + 0x00 + 2) 26#define AT91_PIN_PA2 (PIN_BASE + 0x00 + 2)
27#define AT91_PIN_PA3 (PIN_BASE + 0x00 + 3) 27#define AT91_PIN_PA3 (PIN_BASE + 0x00 + 3)
28#define AT91_PIN_PA4 (PIN_BASE + 0x00 + 4) 28#define AT91_PIN_PA4 (PIN_BASE + 0x00 + 4)
29
30#define AT91_PIN_PA5 (PIN_BASE + 0x00 + 5) 29#define AT91_PIN_PA5 (PIN_BASE + 0x00 + 5)
31#define AT91_PIN_PA6 (PIN_BASE + 0x00 + 6) 30#define AT91_PIN_PA6 (PIN_BASE + 0x00 + 6)
32#define AT91_PIN_PA7 (PIN_BASE + 0x00 + 7) 31#define AT91_PIN_PA7 (PIN_BASE + 0x00 + 7)
33#define AT91_PIN_PA8 (PIN_BASE + 0x00 + 8) 32#define AT91_PIN_PA8 (PIN_BASE + 0x00 + 8)
34#define AT91_PIN_PA9 (PIN_BASE + 0x00 + 9) 33#define AT91_PIN_PA9 (PIN_BASE + 0x00 + 9)
35
36#define AT91_PIN_PA10 (PIN_BASE + 0x00 + 10) 34#define AT91_PIN_PA10 (PIN_BASE + 0x00 + 10)
37#define AT91_PIN_PA11 (PIN_BASE + 0x00 + 11) 35#define AT91_PIN_PA11 (PIN_BASE + 0x00 + 11)
38#define AT91_PIN_PA12 (PIN_BASE + 0x00 + 12) 36#define AT91_PIN_PA12 (PIN_BASE + 0x00 + 12)
39#define AT91_PIN_PA13 (PIN_BASE + 0x00 + 13) 37#define AT91_PIN_PA13 (PIN_BASE + 0x00 + 13)
40#define AT91_PIN_PA14 (PIN_BASE + 0x00 + 14) 38#define AT91_PIN_PA14 (PIN_BASE + 0x00 + 14)
41
42#define AT91_PIN_PA15 (PIN_BASE + 0x00 + 15) 39#define AT91_PIN_PA15 (PIN_BASE + 0x00 + 15)
43#define AT91_PIN_PA16 (PIN_BASE + 0x00 + 16) 40#define AT91_PIN_PA16 (PIN_BASE + 0x00 + 16)
44#define AT91_PIN_PA17 (PIN_BASE + 0x00 + 17) 41#define AT91_PIN_PA17 (PIN_BASE + 0x00 + 17)
45#define AT91_PIN_PA18 (PIN_BASE + 0x00 + 18) 42#define AT91_PIN_PA18 (PIN_BASE + 0x00 + 18)
46#define AT91_PIN_PA19 (PIN_BASE + 0x00 + 19) 43#define AT91_PIN_PA19 (PIN_BASE + 0x00 + 19)
47
48#define AT91_PIN_PA20 (PIN_BASE + 0x00 + 20) 44#define AT91_PIN_PA20 (PIN_BASE + 0x00 + 20)
49#define AT91_PIN_PA21 (PIN_BASE + 0x00 + 21) 45#define AT91_PIN_PA21 (PIN_BASE + 0x00 + 21)
50#define AT91_PIN_PA22 (PIN_BASE + 0x00 + 22) 46#define AT91_PIN_PA22 (PIN_BASE + 0x00 + 22)
51#define AT91_PIN_PA23 (PIN_BASE + 0x00 + 23) 47#define AT91_PIN_PA23 (PIN_BASE + 0x00 + 23)
52#define AT91_PIN_PA24 (PIN_BASE + 0x00 + 24) 48#define AT91_PIN_PA24 (PIN_BASE + 0x00 + 24)
53
54#define AT91_PIN_PA25 (PIN_BASE + 0x00 + 25) 49#define AT91_PIN_PA25 (PIN_BASE + 0x00 + 25)
55#define AT91_PIN_PA26 (PIN_BASE + 0x00 + 26) 50#define AT91_PIN_PA26 (PIN_BASE + 0x00 + 26)
56#define AT91_PIN_PA27 (PIN_BASE + 0x00 + 27) 51#define AT91_PIN_PA27 (PIN_BASE + 0x00 + 27)
57#define AT91_PIN_PA28 (PIN_BASE + 0x00 + 28) 52#define AT91_PIN_PA28 (PIN_BASE + 0x00 + 28)
58#define AT91_PIN_PA29 (PIN_BASE + 0x00 + 29) 53#define AT91_PIN_PA29 (PIN_BASE + 0x00 + 29)
59
60#define AT91_PIN_PA30 (PIN_BASE + 0x00 + 30) 54#define AT91_PIN_PA30 (PIN_BASE + 0x00 + 30)
61#define AT91_PIN_PA31 (PIN_BASE + 0x00 + 31) 55#define AT91_PIN_PA31 (PIN_BASE + 0x00 + 31)
62 56
@@ -65,37 +59,31 @@
65#define AT91_PIN_PB2 (PIN_BASE + 0x20 + 2) 59#define AT91_PIN_PB2 (PIN_BASE + 0x20 + 2)
66#define AT91_PIN_PB3 (PIN_BASE + 0x20 + 3) 60#define AT91_PIN_PB3 (PIN_BASE + 0x20 + 3)
67#define AT91_PIN_PB4 (PIN_BASE + 0x20 + 4) 61#define AT91_PIN_PB4 (PIN_BASE + 0x20 + 4)
68
69#define AT91_PIN_PB5 (PIN_BASE + 0x20 + 5) 62#define AT91_PIN_PB5 (PIN_BASE + 0x20 + 5)
70#define AT91_PIN_PB6 (PIN_BASE + 0x20 + 6) 63#define AT91_PIN_PB6 (PIN_BASE + 0x20 + 6)
71#define AT91_PIN_PB7 (PIN_BASE + 0x20 + 7) 64#define AT91_PIN_PB7 (PIN_BASE + 0x20 + 7)
72#define AT91_PIN_PB8 (PIN_BASE + 0x20 + 8) 65#define AT91_PIN_PB8 (PIN_BASE + 0x20 + 8)
73#define AT91_PIN_PB9 (PIN_BASE + 0x20 + 9) 66#define AT91_PIN_PB9 (PIN_BASE + 0x20 + 9)
74
75#define AT91_PIN_PB10 (PIN_BASE + 0x20 + 10) 67#define AT91_PIN_PB10 (PIN_BASE + 0x20 + 10)
76#define AT91_PIN_PB11 (PIN_BASE + 0x20 + 11) 68#define AT91_PIN_PB11 (PIN_BASE + 0x20 + 11)
77#define AT91_PIN_PB12 (PIN_BASE + 0x20 + 12) 69#define AT91_PIN_PB12 (PIN_BASE + 0x20 + 12)
78#define AT91_PIN_PB13 (PIN_BASE + 0x20 + 13) 70#define AT91_PIN_PB13 (PIN_BASE + 0x20 + 13)
79#define AT91_PIN_PB14 (PIN_BASE + 0x20 + 14) 71#define AT91_PIN_PB14 (PIN_BASE + 0x20 + 14)
80
81#define AT91_PIN_PB15 (PIN_BASE + 0x20 + 15) 72#define AT91_PIN_PB15 (PIN_BASE + 0x20 + 15)
82#define AT91_PIN_PB16 (PIN_BASE + 0x20 + 16) 73#define AT91_PIN_PB16 (PIN_BASE + 0x20 + 16)
83#define AT91_PIN_PB17 (PIN_BASE + 0x20 + 17) 74#define AT91_PIN_PB17 (PIN_BASE + 0x20 + 17)
84#define AT91_PIN_PB18 (PIN_BASE + 0x20 + 18) 75#define AT91_PIN_PB18 (PIN_BASE + 0x20 + 18)
85#define AT91_PIN_PB19 (PIN_BASE + 0x20 + 19) 76#define AT91_PIN_PB19 (PIN_BASE + 0x20 + 19)
86
87#define AT91_PIN_PB20 (PIN_BASE + 0x20 + 20) 77#define AT91_PIN_PB20 (PIN_BASE + 0x20 + 20)
88#define AT91_PIN_PB21 (PIN_BASE + 0x20 + 21) 78#define AT91_PIN_PB21 (PIN_BASE + 0x20 + 21)
89#define AT91_PIN_PB22 (PIN_BASE + 0x20 + 22) 79#define AT91_PIN_PB22 (PIN_BASE + 0x20 + 22)
90#define AT91_PIN_PB23 (PIN_BASE + 0x20 + 23) 80#define AT91_PIN_PB23 (PIN_BASE + 0x20 + 23)
91#define AT91_PIN_PB24 (PIN_BASE + 0x20 + 24) 81#define AT91_PIN_PB24 (PIN_BASE + 0x20 + 24)
92
93#define AT91_PIN_PB25 (PIN_BASE + 0x20 + 25) 82#define AT91_PIN_PB25 (PIN_BASE + 0x20 + 25)
94#define AT91_PIN_PB26 (PIN_BASE + 0x20 + 26) 83#define AT91_PIN_PB26 (PIN_BASE + 0x20 + 26)
95#define AT91_PIN_PB27 (PIN_BASE + 0x20 + 27) 84#define AT91_PIN_PB27 (PIN_BASE + 0x20 + 27)
96#define AT91_PIN_PB28 (PIN_BASE + 0x20 + 28) 85#define AT91_PIN_PB28 (PIN_BASE + 0x20 + 28)
97#define AT91_PIN_PB29 (PIN_BASE + 0x20 + 29) 86#define AT91_PIN_PB29 (PIN_BASE + 0x20 + 29)
98
99#define AT91_PIN_PB30 (PIN_BASE + 0x20 + 30) 87#define AT91_PIN_PB30 (PIN_BASE + 0x20 + 30)
100#define AT91_PIN_PB31 (PIN_BASE + 0x20 + 31) 88#define AT91_PIN_PB31 (PIN_BASE + 0x20 + 31)
101 89
@@ -104,37 +92,31 @@
104#define AT91_PIN_PC2 (PIN_BASE + 0x40 + 2) 92#define AT91_PIN_PC2 (PIN_BASE + 0x40 + 2)
105#define AT91_PIN_PC3 (PIN_BASE + 0x40 + 3) 93#define AT91_PIN_PC3 (PIN_BASE + 0x40 + 3)
106#define AT91_PIN_PC4 (PIN_BASE + 0x40 + 4) 94#define AT91_PIN_PC4 (PIN_BASE + 0x40 + 4)
107
108#define AT91_PIN_PC5 (PIN_BASE + 0x40 + 5) 95#define AT91_PIN_PC5 (PIN_BASE + 0x40 + 5)
109#define AT91_PIN_PC6 (PIN_BASE + 0x40 + 6) 96#define AT91_PIN_PC6 (PIN_BASE + 0x40 + 6)
110#define AT91_PIN_PC7 (PIN_BASE + 0x40 + 7) 97#define AT91_PIN_PC7 (PIN_BASE + 0x40 + 7)
111#define AT91_PIN_PC8 (PIN_BASE + 0x40 + 8) 98#define AT91_PIN_PC8 (PIN_BASE + 0x40 + 8)
112#define AT91_PIN_PC9 (PIN_BASE + 0x40 + 9) 99#define AT91_PIN_PC9 (PIN_BASE + 0x40 + 9)
113
114#define AT91_PIN_PC10 (PIN_BASE + 0x40 + 10) 100#define AT91_PIN_PC10 (PIN_BASE + 0x40 + 10)
115#define AT91_PIN_PC11 (PIN_BASE + 0x40 + 11) 101#define AT91_PIN_PC11 (PIN_BASE + 0x40 + 11)
116#define AT91_PIN_PC12 (PIN_BASE + 0x40 + 12) 102#define AT91_PIN_PC12 (PIN_BASE + 0x40 + 12)
117#define AT91_PIN_PC13 (PIN_BASE + 0x40 + 13) 103#define AT91_PIN_PC13 (PIN_BASE + 0x40 + 13)
118#define AT91_PIN_PC14 (PIN_BASE + 0x40 + 14) 104#define AT91_PIN_PC14 (PIN_BASE + 0x40 + 14)
119
120#define AT91_PIN_PC15 (PIN_BASE + 0x40 + 15) 105#define AT91_PIN_PC15 (PIN_BASE + 0x40 + 15)
121#define AT91_PIN_PC16 (PIN_BASE + 0x40 + 16) 106#define AT91_PIN_PC16 (PIN_BASE + 0x40 + 16)
122#define AT91_PIN_PC17 (PIN_BASE + 0x40 + 17) 107#define AT91_PIN_PC17 (PIN_BASE + 0x40 + 17)
123#define AT91_PIN_PC18 (PIN_BASE + 0x40 + 18) 108#define AT91_PIN_PC18 (PIN_BASE + 0x40 + 18)
124#define AT91_PIN_PC19 (PIN_BASE + 0x40 + 19) 109#define AT91_PIN_PC19 (PIN_BASE + 0x40 + 19)
125
126#define AT91_PIN_PC20 (PIN_BASE + 0x40 + 20) 110#define AT91_PIN_PC20 (PIN_BASE + 0x40 + 20)
127#define AT91_PIN_PC21 (PIN_BASE + 0x40 + 21) 111#define AT91_PIN_PC21 (PIN_BASE + 0x40 + 21)
128#define AT91_PIN_PC22 (PIN_BASE + 0x40 + 22) 112#define AT91_PIN_PC22 (PIN_BASE + 0x40 + 22)
129#define AT91_PIN_PC23 (PIN_BASE + 0x40 + 23) 113#define AT91_PIN_PC23 (PIN_BASE + 0x40 + 23)
130#define AT91_PIN_PC24 (PIN_BASE + 0x40 + 24) 114#define AT91_PIN_PC24 (PIN_BASE + 0x40 + 24)
131
132#define AT91_PIN_PC25 (PIN_BASE + 0x40 + 25) 115#define AT91_PIN_PC25 (PIN_BASE + 0x40 + 25)
133#define AT91_PIN_PC26 (PIN_BASE + 0x40 + 26) 116#define AT91_PIN_PC26 (PIN_BASE + 0x40 + 26)
134#define AT91_PIN_PC27 (PIN_BASE + 0x40 + 27) 117#define AT91_PIN_PC27 (PIN_BASE + 0x40 + 27)
135#define AT91_PIN_PC28 (PIN_BASE + 0x40 + 28) 118#define AT91_PIN_PC28 (PIN_BASE + 0x40 + 28)
136#define AT91_PIN_PC29 (PIN_BASE + 0x40 + 29) 119#define AT91_PIN_PC29 (PIN_BASE + 0x40 + 29)
137
138#define AT91_PIN_PC30 (PIN_BASE + 0x40 + 30) 120#define AT91_PIN_PC30 (PIN_BASE + 0x40 + 30)
139#define AT91_PIN_PC31 (PIN_BASE + 0x40 + 31) 121#define AT91_PIN_PC31 (PIN_BASE + 0x40 + 31)
140 122
@@ -143,40 +125,67 @@
143#define AT91_PIN_PD2 (PIN_BASE + 0x60 + 2) 125#define AT91_PIN_PD2 (PIN_BASE + 0x60 + 2)
144#define AT91_PIN_PD3 (PIN_BASE + 0x60 + 3) 126#define AT91_PIN_PD3 (PIN_BASE + 0x60 + 3)
145#define AT91_PIN_PD4 (PIN_BASE + 0x60 + 4) 127#define AT91_PIN_PD4 (PIN_BASE + 0x60 + 4)
146
147#define AT91_PIN_PD5 (PIN_BASE + 0x60 + 5) 128#define AT91_PIN_PD5 (PIN_BASE + 0x60 + 5)
148#define AT91_PIN_PD6 (PIN_BASE + 0x60 + 6) 129#define AT91_PIN_PD6 (PIN_BASE + 0x60 + 6)
149#define AT91_PIN_PD7 (PIN_BASE + 0x60 + 7) 130#define AT91_PIN_PD7 (PIN_BASE + 0x60 + 7)
150#define AT91_PIN_PD8 (PIN_BASE + 0x60 + 8) 131#define AT91_PIN_PD8 (PIN_BASE + 0x60 + 8)
151#define AT91_PIN_PD9 (PIN_BASE + 0x60 + 9) 132#define AT91_PIN_PD9 (PIN_BASE + 0x60 + 9)
152
153#define AT91_PIN_PD10 (PIN_BASE + 0x60 + 10) 133#define AT91_PIN_PD10 (PIN_BASE + 0x60 + 10)
154#define AT91_PIN_PD11 (PIN_BASE + 0x60 + 11) 134#define AT91_PIN_PD11 (PIN_BASE + 0x60 + 11)
155#define AT91_PIN_PD12 (PIN_BASE + 0x60 + 12) 135#define AT91_PIN_PD12 (PIN_BASE + 0x60 + 12)
156#define AT91_PIN_PD13 (PIN_BASE + 0x60 + 13) 136#define AT91_PIN_PD13 (PIN_BASE + 0x60 + 13)
157#define AT91_PIN_PD14 (PIN_BASE + 0x60 + 14) 137#define AT91_PIN_PD14 (PIN_BASE + 0x60 + 14)
158
159#define AT91_PIN_PD15 (PIN_BASE + 0x60 + 15) 138#define AT91_PIN_PD15 (PIN_BASE + 0x60 + 15)
160#define AT91_PIN_PD16 (PIN_BASE + 0x60 + 16) 139#define AT91_PIN_PD16 (PIN_BASE + 0x60 + 16)
161#define AT91_PIN_PD17 (PIN_BASE + 0x60 + 17) 140#define AT91_PIN_PD17 (PIN_BASE + 0x60 + 17)
162#define AT91_PIN_PD18 (PIN_BASE + 0x60 + 18) 141#define AT91_PIN_PD18 (PIN_BASE + 0x60 + 18)
163#define AT91_PIN_PD19 (PIN_BASE + 0x60 + 19) 142#define AT91_PIN_PD19 (PIN_BASE + 0x60 + 19)
164
165#define AT91_PIN_PD20 (PIN_BASE + 0x60 + 20) 143#define AT91_PIN_PD20 (PIN_BASE + 0x60 + 20)
166#define AT91_PIN_PD21 (PIN_BASE + 0x60 + 21) 144#define AT91_PIN_PD21 (PIN_BASE + 0x60 + 21)
167#define AT91_PIN_PD22 (PIN_BASE + 0x60 + 22) 145#define AT91_PIN_PD22 (PIN_BASE + 0x60 + 22)
168#define AT91_PIN_PD23 (PIN_BASE + 0x60 + 23) 146#define AT91_PIN_PD23 (PIN_BASE + 0x60 + 23)
169#define AT91_PIN_PD24 (PIN_BASE + 0x60 + 24) 147#define AT91_PIN_PD24 (PIN_BASE + 0x60 + 24)
170
171#define AT91_PIN_PD25 (PIN_BASE + 0x60 + 25) 148#define AT91_PIN_PD25 (PIN_BASE + 0x60 + 25)
172#define AT91_PIN_PD26 (PIN_BASE + 0x60 + 26) 149#define AT91_PIN_PD26 (PIN_BASE + 0x60 + 26)
173#define AT91_PIN_PD27 (PIN_BASE + 0x60 + 27) 150#define AT91_PIN_PD27 (PIN_BASE + 0x60 + 27)
174#define AT91_PIN_PD28 (PIN_BASE + 0x60 + 28) 151#define AT91_PIN_PD28 (PIN_BASE + 0x60 + 28)
175#define AT91_PIN_PD29 (PIN_BASE + 0x60 + 29) 152#define AT91_PIN_PD29 (PIN_BASE + 0x60 + 29)
176
177#define AT91_PIN_PD30 (PIN_BASE + 0x60 + 30) 153#define AT91_PIN_PD30 (PIN_BASE + 0x60 + 30)
178#define AT91_PIN_PD31 (PIN_BASE + 0x60 + 31) 154#define AT91_PIN_PD31 (PIN_BASE + 0x60 + 31)
179 155
156#define AT91_PIN_PE0 (PIN_BASE + 0x80 + 0)
157#define AT91_PIN_PE1 (PIN_BASE + 0x80 + 1)
158#define AT91_PIN_PE2 (PIN_BASE + 0x80 + 2)
159#define AT91_PIN_PE3 (PIN_BASE + 0x80 + 3)
160#define AT91_PIN_PE4 (PIN_BASE + 0x80 + 4)
161#define AT91_PIN_PE5 (PIN_BASE + 0x80 + 5)
162#define AT91_PIN_PE6 (PIN_BASE + 0x80 + 6)
163#define AT91_PIN_PE7 (PIN_BASE + 0x80 + 7)
164#define AT91_PIN_PE8 (PIN_BASE + 0x80 + 8)
165#define AT91_PIN_PE9 (PIN_BASE + 0x80 + 9)
166#define AT91_PIN_PE10 (PIN_BASE + 0x80 + 10)
167#define AT91_PIN_PE11 (PIN_BASE + 0x80 + 11)
168#define AT91_PIN_PE12 (PIN_BASE + 0x80 + 12)
169#define AT91_PIN_PE13 (PIN_BASE + 0x80 + 13)
170#define AT91_PIN_PE14 (PIN_BASE + 0x80 + 14)
171#define AT91_PIN_PE15 (PIN_BASE + 0x80 + 15)
172#define AT91_PIN_PE16 (PIN_BASE + 0x80 + 16)
173#define AT91_PIN_PE17 (PIN_BASE + 0x80 + 17)
174#define AT91_PIN_PE18 (PIN_BASE + 0x80 + 18)
175#define AT91_PIN_PE19 (PIN_BASE + 0x80 + 19)
176#define AT91_PIN_PE20 (PIN_BASE + 0x80 + 20)
177#define AT91_PIN_PE21 (PIN_BASE + 0x80 + 21)
178#define AT91_PIN_PE22 (PIN_BASE + 0x80 + 22)
179#define AT91_PIN_PE23 (PIN_BASE + 0x80 + 23)
180#define AT91_PIN_PE24 (PIN_BASE + 0x80 + 24)
181#define AT91_PIN_PE25 (PIN_BASE + 0x80 + 25)
182#define AT91_PIN_PE26 (PIN_BASE + 0x80 + 26)
183#define AT91_PIN_PE27 (PIN_BASE + 0x80 + 27)
184#define AT91_PIN_PE28 (PIN_BASE + 0x80 + 28)
185#define AT91_PIN_PE29 (PIN_BASE + 0x80 + 29)
186#define AT91_PIN_PE30 (PIN_BASE + 0x80 + 30)
187#define AT91_PIN_PE31 (PIN_BASE + 0x80 + 31)
188
180#ifndef __ASSEMBLY__ 189#ifndef __ASSEMBLY__
181/* setup setup routines, called from board init or driver probe() */ 190/* setup setup routines, called from board init or driver probe() */
182extern int __init_or_module at91_set_GPIO_periph(unsigned pin, int use_pullup); 191extern int __init_or_module at91_set_GPIO_periph(unsigned pin, int use_pullup);
diff --git a/include/asm-arm/arch-at91rm9200/hardware.h b/include/asm-arm/arch-at91/hardware.h
index 9ea5bfe06320..eaaf1c12b753 100644
--- a/include/asm-arm/arch-at91rm9200/hardware.h
+++ b/include/asm-arm/arch-at91/hardware.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/hardware.h 2 * include/asm-arm/arch-at91/hardware.h
3 * 3 *
4 * Copyright (C) 2003 SAN People 4 * Copyright (C) 2003 SAN People
5 * Copyright (C) 2003 ATMEL 5 * Copyright (C) 2003 ATMEL
@@ -22,21 +22,23 @@
22#include <asm/arch/at91sam9260.h> 22#include <asm/arch/at91sam9260.h>
23#elif defined(CONFIG_ARCH_AT91SAM9261) 23#elif defined(CONFIG_ARCH_AT91SAM9261)
24#include <asm/arch/at91sam9261.h> 24#include <asm/arch/at91sam9261.h>
25#elif defined(CONFIG_ARCH_AT91SAM9263)
26#include <asm/arch/at91sam9263.h>
25#else 27#else
26#error "Unsupported AT91 processor" 28#error "Unsupported AT91 processor"
27#endif 29#endif
28 30
29 31
30/* 32/*
31 * Remap the peripherals from address 0xFFFA0000 .. 0xFFFFFFFF 33 * Remap the peripherals from address 0xFFF78000 .. 0xFFFFFFFF
32 * to 0xFEFA0000 .. 0xFF000000. (384Kb) 34 * to 0xFEF78000 .. 0xFF000000. (5444Kb)
33 */ 35 */
34#define AT91_IO_PHYS_BASE 0xFFFA0000 36#define AT91_IO_PHYS_BASE 0xFFF78000
35#define AT91_IO_SIZE (0xFFFFFFFF - AT91_IO_PHYS_BASE + 1) 37#define AT91_IO_SIZE (0xFFFFFFFF - AT91_IO_PHYS_BASE + 1)
36#define AT91_IO_VIRT_BASE (0xFF000000 - AT91_IO_SIZE) 38#define AT91_IO_VIRT_BASE (0xFF000000 - AT91_IO_SIZE)
37 39
38 /* Convert a physical IO address to virtual IO address */ 40 /* Convert a physical IO address to virtual IO address */
39#define AT91_IO_P2V(x) ((x) - AT91_IO_PHYS_BASE + AT91_IO_VIRT_BASE) 41#define AT91_IO_P2V(x) ((x) - AT91_IO_PHYS_BASE + AT91_IO_VIRT_BASE)
40 42
41/* 43/*
42 * Virtual to Physical Address mapping for IO devices. 44 * Virtual to Physical Address mapping for IO devices.
diff --git a/include/asm-arm/arch-at91rm9200/io.h b/include/asm-arm/arch-at91/io.h
index 88fd1bebcef3..401f327ec047 100644
--- a/include/asm-arm/arch-at91rm9200/io.h
+++ b/include/asm-arm/arch-at91/io.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/io.h 2 * include/asm-arm/arch-at91/io.h
3 * 3 *
4 * Copyright (C) 2003 SAN People 4 * Copyright (C) 2003 SAN People
5 * 5 *
diff --git a/include/asm-arm/arch-at91rm9200/irqs.h b/include/asm-arm/arch-at91/irqs.h
index c0679eaefaf2..1ffa3bb9a9c1 100644
--- a/include/asm-arm/arch-at91rm9200/irqs.h
+++ b/include/asm-arm/arch-at91/irqs.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/irqs.h 2 * include/asm-arm/arch-at91/irqs.h
3 * 3 *
4 * Copyright (C) 2004 SAN People 4 * Copyright (C) 2004 SAN People
5 * 5 *
@@ -37,8 +37,8 @@
37 * IRQ interrupt symbols are the AT91xxx_ID_* symbols 37 * IRQ interrupt symbols are the AT91xxx_ID_* symbols
38 * for IRQs handled directly through the AIC, or else the AT91_PIN_* 38 * for IRQs handled directly through the AIC, or else the AT91_PIN_*
39 * symbols in gpio.h for ones handled indirectly as GPIOs. 39 * symbols in gpio.h for ones handled indirectly as GPIOs.
40 * We make provision for 4 banks of GPIO. 40 * We make provision for 5 banks of GPIO.
41 */ 41 */
42#define NR_IRQS (NR_AIC_IRQS + (4 * 32)) 42#define NR_IRQS (NR_AIC_IRQS + (5 * 32))
43 43
44#endif 44#endif
diff --git a/include/asm-arm/arch-at91rm9200/memory.h b/include/asm-arm/arch-at91/memory.h
index f985069e6d01..4835d6784509 100644
--- a/include/asm-arm/arch-at91rm9200/memory.h
+++ b/include/asm-arm/arch-at91/memory.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/memory.h 2 * include/asm-arm/arch-at91/memory.h
3 * 3 *
4 * Copyright (C) 2004 SAN People 4 * Copyright (C) 2004 SAN People
5 * 5 *
diff --git a/include/asm-arm/arch-at91rm9200/system.h b/include/asm-arm/arch-at91/system.h
index 9c67130603b2..6bf846098ea9 100644
--- a/include/asm-arm/arch-at91rm9200/system.h
+++ b/include/asm-arm/arch-at91/system.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/system.h 2 * include/asm-arm/arch-at91/system.h
3 * 3 *
4 * Copyright (C) 2003 SAN People 4 * Copyright (C) 2003 SAN People
5 * 5 *
diff --git a/include/asm-arm/arch-at91rm9200/timex.h b/include/asm-arm/arch-at91/timex.h
index faeca45a8d44..f41636d607a2 100644
--- a/include/asm-arm/arch-at91rm9200/timex.h
+++ b/include/asm-arm/arch-at91/timex.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/timex.h 2 * include/asm-arm/arch-at91/timex.h
3 * 3 *
4 * Copyright (C) 2003 SAN People 4 * Copyright (C) 2003 SAN People
5 * 5 *
@@ -32,6 +32,11 @@
32#define AT91SAM9_MASTER_CLOCK 99300000 32#define AT91SAM9_MASTER_CLOCK 99300000
33#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16) 33#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
34 34
35#elif defined(CONFIG_ARCH_AT91SAM9263)
36
37#define AT91SAM9_MASTER_CLOCK 99959500
38#define CLOCK_TICK_RATE (AT91SAM9_MASTER_CLOCK/16)
39
35#endif 40#endif
36 41
37#endif 42#endif
diff --git a/include/asm-arm/arch-at91rm9200/uncompress.h b/include/asm-arm/arch-at91/uncompress.h
index 34b4b93fa015..a193d28304b6 100644
--- a/include/asm-arm/arch-at91rm9200/uncompress.h
+++ b/include/asm-arm/arch-at91/uncompress.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/uncompress.h 2 * include/asm-arm/arch-at91/uncompress.h
3 * 3 *
4 * Copyright (C) 2003 SAN People 4 * Copyright (C) 2003 SAN People
5 * 5 *
diff --git a/include/asm-arm/arch-at91rm9200/vmalloc.h b/include/asm-arm/arch-at91/vmalloc.h
index 0a23b8c562b9..bb05e70e932a 100644
--- a/include/asm-arm/arch-at91rm9200/vmalloc.h
+++ b/include/asm-arm/arch-at91/vmalloc.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * include/asm-arm/arch-at91rm9200/vmalloc.h 2 * include/asm-arm/arch-at91/vmalloc.h
3 * 3 *
4 * Copyright (C) 2003 SAN People 4 * Copyright (C) 2003 SAN People
5 * 5 *
diff --git a/include/asm-arm/arch-at91rm9200/at91_pdc.h b/include/asm-arm/arch-at91rm9200/at91_pdc.h
deleted file mode 100644
index 79d6e02fa45e..000000000000
--- a/include/asm-arm/arch-at91rm9200/at91_pdc.h
+++ /dev/null
@@ -1,36 +0,0 @@
1/*
2 * include/asm-arm/arch-at91rm9200/at91_pdc.h
3 *
4 * Copyright (C) 2005 Ivan Kokshaysky
5 * Copyright (C) SAN People
6 *
7 * Peripheral Data Controller (PDC) registers.
8 * Based on AT91RM9200 datasheet revision E.
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 of the License, or
13 * (at your option) any later version.
14 */
15
16#ifndef AT91_PDC_H
17#define AT91_PDC_H
18
19#define AT91_PDC_RPR 0x100 /* Receive Pointer Register */
20#define AT91_PDC_RCR 0x104 /* Receive Counter Register */
21#define AT91_PDC_TPR 0x108 /* Transmit Pointer Register */
22#define AT91_PDC_TCR 0x10c /* Transmit Counter Register */
23#define AT91_PDC_RNPR 0x110 /* Receive Next Pointer Register */
24#define AT91_PDC_RNCR 0x114 /* Receive Next Counter Register */
25#define AT91_PDC_TNPR 0x118 /* Transmit Next Pointer Register */
26#define AT91_PDC_TNCR 0x11c /* Transmit Next Counter Register */
27
28#define AT91_PDC_PTCR 0x120 /* Transfer Control Register */
29#define AT91_PDC_RXTEN (1 << 0) /* Receiver Transfer Enable */
30#define AT91_PDC_RXTDIS (1 << 1) /* Receiver Transfer Disable */
31#define AT91_PDC_TXTEN (1 << 8) /* Transmitter Transfer Enable */
32#define AT91_PDC_TXTDIS (1 << 9) /* Transmitter Transfer Disable */
33
34#define AT91_PDC_PTSR 0x124 /* Transfer Status Register */
35
36#endif
diff --git a/include/asm-arm/arch-at91rm9200/debug-macro.S b/include/asm-arm/arch-at91rm9200/debug-macro.S
deleted file mode 100644
index 85cdadf26634..000000000000
--- a/include/asm-arm/arch-at91rm9200/debug-macro.S
+++ /dev/null
@@ -1,39 +0,0 @@
1/*
2 * include/asm-arm/arch-at91rm9200/debug-macro.S
3 *
4 * Copyright (C) 2003-2005 SAN People
5 *
6 * Debugging macro include header
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 version 2 as
10 * published by the Free Software Foundation.
11 *
12*/
13
14#include <asm/hardware.h>
15#include <asm/arch/at91_dbgu.h>
16
17 .macro addruart,rx
18 mrc p15, 0, \rx, c1, c0
19 tst \rx, #1 @ MMU enabled?
20 ldreq \rx, =AT91_BASE_SYS @ System peripherals (phys address)
21 ldrne \rx, =AT91_VA_BASE_SYS @ System peripherals (virt address)
22 .endm
23
24 .macro senduart,rd,rx
25 strb \rd, [\rx, #AT91_DBGU_THR] @ Write to Transmitter Holding Register
26 .endm
27
28 .macro waituart,rd,rx
291001: ldr \rd, [\rx, #AT91_DBGU_SR] @ Read Status Register
30 tst \rd, #AT91_DBGU_TXRDY @ DBGU_TXRDY = 1 when ready to transmit
31 beq 1001b
32 .endm
33
34 .macro busyuart,rd,rx
351001: ldr \rd, [\rx, #AT91_DBGU_SR] @ Read Status Register
36 tst \rd, #AT91_DBGU_TXEMPTY @ DBGU_TXEMPTY = 1 when transmission complete
37 beq 1001b
38 .endm
39
diff --git a/include/asm-arm/arch-at91rm9200/entry-macro.S b/include/asm-arm/arch-at91rm9200/entry-macro.S
deleted file mode 100644
index 57248a796472..000000000000
--- a/include/asm-arm/arch-at91rm9200/entry-macro.S
+++ /dev/null
@@ -1,26 +0,0 @@
1/*
2 * include/asm-arm/arch-at91rm9200/entry-macro.S
3 *
4 * Copyright (C) 2003-2005 SAN People
5 *
6 * Low-level IRQ helper macros for AT91RM9200 platforms
7 *
8 * This file is licensed under the terms of the GNU General Public
9 * License version 2. This program is licensed "as is" without any
10 * warranty of any kind, whether express or implied.
11 */
12
13#include <asm/hardware.h>
14#include <asm/arch/at91_aic.h>
15
16 .macro disable_fiq
17 .endm
18
19 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
20 ldr \base, =(AT91_VA_BASE_SYS) @ base virtual address of SYS peripherals
21 ldr \irqnr, [\base, #AT91_AIC_IVR] @ read IRQ vector register: de-asserts nIRQ to processor (and clears interrupt)
22 ldr \irqstat, [\base, #AT91_AIC_ISR] @ read interrupt source number
23 teq \irqstat, #0 @ ISR is 0 when no current interrupt, or spurious interrupt
24 streq \tmp, [\base, #AT91_AIC_EOICR] @ not going to be handled further, then ACK it now.
25 .endm
26
diff --git a/include/asm-arm/arch-ep93xx/ep93xx-regs.h b/include/asm-arm/arch-ep93xx/ep93xx-regs.h
index 593f562f85c3..625c6f0abc03 100644
--- a/include/asm-arm/arch-ep93xx/ep93xx-regs.h
+++ b/include/asm-arm/arch-ep93xx/ep93xx-regs.h
@@ -73,6 +73,11 @@
73 73
74#define EP93XX_GPIO_BASE (EP93XX_APB_VIRT_BASE + 0x00040000) 74#define EP93XX_GPIO_BASE (EP93XX_APB_VIRT_BASE + 0x00040000)
75#define EP93XX_GPIO_REG(x) (EP93XX_GPIO_BASE + (x)) 75#define EP93XX_GPIO_REG(x) (EP93XX_GPIO_BASE + (x))
76#define EP93XX_GPIO_F_INT_TYPE1 EP93XX_GPIO_REG(0x4c)
77#define EP93XX_GPIO_F_INT_TYPE2 EP93XX_GPIO_REG(0x50)
78#define EP93XX_GPIO_F_INT_ACK EP93XX_GPIO_REG(0x54)
79#define EP93XX_GPIO_F_INT_ENABLE EP93XX_GPIO_REG(0x58)
80#define EP93XX_GPIO_F_INT_STATUS EP93XX_GPIO_REG(0x5c)
76#define EP93XX_GPIO_A_INT_TYPE1 EP93XX_GPIO_REG(0x90) 81#define EP93XX_GPIO_A_INT_TYPE1 EP93XX_GPIO_REG(0x90)
77#define EP93XX_GPIO_A_INT_TYPE2 EP93XX_GPIO_REG(0x94) 82#define EP93XX_GPIO_A_INT_TYPE2 EP93XX_GPIO_REG(0x94)
78#define EP93XX_GPIO_A_INT_ACK EP93XX_GPIO_REG(0x98) 83#define EP93XX_GPIO_A_INT_ACK EP93XX_GPIO_REG(0x98)
diff --git a/include/asm-arm/arch-ep93xx/irqs.h b/include/asm-arm/arch-ep93xx/irqs.h
index ae532e304bf1..2a8c63638c5e 100644
--- a/include/asm-arm/arch-ep93xx/irqs.h
+++ b/include/asm-arm/arch-ep93xx/irqs.h
@@ -67,9 +67,13 @@
67#define IRQ_EP93XX_SAI 60 67#define IRQ_EP93XX_SAI 60
68#define EP93XX_VIC2_VALID_IRQ_MASK 0x1fffffff 68#define EP93XX_VIC2_VALID_IRQ_MASK 0x1fffffff
69 69
70#define IRQ_EP93XX_GPIO(x) (64 + (x)) 70/*
71 * Map GPIO A0..A7 to irq 64..71, B0..B7 to 72..79, and
72 * F0..F7 to 80..87.
73 */
74#define IRQ_EP93XX_GPIO(x) (64 + (((x) + (((x) >> 2) & 8)) & 0x1f))
71 75
72#define NR_EP93XX_IRQS IRQ_EP93XX_GPIO(16) 76#define NR_EP93XX_IRQS (64 + 24)
73 77
74#define EP93XX_BOARD_IRQ(x) (NR_EP93XX_IRQS + (x)) 78#define EP93XX_BOARD_IRQ(x) (NR_EP93XX_IRQS + (x))
75#define EP93XX_BOARD_IRQS 32 79#define EP93XX_BOARD_IRQS 32
diff --git a/include/asm-arm/arch-ep93xx/platform.h b/include/asm-arm/arch-ep93xx/platform.h
index b4a8deb8bdef..44eccec2cba4 100644
--- a/include/asm-arm/arch-ep93xx/platform.h
+++ b/include/asm-arm/arch-ep93xx/platform.h
@@ -8,7 +8,6 @@ void ep93xx_map_io(void);
8void ep93xx_init_irq(void); 8void ep93xx_init_irq(void);
9void ep93xx_init_time(unsigned long); 9void ep93xx_init_time(unsigned long);
10void ep93xx_init_devices(void); 10void ep93xx_init_devices(void);
11void ep93xx_clock_init(void);
12extern struct sys_timer ep93xx_timer; 11extern struct sys_timer ep93xx_timer;
13 12
14struct ep93xx_eth_data 13struct ep93xx_eth_data
diff --git a/include/asm-arm/arch-imx/entry-macro.S b/include/asm-arm/arch-imx/entry-macro.S
index 3b9ef6914627..61bb0bdc1b16 100644
--- a/include/asm-arm/arch-imx/entry-macro.S
+++ b/include/asm-arm/arch-imx/entry-macro.S
@@ -13,19 +13,13 @@
13 .endm 13 .endm
14#define AITC_NIVECSR 0x40 14#define AITC_NIVECSR 0x40
15 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp 15 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
16 ldr \irqstat, =IO_ADDRESS(IMX_AITC_BASE) 16 ldr \base, =IO_ADDRESS(IMX_AITC_BASE)
17 @ Load offset & priority of the highest priority 17 @ Load offset & priority of the highest priority
18 @ interrupt pending. 18 @ interrupt pending.
19 ldr \irqnr, [\irqstat, #AITC_NIVECSR] 19 ldr \irqstat, [\base, #AITC_NIVECSR]
20 @ Shift off the priority leaving the offset or 20 @ Shift off the priority leaving the offset or
21 @ "interrupt number" 21 @ "interrupt number", use arithmetic shift to
22 mov \irqnr, \irqnr, lsr #16 22 @ transform illegal source (0xffff) as -1
23 ldr \irqstat, =1 @ dummy compare 23 mov \irqnr, \irqstat, asr #16
24 ldr \base, =0xFFFF // invalid interrupt 24 adds \tmp, \irqnr, #1
25 cmp \irqnr, \base
26 bne 1001f
27 ldr \irqstat, =0
281001:
29 tst \irqstat, #1 @ to make the condition code = TRUE
30 .endm 25 .endm
31
diff --git a/include/asm-arm/arch-iop32x/io.h b/include/asm-arm/arch-iop32x/io.h
index 12d9ee02cde3..5f570a598a37 100644
--- a/include/asm-arm/arch-iop32x/io.h
+++ b/include/asm-arm/arch-iop32x/io.h
@@ -13,10 +13,16 @@
13 13
14#include <asm/hardware.h> 14#include <asm/hardware.h>
15 15
16#define IO_SPACE_LIMIT 0xffffffff 16extern void __iomem * __ioremap(unsigned long, size_t, unsigned long);
17extern void __iomem *__iop3xx_ioremap(unsigned long cookie, size_t size,
18 unsigned long flags);
19extern void __iop3xx_iounmap(void __iomem *addr);
17 20
18#define __io(p) ((void __iomem *)(p)) 21#define IO_SPACE_LIMIT 0xffffffff
22#define __io(p) ((void __iomem *)IOP3XX_PCI_IO_PHYS_TO_VIRT(p))
19#define __mem_pci(a) (a) 23#define __mem_pci(a) (a)
20 24
25#define __arch_ioremap(a, s, f) __iop3xx_ioremap(a, s, f)
26#define __arch_iounmap(a) __iop3xx_iounmap(a)
21 27
22#endif 28#endif
diff --git a/include/asm-arm/arch-iop33x/io.h b/include/asm-arm/arch-iop33x/io.h
index c017402bab96..1bb5071e1fa8 100644
--- a/include/asm-arm/arch-iop33x/io.h
+++ b/include/asm-arm/arch-iop33x/io.h
@@ -13,9 +13,16 @@
13 13
14#include <asm/hardware.h> 14#include <asm/hardware.h>
15 15
16extern void __iomem * __ioremap(unsigned long, size_t, unsigned long);
17extern void __iomem *__iop3xx_ioremap(unsigned long cookie, size_t size,
18 unsigned long flags);
19extern void __iop3xx_iounmap(void __iomem *addr);
20
16#define IO_SPACE_LIMIT 0xffffffff 21#define IO_SPACE_LIMIT 0xffffffff
17#define __io(p) ((void __iomem *)(p)) 22#define __io(p) ((void __iomem *)IOP3XX_PCI_IO_PHYS_TO_VIRT(p))
18#define __mem_pci(a) (a) 23#define __mem_pci(a) (a)
19 24
25#define __arch_ioremap(a, s, f) __iop3xx_ioremap(a, s, f)
26#define __arch_iounmap(a) __iop3xx_iounmap(a)
20 27
21#endif 28#endif
diff --git a/include/asm-arm/arch-ixp4xx/avila.h b/include/asm-arm/arch-ixp4xx/avila.h
new file mode 100644
index 000000000000..0dfea0ccd6ba
--- /dev/null
+++ b/include/asm-arm/arch-ixp4xx/avila.h
@@ -0,0 +1,39 @@
1/*
2 * include/asm-arm/arch-ixp4xx/avila.h
3 *
4 * Gateworks Avila platform specific definitions
5 *
6 * Author: Michael-Luke Jones <mlj28@cam.ac.uk>
7 *
8 * Based on ixdp425.h
9 * Author: Deepak Saxena <dsaxena@plexity.net>
10 *
11 * Copyright 2004 (c) MontaVista, Software, Inc.
12 *
13 * This file is licensed under the terms of the GNU General Public
14 * License version 2. This program is licensed "as is" without any
15 * warranty of any kind, whether express or implied.
16 */
17
18#ifndef __ASM_ARCH_HARDWARE_H__
19#error "Do not include this directly, instead #include <asm/hardware.h>"
20#endif
21
22#define AVILA_SDA_PIN 7
23#define AVILA_SCL_PIN 6
24
25/*
26 * AVILA PCI IRQs
27 */
28#define AVILA_PCI_MAX_DEV 4
29#define LOFT_PCI_MAX_DEV 6
30#define AVILA_PCI_IRQ_LINES 4
31
32
33/* PCI controller GPIO to IRQ pin mappings */
34#define AVILA_PCI_INTA_PIN 11
35#define AVILA_PCI_INTB_PIN 10
36#define AVILA_PCI_INTC_PIN 9
37#define AVILA_PCI_INTD_PIN 8
38
39
diff --git a/include/asm-arm/arch-ixp4xx/hardware.h b/include/asm-arm/arch-ixp4xx/hardware.h
index 6acb69c95ef9..88fd0877dcc1 100644
--- a/include/asm-arm/arch-ixp4xx/hardware.h
+++ b/include/asm-arm/arch-ixp4xx/hardware.h
@@ -42,6 +42,7 @@ extern unsigned int processor_id;
42 42
43/* Platform specific details */ 43/* Platform specific details */
44#include "ixdp425.h" 44#include "ixdp425.h"
45#include "avila.h"
45#include "coyote.h" 46#include "coyote.h"
46#include "prpmc1100.h" 47#include "prpmc1100.h"
47#include "nslu2.h" 48#include "nslu2.h"
diff --git a/include/asm-arm/arch-ixp4xx/irqs.h b/include/asm-arm/arch-ixp4xx/irqs.h
index f24b763ca18e..e44a563d00ff 100644
--- a/include/asm-arm/arch-ixp4xx/irqs.h
+++ b/include/asm-arm/arch-ixp4xx/irqs.h
@@ -79,6 +79,15 @@
79#define IRQ_IXDP425_PCI_INTD IRQ_IXP4XX_GPIO8 79#define IRQ_IXDP425_PCI_INTD IRQ_IXP4XX_GPIO8
80 80
81/* 81/*
82 * Gateworks Avila board IRQs
83 */
84#define IRQ_AVILA_PCI_INTA IRQ_IXP4XX_GPIO11
85#define IRQ_AVILA_PCI_INTB IRQ_IXP4XX_GPIO10
86#define IRQ_AVILA_PCI_INTC IRQ_IXP4XX_GPIO9
87#define IRQ_AVILA_PCI_INTD IRQ_IXP4XX_GPIO8
88
89
90/*
82 * PrPMC1100 Board IRQs 91 * PrPMC1100 Board IRQs
83 */ 92 */
84#define IRQ_PRPMC1100_PCI_INTA IRQ_IXP4XX_GPIO11 93#define IRQ_PRPMC1100_PCI_INTA IRQ_IXP4XX_GPIO11
diff --git a/include/asm-arm/arch-ixp4xx/udc.h b/include/asm-arm/arch-ixp4xx/udc.h
index dbdec36ff0d1..79b850a3be47 100644
--- a/include/asm-arm/arch-ixp4xx/udc.h
+++ b/include/asm-arm/arch-ixp4xx/udc.h
@@ -6,3 +6,25 @@
6 6
7extern void ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info *info); 7extern void ixp4xx_set_udc_info(struct pxa2xx_udc_mach_info *info);
8 8
9static inline int udc_gpio_to_irq(unsigned gpio)
10{
11 return 0;
12}
13
14static inline void udc_gpio_init_vbus(unsigned gpio)
15{
16}
17
18static inline void udc_gpio_init_pullup(unsigned gpio)
19{
20}
21
22static inline int udc_gpio_get(unsigned gpio)
23{
24 return 0;
25}
26
27static inline void udc_gpio_set(unsigned gpio, int is_on)
28{
29}
30
diff --git a/include/asm-arm/arch-ns9xxx/board.h b/include/asm-arm/arch-ns9xxx/board.h
new file mode 100644
index 000000000000..91dc8fb1027f
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/board.h
@@ -0,0 +1,18 @@
1/*
2 * include/asm-arm/arch-ns9xxx/board.h
3 *
4 * Copyright (C) 2006 by Digi International Inc.
5 * All rights reserved.
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 version 2 as published by
9 * the Free Software Foundation.
10 */
11#ifndef __ASM_ARCH_BOARD_H
12#define __ASM_ARCH_BOARD_H
13
14#include <asm/mach-types.h>
15
16#define board_is_a9m9750dev() (machine_is_cc9p9360dev())
17
18#endif /* ifndef __ASM_ARCH_BOARD_H */
diff --git a/include/asm-arm/arch-ns9xxx/clock.h b/include/asm-arm/arch-ns9xxx/clock.h
new file mode 100644
index 000000000000..4371a485db47
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/clock.h
@@ -0,0 +1,37 @@
1/*
2 * include/asm-arm/arch-ns9xxx/clock.h
3 *
4 * Copyright (C) 2007 by Digi International Inc.
5 * All rights reserved.
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 version 2 as published by
9 * the Free Software Foundation.
10 */
11#ifndef __ASM_ARCH_CLOCK_H
12#define __ASM_ARCH_CLOCK_H
13
14static inline u32 ns9xxx_systemclock(void)
15{
16 /*
17 * This should be a multiple of HZ * TIMERCLOCKSELECT (in time.c)
18 */
19 return 353894400;
20}
21
22static inline const u32 ns9xxx_cpuclock(void)
23{
24 return ns9xxx_systemclock() / 2;
25}
26
27static inline const u32 ns9xxx_ahbclock(void)
28{
29 return ns9xxx_systemclock() / 4;
30}
31
32static inline const u32 ns9xxx_bbusclock(void)
33{
34 return ns9xxx_systemclock() / 8;
35}
36
37#endif /* ifndef __ASM_ARCH_CLOCK_H */
diff --git a/include/asm-arm/arch-ns9xxx/debug-macro.S b/include/asm-arm/arch-ns9xxx/debug-macro.S
new file mode 100644
index 000000000000..b21b93eb2dbc
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/debug-macro.S
@@ -0,0 +1,22 @@
1/*
2 * include/asm-arm/arch-ns9xxx/debug-macro.S
3 * Copyright (C) 2006 by Digi International Inc.
4 * All rights reserved.
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 version 2 as published by
8 * the Free Software Foundation.
9 */
10#include <asm/hardware.h>
11
12#include <asm/arch-ns9xxx/regs-board-a9m9750dev.h>
13
14 .macro addruart,rx
15 mrc p15, 0, \rx, c1, c0
16 tst \rx, #1
17 ldreq \rx, =NS9XXX_CSxSTAT_PHYS(0)
18 ldrne \rx, =io_p2v(NS9XXX_CSxSTAT_PHYS(0))
19 .endm
20
21#define UART_SHIFT 2
22#include <asm/hardware/debug-8250.S>
diff --git a/include/asm-arm/arch-ns9xxx/dma.h b/include/asm-arm/arch-ns9xxx/dma.h
new file mode 100644
index 000000000000..a67cbbe009c4
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/dma.h
@@ -0,0 +1,14 @@
1/*
2 * include/asm-arm/arch-ns9xxx/dma.h
3 *
4 * Copyright (C) 2006 by Digi International Inc.
5 * All rights reserved.
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 version 2 as published by
9 * the Free Software Foundation.
10 */
11#ifndef __ASM_ARCH_DMA_H
12#define __ASM_ARCH_DMA_H
13
14#endif /* ifndef __ASM_ARCH_DMA_H */
diff --git a/include/asm-arm/arch-ns9xxx/entry-macro.S b/include/asm-arm/arch-ns9xxx/entry-macro.S
new file mode 100644
index 000000000000..467a1986d259
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/entry-macro.S
@@ -0,0 +1,22 @@
1/*
2 * include/asm-arm/arch-ns9xxx/entry-macro.S
3 *
4 * Copyright (C) 2006 by Digi International Inc.
5 * All rights reserved.
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 version 2 as published by
9 * the Free Software Foundation.
10 */
11#include <asm/hardware.h>
12#include <asm/arch-ns9xxx/regs-sys.h>
13
14 .macro get_irqnr_and_base, irqnr, irqstat, base, tmp
15 ldr \base, =SYS_ISRADDR
16 ldr \irqstat, [\base, #(SYS_ISA - SYS_ISRADDR)]
17 cmp \irqstat, #0
18 ldrne \irqnr, [\base]
19 .endm
20
21 .macro disable_fiq
22 .endm
diff --git a/include/asm-arm/arch-ns9xxx/hardware.h b/include/asm-arm/arch-ns9xxx/hardware.h
new file mode 100644
index 000000000000..6819da7c48d4
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/hardware.h
@@ -0,0 +1,67 @@
1/*
2 * include/asm-arm/arch-ns9xxx/hardware.h
3 *
4 * Copyright (C) 2006 by Digi International Inc.
5 * All rights reserved.
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 version 2 as published by
9 * the Free Software Foundation.
10 */
11#ifndef __ASM_ARCH_HARDWARE_H
12#define __ASM_ARCH_HARDWARE_H
13
14#include <asm/memory.h>
15
16/*
17 * NetSilicon NS9xxx internal mapping:
18 *
19 * physical <--> virtual
20 * 0x90000000 - 0x906fffff <--> 0xf9000000 - 0xf96fffff
21 * 0xa0100000 - 0xa0afffff <--> 0xfa100000 - 0xfaafffff
22 */
23#define io_p2v(x) (0xf0000000 \
24 + (((x) & 0xf0000000) >> 4) \
25 + ((x) & 0x00ffffff))
26
27#define io_v2p(x) ((((x) & 0x0f000000) << 4) \
28 + ((x) & 0x00ffffff))
29
30#define __REGBIT(bit) ((u32)1 << (bit))
31#define __REGBITS(hbit, lbit) ((((u32)1 << ((hbit) - (lbit) + 1)) - 1) << (lbit))
32#define __REGVAL(mask, value) (((value) * ((mask) & (-(mask))) & (mask)))
33
34#ifndef __ASSEMBLY__
35
36# define __REG(x) (*((volatile u32 *)io_p2v((x))))
37# define __REG2(x, y) (*((volatile u32 *)io_p2v((x)) + (y)))
38
39# define __REGB(x) (*((volatile u8 *)io_p2v((x))))
40# define __REGB2(x) (*((volatile u8 *)io_p2v((x)) + (y)))
41
42# define REGSET(var, reg, field, value) \
43 ((var) = (((var) \
44 & ~(reg ## _ ## field & \
45 ~ reg ## _ ## field ## _ ## value)) \
46 | (reg ## _ ## field ## _ ## value)))
47
48# define REGSETIM(var, reg, field, value) \
49 ((var) = (((var) \
50 & ~(reg ## _ ## field & \
51 ~(__REGVAL(reg ## _ ## field, value)))) \
52 | (__REGVAL(reg ## _ ## field, value))))
53
54# define REGGET(reg, field) \
55 ((reg & (reg ## _ ## field)) / (field & (-field)))
56
57#else
58
59# define __REG(x) io_p2v(x)
60# define __REG2(x, y) io_p2v((x) + (y))
61
62# define __REGB(x) __REG((x))
63# define __REGB2(x, y) __REG2((x), (y))
64
65#endif
66
67#endif /* ifndef __ASM_ARCH_HARDWARE_H */
diff --git a/include/asm-arm/arch-ns9xxx/io.h b/include/asm-arm/arch-ns9xxx/io.h
new file mode 100644
index 000000000000..6f82d28af120
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/io.h
@@ -0,0 +1,20 @@
1/*
2 * include/asm-arm/arch-ns9xxx/io.h
3 *
4 * Copyright (C) 2006 by Digi International Inc.
5 * All rights reserved.
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 version 2 as published by
9 * the Free Software Foundation.
10 */
11#ifndef __ASM_ARCH_IO_H
12#define __ASM_ARCH_IO_H
13
14#define IO_SPACE_LIMIT 0xffffffff /* XXX */
15
16#define __io(a) ((void __iomem *)(a))
17#define __mem_pci(a) (a)
18#define __mem_isa(a) (IO_BASE + (a))
19
20#endif /* ifndef __ASM_ARCH_IO_H */
diff --git a/include/asm-arm/arch-ns9xxx/irqs.h b/include/asm-arm/arch-ns9xxx/irqs.h
new file mode 100644
index 000000000000..25d8d28b27f3
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/irqs.h
@@ -0,0 +1,85 @@
1/*
2 * include/asm-arm/arch-ns9xxx/irqs.h
3 *
4 * Copyright (C) 2006 by Digi International Inc.
5 * All rights reserved.
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 version 2 as published by
9 * the Free Software Foundation.
10 */
11#ifndef __ASM_ARCH_IRQS_H
12#define __ASM_ARCH_IRQS_H
13
14#define IRQ_WATCHDOG 0
15#define IRQ_AHBBUSERR 1
16#define IRQ_BBUSAGG 2
17/* irq 3 is reserved for NS9360 */
18#define IRQ_ETHRX 4
19#define IRQ_ETHTX 5
20#define IRQ_ETHPHY 6
21#define IRQ_LCD 7
22#define IRQ_SERBRX 8
23#define IRQ_SERBTX 9
24#define IRQ_SERARX 10
25#define IRQ_SERATX 11
26#define IRQ_SERCRX 12
27#define IRQ_SERCTX 13
28#define IRQ_I2C 14
29#define IRQ_BBUSDMA 15
30#define IRQ_TIMER0 16
31#define IRQ_TIMER1 17
32#define IRQ_TIMER2 18
33#define IRQ_TIMER3 19
34#define IRQ_TIMER4 20
35#define IRQ_TIMER5 21
36#define IRQ_TIMER6 22
37#define IRQ_TIMER7 23
38#define IRQ_RTC 24
39#define IRQ_USBHOST 25
40#define IRQ_USBDEVICE 26
41#define IRQ_IEEE1284 27
42#define IRQ_EXT0 28
43#define IRQ_EXT1 29
44#define IRQ_EXT2 30
45#define IRQ_EXT3 31
46
47#define BBUS_IRQ(irq) (32 + irq)
48
49#define IRQ_BBUS_DMA BBUS_IRQ(0)
50#define IRQ_BBUS_SERBRX BBUS_IRQ(2)
51#define IRQ_BBUS_SERBTX BBUS_IRQ(3)
52#define IRQ_BBUS_SERARX BBUS_IRQ(4)
53#define IRQ_BBUS_SERATX BBUS_IRQ(5)
54#define IRQ_BBUS_SERCRX BBUS_IRQ(6)
55#define IRQ_BBUS_SERCTX BBUS_IRQ(7)
56#define IRQ_BBUS_SERDRX BBUS_IRQ(8)
57#define IRQ_BBUS_SERDTX BBUS_IRQ(9)
58#define IRQ_BBUS_I2C BBUS_IRQ(10)
59#define IRQ_BBUS_1284 BBUS_IRQ(11)
60#define IRQ_BBUS_UTIL BBUS_IRQ(12)
61#define IRQ_BBUS_RTC BBUS_IRQ(13)
62#define IRQ_BBUS_USBHST BBUS_IRQ(14)
63#define IRQ_BBUS_USBDEV BBUS_IRQ(15)
64#define IRQ_BBUS_AHBDMA1 BBUS_IRQ(24)
65#define IRQ_BBUS_AHBDMA2 BBUS_IRQ(25)
66
67/*
68 * these Interrupts are specific for the a9m9750dev board.
69 * They are generated by an FPGA that interrupts the CPU on
70 * IRQ_EXT2
71 */
72#define FPGA_IRQ(irq) (64 + irq)
73
74#define IRQ_FPGA_UARTA FPGA_IRQ(0)
75#define IRQ_FPGA_UARTB FPGA_IRQ(1)
76#define IRQ_FPGA_UARTC FPGA_IRQ(2)
77#define IRQ_FPGA_UARTD FPGA_IRQ(3)
78#define IRQ_FPGA_TOUCH FPGA_IRQ(4)
79#define IRQ_FPGA_CF FPGA_IRQ(5)
80#define IRQ_FPGA_CAN0 FPGA_IRQ(6)
81#define IRQ_FPGA_CAN1 FPGA_IRQ(7)
82
83#define NR_IRQS 72
84
85#endif /* __ASM_ARCH_IRQS_H */
diff --git a/include/asm-arm/arch-ns9xxx/memory.h b/include/asm-arm/arch-ns9xxx/memory.h
new file mode 100644
index 000000000000..ce1343e593e1
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/memory.h
@@ -0,0 +1,27 @@
1/*
2 * include/asm-arm/arch-ns9xxx/memory.h
3 *
4 * Copyright (C) 2006 by Digi International Inc.
5 * All rights reserved.
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 version 2 as published by
9 * the Free Software Foundation.
10*/
11#ifndef __ASM_ARCH_MEMORY_H
12#define __ASM_ARCH_MEMORY_H
13
14/* x in [0..3] */
15#define NS9XXX_CSxSTAT_PHYS(x) UL(((x) + 4) << 28)
16
17#define NS9XXX_CS0STAT_LENGTH UL(0x1000)
18#define NS9XXX_CS1STAT_LENGTH UL(0x1000)
19#define NS9XXX_CS2STAT_LENGTH UL(0x1000)
20#define NS9XXX_CS3STAT_LENGTH UL(0x1000)
21
22#define PHYS_OFFSET UL(0x00000000)
23
24#define __virt_to_bus(x) __virt_to_phys(x)
25#define __bus_to_virt(x) __phys_to_virt(x)
26
27#endif
diff --git a/include/asm-arm/arch-ns9xxx/processor.h b/include/asm-arm/arch-ns9xxx/processor.h
new file mode 100644
index 000000000000..716c106ac0bf
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/processor.h
@@ -0,0 +1,18 @@
1/*
2 * include/asm-arm/arch-ns9xxx/processor.h
3 *
4 * Copyright (C) 2006 by Digi International Inc.
5 * All rights reserved.
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 version 2 as published by
9 * the Free Software Foundation.
10 */
11#ifndef __ASM_ARCH_PROCESSOR_H
12#define __ASM_ARCH_PROCESSOR_H
13
14#include <asm/mach-types.h>
15
16#define processor_is_ns9360() (machine_is_cc9p9360dev())
17
18#endif /* ifndef __ASM_ARCH_PROCESSOR_H */
diff --git a/include/asm-arm/arch-ns9xxx/regs-bbu.h b/include/asm-arm/arch-ns9xxx/regs-bbu.h
new file mode 100644
index 000000000000..e26269546240
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/regs-bbu.h
@@ -0,0 +1,21 @@
1/*
2 * include/asm-arm/arch-ns9xxx/regs-bbu.h
3 *
4 * Copyright (C) 2006 by Digi International Inc.
5 * All rights reserved.
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 version 2 as published by
9 * the Free Software Foundation.
10 */
11#ifndef __ASM_ARCH_REGSBBU_H
12#define __ASM_ARCH_REGSBBU_H
13
14#include <asm/hardware.h>
15
16/* BBus Utility */
17
18/* GPIO Configuration Register */
19#define BBU_GC(x) __REG2(0x9060000c, (x))
20
21#endif /* ifndef __ASM_ARCH_REGSBBU_H */
diff --git a/include/asm-arm/arch-ns9xxx/regs-board-a9m9750dev.h b/include/asm-arm/arch-ns9xxx/regs-board-a9m9750dev.h
new file mode 100644
index 000000000000..c3dc532dd20c
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/regs-board-a9m9750dev.h
@@ -0,0 +1,24 @@
1/*
2 * include/asm-arm/arch-ns9xxx/regs-board-a9m9750dev.h
3 *
4 * Copyright (C) 2006 by Digi International Inc.
5 * All rights reserved.
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 version 2 as published by
9 * the Free Software Foundation.
10 */
11#ifndef __ASM_ARCH_REGSBOARDA9M9750_H
12#define __ASM_ARCH_REGSBOARDA9M9750_H
13
14#include <asm/hardware.h>
15
16#define FPGA_UARTA_BASE io_p2v(NS9XXX_CSxSTAT_PHYS(0))
17#define FPGA_UARTB_BASE io_p2v(NS9XXX_CSxSTAT_PHYS(0) + 0x08)
18#define FPGA_UARTC_BASE io_p2v(NS9XXX_CSxSTAT_PHYS(0) + 0x10)
19#define FPGA_UARTD_BASE io_p2v(NS9XXX_CSxSTAT_PHYS(0) + 0x18)
20
21#define FPGA_IER __REGB(NS9XXX_CSxSTAT_PHYS(0) + 0x50)
22#define FPGA_ISR __REGB(NS9XXX_CSxSTAT_PHYS(0) + 0x60)
23
24#endif /* ifndef __ASM_ARCH_REGSBOARDA9M9750_H */
diff --git a/include/asm-arm/arch-ns9xxx/regs-mem.h b/include/asm-arm/arch-ns9xxx/regs-mem.h
new file mode 100644
index 000000000000..8ed8448767b9
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/regs-mem.h
@@ -0,0 +1,135 @@
1/*
2 * include/asm-arm/arch-ns9xxx/regs-mem.h
3 *
4 * Copyright (C) 2006 by Digi International Inc.
5 * All rights reserved.
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 version 2 as published by
9 * the Free Software Foundation.
10 */
11#ifndef __ASM_ARCH_REGSMEM_H
12#define __ASM_ARCH_REGSMEM_H
13
14#include <asm/hardware.h>
15
16/* Memory Module */
17
18/* Control register */
19#define MEM_CTRL __REG(0xa0700000)
20
21/* Status register */
22#define MEM_STAT __REG(0xa0700004)
23
24/* Configuration register */
25#define MEM_CONF __REG(0xa0700008)
26
27/* Dynamic Memory Control register */
28#define MEM_DMCTRL __REG(0xa0700020)
29
30/* Dynamic Memory Refresh Timer */
31#define MEM_DMRT __REG(0xa0700024)
32
33/* Dynamic Memory Read Configuration register */
34#define MEM_DMRC __REG(0xa0700028)
35
36/* Dynamic Memory Precharge Command Period (tRP) */
37#define MEM_DMPCP __REG(0xa0700030)
38
39/* Dynamic Memory Active to Precharge Command Period (tRAS) */
40#define MEM_DMAPCP __REG(0xa0700034)
41
42/* Dynamic Memory Self-Refresh Exit Time (tSREX) */
43#define MEM_DMSRET __REG(0xa0700038)
44
45/* Dynamic Memory Last Data Out to Active Time (tAPR) */
46#define MEM_DMLDOAT __REG(0xa070003c)
47
48/* Dynamic Memory Data-in to Active Command Time (tDAL or TAPW) */
49#define MEM_DMDIACT __REG(0xa0700040)
50
51/* Dynamic Memory Write Recovery Time (tWR, tDPL, tRWL, tRDL) */
52#define MEM_DMWRT __REG(0xa0700044)
53
54/* Dynamic Memory Active to Active Command Period (tRC) */
55#define MEM_DMAACP __REG(0xa0700048)
56
57/* Dynamic Memory Auto Refresh Period, and Auto Refresh to Active Command Period (tRFC) */
58#define MEM_DMARP __REG(0xa070004c)
59
60/* Dynamic Memory Exit Self-Refresh to Active Command (tXSR) */
61#define MEM_DMESRAC __REG(0xa0700050)
62
63/* Dynamic Memory Active Bank A to Active B Time (tRRD) */
64#define MEM_DMABAABT __REG(0xa0700054)
65
66/* Dynamic Memory Load Mode register to Active Command Time (tMRD) */
67#define MEM_DMLMACT __REG(0xa0700058)
68
69/* Static Memory Extended Wait */
70#define MEM_SMEW __REG(0xa0700080)
71
72/* Dynamic Memory Configuration Register x */
73#define MEM_DMCONF(x) __REG2(0xa0700100, (x) << 3)
74
75/* Dynamic Memory RAS and CAS Delay x */
76#define MEM_DMRCD(x) __REG2(0xa0700104, (x) << 3)
77
78/* Static Memory Configuration Register x */
79#define MEM_SMC(x) __REG2(0xa0700200, (x) << 3)
80
81/* Static Memory Configuration Register x: Write protect */
82#define MEM_SMC_WSMC __REGBIT(20)
83#define MEM_SMC_WSMC_OFF __REGVAL(MEM_SMC_WSMC, 0)
84#define MEM_SMC_WSMC_ON __REGVAL(MEM_SMC_WSMC, 1)
85
86/* Static Memory Configuration Register x: Buffer enable */
87#define MEM_SMC_BSMC __REGBIT(19)
88#define MEM_SMC_BSMC_OFF __REGVAL(MEM_SMC_BSMC, 0)
89#define MEM_SMC_BSMC_ON __REGVAL(MEM_SMC_BSMC, 1)
90
91/* Static Memory Configuration Register x: Extended Wait */
92#define MEM_SMC_EW __REGBIT(8)
93#define MEM_SMC_EW_OFF __REGVAL(MEM_SMC_EW, 0)
94#define MEM_SMC_EW_ON __REGVAL(MEM_SMC_EW, 1)
95
96/* Static Memory Configuration Register x: Byte lane state */
97#define MEM_SMC_PB __REGBIT(7)
98#define MEM_SMC_PB_0 __REGVAL(MEM_SMC_PB, 0)
99#define MEM_SMC_PB_1 __REGVAL(MEM_SMC_PB, 1)
100
101/* Static Memory Configuration Register x: Chip select polarity */
102#define MEM_SMC_PC __REGBIT(6)
103#define MEM_SMC_PC_AL __REGVAL(MEM_SMC_PC, 0)
104#define MEM_SMC_PC_AH __REGVAL(MEM_SMC_PC, 1)
105
106/* static memory configuration register x: page mode*/
107#define MEM_SMC_PM __REGBIT(3)
108#define MEM_SMC_PM_DIS __REGVAL(MEM_SMC_PM, 0)
109#define MEM_SMC_PM_ASYNC __REGVAL(MEM_SMC_PM, 1)
110
111/* static memory configuration register x: Memory width */
112#define MEM_SMC_MW __REGBITS(1, 0)
113#define MEM_SMC_MW_8 __REGVAL(MEM_SMC_MW, 0)
114#define MEM_SMC_MW_16 __REGVAL(MEM_SMC_MW, 1)
115#define MEM_SMC_MW_32 __REGVAL(MEM_SMC_MW, 2)
116
117/* Static Memory Write Enable Delay x */
118#define MEM_SMWED(x) __REG2(0xa0700204, (x) << 3)
119
120/* Static Memory Output Enable Delay x */
121#define MEM_SMOED(x) __REG2(0xa0700208, (x) << 3)
122
123/* Static Memory Read Delay x */
124#define MEM_SMRD(x) __REG2(0xa070020c, (x) << 3)
125
126/* Static Memory Page Mode Read Delay 0 */
127#define MEM_SMPMRD(x) __REG2(0xa0700210, (x) << 3)
128
129/* Static Memory Write Delay */
130#define MEM_SMWD(x) __REG2(0xa0700214, (x) << 3)
131
132/* Static Memory Turn Round Delay x */
133#define MEM_SWT(x) __REG2(0xa0700218, (x) << 3)
134
135#endif /* ifndef __ASM_ARCH_REGSMEM_H */
diff --git a/include/asm-arm/arch-ns9xxx/regs-sys.h b/include/asm-arm/arch-ns9xxx/regs-sys.h
new file mode 100644
index 000000000000..8162a50bb273
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/regs-sys.h
@@ -0,0 +1,157 @@
1/*
2 * include/asm-arm/arch-ns9xxx/regs-sys.h
3 *
4 * Copyright (C) 2006 by Digi International Inc.
5 * All rights reserved.
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 version 2 as published by
9 * the Free Software Foundation.
10 */
11#ifndef __ASM_ARCH_REGSSYS_H
12#define __ASM_ARCH_REGSSYS_H
13
14#include <asm/hardware.h>
15
16/* System Control Module */
17
18/* AHB Arbiter Gen Configuration */
19#define SYS_AHBAGENCONF __REG(0xa0900000)
20
21/* BRC */
22#define SYS_BRC(x) __REG2(0xa0900004, (x))
23
24/* Timer x Reload Count register */
25#define SYS_TRC(x) __REG2(0xa0900044, (x))
26
27/* Timer x Read register */
28#define SYS_TR(x) __REG2(0xa0900084, (x))
29
30/* Interrupt Vector Address Register Level x */
31#define SYS_IVA(x) __REG2(0xa09000c4, (x))
32
33/* Interrupt Configuration registers */
34#define SYS_IC(x) __REG2(0xa0900144, (x))
35
36/* ISRADDR */
37#define SYS_ISRADDR __REG(0xa0900164)
38
39/* Interrupt Status Active */
40#define SYS_ISA __REG(0xa0900168)
41
42/* Interrupt Status Raw */
43#define SYS_ISR __REG(0xa090016c)
44
45/* Timer Interrupt Status register */
46#define SYS_TIS __REG(0xa0900170)
47
48/* PLL Configuration register */
49#define SYS_PLL __REG(0xa0900188)
50
51/* PLL Configuration register: PLL SW change */
52#define SYS_PLL_SWC __REGBIT(15)
53#define SYS_PLL_SWC_NO __REGVAL(SYS_PLL_SWC, 0)
54#define SYS_PLL_SWC_YES __REGVAL(SYS_PLL_SWC, 1)
55
56/* Timer x Control register */
57#define SYS_TC(x) __REG2(0xa0900190, (x))
58
59/* Timer x Control register: Timer enable */
60#define SYS_TCx_TEN __REGBIT(15)
61#define SYS_TCx_TEN_DIS __REGVAL(SYS_TCx_TEN, 1)
62#define SYS_TCx_TEN_EN __REGVAL(SYS_TCx_TEN, 1)
63
64/* Timer x Control register: CPU debug mode */
65#define SYS_TCx_TDBG __REGBIT(10)
66#define SYS_TCx_TDBG_CONT __REGVAL(SYS_TCx_TDBG, 0)
67#define SYS_TCx_TDBG_STOP __REGVAL(SYS_TCx_TDBG, 1)
68
69/* Timer x Control register: Interrupt clear */
70#define SYS_TCx_INTC __REGBIT(9)
71#define SYS_TCx_INTC_UNSET __REGVAL(SYS_TCx_INTC, 0)
72#define SYS_TCx_INTC_SET __REGVAL(SYS_TCx_INTC, 1)
73
74/* Timer x Control register: Timer clock select */
75#define SYS_TCx_TLCS __REGBITS(8, 6)
76#define SYS_TCx_TLCS_CPU __REGVAL(SYS_TCx_TLCS, 0) /* CPU clock */
77#define SYS_TCx_TLCS_DIV2 __REGVAL(SYS_TCx_TLCS, 1) /* CPU clock / 2 */
78#define SYS_TCx_TLCS_DIV4 __REGVAL(SYS_TCx_TLCS, 2) /* CPU clock / 4 */
79#define SYS_TCx_TLCS_DIV8 __REGVAL(SYS_TCx_TLCS, 3) /* CPU clock / 8 */
80#define SYS_TCx_TLCS_DIV16 __REGVAL(SYS_TCx_TLCS, 4) /* CPU clock / 16 */
81#define SYS_TCx_TLCS_DIV32 __REGVAL(SYS_TCx_TLCS, 5) /* CPU clock / 32 */
82#define SYS_TCx_TLCS_DIV64 __REGVAL(SYS_TCx_TLCS, 6) /* CPU clock / 64 */
83#define SYS_TCx_TLCS_EXT __REGVAL(SYS_TCx_TLCS, 7)
84
85/* Timer x Control register: Timer mode */
86#define SYS_TCx_TM __REGBITS(5, 4)
87#define SYS_TCx_TM_IEE __REGVAL(SYS_TCx_TM, 0) /* Internal timer or external event */
88#define SYS_TCx_TM_ELL __REGVAL(SYS_TCx_TM, 1) /* External low-level, gated timer */
89#define SYS_TCx_TM_EHL __REGVAL(SYS_TCx_TM, 2) /* External high-level, gated timer */
90#define SYS_TCx_TM_CONCAT __REGVAL(SYS_TCx_TM, 3) /* Concatenate the lower timer. */
91
92/* Timer x Control register: Interrupt select */
93#define SYS_TCx_INTS __REGBIT(3)
94#define SYS_TCx_INTS_DIS __REGVAL(SYS_TCx_INTS, 0)
95#define SYS_TCx_INTS_EN __REGVAL(SYS_TCx_INTS, 1)
96
97/* Timer x Control register: Up/down select */
98#define SYS_TCx_UDS __REGBIT(2)
99#define SYS_TCx_UDS_UP __REGVAL(SYS_TCx_UDS, 0)
100#define SYS_TCx_UDS_DOWN __REGVAL(SYS_TCx_UDS, 1)
101
102/* Timer x Control register: 32- or 16-bit timer */
103#define SYS_TCx_TSZ __REGBIT(1)
104#define SYS_TCx_TSZ_16 __REGVAL(SYS_TCx_TSZ, 0)
105#define SYS_TCx_TSZ_32 __REGVAL(SYS_TCx_TSZ, 1)
106
107/* Timer x Control register: Reload enable */
108#define SYS_TCx_REN __REGBIT(0)
109#define SYS_TCx_REN_DIS __REGVAL(SYS_TCx_REN, 0)
110#define SYS_TCx_REN_EN __REGVAL(SYS_TCx_REN, 1)
111
112/* System Memory Chip Select x Dynamic Memory Base */
113#define SYS_SMCSDMB(x) __REG2(0xa09001d0, (x) << 1)
114
115/* System Memory Chip Select x Dynamic Memory Mask */
116#define SYS_SMCSDMM(x) __REG2(0xa09001d4, (x) << 1)
117
118/* System Memory Chip Select x Static Memory Base */
119#define SYS_SMCSSMB(x) __REG2(0xa09001f0, (x) << 1)
120
121/* System Memory Chip Select x Static Memory Base: Chip select x base */
122#define SYS_SMCSSMB_CSxB __REGBITS(31, 12)
123
124/* System Memory Chip Select x Static Memory Mask */
125#define SYS_SMCSSMM(x) __REG2(0xa09001f4, (x) << 1)
126
127/* System Memory Chip Select x Static Memory Mask: Chip select x mask */
128#define SYS_SMCSSMM_CSxM __REGBITS(31, 12)
129
130/* System Memory Chip Select x Static Memory Mask: Chip select x enable */
131#define SYS_SMCSSMM_CSEx __REGBIT(0)
132#define SYS_SMCSSMM_CSEx_DIS __REGVAL(SYS_SMCSSMM_CSEx, 0)
133#define SYS_SMCSSMM_CSEx_EN __REGVAL(SYS_SMCSSMM_CSEx, 1)
134
135/* General purpose, user-defined ID register */
136#define SYS_GENID __REG(0xa0900210)
137
138/* External Interrupt x Control register */
139#define SYS_EIC(x) __REG2(0xa0900214, (x))
140
141/* External Interrupt x Control register: Status */
142#define SYS_EIC_STS __REGBIT(3)
143
144/* External Interrupt x Control register: Clear */
145#define SYS_EIC_CLR __REGBIT(2)
146
147/* External Interrupt x Control register: Polarity */
148#define SYS_EIC_PLTY __REGBIT(1)
149#define SYS_EIC_PLTY_AH __REGVAL(SYS_EIC_PLTY, 0)
150#define SYS_EIC_PLTY_AL __REGVAL(SYS_EIC_PLTY, 1)
151
152/* External Interrupt x Control register: Level edge */
153#define SYS_EIC_LVEDG __REGBIT(0)
154#define SYS_EIC_LVEDG_LEVEL __REGVAL(SYS_EIC_LVEDG, 0)
155#define SYS_EIC_LVEDG_EDGE __REGVAL(SYS_EIC_LVEDG, 1)
156
157#endif /* ifndef __ASM_ARCH_REGSSYS_H */
diff --git a/include/asm-arm/arch-ns9xxx/system.h b/include/asm-arm/arch-ns9xxx/system.h
new file mode 100644
index 000000000000..e3cd4d31b3f3
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/system.h
@@ -0,0 +1,34 @@
1/*
2 * include/asm-arm/arch-ns9xxx/system.h
3 *
4 * Copyright (C) 2006 by Digi International Inc.
5 * All rights reserved.
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 version 2 as published by
9 * the Free Software Foundation.
10 */
11#ifndef __ASM_ARCH_SYSTEM_H
12#define __ASM_ARCH_SYSTEM_H
13
14#include <asm/proc-fns.h>
15#include <asm/arch-ns9xxx/regs-sys.h>
16#include <asm/mach-types.h>
17
18static inline void arch_idle(void)
19{
20 cpu_do_idle();
21}
22
23static inline void arch_reset(char mode)
24{
25 u32 reg;
26
27 reg = SYS_PLL >> 16;
28 REGSET(reg, SYS_PLL, SWC, YES);
29 SYS_PLL = reg;
30
31 BUG();
32}
33
34#endif /* ifndef __ASM_ARCH_SYSTEM_H */
diff --git a/include/asm-arm/arch-ns9xxx/timex.h b/include/asm-arm/arch-ns9xxx/timex.h
new file mode 100644
index 000000000000..f776cbd2622d
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/timex.h
@@ -0,0 +1,20 @@
1/*
2 * include/asm-arm/arch-ns9xxx/timex.h
3 *
4 * Copyright (C) 2005-2006 by Digi International Inc.
5 * All rights reserved.
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 version 2 as published by
9 * the Free Software Foundation.
10 */
11#ifndef __ASM_ARCH_TIMEX_H
12#define __ASM_ARCH_TIMEX_H
13
14/*
15 * value for CLOCK_TICK_RATE stolen from include/asm-arm/arch-s3c2410/timex.h.
16 * See there for an explanation.
17 */
18#define CLOCK_TICK_RATE 12000000
19
20#endif /* ifndef __ASM_ARCH_TIMEX_H */
diff --git a/include/asm-arm/arch-ns9xxx/uncompress.h b/include/asm-arm/arch-ns9xxx/uncompress.h
new file mode 100644
index 000000000000..961ca7dc9954
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/uncompress.h
@@ -0,0 +1,35 @@
1/*
2 * include/asm-arm/arch-ns9xxx/uncompress.h
3 *
4 * Copyright (C) 2006 by Digi International Inc.
5 * All rights reserved.
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 version 2 as published by
9 * the Free Software Foundation.
10 */
11#ifndef __ASM_ARCH_UNCOMPRESS_H
12#define __ASM_ARCH_UNCOMPRESS_H
13
14static void putc(char c)
15{
16 volatile u8 *base = (volatile u8 *)0x40000000;
17 int t = 0x10000;
18
19 do {
20 if (base[5] & 0x20) {
21 base[0] = c;
22 break;
23 }
24 } while (--t);
25}
26
27#define arch_decomp_setup()
28#define arch_decomp_wdog()
29
30static void flush(void)
31{
32 /* nothing */
33}
34
35#endif /* ifndef __ASM_ARCH_UNCOMPRESS_H */
diff --git a/include/asm-arm/arch-ns9xxx/vmalloc.h b/include/asm-arm/arch-ns9xxx/vmalloc.h
new file mode 100644
index 000000000000..2f3cb6f6be24
--- /dev/null
+++ b/include/asm-arm/arch-ns9xxx/vmalloc.h
@@ -0,0 +1,16 @@
1/*
2 * include/asm-arm/arch-ns9xxx/vmalloc.h
3 *
4 * Copyright (C) 2006 by Digi International Inc.
5 * All rights reserved.
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 version 2 as published by
9 * the Free Software Foundation.
10 */
11#ifndef __ASM_ARCH_VMALLOC_H
12#define __ASM_ARCH_VMALLOC_H
13
14#define VMALLOC_END (0xf0000000)
15
16#endif /* ifndef __ASM_ARCH_VMALLOC_H */
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
index e24f6b6c79ae..aec835b6f057 100644
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -463,9 +463,6 @@
463 * Serial Audio Controller 463 * Serial Audio Controller
464 */ 464 */
465 465
466/* FIXME: This clash with SA1111 defines */
467#ifndef _ASM_ARCH_SA1111
468
469#define SACR0 __REG(0x40400000) /* Global Control Register */ 466#define SACR0 __REG(0x40400000) /* Global Control Register */
470#define SACR1 __REG(0x40400004) /* Serial Audio I 2 S/MSB-Justified Control Register */ 467#define SACR1 __REG(0x40400004) /* Serial Audio I 2 S/MSB-Justified Control Register */
471#define SASR0 __REG(0x4040000C) /* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */ 468#define SASR0 __REG(0x4040000C) /* Serial Audio I 2 S/MSB-Justified Interface and FIFO Status Register */
@@ -474,8 +471,8 @@
474#define SADIV __REG(0x40400060) /* Audio Clock Divider Register. */ 471#define SADIV __REG(0x40400060) /* Audio Clock Divider Register. */
475#define SADR __REG(0x40400080) /* Serial Audio Data Register (TX and RX FIFO access Register). */ 472#define SADR __REG(0x40400080) /* Serial Audio Data Register (TX and RX FIFO access Register). */
476 473
477#define SACR0_RFTH(x) (x << 12) /* Rx FIFO Interrupt or DMA Trigger Threshold */ 474#define SACR0_RFTH(x) ((x) << 12) /* Rx FIFO Interrupt or DMA Trigger Threshold */
478#define SACR0_TFTH(x) (x << 8) /* Tx FIFO Interrupt or DMA Trigger Threshold */ 475#define SACR0_TFTH(x) ((x) << 8) /* Tx FIFO Interrupt or DMA Trigger Threshold */
479#define SACR0_STRF (1 << 5) /* FIFO Select for EFWR Special Function */ 476#define SACR0_STRF (1 << 5) /* FIFO Select for EFWR Special Function */
480#define SACR0_EFWR (1 << 4) /* Enable EFWR Function */ 477#define SACR0_EFWR (1 << 4) /* Enable EFWR Function */
481#define SACR0_RST (1 << 3) /* FIFO, i2s Register Reset */ 478#define SACR0_RST (1 << 3) /* FIFO, i2s Register Reset */
@@ -503,8 +500,6 @@
503#define SAIMR_RFS (1 << 4) /* Enable Rx FIFO Service Interrupt */ 500#define SAIMR_RFS (1 << 4) /* Enable Rx FIFO Service Interrupt */
504#define SAIMR_TFS (1 << 3) /* Enable Tx FIFO Service Interrupt */ 501#define SAIMR_TFS (1 << 3) /* Enable Tx FIFO Service Interrupt */
505 502
506#endif
507
508/* 503/*
509 * AC97 Controller registers 504 * AC97 Controller registers
510 */ 505 */
@@ -1682,15 +1677,18 @@
1682#define SSSR_PINT (1 << 18) /* Peripheral Trailing Byte Interrupt */ 1677#define SSSR_PINT (1 << 18) /* Peripheral Trailing Byte Interrupt */
1683 1678
1684#define SSPSP_FSRT (1 << 25) /* Frame Sync Relative Timing */ 1679#define SSPSP_FSRT (1 << 25) /* Frame Sync Relative Timing */
1685#define SSPSP_DMYSTOP(x) (x << 23) /* Dummy Stop */ 1680#define SSPSP_DMYSTOP(x) ((x) << 23) /* Dummy Stop */
1686#define SSPSP_SFRMWDTH(x) (x << 16) /* Serial Frame Width */ 1681#define SSPSP_SFRMWDTH(x) ((x) << 16) /* Serial Frame Width */
1687#define SSPSP_SFRMDLY(x) (x << 9) /* Serial Frame Delay */ 1682#define SSPSP_SFRMDLY(x) ((x) << 9) /* Serial Frame Delay */
1688#define SSPSP_DMYSTRT(x) (x << 7) /* Dummy Start */ 1683#define SSPSP_DMYSTRT(x) ((x) << 7) /* Dummy Start */
1689#define SSPSP_STRTDLY(x) (x << 4) /* Start Delay */ 1684#define SSPSP_STRTDLY(x) ((x) << 4) /* Start Delay */
1690#define SSPSP_ETDS (1 << 3) /* End of Transfer data State */ 1685#define SSPSP_ETDS (1 << 3) /* End of Transfer data State */
1691#define SSPSP_SFRMP (1 << 2) /* Serial Frame Polarity */ 1686#define SSPSP_SFRMP (1 << 2) /* Serial Frame Polarity */
1692#define SSPSP_SCMODE(x) (x << 0) /* Serial Bit Rate Clock Mode */ 1687#define SSPSP_SCMODE(x) ((x) << 0) /* Serial Bit Rate Clock Mode */
1693 1688
1689#define SSACD_SCDB (1 << 3) /* SSPSYSCLK Divider Bypass */
1690#define SSACD_ACPS(x) ((x) << 4) /* Audio clock PLL select */
1691#define SSACD_ACDS(x) ((x) << 0) /* Audio clock divider select */
1694 1692
1695#define SSCR0_P1 __REG(0x41000000) /* SSP Port 1 Control Register 0 */ 1693#define SSCR0_P1 __REG(0x41000000) /* SSP Port 1 Control Register 0 */
1696#define SSCR1_P1 __REG(0x41000004) /* SSP Port 1 Control Register 1 */ 1694#define SSCR1_P1 __REG(0x41000004) /* SSP Port 1 Control Register 1 */
diff --git a/include/asm-arm/arch-pxa/udc.h b/include/asm-arm/arch-pxa/udc.h
index 646480d37256..8bc6f9c3e3ea 100644
--- a/include/asm-arm/arch-pxa/udc.h
+++ b/include/asm-arm/arch-pxa/udc.h
@@ -9,3 +9,33 @@
9 9
10extern void pxa_set_udc_info(struct pxa2xx_udc_mach_info *info); 10extern void pxa_set_udc_info(struct pxa2xx_udc_mach_info *info);
11 11
12static inline int udc_gpio_to_irq(unsigned gpio)
13{
14 return IRQ_GPIO(gpio & GPIO_MD_MASK_NR);
15}
16
17static inline void udc_gpio_init_vbus(unsigned gpio)
18{
19 pxa_gpio_mode((gpio & GPIO_MD_MASK_NR) | GPIO_IN);
20}
21
22static inline void udc_gpio_init_pullup(unsigned gpio)
23{
24 pxa_gpio_mode((gpio & GPIO_MD_MASK_NR) | GPIO_OUT | GPIO_DFLT_LOW);
25}
26
27static inline int udc_gpio_get(unsigned gpio)
28{
29 return (GPLR(gpio) & GPIO_bit(gpio)) != 0;
30}
31
32static inline void udc_gpio_set(unsigned gpio, int is_on)
33{
34 int mask = GPIO_bit(gpio);
35
36 if (is_on)
37 GPSR(gpio) = mask;
38 else
39 GPCR(gpio) = mask;
40}
41
diff --git a/include/asm-arm/arch-realview/hardware.h b/include/asm-arm/arch-realview/hardware.h
index 9ca76dc3a7af..aa78fe087ab2 100644
--- a/include/asm-arm/arch-realview/hardware.h
+++ b/include/asm-arm/arch-realview/hardware.h
@@ -26,7 +26,7 @@
26#include <asm/arch/platform.h> 26#include <asm/arch/platform.h>
27 27
28/* macro to get at IO space when running virtually */ 28/* macro to get at IO space when running virtually */
29#define IO_ADDRESS(x) (((x) & 0x0fffffff) + (((x) >> 4) & 0x0f000000) + 0xf0000000) 29#define IO_ADDRESS(x) ((((x) & 0x0effffff) | (((x) >> 4) & 0x0f000000)) + 0xf0000000)
30#define __io_address(n) __io(IO_ADDRESS(n)) 30#define __io_address(n) __io(IO_ADDRESS(n))
31 31
32#endif 32#endif
diff --git a/include/asm-arm/arch-realview/irqs.h b/include/asm-arm/arch-realview/irqs.h
index c16223c9588d..5a5db56f86b8 100644
--- a/include/asm-arm/arch-realview/irqs.h
+++ b/include/asm-arm/arch-realview/irqs.h
@@ -65,6 +65,21 @@
65#define IRQ_AACI (IRQ_GIC_START + INT_AACI) 65#define IRQ_AACI (IRQ_GIC_START + INT_AACI)
66#define IRQ_ETH (IRQ_GIC_START + INT_ETH) 66#define IRQ_ETH (IRQ_GIC_START + INT_ETH)
67#define IRQ_USB (IRQ_GIC_START + INT_USB) 67#define IRQ_USB (IRQ_GIC_START + INT_USB)
68#define IRQ_PMU_CPU0 (IRQ_GIC_START + INT_PMU_CPU0)
69#define IRQ_PMU_CPU1 (IRQ_GIC_START + INT_PMU_CPU1)
70#define IRQ_PMU_CPU2 (IRQ_GIC_START + INT_PMU_CPU2)
71#define IRQ_PMU_CPU3 (IRQ_GIC_START + INT_PMU_CPU3)
72#define IRQ_PMU_SCU0 (IRQ_GIC_START + INT_PMU_SCU0)
73#define IRQ_PMU_SCU1 (IRQ_GIC_START + INT_PMU_SCU1)
74#define IRQ_PMU_SCU2 (IRQ_GIC_START + INT_PMU_SCU2)
75#define IRQ_PMU_SCU3 (IRQ_GIC_START + INT_PMU_SCU3)
76#define IRQ_PMU_SCU4 (IRQ_GIC_START + INT_PMU_SCU4)
77#define IRQ_PMU_SCU5 (IRQ_GIC_START + INT_PMU_SCU5)
78#define IRQ_PMU_SCU6 (IRQ_GIC_START + INT_PMU_SCU6)
79#define IRQ_PMU_SCU7 (IRQ_GIC_START + INT_PMU_SCU7)
80
81#define IRQ_EB_IRQ1 (IRQ_GIC_START + INT_EB_IRQ1)
82#define IRQ_EB_IRQ2 (IRQ_GIC_START + INT_EB_IRQ2)
68 83
69#define IRQMASK_WDOGINT INTMASK_WDOGINT 84#define IRQMASK_WDOGINT INTMASK_WDOGINT
70#define IRQMASK_SOFTINT INTMASK_SOFTINT 85#define IRQMASK_SOFTINT INTMASK_SOFTINT
@@ -103,4 +118,4 @@
103#define IRQMASK_ETH INTMASK_ETH 118#define IRQMASK_ETH INTMASK_ETH
104#define IRQMASK_USB INTMASK_USB 119#define IRQMASK_USB INTMASK_USB
105 120
106#define NR_IRQS (IRQ_GIC_START + 64) 121#define NR_IRQS (IRQ_GIC_START + 96)
diff --git a/include/asm-arm/arch-realview/platform.h b/include/asm-arm/arch-realview/platform.h
index 18d7c18b738c..6e0eab95a3a2 100644
--- a/include/asm-arm/arch-realview/platform.h
+++ b/include/asm-arm/arch-realview/platform.h
@@ -207,11 +207,25 @@
207#define REALVIEW_GIC_CPU_BASE 0x10040000 /* Generic interrupt controller CPU interface */ 207#define REALVIEW_GIC_CPU_BASE 0x10040000 /* Generic interrupt controller CPU interface */
208#define REALVIEW_GIC_DIST_BASE 0x10041000 /* Generic interrupt controller distributor */ 208#define REALVIEW_GIC_DIST_BASE 0x10041000 /* Generic interrupt controller distributor */
209#else 209#else
210#ifdef CONFIG_REALVIEW_MPCORE_REVB
210#define REALVIEW_MPCORE_SCU_BASE 0x10100000 /* SCU registers */ 211#define REALVIEW_MPCORE_SCU_BASE 0x10100000 /* SCU registers */
211#define REALVIEW_GIC_CPU_BASE 0x10100100 /* Generic interrupt controller CPU interface */ 212#define REALVIEW_GIC_CPU_BASE 0x10100100 /* Generic interrupt controller CPU interface */
212#define REALVIEW_TWD_BASE 0x10100700 213#define REALVIEW_TWD_BASE 0x10100700
213#define REALVIEW_TWD_SIZE 0x00000100 214#define REALVIEW_TWD_SIZE 0x00000100
214#define REALVIEW_GIC_DIST_BASE 0x10101000 /* Generic interrupt controller distributor */ 215#define REALVIEW_GIC_DIST_BASE 0x10101000 /* Generic interrupt controller distributor */
216#define REALVIEW_MPCORE_L220_BASE 0x10102000 /* L220 registers */
217#define REALVIEW_MPCORE_SYS_PLD_CTRL1 0xD8 /* Register offset for MPCore sysctl */
218#else
219#define REALVIEW_MPCORE_SCU_BASE 0x1F000000 /* SCU registers */
220#define REALVIEW_GIC_CPU_BASE 0x1F000100 /* Generic interrupt controller CPU interface */
221#define REALVIEW_TWD_BASE 0x1F000700
222#define REALVIEW_TWD_SIZE 0x00000100
223#define REALVIEW_GIC_DIST_BASE 0x1F001000 /* Generic interrupt controller distributor */
224#define REALVIEW_MPCORE_L220_BASE 0x1F002000 /* L220 registers */
225#define REALVIEW_MPCORE_SYS_PLD_CTRL1 0x74 /* Register offset for MPCore sysctl */
226#endif
227#define REALVIEW_GIC1_CPU_BASE 0x10040000 /* Generic interrupt controller CPU interface */
228#define REALVIEW_GIC1_DIST_BASE 0x10041000 /* Generic interrupt controller distributor */
215#endif 229#endif
216#define REALVIEW_SMC_BASE 0x10080000 /* SMC */ 230#define REALVIEW_SMC_BASE 0x10080000 /* SMC */
217 /* Reserved 0x10090000 - 0x100EFFFF */ 231 /* Reserved 0x10090000 - 0x100EFFFF */
@@ -306,7 +320,11 @@
306#define INT_USB 29 /* USB controller */ 320#define INT_USB 29 /* USB controller */
307#define INT_TSPENINT 30 /* Touchscreen pen */ 321#define INT_TSPENINT 30 /* Touchscreen pen */
308#define INT_TSKPADINT 31 /* Touchscreen keypad */ 322#define INT_TSKPADINT 31 /* Touchscreen keypad */
323
309#else 324#else
325
326#define MAX_GIC_NR 2
327
310#define INT_AACI 0 328#define INT_AACI 0
311#define INT_TIMERINT0_1 1 329#define INT_TIMERINT0_1 1
312#define INT_TIMERINT2_3 2 330#define INT_TIMERINT2_3 2
diff --git a/include/asm-arm/arch-realview/scu.h b/include/asm-arm/arch-realview/scu.h
new file mode 100644
index 000000000000..cc293640178e
--- /dev/null
+++ b/include/asm-arm/arch-realview/scu.h
@@ -0,0 +1,8 @@
1#ifndef __ASMARM_ARCH_SCU_H
2#define __ASMARM_ARCH_SCU_H
3
4#include <asm/arch/platform.h>
5
6#define SCU_BASE REALVIEW_MPCORE_SCU_BASE
7
8#endif
diff --git a/include/asm-arm/arch-s3c2410/dma.h b/include/asm-arm/arch-s3c2410/dma.h
index 58ffa7ba3c88..c6e8d8f64938 100644
--- a/include/asm-arm/arch-s3c2410/dma.h
+++ b/include/asm-arm/arch-s3c2410/dma.h
@@ -51,13 +51,19 @@ enum dma_ch {
51 DMACH_UART0_SRC2, /* s3c2412 second uart sources */ 51 DMACH_UART0_SRC2, /* s3c2412 second uart sources */
52 DMACH_UART1_SRC2, 52 DMACH_UART1_SRC2,
53 DMACH_UART2_SRC2, 53 DMACH_UART2_SRC2,
54 DMACH_UART3, /* s3c2443 has extra uart */
55 DMACH_UART3_SRC2,
54 DMACH_MAX, /* the end entry */ 56 DMACH_MAX, /* the end entry */
55}; 57};
56 58
57#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */ 59#define DMACH_LOW_LEVEL (1<<28) /* use this to specifiy hardware ch no */
58 60
59/* we have 4 dma channels */ 61/* we have 4 dma channels */
60#define S3C2410_DMA_CHANNELS (4) 62#ifndef CONFIG_CPU_S3C2443
63#define S3C2410_DMA_CHANNELS (4)
64#else
65#define S3C2410_DMA_CHANNELS (6)
66#endif
61 67
62/* types */ 68/* types */
63 69
@@ -321,6 +327,7 @@ extern int s3c2410_dma_set_buffdone_fn(dmach_t, s3c2410_dma_cbfn_t rtn);
321#define S3C2410_DMA_DCDST (0x1C) 327#define S3C2410_DMA_DCDST (0x1C)
322#define S3C2410_DMA_DMASKTRIG (0x20) 328#define S3C2410_DMA_DMASKTRIG (0x20)
323#define S3C2412_DMA_DMAREQSEL (0x24) 329#define S3C2412_DMA_DMAREQSEL (0x24)
330#define S3C2443_DMA_DMAREQSEL (0x24)
324 331
325#define S3C2410_DISRCC_INC (1<<0) 332#define S3C2410_DISRCC_INC (1<<0)
326#define S3C2410_DISRCC_APB (1<<1) 333#define S3C2410_DISRCC_APB (1<<1)
@@ -415,4 +422,31 @@ extern int s3c2410_dma_set_buffdone_fn(dmach_t, s3c2410_dma_cbfn_t rtn);
415#define S3C2412_DMAREQSEL_UART2_1 S3C2412_DMAREQSEL_SRC(24) 422#define S3C2412_DMAREQSEL_UART2_1 S3C2412_DMAREQSEL_SRC(24)
416 423
417#endif 424#endif
425
426#define S3C2443_DMAREQSEL_SRC(x) ((x)<<1)
427
428#define S3C2443_DMAREQSEL_HW (1)
429
430#define S3C2443_DMAREQSEL_SPI0TX S3C2443_DMAREQSEL_SRC(0)
431#define S3C2443_DMAREQSEL_SPI0RX S3C2443_DMAREQSEL_SRC(1)
432#define S3C2443_DMAREQSEL_SPI1TX S3C2443_DMAREQSEL_SRC(2)
433#define S3C2443_DMAREQSEL_SPI1RX S3C2443_DMAREQSEL_SRC(3)
434#define S3C2443_DMAREQSEL_I2STX S3C2443_DMAREQSEL_SRC(4)
435#define S3C2443_DMAREQSEL_I2SRX S3C2443_DMAREQSEL_SRC(5)
436#define S3C2443_DMAREQSEL_TIMER S3C2443_DMAREQSEL_SRC(9)
437#define S3C2443_DMAREQSEL_SDI S3C2443_DMAREQSEL_SRC(10)
438#define S3C2443_DMAREQSEL_XDREQ0 S3C2443_DMAREQSEL_SRC(17)
439#define S3C2443_DMAREQSEL_XDREQ1 S3C2443_DMAREQSEL_SRC(18)
440#define S3C2443_DMAREQSEL_UART0_0 S3C2443_DMAREQSEL_SRC(19)
441#define S3C2443_DMAREQSEL_UART0_1 S3C2443_DMAREQSEL_SRC(20)
442#define S3C2443_DMAREQSEL_UART1_0 S3C2443_DMAREQSEL_SRC(21)
443#define S3C2443_DMAREQSEL_UART1_1 S3C2443_DMAREQSEL_SRC(22)
444#define S3C2443_DMAREQSEL_UART2_0 S3C2443_DMAREQSEL_SRC(23)
445#define S3C2443_DMAREQSEL_UART2_1 S3C2443_DMAREQSEL_SRC(24)
446#define S3C2443_DMAREQSEL_UART3_0 S3C2443_DMAREQSEL_SRC(25)
447#define S3C2443_DMAREQSEL_UART3_1 S3C2443_DMAREQSEL_SRC(26)
448#define S3C2443_DMAREQSEL_PCMOUT S3C2443_DMAREQSEL_SRC(27)
449#define S3C2443_DMAREQSEL_PCMIN S3C2443_DMAREQSEL_SRC(28)
450#define S3C2443_DMAREQSEL_MICIN S3C2443_DMAREQSEL_SRC(29)
451
418#endif /* __ASM_ARCH_DMA_H */ 452#endif /* __ASM_ARCH_DMA_H */
diff --git a/include/asm-arm/arch-s3c2410/irqs.h b/include/asm-arm/arch-s3c2410/irqs.h
index 4b7cff456c4e..c79cb1819913 100644
--- a/include/asm-arm/arch-s3c2410/irqs.h
+++ b/include/asm-arm/arch-s3c2410/irqs.h
@@ -34,10 +34,10 @@
34#define IRQ_EINT4t7 S3C2410_IRQ(4) /* 20 */ 34#define IRQ_EINT4t7 S3C2410_IRQ(4) /* 20 */
35#define IRQ_EINT8t23 S3C2410_IRQ(5) 35#define IRQ_EINT8t23 S3C2410_IRQ(5)
36#define IRQ_RESERVED6 S3C2410_IRQ(6) /* for s3c2410 */ 36#define IRQ_RESERVED6 S3C2410_IRQ(6) /* for s3c2410 */
37#define IRQ_CAM S3C2410_IRQ(6) /* for s3c2440 */ 37#define IRQ_CAM S3C2410_IRQ(6) /* for s3c2440,s3c2443 */
38#define IRQ_BATT_FLT S3C2410_IRQ(7) 38#define IRQ_BATT_FLT S3C2410_IRQ(7)
39#define IRQ_TICK S3C2410_IRQ(8) /* 24 */ 39#define IRQ_TICK S3C2410_IRQ(8) /* 24 */
40#define IRQ_WDT S3C2410_IRQ(9) 40#define IRQ_WDT S3C2410_IRQ(9) /* WDT/AC97 for s3c2443 */
41#define IRQ_TIMER0 S3C2410_IRQ(10) 41#define IRQ_TIMER0 S3C2410_IRQ(10)
42#define IRQ_TIMER1 S3C2410_IRQ(11) 42#define IRQ_TIMER1 S3C2410_IRQ(11)
43#define IRQ_TIMER2 S3C2410_IRQ(12) 43#define IRQ_TIMER2 S3C2410_IRQ(12)
@@ -45,7 +45,7 @@
45#define IRQ_TIMER4 S3C2410_IRQ(14) 45#define IRQ_TIMER4 S3C2410_IRQ(14)
46#define IRQ_UART2 S3C2410_IRQ(15) 46#define IRQ_UART2 S3C2410_IRQ(15)
47#define IRQ_LCD S3C2410_IRQ(16) /* 32 */ 47#define IRQ_LCD S3C2410_IRQ(16) /* 32 */
48#define IRQ_DMA0 S3C2410_IRQ(17) 48#define IRQ_DMA0 S3C2410_IRQ(17) /* IRQ_DMA for s3c2443 */
49#define IRQ_DMA1 S3C2410_IRQ(18) 49#define IRQ_DMA1 S3C2410_IRQ(18)
50#define IRQ_DMA2 S3C2410_IRQ(19) 50#define IRQ_DMA2 S3C2410_IRQ(19)
51#define IRQ_DMA3 S3C2410_IRQ(20) 51#define IRQ_DMA3 S3C2410_IRQ(20)
@@ -94,29 +94,63 @@
94 * these need to be ordered in number of appearance in the 94 * these need to be ordered in number of appearance in the
95 * SUBSRC mask register 95 * SUBSRC mask register
96*/ 96*/
97#define IRQ_S3CUART_RX0 S3C2410_IRQ(54) /* 70 */
98#define IRQ_S3CUART_TX0 S3C2410_IRQ(55) /* 71 */
99#define IRQ_S3CUART_ERR0 S3C2410_IRQ(56)
100 97
101#define IRQ_S3CUART_RX1 S3C2410_IRQ(57) 98#define S3C2410_IRQSUB(x) S3C2410_IRQ((x)+54)
102#define IRQ_S3CUART_TX1 S3C2410_IRQ(58)
103#define IRQ_S3CUART_ERR1 S3C2410_IRQ(59)
104 99
105#define IRQ_S3CUART_RX2 S3C2410_IRQ(60) 100#define IRQ_S3CUART_RX0 S3C2410_IRQSUB(0) /* 70 */
106#define IRQ_S3CUART_TX2 S3C2410_IRQ(61) 101#define IRQ_S3CUART_TX0 S3C2410_IRQSUB(1)
107#define IRQ_S3CUART_ERR2 S3C2410_IRQ(62) 102#define IRQ_S3CUART_ERR0 S3C2410_IRQSUB(2)
108 103
109#define IRQ_TC S3C2410_IRQ(63) 104#define IRQ_S3CUART_RX1 S3C2410_IRQSUB(3) /* 73 */
110#define IRQ_ADC S3C2410_IRQ(64) 105#define IRQ_S3CUART_TX1 S3C2410_IRQSUB(4)
106#define IRQ_S3CUART_ERR1 S3C2410_IRQSUB(5)
111 107
112/* extra irqs for s3c2440 */ 108#define IRQ_S3CUART_RX2 S3C2410_IRQSUB(6) /* 76 */
109#define IRQ_S3CUART_TX2 S3C2410_IRQSUB(7)
110#define IRQ_S3CUART_ERR2 S3C2410_IRQSUB(8)
113 111
114#define IRQ_S3C2440_CAM_C S3C2410_IRQ(65) 112#define IRQ_TC S3C2410_IRQSUB(9)
115#define IRQ_S3C2440_CAM_P S3C2410_IRQ(66) 113#define IRQ_ADC S3C2410_IRQSUB(10)
116#define IRQ_S3C2440_WDT S3C2410_IRQ(67)
117#define IRQ_S3C2440_AC97 S3C2410_IRQ(68)
118 114
119#define NR_IRQS (IRQ_S3C2440_AC97+1) 115/* extra irqs for s3c2440 */
120 116
117#define IRQ_S3C2440_CAM_C S3C2410_IRQSUB(11) /* S3C2443 too */
118#define IRQ_S3C2440_CAM_P S3C2410_IRQSUB(12) /* S3C2443 too */
119#define IRQ_S3C2440_WDT S3C2410_IRQSUB(13)
120#define IRQ_S3C2440_AC97 S3C2410_IRQSUB(14)
121
122/* irqs for s3c2443 */
123
124#define IRQ_S3C2443_DMA S3C2410_IRQ(17) /* IRQ_DMA1 */
125#define IRQ_S3C2443_UART3 S3C2410_IRQ(18) /* IRQ_DMA2 */
126#define IRQ_S3C2443_CFCON S3C2410_IRQ(19) /* IRQ_DMA3 */
127#define IRQ_S3C2443_SDI1 S3C2410_IRQ(20) /* IRQ_SDI */
128#define IRQ_S3C2443_NAND S3C2410_IRQ(24) /* reserved */
129
130#define IRQ_S3C2443_LCD1 S3C2410_IRQSUB(14)
131#define IRQ_S3C2443_LCD2 S3C2410_IRQSUB(15)
132#define IRQ_S3C2443_LCD3 S3C2410_IRQSUB(16)
133#define IRQ_S3C2443_LCD4 S3C2410_IRQSUB(17)
134
135#define IRQ_S3C2443_DMA0 S3C2410_IRQSUB(18)
136#define IRQ_S3C2443_DMA1 S3C2410_IRQSUB(19)
137#define IRQ_S3C2443_DMA2 S3C2410_IRQSUB(20)
138#define IRQ_S3C2443_DMA3 S3C2410_IRQSUB(21)
139#define IRQ_S3C2443_DMA4 S3C2410_IRQSUB(22)
140#define IRQ_S3C2443_DMA5 S3C2410_IRQSUB(23)
141
142/* UART3 */
143#define IRQ_S3C2443_RX3 S3C2410_IRQSUB(24)
144#define IRQ_S3C2443_TX3 S3C2410_IRQSUB(25)
145#define IRQ_S3C2443_ERR3 S3C2410_IRQSUB(26)
146
147#define IRQ_S3C2443_WDT S3C2410_IRQSUB(27)
148#define IRQ_S3C2443_AC97 S3C2410_IRQSUB(28)
149
150#ifdef CONFIG_CPU_S3C2443
151#define NR_IRQS (IRQ_S3C2443_AC97+1)
152#else
153#define NR_IRQS (IRQ_S3C2440_AC97+1)
154#endif
121 155
122#endif /* __ASM_ARCH_IRQ_H */ 156#endif /* __ASM_ARCH_IRQ_H */
diff --git a/include/asm-arm/arch-s3c2410/regs-adc.h b/include/asm-arm/arch-s3c2410/regs-adc.h
index 3196a2849e8a..c7f231963e76 100644
--- a/include/asm-arm/arch-s3c2410/regs-adc.h
+++ b/include/asm-arm/arch-s3c2410/regs-adc.h
@@ -41,7 +41,7 @@
41#define S3C2410_ADCTSC_XP_SEN (1<<4) 41#define S3C2410_ADCTSC_XP_SEN (1<<4)
42#define S3C2410_ADCTSC_PULL_UP_DISABLE (1<<3) 42#define S3C2410_ADCTSC_PULL_UP_DISABLE (1<<3)
43#define S3C2410_ADCTSC_AUTO_PST (1<<2) 43#define S3C2410_ADCTSC_AUTO_PST (1<<2)
44#define S3C2410_ADCTSC_XY_PST (0x3<<0) 44#define S3C2410_ADCTSC_XY_PST(x) (((x)&0x3)<<0)
45 45
46/* ADCDAT0 Bits */ 46/* ADCDAT0 Bits */
47#define S3C2410_ADCDAT0_UPDOWN (1<<15) 47#define S3C2410_ADCDAT0_UPDOWN (1<<15)
diff --git a/include/asm-arm/arch-s3c2410/regs-gpio.h b/include/asm-arm/arch-s3c2410/regs-gpio.h
index eae91694edcd..dea578b8f7f6 100644
--- a/include/asm-arm/arch-s3c2410/regs-gpio.h
+++ b/include/asm-arm/arch-s3c2410/regs-gpio.h
@@ -201,7 +201,7 @@
201#define S3C2400_GPBDAT S3C2410_GPIOREG(0x0C) 201#define S3C2400_GPBDAT S3C2410_GPIOREG(0x0C)
202#define S3C2400_GPBUP S3C2410_GPIOREG(0x10) 202#define S3C2400_GPBUP S3C2410_GPIOREG(0x10)
203 203
204/* no i/o pin in port b can have value 3! */ 204/* no i/o pin in port b can have value 3 (unless it is a s3c2443) ! */
205 205
206#define S3C2410_GPB0 S3C2410_GPIONO(S3C2410_GPIO_BANKB, 0) 206#define S3C2410_GPB0 S3C2410_GPIONO(S3C2410_GPIO_BANKB, 0)
207#define S3C2410_GPB0_INP (0x00 << 0) 207#define S3C2410_GPB0_INP (0x00 << 0)
@@ -242,6 +242,7 @@
242#define S3C2410_GPB5_INP (0x00 << 10) 242#define S3C2410_GPB5_INP (0x00 << 10)
243#define S3C2410_GPB5_OUTP (0x01 << 10) 243#define S3C2410_GPB5_OUTP (0x01 << 10)
244#define S3C2410_GPB5_nXBACK (0x02 << 10) 244#define S3C2410_GPB5_nXBACK (0x02 << 10)
245#define S3C2443_GPB5_XBACK (0x03 << 10)
245#define S3C2400_GPB5_DATA21 (0x02 << 10) 246#define S3C2400_GPB5_DATA21 (0x02 << 10)
246#define S3C2400_GPB5_nCTS1 (0x03 << 10) 247#define S3C2400_GPB5_nCTS1 (0x03 << 10)
247 248
@@ -249,6 +250,7 @@
249#define S3C2410_GPB6_INP (0x00 << 12) 250#define S3C2410_GPB6_INP (0x00 << 12)
250#define S3C2410_GPB6_OUTP (0x01 << 12) 251#define S3C2410_GPB6_OUTP (0x01 << 12)
251#define S3C2410_GPB6_nXBREQ (0x02 << 12) 252#define S3C2410_GPB6_nXBREQ (0x02 << 12)
253#define S3C2443_GPB6_XBREQ (0x03 << 12)
252#define S3C2400_GPB6_DATA22 (0x02 << 12) 254#define S3C2400_GPB6_DATA22 (0x02 << 12)
253#define S3C2400_GPB6_nRTS1 (0x03 << 12) 255#define S3C2400_GPB6_nRTS1 (0x03 << 12)
254 256
@@ -256,6 +258,7 @@
256#define S3C2410_GPB7_INP (0x00 << 14) 258#define S3C2410_GPB7_INP (0x00 << 14)
257#define S3C2410_GPB7_OUTP (0x01 << 14) 259#define S3C2410_GPB7_OUTP (0x01 << 14)
258#define S3C2410_GPB7_nXDACK1 (0x02 << 14) 260#define S3C2410_GPB7_nXDACK1 (0x02 << 14)
261#define S3C2443_GPB7_XDACK1 (0x03 << 14)
259#define S3C2400_GPB7_DATA23 (0x02 << 14) 262#define S3C2400_GPB7_DATA23 (0x02 << 14)
260 263
261#define S3C2410_GPB8 S3C2410_GPIONO(S3C2410_GPIO_BANKB, 8) 264#define S3C2410_GPB8 S3C2410_GPIONO(S3C2410_GPIO_BANKB, 8)
@@ -268,6 +271,7 @@
268#define S3C2410_GPB9_INP (0x00 << 18) 271#define S3C2410_GPB9_INP (0x00 << 18)
269#define S3C2410_GPB9_OUTP (0x01 << 18) 272#define S3C2410_GPB9_OUTP (0x01 << 18)
270#define S3C2410_GPB9_nXDACK0 (0x02 << 18) 273#define S3C2410_GPB9_nXDACK0 (0x02 << 18)
274#define S3C2443_GPB9_XDACK0 (0x03 << 18)
271#define S3C2400_GPB9_DATA25 (0x02 << 18) 275#define S3C2400_GPB9_DATA25 (0x02 << 18)
272#define S3C2400_GPB9_I2SSDI (0x03 << 18) 276#define S3C2400_GPB9_I2SSDI (0x03 << 18)
273 277
@@ -275,6 +279,7 @@
275#define S3C2410_GPB10_INP (0x00 << 20) 279#define S3C2410_GPB10_INP (0x00 << 20)
276#define S3C2410_GPB10_OUTP (0x01 << 20) 280#define S3C2410_GPB10_OUTP (0x01 << 20)
277#define S3C2410_GPB10_nXDRE0 (0x02 << 20) 281#define S3C2410_GPB10_nXDRE0 (0x02 << 20)
282#define S3C2443_GPB10_XDREQ0 (0x03 << 20)
278#define S3C2400_GPB10_DATA26 (0x02 << 20) 283#define S3C2400_GPB10_DATA26 (0x02 << 20)
279#define S3C2400_GPB10_nSS (0x03 << 20) 284#define S3C2400_GPB10_nSS (0x03 << 20)
280 285
@@ -556,6 +561,7 @@
556#define S3C2410_GPE0_INP (0x00 << 0) 561#define S3C2410_GPE0_INP (0x00 << 0)
557#define S3C2410_GPE0_OUTP (0x01 << 0) 562#define S3C2410_GPE0_OUTP (0x01 << 0)
558#define S3C2410_GPE0_I2SLRCK (0x02 << 0) 563#define S3C2410_GPE0_I2SLRCK (0x02 << 0)
564#define S3C2443_GPE0_AC_nRESET (0x03 << 0)
559#define S3C2400_GPE0_EINT0 (0x02 << 0) 565#define S3C2400_GPE0_EINT0 (0x02 << 0)
560#define S3C2410_GPE0_MASK (0x03 << 0) 566#define S3C2410_GPE0_MASK (0x03 << 0)
561 567
@@ -563,6 +569,7 @@
563#define S3C2410_GPE1_INP (0x00 << 2) 569#define S3C2410_GPE1_INP (0x00 << 2)
564#define S3C2410_GPE1_OUTP (0x01 << 2) 570#define S3C2410_GPE1_OUTP (0x01 << 2)
565#define S3C2410_GPE1_I2SSCLK (0x02 << 2) 571#define S3C2410_GPE1_I2SSCLK (0x02 << 2)
572#define S3C2443_GPE1_AC_SYNC (0x03 << 2)
566#define S3C2400_GPE1_EINT1 (0x02 << 2) 573#define S3C2400_GPE1_EINT1 (0x02 << 2)
567#define S3C2400_GPE1_nSS (0x03 << 2) 574#define S3C2400_GPE1_nSS (0x03 << 2)
568#define S3C2410_GPE1_MASK (0x03 << 2) 575#define S3C2410_GPE1_MASK (0x03 << 2)
@@ -571,6 +578,7 @@
571#define S3C2410_GPE2_INP (0x00 << 4) 578#define S3C2410_GPE2_INP (0x00 << 4)
572#define S3C2410_GPE2_OUTP (0x01 << 4) 579#define S3C2410_GPE2_OUTP (0x01 << 4)
573#define S3C2410_GPE2_CDCLK (0x02 << 4) 580#define S3C2410_GPE2_CDCLK (0x02 << 4)
581#define S3C2443_GPE2_AC_BITCLK (0x03 << 4)
574#define S3C2400_GPE2_EINT2 (0x02 << 4) 582#define S3C2400_GPE2_EINT2 (0x02 << 4)
575#define S3C2400_GPE2_I2SSDI (0x03 << 4) 583#define S3C2400_GPE2_I2SSDI (0x03 << 4)
576 584
@@ -578,6 +586,7 @@
578#define S3C2410_GPE3_INP (0x00 << 6) 586#define S3C2410_GPE3_INP (0x00 << 6)
579#define S3C2410_GPE3_OUTP (0x01 << 6) 587#define S3C2410_GPE3_OUTP (0x01 << 6)
580#define S3C2410_GPE3_I2SSDI (0x02 << 6) 588#define S3C2410_GPE3_I2SSDI (0x02 << 6)
589#define S3C2443_GPE3_AC_SDI (0x03 << 6)
581#define S3C2400_GPE3_EINT3 (0x02 << 6) 590#define S3C2400_GPE3_EINT3 (0x02 << 6)
582#define S3C2400_GPE3_nCTS1 (0x03 << 6) 591#define S3C2400_GPE3_nCTS1 (0x03 << 6)
583#define S3C2410_GPE3_nSS0 (0x03 << 6) 592#define S3C2410_GPE3_nSS0 (0x03 << 6)
@@ -587,6 +596,7 @@
587#define S3C2410_GPE4_INP (0x00 << 8) 596#define S3C2410_GPE4_INP (0x00 << 8)
588#define S3C2410_GPE4_OUTP (0x01 << 8) 597#define S3C2410_GPE4_OUTP (0x01 << 8)
589#define S3C2410_GPE4_I2SSDO (0x02 << 8) 598#define S3C2410_GPE4_I2SSDO (0x02 << 8)
599#define S3C2443_GPE4_AC_SDO (0x03 << 8)
590#define S3C2400_GPE4_EINT4 (0x02 << 8) 600#define S3C2400_GPE4_EINT4 (0x02 << 8)
591#define S3C2400_GPE4_nRTS1 (0x03 << 8) 601#define S3C2400_GPE4_nRTS1 (0x03 << 8)
592#define S3C2410_GPE4_I2SSDI (0x03 << 8) 602#define S3C2410_GPE4_I2SSDI (0x03 << 8)
@@ -596,6 +606,7 @@
596#define S3C2410_GPE5_INP (0x00 << 10) 606#define S3C2410_GPE5_INP (0x00 << 10)
597#define S3C2410_GPE5_OUTP (0x01 << 10) 607#define S3C2410_GPE5_OUTP (0x01 << 10)
598#define S3C2410_GPE5_SDCLK (0x02 << 10) 608#define S3C2410_GPE5_SDCLK (0x02 << 10)
609#define S3C2443_GPE5_SD1_CLK (0x02 << 10)
599#define S3C2400_GPE5_EINT5 (0x02 << 10) 610#define S3C2400_GPE5_EINT5 (0x02 << 10)
600#define S3C2400_GPE5_TCLK1 (0x03 << 10) 611#define S3C2400_GPE5_TCLK1 (0x03 << 10)
601 612
@@ -603,24 +614,32 @@
603#define S3C2410_GPE6_INP (0x00 << 12) 614#define S3C2410_GPE6_INP (0x00 << 12)
604#define S3C2410_GPE6_OUTP (0x01 << 12) 615#define S3C2410_GPE6_OUTP (0x01 << 12)
605#define S3C2410_GPE6_SDCMD (0x02 << 12) 616#define S3C2410_GPE6_SDCMD (0x02 << 12)
617#define S3C2443_GPE6_SD1_CMD (0x02 << 12)
618#define S3C2443_GPE6_AC_BITCLK (0x03 << 12)
606#define S3C2400_GPE6_EINT6 (0x02 << 12) 619#define S3C2400_GPE6_EINT6 (0x02 << 12)
607 620
608#define S3C2410_GPE7 S3C2410_GPIONO(S3C2410_GPIO_BANKE, 7) 621#define S3C2410_GPE7 S3C2410_GPIONO(S3C2410_GPIO_BANKE, 7)
609#define S3C2410_GPE7_INP (0x00 << 14) 622#define S3C2410_GPE7_INP (0x00 << 14)
610#define S3C2410_GPE7_OUTP (0x01 << 14) 623#define S3C2410_GPE7_OUTP (0x01 << 14)
611#define S3C2410_GPE7_SDDAT0 (0x02 << 14) 624#define S3C2410_GPE7_SDDAT0 (0x02 << 14)
625#define S3C2443_GPE5_SD1_DAT0 (0x02 << 14)
626#define S3C2443_GPE7_AC_SDI (0x03 << 14)
612#define S3C2400_GPE7_EINT7 (0x02 << 14) 627#define S3C2400_GPE7_EINT7 (0x02 << 14)
613 628
614#define S3C2410_GPE8 S3C2410_GPIONO(S3C2410_GPIO_BANKE, 8) 629#define S3C2410_GPE8 S3C2410_GPIONO(S3C2410_GPIO_BANKE, 8)
615#define S3C2410_GPE8_INP (0x00 << 16) 630#define S3C2410_GPE8_INP (0x00 << 16)
616#define S3C2410_GPE8_OUTP (0x01 << 16) 631#define S3C2410_GPE8_OUTP (0x01 << 16)
617#define S3C2410_GPE8_SDDAT1 (0x02 << 16) 632#define S3C2410_GPE8_SDDAT1 (0x02 << 16)
633#define S3C2443_GPE8_SD1_DAT1 (0x02 << 16)
634#define S3C2443_GPE8_AC_SDO (0x03 << 16)
618#define S3C2400_GPE8_nXDACK0 (0x02 << 16) 635#define S3C2400_GPE8_nXDACK0 (0x02 << 16)
619 636
620#define S3C2410_GPE9 S3C2410_GPIONO(S3C2410_GPIO_BANKE, 9) 637#define S3C2410_GPE9 S3C2410_GPIONO(S3C2410_GPIO_BANKE, 9)
621#define S3C2410_GPE9_INP (0x00 << 18) 638#define S3C2410_GPE9_INP (0x00 << 18)
622#define S3C2410_GPE9_OUTP (0x01 << 18) 639#define S3C2410_GPE9_OUTP (0x01 << 18)
623#define S3C2410_GPE9_SDDAT2 (0x02 << 18) 640#define S3C2410_GPE9_SDDAT2 (0x02 << 18)
641#define S3C2443_GPE9_SD1_DAT2 (0x02 << 18)
642#define S3C2443_GPE9_AC_SYNC (0x03 << 18)
624#define S3C2400_GPE9_nXDACK1 (0x02 << 18) 643#define S3C2400_GPE9_nXDACK1 (0x02 << 18)
625#define S3C2400_GPE9_nXBACK (0x03 << 18) 644#define S3C2400_GPE9_nXBACK (0x03 << 18)
626 645
@@ -628,6 +647,8 @@
628#define S3C2410_GPE10_INP (0x00 << 20) 647#define S3C2410_GPE10_INP (0x00 << 20)
629#define S3C2410_GPE10_OUTP (0x01 << 20) 648#define S3C2410_GPE10_OUTP (0x01 << 20)
630#define S3C2410_GPE10_SDDAT3 (0x02 << 20) 649#define S3C2410_GPE10_SDDAT3 (0x02 << 20)
650#define S3C2443_GPE10_SD1_DAT3 (0x02 << 20)
651#define S3C2443_GPE10_AC_nRESET (0x03 << 20)
631#define S3C2400_GPE10_nXDREQ0 (0x02 << 20) 652#define S3C2400_GPE10_nXDREQ0 (0x02 << 20)
632 653
633#define S3C2410_GPE11 S3C2410_GPIONO(S3C2410_GPIO_BANKE, 11) 654#define S3C2410_GPE11 S3C2410_GPIONO(S3C2410_GPIO_BANKE, 11)
@@ -796,6 +817,7 @@
796#define S3C2400_GPG4_MMCCLK (0x02 << 8) 817#define S3C2400_GPG4_MMCCLK (0x02 << 8)
797#define S3C2400_GPG4_I2SSDI (0x03 << 8) 818#define S3C2400_GPG4_I2SSDI (0x03 << 8)
798#define S3C2410_GPG4_LCDPWREN (0x03 << 8) 819#define S3C2410_GPG4_LCDPWREN (0x03 << 8)
820#define S3C2443_GPG4_LCDPWRDN (0x03 << 8)
799 821
800#define S3C2410_GPG5 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 5) 822#define S3C2410_GPG5 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 5)
801#define S3C2410_GPG5_INP (0x00 << 10) 823#define S3C2410_GPG5_INP (0x00 << 10)
@@ -803,7 +825,7 @@
803#define S3C2410_GPG5_EINT13 (0x02 << 10) 825#define S3C2410_GPG5_EINT13 (0x02 << 10)
804#define S3C2400_GPG5_MMCCMD (0x02 << 10) 826#define S3C2400_GPG5_MMCCMD (0x02 << 10)
805#define S3C2400_GPG5_IICSDA (0x03 << 10) 827#define S3C2400_GPG5_IICSDA (0x03 << 10)
806#define S3C2410_GPG5_SPIMISO1 (0x03 << 10) 828#define S3C2410_GPG5_SPIMISO1 (0x03 << 10) /* not s3c2443 */
807 829
808#define S3C2410_GPG6 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 6) 830#define S3C2410_GPG6 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 6)
809#define S3C2410_GPG6_INP (0x00 << 12) 831#define S3C2410_GPG6_INP (0x00 << 12)
@@ -845,6 +867,7 @@
845#define S3C2410_GPG11_OUTP (0x01 << 22) 867#define S3C2410_GPG11_OUTP (0x01 << 22)
846#define S3C2410_GPG11_EINT19 (0x02 << 22) 868#define S3C2410_GPG11_EINT19 (0x02 << 22)
847#define S3C2410_GPG11_TCLK1 (0x03 << 22) 869#define S3C2410_GPG11_TCLK1 (0x03 << 22)
870#define S3C2443_GPG11_CF_nIREQ (0x03 << 22)
848 871
849#define S3C2410_GPG12 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 12) 872#define S3C2410_GPG12 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 12)
850#define S3C2410_GPG12_INP (0x00 << 24) 873#define S3C2410_GPG12_INP (0x00 << 24)
@@ -852,25 +875,28 @@
852#define S3C2410_GPG12_EINT20 (0x02 << 24) 875#define S3C2410_GPG12_EINT20 (0x02 << 24)
853#define S3C2410_GPG12_XMON (0x03 << 24) 876#define S3C2410_GPG12_XMON (0x03 << 24)
854#define S3C2442_GPG12_nSPICS0 (0x03 << 24) 877#define S3C2442_GPG12_nSPICS0 (0x03 << 24)
878#define S3C2443_GPG12_nINPACK (0x03 << 24)
855 879
856#define S3C2410_GPG13 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 13) 880#define S3C2410_GPG13 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 13)
857#define S3C2410_GPG13_INP (0x00 << 26) 881#define S3C2410_GPG13_INP (0x00 << 26)
858#define S3C2410_GPG13_OUTP (0x01 << 26) 882#define S3C2410_GPG13_OUTP (0x01 << 26)
859#define S3C2410_GPG13_EINT21 (0x02 << 26) 883#define S3C2410_GPG13_EINT21 (0x02 << 26)
860#define S3C2410_GPG13_nXPON (0x03 << 26) 884#define S3C2410_GPG13_nXPON (0x03 << 26)
885#define S3C2443_GPG13_CF_nREG (0x03 << 26)
861 886
862#define S3C2410_GPG14 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 14) 887#define S3C2410_GPG14 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 14)
863#define S3C2410_GPG14_INP (0x00 << 28) 888#define S3C2410_GPG14_INP (0x00 << 28)
864#define S3C2410_GPG14_OUTP (0x01 << 28) 889#define S3C2410_GPG14_OUTP (0x01 << 28)
865#define S3C2410_GPG14_EINT22 (0x02 << 28) 890#define S3C2410_GPG14_EINT22 (0x02 << 28)
866#define S3C2410_GPG14_YMON (0x03 << 28) 891#define S3C2410_GPG14_YMON (0x03 << 28)
892#define S3C2443_GPG14_CF_RESET (0x03 << 28)
867 893
868#define S3C2410_GPG15 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 15) 894#define S3C2410_GPG15 S3C2410_GPIONO(S3C2410_GPIO_BANKG, 15)
869#define S3C2410_GPG15_INP (0x00 << 30) 895#define S3C2410_GPG15_INP (0x00 << 30)
870#define S3C2410_GPG15_OUTP (0x01 << 30) 896#define S3C2410_GPG15_OUTP (0x01 << 30)
871#define S3C2410_GPG15_EINT23 (0x02 << 30) 897#define S3C2410_GPG15_EINT23 (0x02 << 30)
872#define S3C2410_GPG15_nYPON (0x03 << 30) 898#define S3C2410_GPG15_nYPON (0x03 << 30)
873 899#define S3C2443_GPG15_CF_PWR (0x03 << 30)
874 900
875#define S3C2410_GPG_PUPDIS(x) (1<<(x)) 901#define S3C2410_GPG_PUPDIS(x) (1<<(x))
876 902
diff --git a/include/asm-arm/arch-s3c2410/regs-s3c2443-clock.h b/include/asm-arm/arch-s3c2410/regs-s3c2443-clock.h
new file mode 100644
index 000000000000..ff0536d2de42
--- /dev/null
+++ b/include/asm-arm/arch-s3c2410/regs-s3c2443-clock.h
@@ -0,0 +1,194 @@
1/* linux/include/asm-arm/arch-s3c2410/regs-clock.h
2 *
3 * Copyright (c) 2007 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
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 version 2 as
9 * published by the Free Software Foundation.
10 *
11 * S3C2443 clock register definitions
12*/
13
14#ifndef __ASM_ARM_REGS_S3C2443_CLOCK
15#define __ASM_ARM_REGS_S3C2443_CLOCK
16
17#define S3C2443_CLKREG(x) ((x) + S3C24XX_VA_CLKPWR)
18
19#define S3C2443_PLLCON_MDIVSHIFT 16
20#define S3C2443_PLLCON_PDIVSHIFT 8
21#define S3C2443_PLLCON_SDIVSHIFT 0
22#define S3C2443_PLLCON_MDIVMASK ((1<<(1+(23-16)))-1)
23#define S3C2443_PLLCON_PDIVMASK ((1<<(1+(9-8)))-1)
24#define S3C2443_PLLCON_SDIVMASK (3)
25
26#define S3C2443_MPLLCON S3C2443_CLKREG(0x10)
27#define S3C2443_EPLLCON S3C2443_CLKREG(0x18)
28#define S3C2443_CLKSRC S3C2443_CLKREG(0x20)
29#define S3C2443_CLKDIV0 S3C2443_CLKREG(0x24)
30#define S3C2443_CLKDIV1 S3C2443_CLKREG(0x28)
31#define S3C2443_HCLKCON S3C2443_CLKREG(0x30)
32#define S3C2443_PCLKCON S3C2443_CLKREG(0x34)
33#define S3C2443_SCLKCON S3C2443_CLKREG(0x38)
34#define S3C2443_PWRMODE S3C2443_CLKREG(0x40)
35#define S3C2443_SWRST S3C2443_CLKREG(0x44)
36#define S3C2443_BUSPRI0 S3C2443_CLKREG(0x50)
37#define S3C2443_SYSID S3C2443_CLKREG(0x5C)
38#define S3C2443_PWRCFG S3C2443_CLKREG(0x60)
39#define S3C2443_RSTCON S3C2443_CLKREG(0x64)
40
41#define S3C2443_SWRST_RESET (0x533c2443)
42
43#define S3C2443_PLLCON_OFF (1<<24)
44
45#define S3C2443_CLKSRC_I2S_EXT (1<<14)
46#define S3C2443_CLKSRC_I2S_EPLLDIV (0<<14)
47#define S3C2443_CLKSRC_I2S_EPLLREF (2<<14)
48#define S3C2443_CLKSRC_I2S_EPLLREF3 (3<<14)
49#define S3C2443_CLKSRC_I2S_MASK (3<<14)
50
51#define S3C2443_CLKSRC_EPLLREF_XTAL (2<<8)
52#define S3C2443_CLKSRC_EPLLREF_EXTCLK (3<<8)
53#define S3C2443_CLKSRC_EPLLREF_MPLLREF (0<<8)
54#define S3C2443_CLKSRC_EPLLREF_MPLLREF2 (1<<8)
55#define S3C2443_CLKSRC_EPLLREF_MASK (3<<8)
56
57#define S3C2443_CLKSRC_ESYSCLK_EPLL (1<<6)
58#define S3C2443_CLKSRC_MSYSCLK_MPLL (1<<4)
59#define S3C2443_CLKSRC_EXTCLK_DIV (1<<3)
60
61#define S3C2443_CLKDIV0_DVS (1<<13)
62#define S3C2443_CLKDIV0_HALF_HCLK (1<<3)
63#define S3C2443_CLKDIV0_HALF_PCLK (1<<2)
64
65#define S3C2443_CLKDIV0_HCLKDIV_MASK (3<<0)
66
67#define S3C2443_CLKDIV0_EXTDIV_MASK (3<<6)
68#define S3C2443_CLKDIV0_EXTDIV_SHIFT (6)
69
70#define S3C2443_CLKDIV0_PREDIV_MASK (3<<4)
71#define S3C2443_CLKDIV0_PREDIV_SHIFT (4)
72
73#define S3C2443_CLKDIV0_ARMDIV_MASK (15<<9)
74#define S3C2443_CLKDIV0_ARMDIV_SHIFT (9)
75#define S3C2443_CLKDIV0_ARMDIV_1 (0<<9)
76#define S3C2443_CLKDIV0_ARMDIV_2 (8<<9)
77#define S3C2443_CLKDIV0_ARMDIV_3 (2<<9)
78#define S3C2443_CLKDIV0_ARMDIV_4 (9<<9)
79#define S3C2443_CLKDIV0_ARMDIV_6 (10<<9)
80#define S3C2443_CLKDIV0_ARMDIV_8 (11<<9)
81#define S3C2443_CLKDIV0_ARMDIV_12 (13<<9)
82#define S3C2443_CLKDIV0_ARMDIV_16 (15<<9)
83
84/* S3C2443_CLKDIV1 */
85
86#define S3C2443_CLKDIV1_CAMDIV_MASK (15<<26)
87#define S3C2443_CLKDIV1_CAMDIV_SHIFT (26)
88
89#define S3C2443_CLKDIV1_HSSPIDIV_MASK (3<<24)
90#define S3C2443_CLKDIV1_HSSPIDIV_SHIFT (24)
91
92#define S3C2443_CLKDIV1_DISPDIV_MASK (0xff<<16)
93#define S3C2443_CLKDIV1_DISPDIV_SHIFT (16)
94
95#define S3C2443_CLKDIV1_I2SDIV_MASK (15<<12)
96#define S3C2443_CLKDIV1_I2SDIV_SHIFT (12)
97
98#define S3C2443_CLKDIV1_UARTDIV_MASK (15<<8)
99#define S3C2443_CLKDIV1_UARTDIV_SHIFT (8)
100
101#define S3C2443_CLKDIV1_HSMMCDIV_MASK (3<<6)
102#define S3C2443_CLKDIV1_HSMMCDIV_SHIFT (6)
103
104#define S3C2443_CLKDIV1_USBHOSTDIV_MASK (3<<4)
105#define S3C2443_CLKDIV1_USBHOSTDIV_SHIFT (4)
106
107#define S3C2443_CLKCON_NAND
108
109#define S3C2443_HCLKCON_DMA0 (1<<0)
110#define S3C2443_HCLKCON_DMA1 (1<<1)
111#define S3C2443_HCLKCON_DMA2 (1<<2)
112#define S3C2443_HCLKCON_DMA3 (1<<3)
113#define S3C2443_HCLKCON_DMA4 (1<<4)
114#define S3C2443_HCLKCON_DMA5 (1<<5)
115#define S3C2443_HCLKCON_CAMIF (1<<8)
116#define S3C2443_HCLKCON_DISP (1<<9)
117#define S3C2443_HCLKCON_LCDC (1<<10)
118#define S3C2443_HCLKCON_USBH (1<<11)
119#define S3C2443_HCLKCON_USBD (1<<12)
120#define S3C2443_HCLKCON_HSMMC (1<<16)
121#define S3C2443_HCLKCON_CFC (1<<17)
122#define S3C2443_HCLKCON_SSMC (1<<18)
123#define S3C2443_HCLKCON_DRAMC (1<<19)
124
125#define S3C2443_PCLKCON_UART0 (1<<0)
126#define S3C2443_PCLKCON_UART1 (1<<1)
127#define S3C2443_PCLKCON_UART2 (1<<2)
128#define S3C2443_PCLKCON_UART3 (1<<3)
129#define S3C2443_PCLKCON_IIC (1<<4)
130#define S3C2443_PCLKCON_SDI (1<<5)
131#define S3C2443_PCLKCON_ADC (1<<7)
132#define S3C2443_PCLKCON_IIS (1<<9)
133#define S3C2443_PCLKCON_PWMT (1<<10)
134#define S3C2443_PCLKCON_WDT (1<<11)
135#define S3C2443_PCLKCON_RTC (1<<12)
136#define S3C2443_PCLKCON_GPIO (1<<13)
137#define S3C2443_PCLKCON_SPI0 (1<<14)
138#define S3C2443_PCLKCON_SPI1 (1<<15)
139
140#define S3C2443_SCLKCON_DDRCLK (1<<16)
141#define S3C2443_SCLKCON_SSMCCLK (1<<15)
142#define S3C2443_SCLKCON_HSSPICLK (1<<14)
143#define S3C2443_SCLKCON_HSMMCCLK_EXT (1<<13)
144#define S3C2443_SCLKCON_HSMMCCLK_EPLL (1<<12)
145#define S3C2443_SCLKCON_CAMCLK (1<<11)
146#define S3C2443_SCLKCON_DISPCLK (1<<10)
147#define S3C2443_SCLKCON_I2SCLK (1<<9)
148#define S3C2443_SCLKCON_UARTCLK (1<<8)
149#define S3C2443_SCLKCON_USBHOST (1<<1)
150
151#include <asm/div64.h>
152
153static inline unsigned int
154s3c2443_get_mpll(unsigned int pllval, unsigned int baseclk)
155{
156 unsigned int mdiv, pdiv, sdiv;
157 uint64_t fvco;
158
159 mdiv = pllval >> S3C2443_PLLCON_MDIVSHIFT;
160 pdiv = pllval >> S3C2443_PLLCON_PDIVSHIFT;
161 sdiv = pllval >> S3C2443_PLLCON_SDIVSHIFT;
162
163 mdiv &= S3C2443_PLLCON_MDIVMASK;
164 pdiv &= S3C2443_PLLCON_PDIVMASK;
165 sdiv &= S3C2443_PLLCON_SDIVMASK;
166
167 fvco = (uint64_t)baseclk * (2 * (mdiv + 8));
168 do_div(fvco, pdiv << sdiv);
169
170 return (unsigned int)fvco;
171}
172
173static inline unsigned int
174s3c2443_get_epll(unsigned int pllval, unsigned int baseclk)
175{
176 unsigned int mdiv, pdiv, sdiv;
177 uint64_t fvco;
178
179 mdiv = pllval >> S3C2443_PLLCON_MDIVSHIFT;
180 pdiv = pllval >> S3C2443_PLLCON_PDIVSHIFT;
181 sdiv = pllval >> S3C2443_PLLCON_SDIVSHIFT;
182
183 mdiv &= S3C2443_PLLCON_MDIVMASK;
184 pdiv &= S3C2443_PLLCON_PDIVMASK;
185 sdiv &= S3C2443_PLLCON_SDIVMASK;
186
187 fvco = (uint64_t)baseclk * (mdiv + 8);
188 do_div(fvco, (pdiv + 2) << sdiv);
189
190 return (unsigned int)fvco;
191}
192
193#endif /* __ASM_ARM_REGS_S3C2443_CLOCK */
194
diff --git a/include/asm-arm/arch-s3c2410/regs-serial.h b/include/asm-arm/arch-s3c2410/regs-serial.h
index 46f52401d132..8946702a87f5 100644
--- a/include/asm-arm/arch-s3c2410/regs-serial.h
+++ b/include/asm-arm/arch-s3c2410/regs-serial.h
@@ -35,10 +35,12 @@
35#define S3C24XX_VA_UART0 (S3C24XX_VA_UART) 35#define S3C24XX_VA_UART0 (S3C24XX_VA_UART)
36#define S3C24XX_VA_UART1 (S3C24XX_VA_UART + 0x4000 ) 36#define S3C24XX_VA_UART1 (S3C24XX_VA_UART + 0x4000 )
37#define S3C24XX_VA_UART2 (S3C24XX_VA_UART + 0x8000 ) 37#define S3C24XX_VA_UART2 (S3C24XX_VA_UART + 0x8000 )
38#define S3C24XX_VA_UART3 (S3C24XX_VA_UART + 0xC000 )
38 39
39#define S3C2410_PA_UART0 (S3C24XX_PA_UART) 40#define S3C2410_PA_UART0 (S3C24XX_PA_UART)
40#define S3C2410_PA_UART1 (S3C24XX_PA_UART + 0x4000 ) 41#define S3C2410_PA_UART1 (S3C24XX_PA_UART + 0x4000 )
41#define S3C2410_PA_UART2 (S3C24XX_PA_UART + 0x8000 ) 42#define S3C2410_PA_UART2 (S3C24XX_PA_UART + 0x8000 )
43#define S3C2443_PA_UART3 (S3C24XX_PA_UART + 0xC000 )
42 44
43#define S3C2410_URXH (0x24) 45#define S3C2410_URXH (0x24)
44#define S3C2410_UTXH (0x20) 46#define S3C2410_UTXH (0x20)
@@ -73,6 +75,8 @@
73#define S3C2440_UCON_UCLK (1<<10) 75#define S3C2440_UCON_UCLK (1<<10)
74#define S3C2440_UCON_PCLK2 (2<<10) 76#define S3C2440_UCON_PCLK2 (2<<10)
75#define S3C2440_UCON_FCLK (3<<10) 77#define S3C2440_UCON_FCLK (3<<10)
78#define S3C2443_UCON_EPLL (3<<10)
79
76#define S3C2440_UCON2_FCLK_EN (1<<15) 80#define S3C2440_UCON2_FCLK_EN (1<<15)
77#define S3C2440_UCON0_DIVMASK (15 << 12) 81#define S3C2440_UCON0_DIVMASK (15 << 12)
78#define S3C2440_UCON1_DIVMASK (15 << 12) 82#define S3C2440_UCON1_DIVMASK (15 << 12)
@@ -93,6 +97,8 @@
93#define S3C2410_UCON_TXIRQMODE (1<<2) 97#define S3C2410_UCON_TXIRQMODE (1<<2)
94#define S3C2410_UCON_RXIRQMODE (1<<0) 98#define S3C2410_UCON_RXIRQMODE (1<<0)
95#define S3C2410_UCON_RXFIFO_TOI (1<<7) 99#define S3C2410_UCON_RXFIFO_TOI (1<<7)
100#define S3C2443_UCON_RXERR_IRQEN (1<<6)
101#define S3C2443_UCON_LOOPBACK (1<<5)
96 102
97#define S3C2410_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \ 103#define S3C2410_UCON_DEFAULT (S3C2410_UCON_TXILEVEL | \
98 S3C2410_UCON_RXILEVEL | \ 104 S3C2410_UCON_RXILEVEL | \
@@ -127,7 +133,7 @@
127#define S3C2410_UMCOM_AFC (1<<4) 133#define S3C2410_UMCOM_AFC (1<<4)
128#define S3C2410_UMCOM_RTS_LOW (1<<0) 134#define S3C2410_UMCOM_RTS_LOW (1<<0)
129 135
130#define S3C2412_UMCON_AFC_63 (0<<5) 136#define S3C2412_UMCON_AFC_63 (0<<5) /* same as s3c2443 */
131#define S3C2412_UMCON_AFC_56 (1<<5) 137#define S3C2412_UMCON_AFC_56 (1<<5)
132#define S3C2412_UMCON_AFC_48 (2<<5) 138#define S3C2412_UMCON_AFC_48 (2<<5)
133#define S3C2412_UMCON_AFC_40 (3<<5) 139#define S3C2412_UMCON_AFC_40 (3<<5)
@@ -143,6 +149,7 @@
143#define S3C2410_UFSTAT_RXMASK (15<<0) 149#define S3C2410_UFSTAT_RXMASK (15<<0)
144#define S3C2410_UFSTAT_RXSHIFT (0) 150#define S3C2410_UFSTAT_RXSHIFT (0)
145 151
152/* UFSTAT S3C2443 same as S3C2440 */
146#define S3C2440_UFSTAT_TXFULL (1<<14) 153#define S3C2440_UFSTAT_TXFULL (1<<14)
147#define S3C2440_UFSTAT_RXFULL (1<<6) 154#define S3C2440_UFSTAT_RXFULL (1<<6)
148#define S3C2440_UFSTAT_TXSHIFT (8) 155#define S3C2440_UFSTAT_TXSHIFT (8)
@@ -157,6 +164,8 @@
157#define S3C2410_UERSTAT_OVERRUN (1<<0) 164#define S3C2410_UERSTAT_OVERRUN (1<<0)
158#define S3C2410_UERSTAT_FRAME (1<<2) 165#define S3C2410_UERSTAT_FRAME (1<<2)
159#define S3C2410_UERSTAT_BREAK (1<<3) 166#define S3C2410_UERSTAT_BREAK (1<<3)
167#define S3C2443_UERSTAT_PARITY (1<<1)
168
160#define S3C2410_UERSTAT_ANY (S3C2410_UERSTAT_OVERRUN | \ 169#define S3C2410_UERSTAT_ANY (S3C2410_UERSTAT_OVERRUN | \
161 S3C2410_UERSTAT_FRAME | \ 170 S3C2410_UERSTAT_FRAME | \
162 S3C2410_UERSTAT_BREAK) 171 S3C2410_UERSTAT_BREAK)
@@ -164,6 +173,8 @@
164#define S3C2410_UMSTAT_CTS (1<<0) 173#define S3C2410_UMSTAT_CTS (1<<0)
165#define S3C2410_UMSTAT_DeltaCTS (1<<2) 174#define S3C2410_UMSTAT_DeltaCTS (1<<2)
166 175
176#define S3C2443_DIVSLOT (0x2C)
177
167#ifndef __ASSEMBLY__ 178#ifndef __ASSEMBLY__
168 179
169/* struct s3c24xx_uart_clksrc 180/* struct s3c24xx_uart_clksrc
diff --git a/include/asm-arm/arch-s3c2410/reset.h b/include/asm-arm/arch-s3c2410/reset.h
new file mode 100644
index 000000000000..4f866cdecab0
--- /dev/null
+++ b/include/asm-arm/arch-s3c2410/reset.h
@@ -0,0 +1,22 @@
1/* linux/include/asm-arm/arch-s3c2410/reset.h
2 *
3 * Copyright (c) 2007 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 * http://armlinux.simtec.co.uk/
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 version 2 as
9 * published by the Free Software Foundation.
10 *
11 * S3C2410 CPU reset controls
12*/
13
14#ifndef __ASM_ARCH_RESET_H
15#define __ASM_ARCH_RESET_H __FILE__
16
17/* This allows the over-ride of the default reset code
18*/
19
20extern void (*s3c24xx_reset_hook)(void);
21
22#endif /* __ASM_ARCH_RESET_H */
diff --git a/include/asm-arm/arch-s3c2410/system.h b/include/asm-arm/arch-s3c2410/system.h
index ecf250db45fb..1c74ef17da33 100644
--- a/include/asm-arm/arch-s3c2410/system.h
+++ b/include/asm-arm/arch-s3c2410/system.h
@@ -15,15 +15,16 @@
15 15
16#include <asm/arch/map.h> 16#include <asm/arch/map.h>
17#include <asm/arch/idle.h> 17#include <asm/arch/idle.h>
18#include <asm/arch/reset.h>
18 19
19#include <asm/arch/regs-watchdog.h> 20#include <asm/arch/regs-watchdog.h>
20#include <asm/arch/regs-clock.h> 21#include <asm/arch/regs-clock.h>
21 22
22void (*s3c24xx_idle)(void); 23void (*s3c24xx_idle)(void);
24void (*s3c24xx_reset_hook)(void);
23 25
24void s3c24xx_default_idle(void) 26void s3c24xx_default_idle(void)
25{ 27{
26 void __iomem *reg = S3C2410_CLKCON;
27 unsigned long tmp; 28 unsigned long tmp;
28 int i; 29 int i;
29 30
@@ -33,16 +34,18 @@ void s3c24xx_default_idle(void)
33 34
34 /* Warning: going into idle state upsets jtag scanning */ 35 /* Warning: going into idle state upsets jtag scanning */
35 36
36 __raw_writel(__raw_readl(reg) | (1<<2), reg); 37 __raw_writel(__raw_readl(S3C2410_CLKCON) | S3C2410_CLKCON_IDLE,
38 S3C2410_CLKCON);
37 39
38 /* the samsung port seems to do a loop and then unset idle.. */ 40 /* the samsung port seems to do a loop and then unset idle.. */
39 for (i = 0; i < 50; i++) { 41 for (i = 0; i < 50; i++) {
40 tmp += __raw_readl(reg); /* ensure loop not optimised out */ 42 tmp += __raw_readl(S3C2410_CLKCON); /* ensure loop not optimised out */
41 } 43 }
42 44
43 /* this bit is not cleared on re-start... */ 45 /* this bit is not cleared on re-start... */
44 46
45 __raw_writel(__raw_readl(reg) & ~(1<<2), reg); 47 __raw_writel(__raw_readl(S3C2410_CLKCON) & ~S3C2410_CLKCON_IDLE,
48 S3C2410_CLKCON);
46} 49}
47 50
48static void arch_idle(void) 51static void arch_idle(void)
@@ -53,7 +56,6 @@ static void arch_idle(void)
53 s3c24xx_default_idle(); 56 s3c24xx_default_idle();
54} 57}
55 58
56
57static void 59static void
58arch_reset(char mode) 60arch_reset(char mode)
59{ 61{
@@ -61,6 +63,9 @@ arch_reset(char mode)
61 cpu_reset(0); 63 cpu_reset(0);
62 } 64 }
63 65
66 if (s3c24xx_reset_hook)
67 s3c24xx_reset_hook();
68
64 printk("arch_reset: attempting watchdog reset\n"); 69 printk("arch_reset: attempting watchdog reset\n");
65 70
66 __raw_writel(0, S3C2410_WTCON); /* disable watchdog, to be safe */ 71 __raw_writel(0, S3C2410_WTCON); /* disable watchdog, to be safe */
diff --git a/include/asm-arm/arch-s3c2410/udc.h b/include/asm-arm/arch-s3c2410/udc.h
new file mode 100644
index 000000000000..e59ec339d614
--- /dev/null
+++ b/include/asm-arm/arch-s3c2410/udc.h
@@ -0,0 +1,36 @@
1/* linux/include/asm/arch-s3c2410/udc.h
2 *
3 * Copyright (c) 2005 Arnaud Patard <arnaud.patard@rtp-net.org>
4 *
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
9 *
10 *
11 * Changelog:
12 * 14-Mar-2005 RTP Created file
13 * 02-Aug-2005 RTP File rename
14 * 07-Sep-2005 BJD Minor cleanups, changed cmd to enum
15 * 18-Jan-2007 HMW Add per-platform vbus_draw function
16*/
17
18#ifndef __ASM_ARM_ARCH_UDC_H
19#define __ASM_ARM_ARCH_UDC_H
20
21enum s3c2410_udc_cmd_e {
22 S3C2410_UDC_P_ENABLE = 1, /* Pull-up enable */
23 S3C2410_UDC_P_DISABLE = 2, /* Pull-up disable */
24 S3C2410_UDC_P_RESET = 3, /* UDC reset, in case of */
25};
26
27struct s3c2410_udc_mach_info {
28 void (*udc_command)(enum s3c2410_udc_cmd_e);
29 void (*vbus_draw)(unsigned int ma);
30 unsigned int vbus_pin;
31 unsigned char vbus_pin_inverted;
32};
33
34extern void __init s3c24xx_udc_set_platdata(struct s3c2410_udc_mach_info *);
35
36#endif /* __ASM_ARM_ARCH_UDC_H */
diff --git a/include/asm-arm/cacheflush.h b/include/asm-arm/cacheflush.h
index 5f531ea03059..afad32c76e6c 100644
--- a/include/asm-arm/cacheflush.h
+++ b/include/asm-arm/cacheflush.h
@@ -185,9 +185,15 @@ struct cpu_cache_fns {
185 void (*coherent_user_range)(unsigned long, unsigned long); 185 void (*coherent_user_range)(unsigned long, unsigned long);
186 void (*flush_kern_dcache_page)(void *); 186 void (*flush_kern_dcache_page)(void *);
187 187
188 void (*dma_inv_range)(unsigned long, unsigned long); 188 void (*dma_inv_range)(const void *, const void *);
189 void (*dma_clean_range)(unsigned long, unsigned long); 189 void (*dma_clean_range)(const void *, const void *);
190 void (*dma_flush_range)(unsigned long, unsigned long); 190 void (*dma_flush_range)(const void *, const void *);
191};
192
193struct outer_cache_fns {
194 void (*inv_range)(unsigned long, unsigned long);
195 void (*clean_range)(unsigned long, unsigned long);
196 void (*flush_range)(unsigned long, unsigned long);
191}; 197};
192 198
193/* 199/*
@@ -240,9 +246,40 @@ extern void __cpuc_flush_dcache_page(void *);
240#define dmac_clean_range __glue(_CACHE,_dma_clean_range) 246#define dmac_clean_range __glue(_CACHE,_dma_clean_range)
241#define dmac_flush_range __glue(_CACHE,_dma_flush_range) 247#define dmac_flush_range __glue(_CACHE,_dma_flush_range)
242 248
243extern void dmac_inv_range(unsigned long, unsigned long); 249extern void dmac_inv_range(const void *, const void *);
244extern void dmac_clean_range(unsigned long, unsigned long); 250extern void dmac_clean_range(const void *, const void *);
245extern void dmac_flush_range(unsigned long, unsigned long); 251extern void dmac_flush_range(const void *, const void *);
252
253#endif
254
255#ifdef CONFIG_OUTER_CACHE
256
257extern struct outer_cache_fns outer_cache;
258
259static inline void outer_inv_range(unsigned long start, unsigned long end)
260{
261 if (outer_cache.inv_range)
262 outer_cache.inv_range(start, end);
263}
264static inline void outer_clean_range(unsigned long start, unsigned long end)
265{
266 if (outer_cache.clean_range)
267 outer_cache.clean_range(start, end);
268}
269static inline void outer_flush_range(unsigned long start, unsigned long end)
270{
271 if (outer_cache.flush_range)
272 outer_cache.flush_range(start, end);
273}
274
275#else
276
277static inline void outer_inv_range(unsigned long start, unsigned long end)
278{ }
279static inline void outer_clean_range(unsigned long start, unsigned long end)
280{ }
281static inline void outer_flush_range(unsigned long start, unsigned long end)
282{ }
246 283
247#endif 284#endif
248 285
diff --git a/include/asm-arm/checksum.h b/include/asm-arm/checksum.h
index 8c0bb5bb14ee..eaa0efd8d0d4 100644
--- a/include/asm-arm/checksum.h
+++ b/include/asm-arm/checksum.h
@@ -40,13 +40,27 @@ __wsum
40csum_partial_copy_from_user(const void __user *src, void *dst, int len, __wsum sum, int *err_ptr); 40csum_partial_copy_from_user(const void __user *src, void *dst, int len, __wsum sum, int *err_ptr);
41 41
42/* 42/*
43 * Fold a partial checksum without adding pseudo headers
44 */
45static inline __sum16 csum_fold(__wsum sum)
46{
47 __asm__(
48 "add %0, %1, %1, ror #16 @ csum_fold"
49 : "=r" (sum)
50 : "r" (sum)
51 : "cc");
52 return (__force __sum16)(~(__force u32)sum >> 16);
53}
54
55/*
43 * This is a version of ip_compute_csum() optimized for IP headers, 56 * This is a version of ip_compute_csum() optimized for IP headers,
44 * which always checksum on 4 octet boundaries. 57 * which always checksum on 4 octet boundaries.
45 */ 58 */
46static inline __sum16 59static inline __sum16
47ip_fast_csum(const void *iph, unsigned int ihl) 60ip_fast_csum(const void *iph, unsigned int ihl)
48{ 61{
49 unsigned int sum, tmp1; 62 unsigned int tmp1;
63 __wsum sum;
50 64
51 __asm__ __volatile__( 65 __asm__ __volatile__(
52 "ldr %0, [%1], #4 @ ip_fast_csum \n\ 66 "ldr %0, [%1], #4 @ ip_fast_csum \n\
@@ -62,29 +76,11 @@ ip_fast_csum(const void *iph, unsigned int ihl)
62 subne %2, %2, #1 @ without destroying \n\ 76 subne %2, %2, #1 @ without destroying \n\
63 bne 1b @ the carry flag \n\ 77 bne 1b @ the carry flag \n\
64 adcs %0, %0, %3 \n\ 78 adcs %0, %0, %3 \n\
65 adc %0, %0, #0 \n\ 79 adc %0, %0, #0"
66 adds %0, %0, %0, lsl #16 \n\
67 addcs %0, %0, #0x10000 \n\
68 mvn %0, %0 \n\
69 mov %0, %0, lsr #16"
70 : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (tmp1) 80 : "=r" (sum), "=r" (iph), "=r" (ihl), "=r" (tmp1)
71 : "1" (iph), "2" (ihl) 81 : "1" (iph), "2" (ihl)
72 : "cc", "memory"); 82 : "cc", "memory");
73 return (__force __sum16)sum; 83 return csum_fold(sum);
74}
75
76/*
77 * Fold a partial checksum without adding pseudo headers
78 */
79static inline __sum16 csum_fold(__wsum sum)
80{
81 __asm__(
82 "adds %0, %1, %1, lsl #16 @ csum_fold \n\
83 addcs %0, %0, #0x10000"
84 : "=r" (sum)
85 : "r" (sum)
86 : "cc");
87 return (__force __sum16)(~(__force u32)sum >> 16);
88} 84}
89 85
90static inline __wsum 86static inline __wsum
@@ -114,23 +110,7 @@ static inline __sum16
114csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len, 110csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
115 unsigned short proto, __wsum sum) 111 unsigned short proto, __wsum sum)
116{ 112{
117 __asm__( 113 return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum));
118 "adds %0, %1, %2 @ csum_tcpudp_magic \n\
119 adcs %0, %0, %3 \n"
120#ifdef __ARMEB__
121 "adcs %0, %0, %4 \n"
122#else
123 "adcs %0, %0, %4, lsl #8 \n"
124#endif
125 "adcs %0, %0, %5 \n\
126 adc %0, %0, #0 \n\
127 adds %0, %0, %0, lsl #16 \n\
128 addcs %0, %0, #0x10000 \n\
129 mvn %0, %0"
130 : "=&r"(sum)
131 : "r" (sum), "r" (daddr), "r" (saddr), "r" (len), "Ir" (htons(proto))
132 : "cc");
133 return (__force __sum16)((__force u32)sum >> 16);
134} 114}
135 115
136 116
diff --git a/include/asm-arm/device.h b/include/asm-arm/device.h
index d8f9872b0e2d..c61642b40603 100644
--- a/include/asm-arm/device.h
+++ b/include/asm-arm/device.h
@@ -3,5 +3,13 @@
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 ASMARM_DEVICE_H
7#define ASMARM_DEVICE_H
7 8
9struct dev_archdata {
10#ifdef CONFIG_DMABOUNCE
11 struct dmabounce_device_info *dmabounce;
12#endif
13};
14
15#endif
diff --git a/include/asm-arm/dma-mapping.h b/include/asm-arm/dma-mapping.h
index 9bc46b486afb..abfb75b654c7 100644
--- a/include/asm-arm/dma-mapping.h
+++ b/include/asm-arm/dma-mapping.h
@@ -17,7 +17,7 @@
17 * platforms with CONFIG_DMABOUNCE. 17 * platforms with CONFIG_DMABOUNCE.
18 * Use the driver DMA support - see dma-mapping.h (dma_sync_*) 18 * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
19 */ 19 */
20extern void consistent_sync(void *kaddr, size_t size, int rw); 20extern void consistent_sync(const void *kaddr, size_t size, int rw);
21 21
22/* 22/*
23 * Return whether the given device DMA address mask can be supported 23 * Return whether the given device DMA address mask can be supported
@@ -61,6 +61,22 @@ static inline int dma_mapping_error(dma_addr_t dma_addr)
61 return dma_addr == ~0; 61 return dma_addr == ~0;
62} 62}
63 63
64/*
65 * Dummy noncoherent implementation. We don't provide a dma_cache_sync
66 * function so drivers using this API are highlighted with build warnings.
67 */
68static inline void *
69dma_alloc_noncoherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
70{
71 return NULL;
72}
73
74static inline void
75dma_free_noncoherent(struct device *dev, size_t size, void *cpu_addr,
76 dma_addr_t handle)
77{
78}
79
64/** 80/**
65 * dma_alloc_coherent - allocate consistent memory for DMA 81 * dma_alloc_coherent - allocate consistent memory for DMA
66 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices 82 * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
diff --git a/include/asm-arm/domain.h b/include/asm-arm/domain.h
index 4c2885abbe6c..3c12a7625304 100644
--- a/include/asm-arm/domain.h
+++ b/include/asm-arm/domain.h
@@ -57,6 +57,7 @@
57 __asm__ __volatile__( \ 57 __asm__ __volatile__( \
58 "mcr p15, 0, %0, c3, c0 @ set domain" \ 58 "mcr p15, 0, %0, c3, c0 @ set domain" \
59 : : "r" (x)); \ 59 : : "r" (x)); \
60 isb(); \
60 } while (0) 61 } while (0)
61 62
62#define modify_domain(dom,type) \ 63#define modify_domain(dom,type) \
diff --git a/include/asm-arm/hardware/arm_scu.h b/include/asm-arm/hardware/arm_scu.h
index 9903f60c84b7..7d28eb5a1758 100644
--- a/include/asm-arm/hardware/arm_scu.h
+++ b/include/asm-arm/hardware/arm_scu.h
@@ -1,6 +1,8 @@
1#ifndef ASMARM_HARDWARE_ARM_SCU_H 1#ifndef ASMARM_HARDWARE_ARM_SCU_H
2#define ASMARM_HARDWARE_ARM_SCU_H 2#define ASMARM_HARDWARE_ARM_SCU_H
3 3
4#include <asm/arch/scu.h>
5
4/* 6/*
5 * SCU registers 7 * SCU registers
6 */ 8 */
diff --git a/include/asm-arm/hardware/cache-l2x0.h b/include/asm-arm/hardware/cache-l2x0.h
new file mode 100644
index 000000000000..54029a740396
--- /dev/null
+++ b/include/asm-arm/hardware/cache-l2x0.h
@@ -0,0 +1,56 @@
1/*
2 * include/asm-arm/hardware/cache-l2x0.h
3 *
4 * Copyright (C) 2007 ARM Limited
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2 as
8 * published by the Free Software Foundation.
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 the
13 * 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_ARM_HARDWARE_L2X0_H
21#define __ASM_ARM_HARDWARE_L2X0_H
22
23#define L2X0_CACHE_ID 0x000
24#define L2X0_CACHE_TYPE 0x004
25#define L2X0_CTRL 0x100
26#define L2X0_AUX_CTRL 0x104
27#define L2X0_EVENT_CNT_CTRL 0x200
28#define L2X0_EVENT_CNT1_CFG 0x204
29#define L2X0_EVENT_CNT0_CFG 0x208
30#define L2X0_EVENT_CNT1_VAL 0x20C
31#define L2X0_EVENT_CNT0_VAL 0x210
32#define L2X0_INTR_MASK 0x214
33#define L2X0_MASKED_INTR_STAT 0x218
34#define L2X0_RAW_INTR_STAT 0x21C
35#define L2X0_INTR_CLEAR 0x220
36#define L2X0_CACHE_SYNC 0x730
37#define L2X0_INV_LINE_PA 0x770
38#define L2X0_INV_WAY 0x77C
39#define L2X0_CLEAN_LINE_PA 0x7B0
40#define L2X0_CLEAN_LINE_IDX 0x7B8
41#define L2X0_CLEAN_WAY 0x7BC
42#define L2X0_CLEAN_INV_LINE_PA 0x7F0
43#define L2X0_CLEAN_INV_LINE_IDX 0x7F8
44#define L2X0_CLEAN_INV_WAY 0x7FC
45#define L2X0_LOCKDOWN_WAY_D 0x900
46#define L2X0_LOCKDOWN_WAY_I 0x904
47#define L2X0_TEST_OPERATION 0xF00
48#define L2X0_LINE_DATA 0xF10
49#define L2X0_LINE_TAG 0xF30
50#define L2X0_DEBUG_CTRL 0xF40
51
52#ifndef __ASSEMBLY__
53extern void __init l2x0_init(void __iomem *base, __u32 aux_val, __u32 aux_mask);
54#endif
55
56#endif
diff --git a/include/asm-arm/hardware/gic.h b/include/asm-arm/hardware/gic.h
index 3fa5eb70f64e..966e428ad32c 100644
--- a/include/asm-arm/hardware/gic.h
+++ b/include/asm-arm/hardware/gic.h
@@ -33,8 +33,9 @@
33#define GIC_DIST_SOFTINT 0xf00 33#define GIC_DIST_SOFTINT 0xf00
34 34
35#ifndef __ASSEMBLY__ 35#ifndef __ASSEMBLY__
36void gic_dist_init(void __iomem *base); 36void gic_dist_init(unsigned int gic_nr, void __iomem *base, unsigned int irq_start);
37void gic_cpu_init(void __iomem *base); 37void gic_cpu_init(unsigned int gic_nr, void __iomem *base);
38void gic_cascade_irq(unsigned int gic_nr, unsigned int irq);
38void gic_raise_softirq(cpumask_t cpumask, unsigned int irq); 39void gic_raise_softirq(cpumask_t cpumask, unsigned int irq);
39#endif 40#endif
40 41
diff --git a/include/asm-arm/hardware/iop3xx.h b/include/asm-arm/hardware/iop3xx.h
index 13ac8a4cd01f..c91b546e20ef 100644
--- a/include/asm-arm/hardware/iop3xx.h
+++ b/include/asm-arm/hardware/iop3xx.h
@@ -37,6 +37,13 @@ extern void gpio_line_set(int line, int value);
37#define IOP3XX_PERIPHERAL_PHYS_BASE 0xffffe000 37#define IOP3XX_PERIPHERAL_PHYS_BASE 0xffffe000
38#define IOP3XX_PERIPHERAL_VIRT_BASE 0xfeffe000 38#define IOP3XX_PERIPHERAL_VIRT_BASE 0xfeffe000
39#define IOP3XX_PERIPHERAL_SIZE 0x00002000 39#define IOP3XX_PERIPHERAL_SIZE 0x00002000
40#define IOP3XX_PERIPHERAL_UPPER_PA (IOP3XX_PERIPHERAL_PHYS_BASE +\
41 IOP3XX_PERIPHERAL_SIZE - 1)
42#define IOP3XX_PERIPHERAL_UPPER_VA (IOP3XX_PERIPHERAL_VIRT_BASE +\
43 IOP3XX_PERIPHERAL_SIZE - 1)
44#define IOP3XX_PMMR_PHYS_TO_VIRT(addr) (u32) ((u32) addr -\
45 (IOP3XX_PERIPHERAL_PHYS_BASE\
46 - IOP3XX_PERIPHERAL_VIRT_BASE))
40#define IOP3XX_REG_ADDR(reg) (IOP3XX_PERIPHERAL_VIRT_BASE + (reg)) 47#define IOP3XX_REG_ADDR(reg) (IOP3XX_PERIPHERAL_VIRT_BASE + (reg))
41 48
42/* Address Translation Unit */ 49/* Address Translation Unit */
@@ -258,12 +265,20 @@ extern void gpio_line_set(int line, int value);
258#define IOP3XX_PCI_LOWER_IO_PA 0x90000000 265#define IOP3XX_PCI_LOWER_IO_PA 0x90000000
259#define IOP3XX_PCI_LOWER_IO_VA 0xfe000000 266#define IOP3XX_PCI_LOWER_IO_VA 0xfe000000
260#define IOP3XX_PCI_LOWER_IO_BA (*IOP3XX_OIOWTVR) 267#define IOP3XX_PCI_LOWER_IO_BA (*IOP3XX_OIOWTVR)
268#define IOP3XX_PCI_UPPER_IO_PA (IOP3XX_PCI_LOWER_IO_PA +\
269 IOP3XX_PCI_IO_WINDOW_SIZE - 1)
270#define IOP3XX_PCI_UPPER_IO_VA (IOP3XX_PCI_LOWER_IO_VA +\
271 IOP3XX_PCI_IO_WINDOW_SIZE - 1)
272#define IOP3XX_PCI_IO_PHYS_TO_VIRT(addr) (((u32) addr -\
273 IOP3XX_PCI_LOWER_IO_PA) +\
274 IOP3XX_PCI_LOWER_IO_VA)
261 275
262 276
263#ifndef __ASSEMBLY__ 277#ifndef __ASSEMBLY__
264void iop3xx_map_io(void); 278void iop3xx_map_io(void);
265void iop3xx_init_time(unsigned long); 279void iop3xx_init_time(unsigned long);
266unsigned long iop3xx_gettimeoffset(void); 280unsigned long iop3xx_gettimeoffset(void);
281void iop_init_cp6_handler(void);
267 282
268extern struct platform_device iop3xx_i2c0_device; 283extern struct platform_device iop3xx_i2c0_device;
269extern struct platform_device iop3xx_i2c1_device; 284extern struct platform_device iop3xx_i2c1_device;
diff --git a/include/asm-arm/hardware/sa1111.h b/include/asm-arm/hardware/sa1111.h
index 6aa0a5b75b69..61b1d05c7df7 100644
--- a/include/asm-arm/hardware/sa1111.h
+++ b/include/asm-arm/hardware/sa1111.h
@@ -29,6 +29,9 @@
29#define _SA1111(x) ((x) + sa1111->resource.start) 29#define _SA1111(x) ((x) + sa1111->resource.start)
30#endif 30#endif
31 31
32#define sa1111_writel(val,addr) __raw_writel(val, addr)
33#define sa1111_readl(addr) __raw_readl(addr)
34
32/* 35/*
33 * 26 bits of the SA-1110 address bus are available to the SA-1111. 36 * 26 bits of the SA-1110 address bus are available to the SA-1111.
34 * Use these when feeding target addresses to the DMA engines. 37 * Use these when feeding target addresses to the DMA engines.
@@ -45,14 +48,6 @@
45#define SA1111_SAC_DMA_MIN_XFER (0x800) 48#define SA1111_SAC_DMA_MIN_XFER (0x800)
46 49
47/* 50/*
48 * SA1111 register definitions.
49 */
50#define __CCREG(x) __REGP(SA1111_VBASE + (x))
51
52#define sa1111_writel(val,addr) __raw_writel(val, addr)
53#define sa1111_readl(addr) __raw_readl(addr)
54
55/*
56 * System Bus Interface (SBI) 51 * System Bus Interface (SBI)
57 * 52 *
58 * Registers 53 * Registers
@@ -194,55 +189,37 @@
194 * SADR Serial Audio Data Register (16 x 32-bit) 189 * SADR Serial Audio Data Register (16 x 32-bit)
195 */ 190 */
196 191
197#define _SACR0 _SA1111( 0x0600 ) 192#define SA1111_SERAUDIO 0x0600
198#define _SACR1 _SA1111( 0x0604 ) 193
199#define _SACR2 _SA1111( 0x0608 ) 194/*
200#define _SASR0 _SA1111( 0x060c ) 195 * These are offsets from the above base.
201#define _SASR1 _SA1111( 0x0610 ) 196 */
202#define _SASCR _SA1111( 0x0618 ) 197#define SA1111_SACR0 0x00
203#define _L3_CAR _SA1111( 0x061c ) 198#define SA1111_SACR1 0x04
204#define _L3_CDR _SA1111( 0x0620 ) 199#define SA1111_SACR2 0x08
205#define _ACCAR _SA1111( 0x0624 ) 200#define SA1111_SASR0 0x0c
206#define _ACCDR _SA1111( 0x0628 ) 201#define SA1111_SASR1 0x10
207#define _ACSAR _SA1111( 0x062c ) 202#define SA1111_SASCR 0x18
208#define _ACSDR _SA1111( 0x0630 ) 203#define SA1111_L3_CAR 0x1c
209#define _SADTCS _SA1111( 0x0634 ) 204#define SA1111_L3_CDR 0x20
210#define _SADTSA _SA1111( 0x0638 ) 205#define SA1111_ACCAR 0x24
211#define _SADTCA _SA1111( 0x063c ) 206#define SA1111_ACCDR 0x28
212#define _SADTSB _SA1111( 0x0640 ) 207#define SA1111_ACSAR 0x2c
213#define _SADTCB _SA1111( 0x0644 ) 208#define SA1111_ACSDR 0x30
214#define _SADRCS _SA1111( 0x0648 ) 209#define SA1111_SADTCS 0x34
215#define _SADRSA _SA1111( 0x064c ) 210#define SA1111_SADTSA 0x38
216#define _SADRCA _SA1111( 0x0650 ) 211#define SA1111_SADTCA 0x3c
217#define _SADRSB _SA1111( 0x0654 ) 212#define SA1111_SADTSB 0x40
218#define _SADRCB _SA1111( 0x0658 ) 213#define SA1111_SADTCB 0x44
219#define _SAITR _SA1111( 0x065c ) 214#define SA1111_SADRCS 0x48
220#define _SADR _SA1111( 0x0680 ) 215#define SA1111_SADRSA 0x4c
221 216#define SA1111_SADRCA 0x50
222#define SACR0 __CCREG(0x0600) 217#define SA1111_SADRSB 0x54
223#define SACR1 __CCREG(0x0604) 218#define SA1111_SADRCB 0x58
224#define SACR2 __CCREG(0x0608) 219#define SA1111_SAITR 0x5c
225#define SASR0 __CCREG(0x060c) 220#define SA1111_SADR 0x80
226#define SASR1 __CCREG(0x0610) 221
227#define SASCR __CCREG(0x0618) 222#ifndef CONFIG_ARCH_PXA
228#define L3_CAR __CCREG(0x061c)
229#define L3_CDR __CCREG(0x0620)
230#define ACCAR __CCREG(0x0624)
231#define ACCDR __CCREG(0x0628)
232#define ACSAR __CCREG(0x062c)
233#define ACSDR __CCREG(0x0630)
234#define SADTCS __CCREG(0x0634)
235#define SADTSA __CCREG(0x0638)
236#define SADTCA __CCREG(0x063c)
237#define SADTSB __CCREG(0x0640)
238#define SADTCB __CCREG(0x0644)
239#define SADRCS __CCREG(0x0648)
240#define SADRSA __CCREG(0x064c)
241#define SADRCA __CCREG(0x0650)
242#define SADRSB __CCREG(0x0654)
243#define SADRCB __CCREG(0x0658)
244#define SAITR __CCREG(0x065c)
245#define SADR __CCREG(0x0680)
246 223
247#define SACR0_ENB (1<<0) 224#define SACR0_ENB (1<<0)
248#define SACR0_BCKD (1<<2) 225#define SACR0_BCKD (1<<2)
@@ -330,6 +307,8 @@
330#define SAITR_RDBDA (1<<10) 307#define SAITR_RDBDA (1<<10)
331#define SAITR_RDBDB (1<<11) 308#define SAITR_RDBDB (1<<11)
332 309
310#endif /* !CONFIG_ARCH_PXA */
311
333/* 312/*
334 * General-Purpose I/O Interface 313 * General-Purpose I/O Interface
335 * 314 *
diff --git a/include/asm-arm/kexec.h b/include/asm-arm/kexec.h
new file mode 100644
index 000000000000..8c1c6162a80c
--- /dev/null
+++ b/include/asm-arm/kexec.h
@@ -0,0 +1,30 @@
1#ifndef _ARM_KEXEC_H
2#define _ARM_KEXEC_H
3
4#ifdef CONFIG_KEXEC
5
6/* Maximum physical address we can use pages from */
7#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL)
8/* Maximum address we can reach in physical address mode */
9#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL)
10/* Maximum address we can use for the control code buffer */
11#define KEXEC_CONTROL_MEMORY_LIMIT TASK_SIZE
12
13#define KEXEC_CONTROL_CODE_SIZE 4096
14
15#define KEXEC_ARCH KEXEC_ARCH_ARM
16
17#ifndef __ASSEMBLY__
18
19#define MAX_NOTE_BYTES 1024
20
21struct kimage;
22/* Provide a dummy definition to avoid build failures. */
23static inline void crash_setup_regs(struct pt_regs *newregs,
24 struct pt_regs *oldregs) { }
25
26#endif /* __ASSEMBLY__ */
27
28#endif /* CONFIG_KEXEC */
29
30#endif /* _ARM_KEXEC_H */
diff --git a/include/asm-arm/pgtable.h b/include/asm-arm/pgtable.h
index b8cf2d5ec304..7b2bafce21a2 100644
--- a/include/asm-arm/pgtable.h
+++ b/include/asm-arm/pgtable.h
@@ -175,19 +175,29 @@ extern void __pgd_error(const char *file, int line, unsigned long val);
175#ifndef __ASSEMBLY__ 175#ifndef __ASSEMBLY__
176 176
177/* 177/*
178 * The following macros handle the cache and bufferable bits... 178 * The pgprot_* and protection_map entries will be fixed up in runtime
179 * to include the cachable and bufferable bits based on memory policy,
180 * as well as any architecture dependent bits like global/ASID and SMP
181 * shared mapping bits.
179 */ 182 */
180#define _L_PTE_DEFAULT L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_CACHEABLE | L_PTE_BUFFERABLE 183#define _L_PTE_DEFAULT L_PTE_PRESENT | L_PTE_YOUNG | L_PTE_CACHEABLE | L_PTE_BUFFERABLE
181#define _L_PTE_READ L_PTE_USER | L_PTE_EXEC 184#define _L_PTE_READ L_PTE_USER | L_PTE_EXEC
182 185
186extern pgprot_t pgprot_user;
183extern pgprot_t pgprot_kernel; 187extern pgprot_t pgprot_kernel;
184 188
185#define PAGE_NONE __pgprot(_L_PTE_DEFAULT) 189#define PAGE_NONE pgprot_user
186#define PAGE_COPY __pgprot(_L_PTE_DEFAULT | _L_PTE_READ) 190#define PAGE_COPY __pgprot(pgprot_val(pgprot_user) | _L_PTE_READ)
187#define PAGE_SHARED __pgprot(_L_PTE_DEFAULT | _L_PTE_READ | L_PTE_WRITE) 191#define PAGE_SHARED __pgprot(pgprot_val(pgprot_user) | _L_PTE_READ | \
188#define PAGE_READONLY __pgprot(_L_PTE_DEFAULT | _L_PTE_READ) 192 L_PTE_WRITE)
193#define PAGE_READONLY __pgprot(pgprot_val(pgprot_user) | _L_PTE_READ)
189#define PAGE_KERNEL pgprot_kernel 194#define PAGE_KERNEL pgprot_kernel
190 195
196#define __PAGE_NONE __pgprot(_L_PTE_DEFAULT)
197#define __PAGE_COPY __pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
198#define __PAGE_SHARED __pgprot(_L_PTE_DEFAULT | _L_PTE_READ | L_PTE_WRITE)
199#define __PAGE_READONLY __pgprot(_L_PTE_DEFAULT | _L_PTE_READ)
200
191#endif /* __ASSEMBLY__ */ 201#endif /* __ASSEMBLY__ */
192 202
193/* 203/*
@@ -198,23 +208,23 @@ extern pgprot_t pgprot_kernel;
198 * 2) If we could do execute protection, then read is implied 208 * 2) If we could do execute protection, then read is implied
199 * 3) write implies read permissions 209 * 3) write implies read permissions
200 */ 210 */
201#define __P000 PAGE_NONE 211#define __P000 __PAGE_NONE
202#define __P001 PAGE_READONLY 212#define __P001 __PAGE_READONLY
203#define __P010 PAGE_COPY 213#define __P010 __PAGE_COPY
204#define __P011 PAGE_COPY 214#define __P011 __PAGE_COPY
205#define __P100 PAGE_READONLY 215#define __P100 __PAGE_READONLY
206#define __P101 PAGE_READONLY 216#define __P101 __PAGE_READONLY
207#define __P110 PAGE_COPY 217#define __P110 __PAGE_COPY
208#define __P111 PAGE_COPY 218#define __P111 __PAGE_COPY
209 219
210#define __S000 PAGE_NONE 220#define __S000 __PAGE_NONE
211#define __S001 PAGE_READONLY 221#define __S001 __PAGE_READONLY
212#define __S010 PAGE_SHARED 222#define __S010 __PAGE_SHARED
213#define __S011 PAGE_SHARED 223#define __S011 __PAGE_SHARED
214#define __S100 PAGE_READONLY 224#define __S100 __PAGE_READONLY
215#define __S101 PAGE_READONLY 225#define __S101 __PAGE_READONLY
216#define __S110 PAGE_SHARED 226#define __S110 __PAGE_SHARED
217#define __S111 PAGE_SHARED 227#define __S111 __PAGE_SHARED
218 228
219#ifndef __ASSEMBLY__ 229#ifndef __ASSEMBLY__
220/* 230/*
diff --git a/arch/arm/mach-s3c2410/clock.h b/include/asm-arm/plat-s3c24xx/clock.h
index 7f0ea03e1d49..f6135dbb9fa9 100644
--- a/arch/arm/mach-s3c2410/clock.h
+++ b/include/asm-arm/plat-s3c24xx/clock.h
@@ -1,4 +1,4 @@
1/* 1/* linux/include/asm-arm/plat-s3c24xx/clock.h
2 * linux/arch/arm/mach-s3c2410/clock.h 2 * linux/arch/arm/mach-s3c2410/clock.h
3 * 3 *
4 * Copyright (c) 2004-2005 Simtec Electronics 4 * Copyright (c) 2004-2005 Simtec Electronics
diff --git a/arch/arm/mach-s3c2410/common-smdk.h b/include/asm-arm/plat-s3c24xx/common-smdk.h
index 0e3a3be330a3..58d9094c935c 100644
--- a/arch/arm/mach-s3c2410/common-smdk.h
+++ b/include/asm-arm/plat-s3c24xx/common-smdk.h
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/common-smdk.h 1/* linux/include/asm-arm/plat-s3c24xx/common-smdk.h
2 * 2 *
3 * Copyright (c) 2006 Simtec Electronics 3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/mach-s3c2410/cpu.h b/include/asm-arm/plat-s3c24xx/cpu.h
index be42e4032a6d..15dd18810905 100644
--- a/arch/arm/mach-s3c2410/cpu.h
+++ b/include/asm-arm/plat-s3c24xx/cpu.h
@@ -1,4 +1,4 @@
1/* arch/arm/mach-s3c2410/cpu.h 1/* linux/include/asm-arm/plat-s3c24xx/cpu.h
2 * 2 *
3 * Copyright (c) 2004-2005 Simtec Electronics 3 * Copyright (c) 2004-2005 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
@@ -67,3 +67,4 @@ extern struct sysdev_class s3c2410_sysclass;
67extern struct sysdev_class s3c2412_sysclass; 67extern struct sysdev_class s3c2412_sysclass;
68extern struct sysdev_class s3c2440_sysclass; 68extern struct sysdev_class s3c2440_sysclass;
69extern struct sysdev_class s3c2442_sysclass; 69extern struct sysdev_class s3c2442_sysclass;
70extern struct sysdev_class s3c2443_sysclass;
diff --git a/arch/arm/mach-s3c2410/devs.h b/include/asm-arm/plat-s3c24xx/devs.h
index 14fb0bade716..dddf485fc067 100644
--- a/arch/arm/mach-s3c2410/devs.h
+++ b/include/asm-arm/plat-s3c24xx/devs.h
@@ -1,4 +1,4 @@
1/* arch/arm/mach-s3c2410/devs.h 1/* linux/include/asm-arm/plat-s3c24xx/devs.h
2 * 2 *
3 * Copyright (c) 2004 Simtec Electronics 3 * Copyright (c) 2004 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/mach-s3c2410/dma.h b/include/asm-arm/plat-s3c24xx/dma.h
index 0ebfe0aab80b..2c59406435e5 100644
--- a/arch/arm/mach-s3c2410/dma.h
+++ b/include/asm-arm/plat-s3c24xx/dma.h
@@ -1,4 +1,4 @@
1/* arch/arm/mach-s3c2410/dma.h 1/* linux/include/asm-arm/plat-s3c24xx/dma.h
2 * 2 *
3 * Copyright (C) 2006 Simtec Electronics 3 * Copyright (C) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
@@ -14,6 +14,7 @@ extern struct sysdev_class dma_sysclass;
14extern struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS]; 14extern struct s3c2410_dma_chan s3c2410_chans[S3C2410_DMA_CHANNELS];
15 15
16#define DMA_CH_VALID (1<<31) 16#define DMA_CH_VALID (1<<31)
17#define DMA_CH_NEVER (1<<30)
17 18
18struct s3c24xx_dma_addr { 19struct s3c24xx_dma_addr {
19 unsigned long from; 20 unsigned long from;
@@ -43,3 +44,34 @@ struct s3c24xx_dma_selection {
43}; 44};
44 45
45extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel); 46extern int s3c24xx_dma_init_map(struct s3c24xx_dma_selection *sel);
47
48/* struct s3c24xx_dma_order_ch
49 *
50 * channel map for one of the `enum dma_ch` dma channels. the list
51 * entry contains a set of low-level channel numbers, orred with
52 * DMA_CH_VALID, which are checked in the order in the array.
53*/
54
55struct s3c24xx_dma_order_ch {
56 unsigned int list[S3C2410_DMA_CHANNELS]; /* list of channels */
57 unsigned int flags; /* flags */
58};
59
60/* struct s3c24xx_dma_order
61 *
62 * information provided by either the core or the board to give the
63 * dma system a hint on how to allocate channels
64*/
65
66struct s3c24xx_dma_order {
67 struct s3c24xx_dma_order_ch channels[DMACH_MAX];
68};
69
70extern int s3c24xx_dma_order_set(struct s3c24xx_dma_order *map);
71
72/* DMA init code, called from the cpu support code */
73
74extern int s3c2410_dma_init(void);
75
76extern int s3c24xx_dma_init(unsigned int channels, unsigned int irq,
77 unsigned int stride);
diff --git a/arch/arm/mach-s3c2410/irq.h b/include/asm-arm/plat-s3c24xx/irq.h
index e5913da3b919..8af6d9579b31 100644
--- a/arch/arm/mach-s3c2410/irq.h
+++ b/include/asm-arm/plat-s3c24xx/irq.h
@@ -1,4 +1,4 @@
1/* arch/arm/mach-s3c2410/irq.h 1/* linux/include/asm-arm/plat-s3c24xx/irq.h
2 * 2 *
3 * Copyright (c) 2004-2005 Simtec Electronics 3 * Copyright (c) 2004-2005 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/mach-s3c2410/pm.h b/include/asm-arm/plat-s3c24xx/pm.h
index ffe197a119fb..cc623667e48a 100644
--- a/arch/arm/mach-s3c2410/pm.h
+++ b/include/asm-arm/plat-s3c24xx/pm.h
@@ -1,4 +1,4 @@
1/* linux/arch/arm/mach-s3c2410/pm.h 1/* linux/include/asm-arm/plat-s3c24xx/pm.h
2 * 2 *
3 * Copyright (c) 2004 Simtec Electronics 3 * Copyright (c) 2004 Simtec Electronics
4 * Written by Ben Dooks, <ben@simtec.co.uk> 4 * Written by Ben Dooks, <ben@simtec.co.uk>
diff --git a/arch/arm/mach-s3c2410/s3c2400.h b/include/asm-arm/plat-s3c24xx/s3c2400.h
index 8b2394e1ed40..3a5a16821af8 100644
--- a/arch/arm/mach-s3c2410/s3c2400.h
+++ b/include/asm-arm/plat-s3c24xx/s3c2400.h
@@ -1,4 +1,4 @@
1/* arch/arm/mach-s3c2410/s3c2400.h 1/* linux/include/asm-arm/plat-s3c24xx/s3c2400.h
2 * 2 *
3 * Copyright (c) 2004 Simtec Electronics 3 * Copyright (c) 2004 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/mach-s3c2410/s3c2410.h b/include/asm-arm/plat-s3c24xx/s3c2410.h
index fbed084f26d0..36de0b835873 100644
--- a/arch/arm/mach-s3c2410/s3c2410.h
+++ b/include/asm-arm/plat-s3c24xx/s3c2410.h
@@ -1,4 +1,4 @@
1/* arch/arm/mach-s3c2410/s3c2410.h 1/* linux/include/asm-arm/plat-s3c24xx/s3c2410.h
2 * 2 *
3 * Copyright (c) 2004 Simtec Electronics 3 * Copyright (c) 2004 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/mach-s3c2410/s3c2412.h b/include/asm-arm/plat-s3c24xx/s3c2412.h
index c6e56032a6e7..3ec97685e781 100644
--- a/arch/arm/mach-s3c2410/s3c2412.h
+++ b/include/asm-arm/plat-s3c24xx/s3c2412.h
@@ -1,4 +1,4 @@
1/* arch/arm/mach-s3c2410/s3c2412.h 1/* linux/include/asm-arm/plat-s3c24xx/s3c2412.h
2 * 2 *
3 * Copyright (c) 2006 Simtec Electronics 3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/mach-s3c2410/s3c2440.h b/include/asm-arm/plat-s3c24xx/s3c2440.h
index dcd316076c59..107853bf9481 100644
--- a/arch/arm/mach-s3c2410/s3c2440.h
+++ b/include/asm-arm/plat-s3c24xx/s3c2440.h
@@ -1,4 +1,4 @@
1/* arch/arm/mach-s3c2410/s3c2440.h 1/* linux/include/asm-arm/plat-s3c24xx/s3c2440.h
2 * 2 *
3 * Copyright (c) 2004-2005 Simtec Electronics 3 * Copyright (c) 2004-2005 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
diff --git a/arch/arm/mach-s3c2410/s3c2442.h b/include/asm-arm/plat-s3c24xx/s3c2442.h
index 0ae37d24866c..451a23a2092a 100644
--- a/arch/arm/mach-s3c2410/s3c2442.h
+++ b/include/asm-arm/plat-s3c24xx/s3c2442.h
@@ -1,4 +1,4 @@
1/* arch/arm/mach-s3c2410/s3c2442.h 1/* linux/include/asm-arm/plat-s3c24xx/s3c2442.h
2 * 2 *
3 * Copyright (c) 2006 Simtec Electronics 3 * Copyright (c) 2006 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk> 4 * Ben Dooks <ben@simtec.co.uk>
diff --git a/include/asm-arm/plat-s3c24xx/s3c2443.h b/include/asm-arm/plat-s3c24xx/s3c2443.h
new file mode 100644
index 000000000000..11d83b5c84e6
--- /dev/null
+++ b/include/asm-arm/plat-s3c24xx/s3c2443.h
@@ -0,0 +1,32 @@
1/* linux/include/asm-arm/plat-s3c24xx/s3c2443.h
2 *
3 * Copyright (c) 2004-2005 Simtec Electronics
4 * Ben Dooks <ben@simtec.co.uk>
5 *
6 * Header file for s3c2443 cpu support
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 version 2 as
10 * published by the Free Software Foundation.
11*/
12
13#ifdef CONFIG_CPU_S3C2443
14
15struct s3c2410_uartcfg;
16
17extern int s3c2443_init(void);
18
19extern void s3c2443_map_io(struct map_desc *mach_desc, int size);
20
21extern void s3c2443_init_uarts(struct s3c2410_uartcfg *cfg, int no);
22
23extern void s3c2443_init_clocks(int xtal);
24
25extern int s3c2443_baseclk_add(void);
26
27#else
28#define s3c2443_init_clocks NULL
29#define s3c2443_init_uarts NULL
30#define s3c2443_map_io NULL
31#define s3c2443_init NULL
32#endif
diff --git a/include/asm-arm/system.h b/include/asm-arm/system.h
index aa223fc546af..f4386906b200 100644
--- a/include/asm-arm/system.h
+++ b/include/asm-arm/system.h
@@ -140,6 +140,40 @@ static inline int cpu_is_xsc3(void)
140#define cpu_is_xscale() 1 140#define cpu_is_xscale() 1
141#endif 141#endif
142 142
143#define UDBG_UNDEFINED (1 << 0)
144#define UDBG_SYSCALL (1 << 1)
145#define UDBG_BADABORT (1 << 2)
146#define UDBG_SEGV (1 << 3)
147#define UDBG_BUS (1 << 4)
148
149extern unsigned int user_debug;
150
151#if __LINUX_ARM_ARCH__ >= 4
152#define vectors_high() (cr_alignment & CR_V)
153#else
154#define vectors_high() (0)
155#endif
156
157#if __LINUX_ARM_ARCH__ >= 6
158#define isb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c5, 4" \
159 : : "r" (0) : "memory")
160#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
161 : : "r" (0) : "memory")
162#define dmb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
163 : : "r" (0) : "memory")
164#else
165#define isb() __asm__ __volatile__ ("" : : : "memory")
166#define dsb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 4" \
167 : : "r" (0) : "memory")
168#define dmb() __asm__ __volatile__ ("" : : : "memory")
169#endif
170#define mb() dmb()
171#define rmb() mb()
172#define wmb() mb()
173#define read_barrier_depends() do { } while(0)
174#define set_mb(var, value) do { var = value; mb(); } while (0)
175#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
176
143extern unsigned long cr_no_alignment; /* defined in entry-armv.S */ 177extern unsigned long cr_no_alignment; /* defined in entry-armv.S */
144extern unsigned long cr_alignment; /* defined in entry-armv.S */ 178extern unsigned long cr_alignment; /* defined in entry-armv.S */
145 179
@@ -154,6 +188,7 @@ static inline void set_cr(unsigned int val)
154{ 188{
155 asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR" 189 asm volatile("mcr p15, 0, %0, c1, c0, 0 @ set CR"
156 : : "r" (val) : "cc"); 190 : : "r" (val) : "cc");
191 isb();
157} 192}
158 193
159#ifndef CONFIG_SMP 194#ifndef CONFIG_SMP
@@ -176,34 +211,9 @@ static inline void set_copro_access(unsigned int val)
176{ 211{
177 asm volatile("mcr p15, 0, %0, c1, c0, 2 @ set copro access" 212 asm volatile("mcr p15, 0, %0, c1, c0, 2 @ set copro access"
178 : : "r" (val) : "cc"); 213 : : "r" (val) : "cc");
214 isb();
179} 215}
180 216
181#define UDBG_UNDEFINED (1 << 0)
182#define UDBG_SYSCALL (1 << 1)
183#define UDBG_BADABORT (1 << 2)
184#define UDBG_SEGV (1 << 3)
185#define UDBG_BUS (1 << 4)
186
187extern unsigned int user_debug;
188
189#if __LINUX_ARM_ARCH__ >= 4
190#define vectors_high() (cr_alignment & CR_V)
191#else
192#define vectors_high() (0)
193#endif
194
195#if __LINUX_ARM_ARCH__ >= 6
196#define mb() __asm__ __volatile__ ("mcr p15, 0, %0, c7, c10, 5" \
197 : : "r" (0) : "memory")
198#else
199#define mb() __asm__ __volatile__ ("" : : : "memory")
200#endif
201#define rmb() mb()
202#define wmb() mb()
203#define read_barrier_depends() do { } while(0)
204#define set_mb(var, value) do { var = value; mb(); } while (0)
205#define nop() __asm__ __volatile__("mov\tr0,r0\t@ nop\n\t");
206
207/* 217/*
208 * switch_mm() may do a full cache flush over the context switch, 218 * switch_mm() may do a full cache flush over the context switch,
209 * so enable interrupts over the context switch to avoid high 219 * so enable interrupts over the context switch to avoid high
diff --git a/include/asm-arm/tlbflush.h b/include/asm-arm/tlbflush.h
index cd10a0b5f8ae..08c6991dc9c9 100644
--- a/include/asm-arm/tlbflush.h
+++ b/include/asm-arm/tlbflush.h
@@ -247,7 +247,7 @@ static inline void local_flush_tlb_all(void)
247 const unsigned int __tlb_flag = __cpu_tlb_flags; 247 const unsigned int __tlb_flag = __cpu_tlb_flags;
248 248
249 if (tlb_flag(TLB_WB)) 249 if (tlb_flag(TLB_WB))
250 asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc"); 250 dsb();
251 251
252 if (tlb_flag(TLB_V3_FULL)) 252 if (tlb_flag(TLB_V3_FULL))
253 asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc"); 253 asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (zero) : "cc");
@@ -257,6 +257,15 @@ static inline void local_flush_tlb_all(void)
257 asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc"); 257 asm("mcr p15, 0, %0, c8, c6, 0" : : "r" (zero) : "cc");
258 if (tlb_flag(TLB_V4_I_FULL | TLB_V6_I_FULL)) 258 if (tlb_flag(TLB_V4_I_FULL | TLB_V6_I_FULL))
259 asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc"); 259 asm("mcr p15, 0, %0, c8, c5, 0" : : "r" (zero) : "cc");
260
261 if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL |
262 TLB_V6_I_PAGE | TLB_V6_D_PAGE |
263 TLB_V6_I_ASID | TLB_V6_D_ASID)) {
264 /* flush the branch target cache */
265 asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
266 dsb();
267 isb();
268 }
260} 269}
261 270
262static inline void local_flush_tlb_mm(struct mm_struct *mm) 271static inline void local_flush_tlb_mm(struct mm_struct *mm)
@@ -266,7 +275,7 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm)
266 const unsigned int __tlb_flag = __cpu_tlb_flags; 275 const unsigned int __tlb_flag = __cpu_tlb_flags;
267 276
268 if (tlb_flag(TLB_WB)) 277 if (tlb_flag(TLB_WB))
269 asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc"); 278 dsb();
270 279
271 if (cpu_isset(smp_processor_id(), mm->cpu_vm_mask)) { 280 if (cpu_isset(smp_processor_id(), mm->cpu_vm_mask)) {
272 if (tlb_flag(TLB_V3_FULL)) 281 if (tlb_flag(TLB_V3_FULL))
@@ -285,6 +294,14 @@ static inline void local_flush_tlb_mm(struct mm_struct *mm)
285 asm("mcr p15, 0, %0, c8, c6, 2" : : "r" (asid) : "cc"); 294 asm("mcr p15, 0, %0, c8, c6, 2" : : "r" (asid) : "cc");
286 if (tlb_flag(TLB_V6_I_ASID)) 295 if (tlb_flag(TLB_V6_I_ASID))
287 asm("mcr p15, 0, %0, c8, c5, 2" : : "r" (asid) : "cc"); 296 asm("mcr p15, 0, %0, c8, c5, 2" : : "r" (asid) : "cc");
297
298 if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL |
299 TLB_V6_I_PAGE | TLB_V6_D_PAGE |
300 TLB_V6_I_ASID | TLB_V6_D_ASID)) {
301 /* flush the branch target cache */
302 asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
303 dsb();
304 }
288} 305}
289 306
290static inline void 307static inline void
@@ -296,7 +313,7 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
296 uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm); 313 uaddr = (uaddr & PAGE_MASK) | ASID(vma->vm_mm);
297 314
298 if (tlb_flag(TLB_WB)) 315 if (tlb_flag(TLB_WB))
299 asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero)); 316 dsb();
300 317
301 if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask)) { 318 if (cpu_isset(smp_processor_id(), vma->vm_mm->cpu_vm_mask)) {
302 if (tlb_flag(TLB_V3_PAGE)) 319 if (tlb_flag(TLB_V3_PAGE))
@@ -317,6 +334,14 @@ local_flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr)
317 asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc"); 334 asm("mcr p15, 0, %0, c8, c6, 1" : : "r" (uaddr) : "cc");
318 if (tlb_flag(TLB_V6_I_PAGE)) 335 if (tlb_flag(TLB_V6_I_PAGE))
319 asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc"); 336 asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (uaddr) : "cc");
337
338 if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL |
339 TLB_V6_I_PAGE | TLB_V6_D_PAGE |
340 TLB_V6_I_ASID | TLB_V6_D_ASID)) {
341 /* flush the branch target cache */
342 asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
343 dsb();
344 }
320} 345}
321 346
322static inline void local_flush_tlb_kernel_page(unsigned long kaddr) 347static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
@@ -327,7 +352,7 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
327 kaddr &= PAGE_MASK; 352 kaddr &= PAGE_MASK;
328 353
329 if (tlb_flag(TLB_WB)) 354 if (tlb_flag(TLB_WB))
330 asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc"); 355 dsb();
331 356
332 if (tlb_flag(TLB_V3_PAGE)) 357 if (tlb_flag(TLB_V3_PAGE))
333 asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (kaddr) : "cc"); 358 asm("mcr p15, 0, %0, c6, c0, 0" : : "r" (kaddr) : "cc");
@@ -347,11 +372,14 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
347 if (tlb_flag(TLB_V6_I_PAGE)) 372 if (tlb_flag(TLB_V6_I_PAGE))
348 asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc"); 373 asm("mcr p15, 0, %0, c8, c5, 1" : : "r" (kaddr) : "cc");
349 374
350 /* The ARM ARM states that the completion of a TLB maintenance 375 if (tlb_flag(TLB_V6_I_FULL | TLB_V6_D_FULL |
351 * operation is only guaranteed by a DSB instruction 376 TLB_V6_I_PAGE | TLB_V6_D_PAGE |
352 */ 377 TLB_V6_I_ASID | TLB_V6_D_ASID)) {
353 if (tlb_flag(TLB_V6_U_PAGE | TLB_V6_D_PAGE | TLB_V6_I_PAGE)) 378 /* flush the branch target cache */
354 asm("mcr p15, 0, %0, c7, c10, 4" : : "r" (zero) : "cc"); 379 asm("mcr p15, 0, %0, c7, c5, 6" : : "r" (zero) : "cc");
380 dsb();
381 isb();
382 }
355} 383}
356 384
357/* 385/*
@@ -369,15 +397,13 @@ static inline void local_flush_tlb_kernel_page(unsigned long kaddr)
369 */ 397 */
370static inline void flush_pmd_entry(pmd_t *pmd) 398static inline void flush_pmd_entry(pmd_t *pmd)
371{ 399{
372 const unsigned int zero = 0;
373 const unsigned int __tlb_flag = __cpu_tlb_flags; 400 const unsigned int __tlb_flag = __cpu_tlb_flags;
374 401
375 if (tlb_flag(TLB_DCLEAN)) 402 if (tlb_flag(TLB_DCLEAN))
376 asm("mcr p15, 0, %0, c7, c10, 1 @ flush_pmd" 403 asm("mcr p15, 0, %0, c7, c10, 1 @ flush_pmd"
377 : : "r" (pmd) : "cc"); 404 : : "r" (pmd) : "cc");
378 if (tlb_flag(TLB_WB)) 405 if (tlb_flag(TLB_WB))
379 asm("mcr p15, 0, %0, c7, c10, 4 @ flush_pmd" 406 dsb();
380 : : "r" (zero) : "cc");
381} 407}
382 408
383static inline void clean_pmd_entry(pmd_t *pmd) 409static inline void clean_pmd_entry(pmd_t *pmd)
diff --git a/include/asm-arm/unistd.h b/include/asm-arm/unistd.h
index 97e7060000cf..0991b7bc3f78 100644
--- a/include/asm-arm/unistd.h
+++ b/include/asm-arm/unistd.h
@@ -372,6 +372,7 @@
372#define __NR_move_pages (__NR_SYSCALL_BASE+344) 372#define __NR_move_pages (__NR_SYSCALL_BASE+344)
373#define __NR_getcpu (__NR_SYSCALL_BASE+345) 373#define __NR_getcpu (__NR_SYSCALL_BASE+345)
374 /* 346 for epoll_pwait */ 374 /* 346 for epoll_pwait */
375#define __NR_sys_kexec_load (__NR_SYSCALL_BASE+347)
375 376
376/* 377/*
377 * The following SWIs are ARM private. 378 * The following SWIs are ARM private.
diff --git a/include/asm-avr32/arch-at32ap/at91_pdc.h b/include/asm-avr32/arch-at32ap/at91_pdc.h
deleted file mode 100644
index 79d6e02fa45e..000000000000
--- a/include/asm-avr32/arch-at32ap/at91_pdc.h
+++ /dev/null
@@ -1,36 +0,0 @@
1/*
2 * include/asm-arm/arch-at91rm9200/at91_pdc.h
3 *
4 * Copyright (C) 2005 Ivan Kokshaysky
5 * Copyright (C) SAN People
6 *
7 * Peripheral Data Controller (PDC) registers.
8 * Based on AT91RM9200 datasheet revision E.
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 of the License, or
13 * (at your option) any later version.
14 */
15
16#ifndef AT91_PDC_H
17#define AT91_PDC_H
18
19#define AT91_PDC_RPR 0x100 /* Receive Pointer Register */
20#define AT91_PDC_RCR 0x104 /* Receive Counter Register */
21#define AT91_PDC_TPR 0x108 /* Transmit Pointer Register */
22#define AT91_PDC_TCR 0x10c /* Transmit Counter Register */
23#define AT91_PDC_RNPR 0x110 /* Receive Next Pointer Register */
24#define AT91_PDC_RNCR 0x114 /* Receive Next Counter Register */
25#define AT91_PDC_TNPR 0x118 /* Transmit Next Pointer Register */
26#define AT91_PDC_TNCR 0x11c /* Transmit Next Counter Register */
27
28#define AT91_PDC_PTCR 0x120 /* Transfer Control Register */
29#define AT91_PDC_RXTEN (1 << 0) /* Receiver Transfer Enable */
30#define AT91_PDC_RXTDIS (1 << 1) /* Receiver Transfer Disable */
31#define AT91_PDC_TXTEN (1 << 8) /* Transmitter Transfer Enable */
32#define AT91_PDC_TXTDIS (1 << 9) /* Transmitter Transfer Disable */
33
34#define AT91_PDC_PTSR 0x124 /* Transfer Status Register */
35
36#endif
diff --git a/include/asm-i386/acpi.h b/include/asm-i386/acpi.h
index 5e657eb8946c..449f3f272e07 100644
--- a/include/asm-i386/acpi.h
+++ b/include/asm-i386/acpi.h
@@ -127,6 +127,7 @@ extern int acpi_irq_balance_set(char *str);
127#define acpi_ioapic 0 127#define acpi_ioapic 0
128static inline void acpi_noirq_set(void) { } 128static inline void acpi_noirq_set(void) { }
129static inline void acpi_disable_pci(void) { } 129static inline void acpi_disable_pci(void) { }
130static inline void disable_acpi(void) { }
130 131
131#endif /* !CONFIG_ACPI */ 132#endif /* !CONFIG_ACPI */
132 133
diff --git a/include/asm-powerpc/atomic.h b/include/asm-powerpc/atomic.h
index f038e33e6d48..2ce4b6b7b348 100644
--- a/include/asm-powerpc/atomic.h
+++ b/include/asm-powerpc/atomic.h
@@ -165,7 +165,8 @@ static __inline__ int atomic_dec_return(atomic_t *v)
165 return t; 165 return t;
166} 166}
167 167
168#define atomic_cmpxchg(v, o, n) ((int)cmpxchg(&((v)->counter), (o), (n))) 168#define atomic_cmpxchg(v, o, n) \
169 ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
169#define atomic_xchg(v, new) (xchg(&((v)->counter), new)) 170#define atomic_xchg(v, new) (xchg(&((v)->counter), new))
170 171
171/** 172/**
@@ -413,6 +414,43 @@ static __inline__ long atomic64_dec_if_positive(atomic64_t *v)
413 return t; 414 return t;
414} 415}
415 416
417#define atomic64_cmpxchg(v, o, n) \
418 ((__typeof__((v)->counter))cmpxchg(&((v)->counter), (o), (n)))
419#define atomic64_xchg(v, new) (xchg(&((v)->counter), new))
420
421/**
422 * atomic64_add_unless - add unless the number is a given value
423 * @v: pointer of type atomic64_t
424 * @a: the amount to add to v...
425 * @u: ...unless v is equal to u.
426 *
427 * Atomically adds @a to @v, so long as it was not @u.
428 * Returns non-zero if @v was not @u, and zero otherwise.
429 */
430static __inline__ int atomic64_add_unless(atomic64_t *v, long a, long u)
431{
432 long t;
433
434 __asm__ __volatile__ (
435 LWSYNC_ON_SMP
436"1: ldarx %0,0,%1 # atomic_add_unless\n\
437 cmpd 0,%0,%3 \n\
438 beq- 2f \n\
439 add %0,%2,%0 \n"
440" stdcx. %0,0,%1 \n\
441 bne- 1b \n"
442 ISYNC_ON_SMP
443" subf %0,%2,%0 \n\
4442:"
445 : "=&r" (t)
446 : "r" (&v->counter), "r" (a), "r" (u)
447 : "cc", "memory");
448
449 return t != u;
450}
451
452#define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0)
453
416#endif /* __powerpc64__ */ 454#endif /* __powerpc64__ */
417 455
418#include <asm-generic/atomic.h> 456#include <asm-generic/atomic.h>
diff --git a/include/asm-powerpc/dcr-native.h b/include/asm-powerpc/dcr-native.h
index d7a1bc1551c6..05af081222f6 100644
--- a/include/asm-powerpc/dcr-native.h
+++ b/include/asm-powerpc/dcr-native.h
@@ -26,8 +26,8 @@ typedef struct {} dcr_host_t;
26 26
27#define DCR_MAP_OK(host) (1) 27#define DCR_MAP_OK(host) (1)
28 28
29#define dcr_map(dev, dcr_n, dcr_c) {} 29#define dcr_map(dev, dcr_n, dcr_c) ((dcr_host_t){})
30#define dcr_unmap(host, dcr_n, dcr_c) {} 30#define dcr_unmap(host, dcr_n, dcr_c) do {} while (0)
31#define dcr_read(host, dcr_n) mfdcr(dcr_n) 31#define dcr_read(host, dcr_n) mfdcr(dcr_n)
32#define dcr_write(host, dcr_n, value) mtdcr(dcr_n, value) 32#define dcr_write(host, dcr_n, value) mtdcr(dcr_n, value)
33 33
diff --git a/include/asm-powerpc/pmi.h b/include/asm-powerpc/pmi.h
new file mode 100644
index 000000000000..cb0f8aa43088
--- /dev/null
+++ b/include/asm-powerpc/pmi.h
@@ -0,0 +1,67 @@
1#ifndef _POWERPC_PMI_H
2#define _POWERPC_PMI_H
3
4/*
5 * Definitions for talking with PMI device on PowerPC
6 *
7 * PMI (Platform Management Interrupt) is a way to communicate
8 * with the BMC (Baseboard Management Controller) via interrupts.
9 * Unlike IPMI it is bidirectional and has a low latency.
10 *
11 * (C) Copyright IBM Deutschland Entwicklung GmbH 2005
12 *
13 * Author: Christian Krafft <krafft@de.ibm.com>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2, or (at your option)
18 * any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, write to the Free Software
27 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
28 */
29
30#ifdef __KERNEL__
31
32#include <asm/of_device.h>
33
34#define PMI_TYPE_FREQ_CHANGE 0x01
35#define PMI_READ_TYPE 0
36#define PMI_READ_DATA0 1
37#define PMI_READ_DATA1 2
38#define PMI_READ_DATA2 3
39#define PMI_WRITE_TYPE 4
40#define PMI_WRITE_DATA0 5
41#define PMI_WRITE_DATA1 6
42#define PMI_WRITE_DATA2 7
43
44#define PMI_ACK 0x80
45
46#define PMI_TIMEOUT 100
47
48typedef struct {
49 u8 type;
50 u8 data0;
51 u8 data1;
52 u8 data2;
53} pmi_message_t;
54
55struct pmi_handler {
56 struct list_head node;
57 u8 type;
58 void (*handle_pmi_message) (struct of_device *, pmi_message_t);
59};
60
61void pmi_register_handler(struct of_device *, struct pmi_handler *);
62void pmi_unregister_handler(struct of_device *, struct pmi_handler *);
63
64void pmi_send_message(struct of_device *, pmi_message_t);
65
66#endif /* __KERNEL__ */
67#endif /* _POWERPC_PMI_H */
diff --git a/include/asm-powerpc/prom.h b/include/asm-powerpc/prom.h
index 0afee17f33b4..020ed015a94b 100644
--- a/include/asm-powerpc/prom.h
+++ b/include/asm-powerpc/prom.h
@@ -255,6 +255,8 @@ extern void kdump_move_device_tree(void);
255/* CPU OF node matching */ 255/* CPU OF node matching */
256struct device_node *of_get_cpu_node(int cpu, unsigned int *thread); 256struct device_node *of_get_cpu_node(int cpu, unsigned int *thread);
257 257
258/* Get the MAC address */
259extern const void *of_get_mac_address(struct device_node *np);
258 260
259/* 261/*
260 * OF interrupt mapping 262 * OF interrupt mapping
diff --git a/include/asm-powerpc/ps3.h b/include/asm-powerpc/ps3.h
index e5982ad46576..821581a8b643 100644
--- a/include/asm-powerpc/ps3.h
+++ b/include/asm-powerpc/ps3.h
@@ -355,13 +355,7 @@ extern struct bus_type ps3_system_bus_type;
355 355
356/* vuart routines */ 356/* vuart routines */
357 357
358struct ps3_vuart_stats { 358struct ps3_vuart_port_priv;
359 unsigned long bytes_written;
360 unsigned long bytes_read;
361 unsigned long tx_interrupts;
362 unsigned long rx_interrupts;
363 unsigned long disconnect_interrupts;
364};
365 359
366/** 360/**
367 * struct ps3_vuart_port_device - a device on a vuart port 361 * struct ps3_vuart_port_device - a device on a vuart port
@@ -370,24 +364,17 @@ struct ps3_vuart_stats {
370struct ps3_vuart_port_device { 364struct ps3_vuart_port_device {
371 enum ps3_match_id match_id; 365 enum ps3_match_id match_id;
372 struct device core; 366 struct device core;
367 struct ps3_vuart_port_priv* priv; /* private driver variables */
373 368
374 /* private driver variables */
375 unsigned int port_number;
376 u64 interrupt_mask;
377 struct {
378 spinlock_t lock;
379 struct list_head head;
380 } tx_list;
381 struct {
382 unsigned long bytes_held;
383 spinlock_t lock;
384 struct list_head head;
385 } rx_list;
386 struct ps3_vuart_stats stats;
387}; 369};
388 370
389int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev); 371int ps3_vuart_port_device_register(struct ps3_vuart_port_device *dev);
390 372
373/* system manager */
374
375void ps3_sys_manager_restart(void);
376void ps3_sys_manager_power_off(void);
377
391struct ps3_prealloc { 378struct ps3_prealloc {
392 const char *name; 379 const char *name;
393 void *address; 380 void *address;
diff --git a/include/asm-powerpc/ucc_slow.h b/include/asm-powerpc/ucc_slow.h
index 1babad99c719..fdaac9d762bb 100644
--- a/include/asm-powerpc/ucc_slow.h
+++ b/include/asm-powerpc/ucc_slow.h
@@ -150,7 +150,7 @@ struct ucc_slow_info {
150 int ucc_num; 150 int ucc_num;
151 enum qe_clock rx_clock; 151 enum qe_clock rx_clock;
152 enum qe_clock tx_clock; 152 enum qe_clock tx_clock;
153 struct ucc_slow *regs; 153 u32 regs;
154 int irq; 154 int irq;
155 u16 uccm_mask; 155 u16 uccm_mask;
156 int data_mem_part; 156 int data_mem_part;
@@ -199,9 +199,9 @@ struct ucc_slow_private {
199 and length for first BD in a frame */ 199 and length for first BD in a frame */
200 u32 tx_base_offset; /* first BD in Tx BD table offset (In MURAM) */ 200 u32 tx_base_offset; /* first BD in Tx BD table offset (In MURAM) */
201 u32 rx_base_offset; /* first BD in Rx BD table offset (In MURAM) */ 201 u32 rx_base_offset; /* first BD in Rx BD table offset (In MURAM) */
202 u8 *confBd; /* next BD for confirm after Tx */ 202 struct qe_bd *confBd; /* next BD for confirm after Tx */
203 u8 *tx_bd; /* next BD for new Tx request */ 203 struct qe_bd *tx_bd; /* next BD for new Tx request */
204 u8 *rx_bd; /* next BD to collect after Rx */ 204 struct qe_bd *rx_bd; /* next BD to collect after Rx */
205 void *p_rx_frame; /* accumulating receive frame */ 205 void *p_rx_frame; /* accumulating receive frame */
206 u16 *p_ucce; /* a pointer to the event register in memory. 206 u16 *p_ucce; /* a pointer to the event register in memory.
207 */ 207 */
diff --git a/include/linux/acpi.h b/include/linux/acpi.h
index 815f1fb4ce21..8bcfaa4c66ae 100644
--- a/include/linux/acpi.h
+++ b/include/linux/acpi.h
@@ -75,7 +75,7 @@ enum acpi_address_range_id {
75 75
76typedef int (*acpi_table_handler) (struct acpi_table_header *table); 76typedef int (*acpi_table_handler) (struct acpi_table_header *table);
77 77
78typedef int (*acpi_madt_entry_handler) (struct acpi_subtable_header *header, const unsigned long end); 78typedef int (*acpi_table_entry_handler) (struct acpi_subtable_header *header, const unsigned long end);
79 79
80char * __acpi_map_table (unsigned long phys_addr, unsigned long size); 80char * __acpi_map_table (unsigned long phys_addr, unsigned long size);
81unsigned long acpi_find_rsdp (void); 81unsigned long acpi_find_rsdp (void);
@@ -85,8 +85,10 @@ int acpi_numa_init (void);
85 85
86int acpi_table_init (void); 86int acpi_table_init (void);
87int acpi_table_parse (char *id, acpi_table_handler handler); 87int acpi_table_parse (char *id, acpi_table_handler handler);
88int acpi_table_parse_madt (enum acpi_madt_type id, acpi_madt_entry_handler handler, unsigned int max_entries); 88int __init acpi_table_parse_entries(char *id, unsigned long table_size,
89int acpi_table_parse_srat (enum acpi_srat_type id, acpi_madt_entry_handler handler, unsigned int max_entries); 89 int entry_id, acpi_table_entry_handler handler, unsigned int max_entries);
90int acpi_table_parse_madt (enum acpi_madt_type id, acpi_table_entry_handler handler, unsigned int max_entries);
91int acpi_table_parse_srat (enum acpi_srat_type id, acpi_table_entry_handler handler, unsigned int max_entries);
90int acpi_parse_mcfg (struct acpi_table_header *header); 92int acpi_parse_mcfg (struct acpi_table_header *header);
91void acpi_table_print_madt_entry (struct acpi_subtable_header *madt); 93void acpi_table_print_madt_entry (struct acpi_subtable_header *madt);
92void acpi_table_print_srat_entry (struct acpi_subtable_header *srat); 94void acpi_table_print_srat_entry (struct acpi_subtable_header *srat);
diff --git a/include/linux/atmel_pdc.h b/include/linux/atmel_pdc.h
new file mode 100644
index 000000000000..5058a31d2ce8
--- /dev/null
+++ b/include/linux/atmel_pdc.h
@@ -0,0 +1,36 @@
1/*
2 * include/linux/atmel_pdc.h
3 *
4 * Copyright (C) 2005 Ivan Kokshaysky
5 * Copyright (C) SAN People
6 *
7 * Peripheral Data Controller (PDC) registers.
8 * Based on AT91RM9200 datasheet revision E.
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 of the License, or
13 * (at your option) any later version.
14 */
15
16#ifndef ATMEL_PDC_H
17#define ATMEL_PDC_H
18
19#define ATMEL_PDC_RPR 0x100 /* Receive Pointer Register */
20#define ATMEL_PDC_RCR 0x104 /* Receive Counter Register */
21#define ATMEL_PDC_TPR 0x108 /* Transmit Pointer Register */
22#define ATMEL_PDC_TCR 0x10c /* Transmit Counter Register */
23#define ATMEL_PDC_RNPR 0x110 /* Receive Next Pointer Register */
24#define ATMEL_PDC_RNCR 0x114 /* Receive Next Counter Register */
25#define ATMEL_PDC_TNPR 0x118 /* Transmit Next Pointer Register */
26#define ATMEL_PDC_TNCR 0x11c /* Transmit Next Counter Register */
27
28#define ATMEL_PDC_PTCR 0x120 /* Transfer Control Register */
29#define ATMEL_PDC_RXTEN (1 << 0) /* Receiver Transfer Enable */
30#define ATMEL_PDC_RXTDIS (1 << 1) /* Receiver Transfer Disable */
31#define ATMEL_PDC_TXTEN (1 << 8) /* Transmitter Transfer Enable */
32#define ATMEL_PDC_TXTDIS (1 << 9) /* Transmitter Transfer Disable */
33
34#define ATMEL_PDC_PTSR 0x124 /* Transfer Status Register */
35
36#endif
diff --git a/include/linux/debugfs.h b/include/linux/debugfs.h
index 047567d34ca7..9fa0983d1aa8 100644
--- a/include/linux/debugfs.h
+++ b/include/linux/debugfs.h
@@ -33,6 +33,9 @@ struct dentry *debugfs_create_file(const char *name, mode_t mode,
33 33
34struct dentry *debugfs_create_dir(const char *name, struct dentry *parent); 34struct dentry *debugfs_create_dir(const char *name, struct dentry *parent);
35 35
36struct dentry *debugfs_create_symlink(const char *name, struct dentry *parent,
37 const char *dest);
38
36void debugfs_remove(struct dentry *dentry); 39void debugfs_remove(struct dentry *dentry);
37 40
38struct dentry *debugfs_create_u8(const char *name, mode_t mode, 41struct dentry *debugfs_create_u8(const char *name, mode_t mode,
@@ -70,6 +73,13 @@ static inline struct dentry *debugfs_create_dir(const char *name,
70 return ERR_PTR(-ENODEV); 73 return ERR_PTR(-ENODEV);
71} 74}
72 75
76static inline struct dentry *debugfs_create_symlink(const char *name,
77 struct dentry *parent,
78 const char *dest)
79{
80 return ERR_PTR(-ENODEV);
81}
82
73static inline void debugfs_remove(struct dentry *dentry) 83static inline void debugfs_remove(struct dentry *dentry)
74{ } 84{ }
75 85
diff --git a/include/linux/device.h b/include/linux/device.h
index 26e4692f2d1a..d5b1b7b3558e 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -2,6 +2,7 @@
2 * device.h - generic, centralized driver model 2 * device.h - generic, centralized driver model
3 * 3 *
4 * Copyright (c) 2001-2003 Patrick Mochel <mochel@osdl.org> 4 * Copyright (c) 2001-2003 Patrick Mochel <mochel@osdl.org>
5 * Copyright (c) 2004-2007 Greg Kroah-Hartman <gregkh@suse.de>
5 * 6 *
6 * This file is released under the GPLv2 7 * This file is released under the GPLv2
7 * 8 *
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 04e0fa97ac99..79c028251c70 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -636,7 +636,6 @@ typedef struct ide_drive_s {
636 unsigned int bios_cyl; /* BIOS/fdisk/LILO number of cyls */ 636 unsigned int bios_cyl; /* BIOS/fdisk/LILO number of cyls */
637 unsigned int cyl; /* "real" number of cyls */ 637 unsigned int cyl; /* "real" number of cyls */
638 unsigned int drive_data; /* use by tuneproc/selectproc */ 638 unsigned int drive_data; /* use by tuneproc/selectproc */
639 unsigned int usage; /* current "open()" count for drive */
640 unsigned int failures; /* current failure count */ 639 unsigned int failures; /* current failure count */
641 unsigned int max_failures; /* maximum allowed failure count */ 640 unsigned int max_failures; /* maximum allowed failure count */
642 u64 probed_capacity;/* initial reported media capacity (ide-cd only currently) */ 641 u64 probed_capacity;/* initial reported media capacity (ide-cd only currently) */
@@ -736,23 +735,22 @@ typedef struct hwif_s {
736 int (*ide_dma_end)(ide_drive_t *drive); 735 int (*ide_dma_end)(ide_drive_t *drive);
737 int (*ide_dma_check)(ide_drive_t *drive); 736 int (*ide_dma_check)(ide_drive_t *drive);
738 int (*ide_dma_on)(ide_drive_t *drive); 737 int (*ide_dma_on)(ide_drive_t *drive);
739 int (*ide_dma_off_quietly)(ide_drive_t *drive); 738 void (*dma_off_quietly)(ide_drive_t *drive);
740 int (*ide_dma_test_irq)(ide_drive_t *drive); 739 int (*ide_dma_test_irq)(ide_drive_t *drive);
741 int (*ide_dma_host_on)(ide_drive_t *drive); 740 void (*ide_dma_clear_irq)(ide_drive_t *drive);
742 int (*ide_dma_host_off)(ide_drive_t *drive); 741 void (*dma_host_on)(ide_drive_t *drive);
742 void (*dma_host_off)(ide_drive_t *drive);
743 int (*ide_dma_lostirq)(ide_drive_t *drive); 743 int (*ide_dma_lostirq)(ide_drive_t *drive);
744 int (*ide_dma_timeout)(ide_drive_t *drive); 744 int (*ide_dma_timeout)(ide_drive_t *drive);
745 745
746 void (*OUTB)(u8 addr, unsigned long port); 746 void (*OUTB)(u8 addr, unsigned long port);
747 void (*OUTBSYNC)(ide_drive_t *drive, u8 addr, unsigned long port); 747 void (*OUTBSYNC)(ide_drive_t *drive, u8 addr, unsigned long port);
748 void (*OUTW)(u16 addr, unsigned long port); 748 void (*OUTW)(u16 addr, unsigned long port);
749 void (*OUTL)(u32 addr, unsigned long port);
750 void (*OUTSW)(unsigned long port, void *addr, u32 count); 749 void (*OUTSW)(unsigned long port, void *addr, u32 count);
751 void (*OUTSL)(unsigned long port, void *addr, u32 count); 750 void (*OUTSL)(unsigned long port, void *addr, u32 count);
752 751
753 u8 (*INB)(unsigned long port); 752 u8 (*INB)(unsigned long port);
754 u16 (*INW)(unsigned long port); 753 u16 (*INW)(unsigned long port);
755 u32 (*INL)(unsigned long port);
756 void (*INSW)(unsigned long port, void *addr, u32 count); 754 void (*INSW)(unsigned long port, void *addr, u32 count);
757 void (*INSL)(unsigned long port, void *addr, u32 count); 755 void (*INSL)(unsigned long port, void *addr, u32 count);
758 756
@@ -774,7 +772,6 @@ typedef struct hwif_s {
774 unsigned int cursg; 772 unsigned int cursg;
775 unsigned int cursg_ofs; 773 unsigned int cursg_ofs;
776 774
777 int mmio; /* hosts iomio (0) or custom (2) select */
778 int rqsize; /* max sectors per request */ 775 int rqsize; /* max sectors per request */
779 int irq; /* our irq number */ 776 int irq; /* our irq number */
780 777
@@ -802,12 +799,11 @@ typedef struct hwif_s {
802 unsigned udma_four : 1; /* 1=ATA-66 capable, 0=default */ 799 unsigned udma_four : 1; /* 1=ATA-66 capable, 0=default */
803 unsigned no_lba48 : 1; /* 1 = cannot do LBA48 */ 800 unsigned no_lba48 : 1; /* 1 = cannot do LBA48 */
804 unsigned no_lba48_dma : 1; /* 1 = cannot do LBA48 DMA */ 801 unsigned no_lba48_dma : 1; /* 1 = cannot do LBA48 DMA */
805 unsigned no_dsc : 1; /* 0 default, 1 dsc_overlap disabled */
806 unsigned auto_poll : 1; /* supports nop auto-poll */ 802 unsigned auto_poll : 1; /* supports nop auto-poll */
807 unsigned sg_mapped : 1; /* sg_table and sg_nents are ready */ 803 unsigned sg_mapped : 1; /* sg_table and sg_nents are ready */
808 unsigned no_io_32bit : 1; /* 1 = can not do 32-bit IO ops */ 804 unsigned no_io_32bit : 1; /* 1 = can not do 32-bit IO ops */
809 unsigned err_stops_fifo : 1; /* 1=data FIFO is cleared by an error */ 805 unsigned err_stops_fifo : 1; /* 1=data FIFO is cleared by an error */
810 unsigned atapi_irq_bogon : 1; /* Generates spurious DMA interrupts in PIO mode */ 806 unsigned mmio : 1; /* host uses MMIO */
811 807
812 struct device gendev; 808 struct device gendev;
813 struct completion gendev_rel_comp; /* To deal with device release() */ 809 struct completion gendev_rel_comp; /* To deal with device release() */
@@ -1280,8 +1276,9 @@ int ide_in_drive_list(struct hd_driveid *, const struct drive_list_entry *);
1280int __ide_dma_bad_drive(ide_drive_t *); 1276int __ide_dma_bad_drive(ide_drive_t *);
1281int __ide_dma_good_drive(ide_drive_t *); 1277int __ide_dma_good_drive(ide_drive_t *);
1282int ide_use_dma(ide_drive_t *); 1278int ide_use_dma(ide_drive_t *);
1283int __ide_dma_off(ide_drive_t *); 1279void ide_dma_off(ide_drive_t *);
1284void ide_dma_verbose(ide_drive_t *); 1280void ide_dma_verbose(ide_drive_t *);
1281int ide_set_dma(ide_drive_t *);
1285ide_startstop_t ide_dma_intr(ide_drive_t *); 1282ide_startstop_t ide_dma_intr(ide_drive_t *);
1286 1283
1287#ifdef CONFIG_BLK_DEV_IDEDMA_PCI 1284#ifdef CONFIG_BLK_DEV_IDEDMA_PCI
@@ -1291,9 +1288,9 @@ extern void ide_destroy_dmatable(ide_drive_t *);
1291extern int ide_release_dma(ide_hwif_t *); 1288extern int ide_release_dma(ide_hwif_t *);
1292extern void ide_setup_dma(ide_hwif_t *, unsigned long, unsigned int); 1289extern void ide_setup_dma(ide_hwif_t *, unsigned long, unsigned int);
1293 1290
1294extern int __ide_dma_host_off(ide_drive_t *); 1291void ide_dma_host_off(ide_drive_t *);
1295extern int __ide_dma_off_quietly(ide_drive_t *); 1292void ide_dma_off_quietly(ide_drive_t *);
1296extern int __ide_dma_host_on(ide_drive_t *); 1293void ide_dma_host_on(ide_drive_t *);
1297extern int __ide_dma_on(ide_drive_t *); 1294extern int __ide_dma_on(ide_drive_t *);
1298extern int __ide_dma_check(ide_drive_t *); 1295extern int __ide_dma_check(ide_drive_t *);
1299extern int ide_dma_setup(ide_drive_t *); 1296extern int ide_dma_setup(ide_drive_t *);
@@ -1305,8 +1302,9 @@ extern int __ide_dma_timeout(ide_drive_t *);
1305 1302
1306#else 1303#else
1307static inline int ide_use_dma(ide_drive_t *drive) { return 0; } 1304static inline int ide_use_dma(ide_drive_t *drive) { return 0; }
1308static inline int __ide_dma_off(ide_drive_t *drive) { return 0; } 1305static inline void ide_dma_off(ide_drive_t *drive) { ; }
1309static inline void ide_dma_verbose(ide_drive_t *drive) { ; } 1306static inline void ide_dma_verbose(ide_drive_t *drive) { ; }
1307static inline int ide_set_dma(ide_drive_t *drive) { return 1; }
1310#endif /* CONFIG_BLK_DEV_IDEDMA */ 1308#endif /* CONFIG_BLK_DEV_IDEDMA */
1311 1309
1312#ifndef CONFIG_BLK_DEV_IDEDMA_PCI 1310#ifndef CONFIG_BLK_DEV_IDEDMA_PCI
@@ -1354,6 +1352,7 @@ extern int ide_dma_enable(ide_drive_t *drive);
1354extern char *ide_xfer_verbose(u8 xfer_rate); 1352extern char *ide_xfer_verbose(u8 xfer_rate);
1355extern void ide_toggle_bounce(ide_drive_t *drive, int on); 1353extern void ide_toggle_bounce(ide_drive_t *drive, int on);
1356extern int ide_set_xfer_rate(ide_drive_t *drive, u8 rate); 1354extern int ide_set_xfer_rate(ide_drive_t *drive, u8 rate);
1355int ide_use_fast_pio(ide_drive_t *);
1357 1356
1358u8 ide_dump_status(ide_drive_t *, const char *, u8); 1357u8 ide_dump_status(ide_drive_t *, const char *, u8);
1359 1358
@@ -1367,7 +1366,6 @@ typedef struct ide_pio_data_s {
1367 u8 pio_mode; 1366 u8 pio_mode;
1368 u8 use_iordy; 1367 u8 use_iordy;
1369 u8 overridden; 1368 u8 overridden;
1370 u8 blacklisted;
1371 unsigned int cycle_time; 1369 unsigned int cycle_time;
1372} ide_pio_data_t; 1370} ide_pio_data_t;
1373 1371
diff --git a/include/linux/kexec.h b/include/linux/kexec.h
index d02425cdd801..696e5ec63f77 100644
--- a/include/linux/kexec.h
+++ b/include/linux/kexec.h
@@ -125,6 +125,7 @@ extern struct kimage *kexec_crash_image;
125#define KEXEC_ARCH_PPC (20 << 16) 125#define KEXEC_ARCH_PPC (20 << 16)
126#define KEXEC_ARCH_PPC64 (21 << 16) 126#define KEXEC_ARCH_PPC64 (21 << 16)
127#define KEXEC_ARCH_IA_64 (50 << 16) 127#define KEXEC_ARCH_IA_64 (50 << 16)
128#define KEXEC_ARCH_ARM (40 << 16)
128#define KEXEC_ARCH_S390 (22 << 16) 129#define KEXEC_ARCH_S390 (22 << 16)
129#define KEXEC_ARCH_SH (42 << 16) 130#define KEXEC_ARCH_SH (42 << 16)
130#define KEXEC_ARCH_MIPS_LE (10 << 16) 131#define KEXEC_ARCH_MIPS_LE (10 << 16)
diff --git a/include/linux/kmod.h b/include/linux/kmod.h
index 10f505c8431d..cc8e674ae27a 100644
--- a/include/linux/kmod.h
+++ b/include/linux/kmod.h
@@ -28,8 +28,10 @@
28#ifdef CONFIG_KMOD 28#ifdef CONFIG_KMOD
29/* modprobe exit status on success, -ve on error. Return value 29/* modprobe exit status on success, -ve on error. Return value
30 * usually useless though. */ 30 * usually useless though. */
31extern void kmod_sysfs_init(void);
31extern int request_module(const char * name, ...) __attribute__ ((format (printf, 1, 2))); 32extern int request_module(const char * name, ...) __attribute__ ((format (printf, 1, 2)));
32#else 33#else
34static inline void kmod_sysfs_init(void) {};
33static inline int request_module(const char * name, ...) { return -ENOSYS; } 35static inline int request_module(const char * name, ...) { return -ENOSYS; }
34#endif 36#endif
35 37
diff --git a/include/linux/module.h b/include/linux/module.h
index 419d3ef293dd..95679eb8571e 100644
--- a/include/linux/module.h
+++ b/include/linux/module.h
@@ -76,8 +76,6 @@ void sort_extable(struct exception_table_entry *start,
76 struct exception_table_entry *finish); 76 struct exception_table_entry *finish);
77void sort_main_extable(void); 77void sort_main_extable(void);
78 78
79extern struct subsystem module_subsys;
80
81#ifdef MODULE 79#ifdef MODULE
82#define MODULE_GENERIC_TABLE(gtype,name) \ 80#define MODULE_GENERIC_TABLE(gtype,name) \
83extern const struct gtype##_id __mod_##gtype##_table \ 81extern const struct gtype##_id __mod_##gtype##_table \
@@ -467,10 +465,6 @@ int unregister_module_notifier(struct notifier_block * nb);
467 465
468extern void print_modules(void); 466extern void print_modules(void);
469 467
470struct device_driver;
471void module_add_driver(struct module *, struct device_driver *);
472void module_remove_driver(struct device_driver *);
473
474#else /* !CONFIG_MODULES... */ 468#else /* !CONFIG_MODULES... */
475#define EXPORT_SYMBOL(sym) 469#define EXPORT_SYMBOL(sym)
476#define EXPORT_SYMBOL_GPL(sym) 470#define EXPORT_SYMBOL_GPL(sym)
@@ -568,18 +562,59 @@ static inline void print_modules(void)
568{ 562{
569} 563}
570 564
565#endif /* CONFIG_MODULES */
566
571struct device_driver; 567struct device_driver;
568#ifdef CONFIG_SYSFS
572struct module; 569struct module;
573 570
574static inline void module_add_driver(struct module *module, struct device_driver *driver) 571extern struct subsystem module_subsys;
572
573int mod_sysfs_init(struct module *mod);
574int mod_sysfs_setup(struct module *mod,
575 struct kernel_param *kparam,
576 unsigned int num_params);
577int module_add_modinfo_attrs(struct module *mod);
578void module_remove_modinfo_attrs(struct module *mod);
579
580#else /* !CONFIG_SYSFS */
581
582static inline int mod_sysfs_init(struct module *mod)
575{ 583{
584 return 0;
576} 585}
577 586
578static inline void module_remove_driver(struct device_driver *driver) 587static inline int mod_sysfs_setup(struct module *mod,
588 struct kernel_param *kparam,
589 unsigned int num_params)
579{ 590{
591 return 0;
580} 592}
581 593
582#endif /* CONFIG_MODULES */ 594static inline int module_add_modinfo_attrs(struct module *mod)
595{
596 return 0;
597}
598
599static inline void module_remove_modinfo_attrs(struct module *mod)
600{ }
601
602#endif /* CONFIG_SYSFS */
603
604#if defined(CONFIG_SYSFS) && defined(CONFIG_MODULES)
605
606void module_add_driver(struct module *mod, struct device_driver *drv);
607void module_remove_driver(struct device_driver *drv);
608
609#else /* not both CONFIG_SYSFS && CONFIG_MODULES */
610
611static inline void module_add_driver(struct module *mod, struct device_driver *drv)
612{ }
613
614static inline void module_remove_driver(struct device_driver *drv)
615{ }
616
617#endif
583 618
584#define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x) 619#define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x)
585 620
diff --git a/include/linux/moduleparam.h b/include/linux/moduleparam.h
index 4a189dadb160..b26b2e5fedc7 100644
--- a/include/linux/moduleparam.h
+++ b/include/linux/moduleparam.h
@@ -169,10 +169,22 @@ extern int param_get_string(char *buffer, struct kernel_param *kp);
169 169
170struct module; 170struct module;
171 171
172#if defined(CONFIG_SYSFS) && defined(CONFIG_MODULES)
172extern int module_param_sysfs_setup(struct module *mod, 173extern int module_param_sysfs_setup(struct module *mod,
173 struct kernel_param *kparam, 174 struct kernel_param *kparam,
174 unsigned int num_params); 175 unsigned int num_params);
175 176
176extern void module_param_sysfs_remove(struct module *mod); 177extern void module_param_sysfs_remove(struct module *mod);
178#else
179static inline int module_param_sysfs_setup(struct module *mod,
180 struct kernel_param *kparam,
181 unsigned int num_params)
182{
183 return 0;
184}
185
186static inline void module_param_sysfs_remove(struct module *mod)
187{ }
188#endif
177 189
178#endif /* _LINUX_MODULE_PARAMS_H */ 190#endif /* _LINUX_MODULE_PARAMS_H */
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 98c8765a488e..2c4b6842dfb9 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -854,5 +854,8 @@ extern int pci_pci_problems;
854#define PCIPCI_ALIMAGIK 32 /* Need low latency setting */ 854#define PCIPCI_ALIMAGIK 32 /* Need low latency setting */
855#define PCIAGP_FAIL 64 /* No PCI to AGP DMA */ 855#define PCIAGP_FAIL 64 /* No PCI to AGP DMA */
856 856
857extern unsigned long pci_cardbus_io_size;
858extern unsigned long pci_cardbus_mem_size;
859
857#endif /* __KERNEL__ */ 860#endif /* __KERNEL__ */
858#endif /* LINUX_PCI_H */ 861#endif /* LINUX_PCI_H */
diff --git a/include/linux/usb.h b/include/linux/usb.h
index b5c226a87ed8..a8e8d1ecebb1 100644
--- a/include/linux/usb.h
+++ b/include/linux/usb.h
@@ -935,7 +935,7 @@ struct usb_iso_packet_descriptor {
935 unsigned int offset; 935 unsigned int offset;
936 unsigned int length; /* expected length */ 936 unsigned int length; /* expected length */
937 unsigned int actual_length; 937 unsigned int actual_length;
938 unsigned int status; 938 int status;
939}; 939};
940 940
941struct urb; 941struct urb;
diff --git a/include/linux/usb/cdc.h b/include/linux/usb/cdc.h
index ba617c372455..956edf3bbecb 100644
--- a/include/linux/usb/cdc.h
+++ b/include/linux/usb/cdc.h
@@ -73,6 +73,13 @@ struct usb_cdc_acm_descriptor {
73 __u8 bmCapabilities; 73 __u8 bmCapabilities;
74} __attribute__ ((packed)); 74} __attribute__ ((packed));
75 75
76/* capabilities from 5.2.3.3 */
77
78#define USB_CDC_COMM_FEATURE 0x01
79#define USB_CDC_CAP_LINE 0x02
80#define USB_CDC_CAP_BRK 0x04
81#define USB_CDC_CAP_NOTIFY 0x08
82
76/* "Union Functional Descriptor" from CDC spec 5.2.3.8 */ 83/* "Union Functional Descriptor" from CDC spec 5.2.3.8 */
77struct usb_cdc_union_desc { 84struct usb_cdc_union_desc {
78 __u8 bLength; 85 __u8 bLength;
diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h
index ae7833749fa2..245c72531228 100644
--- a/include/linux/usb/ch9.h
+++ b/include/linux/usb/ch9.h
@@ -367,7 +367,7 @@ struct usb_debug_descriptor {
367 /* bulk endpoints with 8 byte maxpacket */ 367 /* bulk endpoints with 8 byte maxpacket */
368 __u8 bDebugInEndpoint; 368 __u8 bDebugInEndpoint;
369 __u8 bDebugOutEndpoint; 369 __u8 bDebugOutEndpoint;
370}; 370} __attribute__((packed));
371 371
372/*-------------------------------------------------------------------------*/ 372/*-------------------------------------------------------------------------*/
373 373
@@ -396,7 +396,7 @@ struct usb_security_descriptor {
396 396
397 __le16 wTotalLength; 397 __le16 wTotalLength;
398 __u8 bNumEncryptionTypes; 398 __u8 bNumEncryptionTypes;
399}; 399} __attribute__((packed));
400 400
401/*-------------------------------------------------------------------------*/ 401/*-------------------------------------------------------------------------*/
402 402
@@ -410,7 +410,7 @@ struct usb_key_descriptor {
410 __u8 tTKID[3]; 410 __u8 tTKID[3];
411 __u8 bReserved; 411 __u8 bReserved;
412 __u8 bKeyData[0]; 412 __u8 bKeyData[0];
413}; 413} __attribute__((packed));
414 414
415/*-------------------------------------------------------------------------*/ 415/*-------------------------------------------------------------------------*/
416 416
@@ -426,7 +426,7 @@ struct usb_encryption_descriptor {
426#define USB_ENC_TYPE_RSA_1 3 /* rsa3072/sha1 auth */ 426#define USB_ENC_TYPE_RSA_1 3 /* rsa3072/sha1 auth */
427 __u8 bEncryptionValue; /* use in SET_ENCRYPTION */ 427 __u8 bEncryptionValue; /* use in SET_ENCRYPTION */
428 __u8 bAuthKeyIndex; 428 __u8 bAuthKeyIndex;
429}; 429} __attribute__((packed));
430 430
431 431
432/*-------------------------------------------------------------------------*/ 432/*-------------------------------------------------------------------------*/
@@ -438,7 +438,7 @@ struct usb_bos_descriptor {
438 438
439 __le16 wTotalLength; 439 __le16 wTotalLength;
440 __u8 bNumDeviceCaps; 440 __u8 bNumDeviceCaps;
441}; 441} __attribute__((packed));
442 442
443/*-------------------------------------------------------------------------*/ 443/*-------------------------------------------------------------------------*/
444 444
@@ -447,7 +447,7 @@ struct usb_dev_cap_header {
447 __u8 bLength; 447 __u8 bLength;
448 __u8 bDescriptorType; 448 __u8 bDescriptorType;
449 __u8 bDevCapabilityType; 449 __u8 bDevCapabilityType;
450}; 450} __attribute__((packed));
451 451
452#define USB_CAP_TYPE_WIRELESS_USB 1 452#define USB_CAP_TYPE_WIRELESS_USB 1
453 453
@@ -475,7 +475,7 @@ struct usb_wireless_cap_descriptor { /* Ultra Wide Band */
475 __u8 bmFFITXPowerInfo; /* FFI power levels */ 475 __u8 bmFFITXPowerInfo; /* FFI power levels */
476 __le16 bmBandGroup; 476 __le16 bmBandGroup;
477 __u8 bReserved; 477 __u8 bReserved;
478}; 478} __attribute__((packed));
479 479
480/*-------------------------------------------------------------------------*/ 480/*-------------------------------------------------------------------------*/
481 481
@@ -496,7 +496,7 @@ struct usb_wireless_ep_comp_descriptor {
496#define USB_ENDPOINT_SWITCH_NO 0 496#define USB_ENDPOINT_SWITCH_NO 0
497#define USB_ENDPOINT_SWITCH_SWITCH 1 497#define USB_ENDPOINT_SWITCH_SWITCH 1
498#define USB_ENDPOINT_SWITCH_SCALE 2 498#define USB_ENDPOINT_SWITCH_SCALE 2
499}; 499} __attribute__((packed));
500 500
501/*-------------------------------------------------------------------------*/ 501/*-------------------------------------------------------------------------*/
502 502
@@ -512,7 +512,7 @@ struct usb_handshake {
512 __u8 CDID[16]; 512 __u8 CDID[16];
513 __u8 nonce[16]; 513 __u8 nonce[16];
514 __u8 MIC[8]; 514 __u8 MIC[8];
515}; 515} __attribute__((packed));
516 516
517/*-------------------------------------------------------------------------*/ 517/*-------------------------------------------------------------------------*/
518 518
@@ -524,7 +524,7 @@ struct usb_connection_context {
524 __u8 CHID[16]; /* persistent host id */ 524 __u8 CHID[16]; /* persistent host id */
525 __u8 CDID[16]; /* device id (unique w/in host context) */ 525 __u8 CDID[16]; /* device id (unique w/in host context) */
526 __u8 CK[16]; /* connection key */ 526 __u8 CK[16]; /* connection key */
527}; 527} __attribute__((packed));
528 528
529/*-------------------------------------------------------------------------*/ 529/*-------------------------------------------------------------------------*/
530 530
diff --git a/include/linux/usb/serial.h b/include/linux/usb/serial.h
index 33dcd8576696..32acbae28d24 100644
--- a/include/linux/usb/serial.h
+++ b/include/linux/usb/serial.h
@@ -54,6 +54,8 @@
54 * @write_wait: a wait_queue_head_t used by the port. 54 * @write_wait: a wait_queue_head_t used by the port.
55 * @work: work queue entry for the line discipline waking up. 55 * @work: work queue entry for the line discipline waking up.
56 * @open_count: number of times this port has been opened. 56 * @open_count: number of times this port has been opened.
57 * @throttled: nonzero if the read urb is inactive to throttle the device
58 * @throttle_req: nonzero if the tty wants to throttle us
57 * 59 *
58 * This structure is used by the usb-serial core and drivers for the specific 60 * This structure is used by the usb-serial core and drivers for the specific
59 * ports of a device. 61 * ports of a device.
@@ -88,6 +90,8 @@ struct usb_serial_port {
88 wait_queue_head_t write_wait; 90 wait_queue_head_t write_wait;
89 struct work_struct work; 91 struct work_struct work;
90 int open_count; 92 int open_count;
93 char throttled;
94 char throttle_req;
91 struct device dev; 95 struct device dev;
92}; 96};
93#define to_usb_serial_port(d) container_of(d, struct usb_serial_port, dev) 97#define to_usb_serial_port(d) container_of(d, struct usb_serial_port, dev)
@@ -269,6 +273,8 @@ extern int usb_serial_generic_write_room (struct usb_serial_port *port);
269extern int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port); 273extern int usb_serial_generic_chars_in_buffer (struct usb_serial_port *port);
270extern void usb_serial_generic_read_bulk_callback (struct urb *urb); 274extern void usb_serial_generic_read_bulk_callback (struct urb *urb);
271extern void usb_serial_generic_write_bulk_callback (struct urb *urb); 275extern void usb_serial_generic_write_bulk_callback (struct urb *urb);
276extern void usb_serial_generic_throttle (struct usb_serial_port *port);
277extern void usb_serial_generic_unthrottle (struct usb_serial_port *port);
272extern void usb_serial_generic_shutdown (struct usb_serial *serial); 278extern void usb_serial_generic_shutdown (struct usb_serial *serial);
273extern int usb_serial_generic_register (int debug); 279extern int usb_serial_generic_register (int debug);
274extern void usb_serial_generic_deregister (void); 280extern void usb_serial_generic_deregister (void);
diff --git a/include/linux/usb_usual.h b/include/linux/usb_usual.h
index 2ae76fe52ff7..1b792b9286ba 100644
--- a/include/linux/usb_usual.h
+++ b/include/linux/usb_usual.h
@@ -46,7 +46,9 @@
46 US_FLAG(MAX_SECTORS_64, 0x00000400) \ 46 US_FLAG(MAX_SECTORS_64, 0x00000400) \
47 /* Sets max_sectors to 64 */ \ 47 /* Sets max_sectors to 64 */ \
48 US_FLAG(IGNORE_DEVICE, 0x00000800) \ 48 US_FLAG(IGNORE_DEVICE, 0x00000800) \
49 /* Don't claim device */ 49 /* Don't claim device */ \
50 US_FLAG(CAPACITY_HEURISTICS, 0x00001000) \
51 /* sometimes sizes is too big */
50 52
51#define US_FLAG(name, value) US_FL_##name = value , 53#define US_FLAG(name, value) US_FL_##name = value ,
52enum { US_DO_ALL_FLAGS }; 54enum { US_DO_ALL_FLAGS };
diff --git a/include/linux/usbdevice_fs.h b/include/linux/usbdevice_fs.h
index 617d8a1c59ae..342dd5a7e8bb 100644
--- a/include/linux/usbdevice_fs.h
+++ b/include/linux/usbdevice_fs.h
@@ -159,9 +159,9 @@ struct usbdevfs_ioctl32 {
159#define USBDEVFS_SUBMITURB32 _IOR('U', 10, struct usbdevfs_urb32) 159#define USBDEVFS_SUBMITURB32 _IOR('U', 10, struct usbdevfs_urb32)
160#define USBDEVFS_DISCARDURB _IO('U', 11) 160#define USBDEVFS_DISCARDURB _IO('U', 11)
161#define USBDEVFS_REAPURB _IOW('U', 12, void *) 161#define USBDEVFS_REAPURB _IOW('U', 12, void *)
162#define USBDEVFS_REAPURB32 _IOW('U', 12, u32) 162#define USBDEVFS_REAPURB32 _IOW('U', 12, __u32)
163#define USBDEVFS_REAPURBNDELAY _IOW('U', 13, void *) 163#define USBDEVFS_REAPURBNDELAY _IOW('U', 13, void *)
164#define USBDEVFS_REAPURBNDELAY32 _IOW('U', 13, u32) 164#define USBDEVFS_REAPURBNDELAY32 _IOW('U', 13, __u32)
165#define USBDEVFS_DISCSIGNAL _IOR('U', 14, struct usbdevfs_disconnectsignal) 165#define USBDEVFS_DISCSIGNAL _IOR('U', 14, struct usbdevfs_disconnectsignal)
166#define USBDEVFS_CLAIMINTERFACE _IOR('U', 15, unsigned int) 166#define USBDEVFS_CLAIMINTERFACE _IOR('U', 15, unsigned int)
167#define USBDEVFS_RELEASEINTERFACE _IOR('U', 16, unsigned int) 167#define USBDEVFS_RELEASEINTERFACE _IOR('U', 16, unsigned int)
diff --git a/include/pcmcia/ciscode.h b/include/pcmcia/ciscode.h
index c1da8558339a..eae7e2e84497 100644
--- a/include/pcmcia/ciscode.h
+++ b/include/pcmcia/ciscode.h
@@ -95,6 +95,7 @@
95#define PRODID_QUATECH_DUAL_RS232 0x0012 95#define PRODID_QUATECH_DUAL_RS232 0x0012
96#define PRODID_QUATECH_DUAL_RS232_D1 0x0007 96#define PRODID_QUATECH_DUAL_RS232_D1 0x0007
97#define PRODID_QUATECH_DUAL_RS232_D2 0x0052 97#define PRODID_QUATECH_DUAL_RS232_D2 0x0052
98#define PRODID_QUATECH_DUAL_RS232_G 0x004d
98#define PRODID_QUATECH_QUAD_RS232 0x001b 99#define PRODID_QUATECH_QUAD_RS232 0x001b
99#define PRODID_QUATECH_DUAL_RS422 0x000e 100#define PRODID_QUATECH_DUAL_RS422 0x000e
100#define PRODID_QUATECH_QUAD_RS422 0x0045 101#define PRODID_QUATECH_QUAD_RS422 0x0045
diff --git a/include/rdma/ib_addr.h b/include/rdma/ib_addr.h
index c094e5012862..c36750ff6ae8 100644
--- a/include/rdma/ib_addr.h
+++ b/include/rdma/ib_addr.h
@@ -110,6 +110,12 @@ static inline void ib_addr_set_pkey(struct rdma_dev_addr *dev_addr, u16 pkey)
110 dev_addr->broadcast[9] = (unsigned char) pkey; 110 dev_addr->broadcast[9] = (unsigned char) pkey;
111} 111}
112 112
113static inline void ib_addr_get_mgid(struct rdma_dev_addr *dev_addr,
114 union ib_gid *gid)
115{
116 memcpy(gid, dev_addr->broadcast + 4, sizeof *gid);
117}
118
113static inline void ib_addr_get_sgid(struct rdma_dev_addr *dev_addr, 119static inline void ib_addr_get_sgid(struct rdma_dev_addr *dev_addr,
114 union ib_gid *gid) 120 union ib_gid *gid)
115{ 121{
diff --git a/include/rdma/ib_sa.h b/include/rdma/ib_sa.h
index 97715b0c20b6..5e26b2f53f86 100644
--- a/include/rdma/ib_sa.h
+++ b/include/rdma/ib_sa.h
@@ -285,18 +285,6 @@ int ib_sa_path_rec_get(struct ib_sa_client *client,
285 void *context, 285 void *context,
286 struct ib_sa_query **query); 286 struct ib_sa_query **query);
287 287
288int ib_sa_mcmember_rec_query(struct ib_sa_client *client,
289 struct ib_device *device, u8 port_num,
290 u8 method,
291 struct ib_sa_mcmember_rec *rec,
292 ib_sa_comp_mask comp_mask,
293 int timeout_ms, gfp_t gfp_mask,
294 void (*callback)(int status,
295 struct ib_sa_mcmember_rec *resp,
296 void *context),
297 void *context,
298 struct ib_sa_query **query);
299
300int ib_sa_service_rec_query(struct ib_sa_client *client, 288int ib_sa_service_rec_query(struct ib_sa_client *client,
301 struct ib_device *device, u8 port_num, 289 struct ib_device *device, u8 port_num,
302 u8 method, 290 u8 method,
@@ -309,93 +297,82 @@ int ib_sa_service_rec_query(struct ib_sa_client *client,
309 void *context, 297 void *context,
310 struct ib_sa_query **sa_query); 298 struct ib_sa_query **sa_query);
311 299
300struct ib_sa_multicast {
301 struct ib_sa_mcmember_rec rec;
302 ib_sa_comp_mask comp_mask;
303 int (*callback)(int status,
304 struct ib_sa_multicast *multicast);
305 void *context;
306};
307
312/** 308/**
313 * ib_sa_mcmember_rec_set - Start an MCMember set query 309 * ib_sa_join_multicast - Initiates a join request to the specified multicast
314 * @client:SA client 310 * group.
315 * @device:device to send query on 311 * @client: SA client
316 * @port_num: port number to send query on 312 * @device: Device associated with the multicast group.
317 * @rec:MCMember Record to send in query 313 * @port_num: Port on the specified device to associate with the multicast
318 * @comp_mask:component mask to send in query 314 * group.
319 * @timeout_ms:time to wait for response 315 * @rec: SA multicast member record specifying group attributes.
320 * @gfp_mask:GFP mask to use for internal allocations 316 * @comp_mask: Component mask indicating which group attributes of %rec are
321 * @callback:function called when query completes, times out or is 317 * valid.
322 * canceled 318 * @gfp_mask: GFP mask for memory allocations.
323 * @context:opaque user context passed to callback 319 * @callback: User callback invoked once the join operation completes.
324 * @sa_query:query context, used to cancel query 320 * @context: User specified context stored with the ib_sa_multicast structure.
325 * 321 *
326 * Send an MCMember Set query to the SA (eg to join a multicast 322 * This call initiates a multicast join request with the SA for the specified
327 * group). The callback function will be called when the query 323 * multicast group. If the join operation is started successfully, it returns
328 * completes (or fails); status is 0 for a successful response, -EINTR 324 * an ib_sa_multicast structure that is used to track the multicast operation.
329 * if the query is canceled, -ETIMEDOUT is the query timed out, or 325 * Users must free this structure by calling ib_free_multicast, even if the
330 * -EIO if an error occurred sending the query. The resp parameter of 326 * join operation later fails. (The callback status is non-zero.)
331 * the callback is only valid if status is 0.
332 * 327 *
333 * If the return value of ib_sa_mcmember_rec_set() is negative, it is 328 * If the join operation fails; status will be non-zero, with the following
334 * an error code. Otherwise it is a query ID that can be used to 329 * failures possible:
335 * cancel the query. 330 * -ETIMEDOUT: The request timed out.
331 * -EIO: An error occurred sending the query.
332 * -EINVAL: The MCMemberRecord values differed from the existing group's.
333 * -ENETRESET: Indicates that an fatal error has occurred on the multicast
334 * group, and the user must rejoin the group to continue using it.
336 */ 335 */
337static inline int 336struct ib_sa_multicast *ib_sa_join_multicast(struct ib_sa_client *client,
338ib_sa_mcmember_rec_set(struct ib_sa_client *client, 337 struct ib_device *device, u8 port_num,
339 struct ib_device *device, u8 port_num, 338 struct ib_sa_mcmember_rec *rec,
340 struct ib_sa_mcmember_rec *rec, 339 ib_sa_comp_mask comp_mask, gfp_t gfp_mask,
341 ib_sa_comp_mask comp_mask, 340 int (*callback)(int status,
342 int timeout_ms, gfp_t gfp_mask, 341 struct ib_sa_multicast
343 void (*callback)(int status, 342 *multicast),
344 struct ib_sa_mcmember_rec *resp, 343 void *context);
345 void *context),
346 void *context,
347 struct ib_sa_query **query)
348{
349 return ib_sa_mcmember_rec_query(client, device, port_num,
350 IB_MGMT_METHOD_SET,
351 rec, comp_mask,
352 timeout_ms, gfp_mask, callback,
353 context, query);
354}
355 344
356/** 345/**
357 * ib_sa_mcmember_rec_delete - Start an MCMember delete query 346 * ib_free_multicast - Frees the multicast tracking structure, and releases
358 * @client:SA client 347 * any reference on the multicast group.
359 * @device:device to send query on 348 * @multicast: Multicast tracking structure allocated by ib_join_multicast.
360 * @port_num: port number to send query on
361 * @rec:MCMember Record to send in query
362 * @comp_mask:component mask to send in query
363 * @timeout_ms:time to wait for response
364 * @gfp_mask:GFP mask to use for internal allocations
365 * @callback:function called when query completes, times out or is
366 * canceled
367 * @context:opaque user context passed to callback
368 * @sa_query:query context, used to cancel query
369 *
370 * Send an MCMember Delete query to the SA (eg to leave a multicast
371 * group). The callback function will be called when the query
372 * completes (or fails); status is 0 for a successful response, -EINTR
373 * if the query is canceled, -ETIMEDOUT is the query timed out, or
374 * -EIO if an error occurred sending the query. The resp parameter of
375 * the callback is only valid if status is 0.
376 * 349 *
377 * If the return value of ib_sa_mcmember_rec_delete() is negative, it 350 * This call blocks until the multicast identifier is destroyed. It may
378 * is an error code. Otherwise it is a query ID that can be used to 351 * not be called from within the multicast callback; however, returning a non-
379 * cancel the query. 352 * zero value from the callback will result in destroying the multicast
353 * tracking structure.
354 */
355void ib_sa_free_multicast(struct ib_sa_multicast *multicast);
356
357/**
358 * ib_get_mcmember_rec - Looks up a multicast member record by its MGID and
359 * returns it if found.
360 * @device: Device associated with the multicast group.
361 * @port_num: Port on the specified device to associate with the multicast
362 * group.
363 * @mgid: MGID of multicast group.
364 * @rec: Location to copy SA multicast member record.
380 */ 365 */
381static inline int 366int ib_sa_get_mcmember_rec(struct ib_device *device, u8 port_num,
382ib_sa_mcmember_rec_delete(struct ib_sa_client *client, 367 union ib_gid *mgid, struct ib_sa_mcmember_rec *rec);
383 struct ib_device *device, u8 port_num, 368
384 struct ib_sa_mcmember_rec *rec, 369/**
385 ib_sa_comp_mask comp_mask, 370 * ib_init_ah_from_mcmember - Initialize address handle attributes based on
386 int timeout_ms, gfp_t gfp_mask, 371 * an SA multicast member record.
387 void (*callback)(int status, 372 */
388 struct ib_sa_mcmember_rec *resp, 373int ib_init_ah_from_mcmember(struct ib_device *device, u8 port_num,
389 void *context), 374 struct ib_sa_mcmember_rec *rec,
390 void *context, 375 struct ib_ah_attr *ah_attr);
391 struct ib_sa_query **query)
392{
393 return ib_sa_mcmember_rec_query(client, device, port_num,
394 IB_SA_METHOD_DELETE,
395 rec, comp_mask,
396 timeout_ms, gfp_mask, callback,
397 context, query);
398}
399 376
400/** 377/**
401 * ib_init_ah_from_path - Initialize address handle attributes based on an SA 378 * ib_init_ah_from_path - Initialize address handle attributes based on an SA
diff --git a/include/rdma/rdma_cm.h b/include/rdma/rdma_cm.h
index 36cd8a8526a0..2d6a7705eae7 100644
--- a/include/rdma/rdma_cm.h
+++ b/include/rdma/rdma_cm.h
@@ -52,10 +52,13 @@ enum rdma_cm_event_type {
52 RDMA_CM_EVENT_ESTABLISHED, 52 RDMA_CM_EVENT_ESTABLISHED,
53 RDMA_CM_EVENT_DISCONNECTED, 53 RDMA_CM_EVENT_DISCONNECTED,
54 RDMA_CM_EVENT_DEVICE_REMOVAL, 54 RDMA_CM_EVENT_DEVICE_REMOVAL,
55 RDMA_CM_EVENT_MULTICAST_JOIN,
56 RDMA_CM_EVENT_MULTICAST_ERROR
55}; 57};
56 58
57enum rdma_port_space { 59enum rdma_port_space {
58 RDMA_PS_SDP = 0x0001, 60 RDMA_PS_SDP = 0x0001,
61 RDMA_PS_IPOIB= 0x0002,
59 RDMA_PS_TCP = 0x0106, 62 RDMA_PS_TCP = 0x0106,
60 RDMA_PS_UDP = 0x0111, 63 RDMA_PS_UDP = 0x0111,
61 RDMA_PS_SCTP = 0x0183 64 RDMA_PS_SCTP = 0x0183
@@ -294,5 +297,21 @@ int rdma_reject(struct rdma_cm_id *id, const void *private_data,
294 */ 297 */
295int rdma_disconnect(struct rdma_cm_id *id); 298int rdma_disconnect(struct rdma_cm_id *id);
296 299
297#endif /* RDMA_CM_H */ 300/**
301 * rdma_join_multicast - Join the multicast group specified by the given
302 * address.
303 * @id: Communication identifier associated with the request.
304 * @addr: Multicast address identifying the group to join.
305 * @context: User-defined context associated with the join request, returned
306 * to the user through the private_data pointer in multicast events.
307 */
308int rdma_join_multicast(struct rdma_cm_id *id, struct sockaddr *addr,
309 void *context);
298 310
311/**
312 * rdma_leave_multicast - Leave the multicast group specified by the given
313 * address.
314 */
315void rdma_leave_multicast(struct rdma_cm_id *id, struct sockaddr *addr);
316
317#endif /* RDMA_CM_H */
diff --git a/include/rdma/rdma_cm_ib.h b/include/rdma/rdma_cm_ib.h
index 9b176df1d667..950424b38f16 100644
--- a/include/rdma/rdma_cm_ib.h
+++ b/include/rdma/rdma_cm_ib.h
@@ -44,7 +44,7 @@
44int rdma_set_ib_paths(struct rdma_cm_id *id, 44int rdma_set_ib_paths(struct rdma_cm_id *id,
45 struct ib_sa_path_rec *path_rec, int num_paths); 45 struct ib_sa_path_rec *path_rec, int num_paths);
46 46
47/* Global qkey for UD QPs and multicast groups. */ 47/* Global qkey for UDP QPs and multicast groups. */
48#define RDMA_UD_QKEY 0x01234567 48#define RDMA_UDP_QKEY 0x01234567
49 49
50#endif /* RDMA_CM_IB_H */ 50#endif /* RDMA_CM_IB_H */
diff --git a/include/rdma/rdma_user_cm.h b/include/rdma/rdma_user_cm.h
index 9572ab8eeac1..f632b0c007c9 100644
--- a/include/rdma/rdma_user_cm.h
+++ b/include/rdma/rdma_user_cm.h
@@ -38,7 +38,7 @@
38#include <rdma/ib_user_verbs.h> 38#include <rdma/ib_user_verbs.h>
39#include <rdma/ib_user_sa.h> 39#include <rdma/ib_user_sa.h>
40 40
41#define RDMA_USER_CM_ABI_VERSION 3 41#define RDMA_USER_CM_ABI_VERSION 4
42 42
43#define RDMA_MAX_PRIVATE_DATA 256 43#define RDMA_MAX_PRIVATE_DATA 256
44 44
@@ -58,7 +58,9 @@ enum {
58 RDMA_USER_CM_CMD_GET_EVENT, 58 RDMA_USER_CM_CMD_GET_EVENT,
59 RDMA_USER_CM_CMD_GET_OPTION, 59 RDMA_USER_CM_CMD_GET_OPTION,
60 RDMA_USER_CM_CMD_SET_OPTION, 60 RDMA_USER_CM_CMD_SET_OPTION,
61 RDMA_USER_CM_CMD_NOTIFY 61 RDMA_USER_CM_CMD_NOTIFY,
62 RDMA_USER_CM_CMD_JOIN_MCAST,
63 RDMA_USER_CM_CMD_LEAVE_MCAST
62}; 64};
63 65
64/* 66/*
@@ -188,6 +190,13 @@ struct rdma_ucm_notify {
188 __u32 event; 190 __u32 event;
189}; 191};
190 192
193struct rdma_ucm_join_mcast {
194 __u64 response; /* rdma_ucm_create_id_resp */
195 __u64 uid;
196 struct sockaddr_in6 addr;
197 __u32 id;
198};
199
191struct rdma_ucm_get_event { 200struct rdma_ucm_get_event {
192 __u64 response; 201 __u64 response;
193}; 202};
diff --git a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
index ebf31b16dc49..9dd37e2f5a84 100644
--- a/include/scsi/scsi_device.h
+++ b/include/scsi/scsi_device.h
@@ -122,6 +122,7 @@ struct scsi_device {
122 unsigned no_uld_attach:1; /* disable connecting to upper level drivers */ 122 unsigned no_uld_attach:1; /* disable connecting to upper level drivers */
123 unsigned select_no_atn:1; 123 unsigned select_no_atn:1;
124 unsigned fix_capacity:1; /* READ_CAPACITY is too high by 1 */ 124 unsigned fix_capacity:1; /* READ_CAPACITY is too high by 1 */
125 unsigned guess_capacity:1; /* READ_CAPACITY might be too high by 1 */
125 unsigned retry_hwerror:1; /* Retry HARDWARE_ERROR */ 126 unsigned retry_hwerror:1; /* Retry HARDWARE_ERROR */
126 127
127 unsigned int device_blocked; /* Device returned QUEUE_FULL. */ 128 unsigned int device_blocked; /* Device returned QUEUE_FULL. */
diff --git a/kernel/kmod.c b/kernel/kmod.c
index 796276141e51..9f923f8ce6a0 100644
--- a/kernel/kmod.c
+++ b/kernel/kmod.c
@@ -36,6 +36,8 @@
36#include <linux/resource.h> 36#include <linux/resource.h>
37#include <asm/uaccess.h> 37#include <asm/uaccess.h>
38 38
39extern int delete_module(const char *name, unsigned int flags);
40
39extern int max_threads; 41extern int max_threads;
40 42
41static struct workqueue_struct *khelper_wq; 43static struct workqueue_struct *khelper_wq;
@@ -46,6 +48,7 @@ static struct workqueue_struct *khelper_wq;
46 modprobe_path is set via /proc/sys. 48 modprobe_path is set via /proc/sys.
47*/ 49*/
48char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe"; 50char modprobe_path[KMOD_PATH_LEN] = "/sbin/modprobe";
51struct module_kobject kmod_mk;
49 52
50/** 53/**
51 * request_module - try to load a kernel module 54 * request_module - try to load a kernel module
@@ -75,6 +78,11 @@ int request_module(const char *fmt, ...)
75 static atomic_t kmod_concurrent = ATOMIC_INIT(0); 78 static atomic_t kmod_concurrent = ATOMIC_INIT(0);
76#define MAX_KMOD_CONCURRENT 50 /* Completely arbitrary value - KAO */ 79#define MAX_KMOD_CONCURRENT 50 /* Completely arbitrary value - KAO */
77 static int kmod_loop_msg; 80 static int kmod_loop_msg;
81 char modalias[16 + MODULE_NAME_LEN] = "MODALIAS=";
82 char *uevent_envp[2] = {
83 modalias,
84 NULL
85 };
78 86
79 va_start(args, fmt); 87 va_start(args, fmt);
80 ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args); 88 ret = vsnprintf(module_name, MODULE_NAME_LEN, fmt, args);
@@ -82,6 +90,12 @@ int request_module(const char *fmt, ...)
82 if (ret >= MODULE_NAME_LEN) 90 if (ret >= MODULE_NAME_LEN)
83 return -ENAMETOOLONG; 91 return -ENAMETOOLONG;
84 92
93 strcpy(&modalias[strlen("MODALIAS=")], module_name);
94 kobject_uevent_env(&kmod_mk.kobj, KOBJ_CHANGE, uevent_envp);
95
96 if (modprobe_path[0] == '\0')
97 goto out;
98
85 /* If modprobe needs a service that is in a module, we get a recursive 99 /* If modprobe needs a service that is in a module, we get a recursive
86 * loop. Limit the number of running kmod threads to max_threads/2 or 100 * loop. Limit the number of running kmod threads to max_threads/2 or
87 * MAX_KMOD_CONCURRENT, whichever is the smaller. A cleaner method 101 * MAX_KMOD_CONCURRENT, whichever is the smaller. A cleaner method
@@ -108,9 +122,115 @@ int request_module(const char *fmt, ...)
108 122
109 ret = call_usermodehelper(modprobe_path, argv, envp, 1); 123 ret = call_usermodehelper(modprobe_path, argv, envp, 1);
110 atomic_dec(&kmod_concurrent); 124 atomic_dec(&kmod_concurrent);
125out:
111 return ret; 126 return ret;
112} 127}
113EXPORT_SYMBOL(request_module); 128EXPORT_SYMBOL(request_module);
129
130static ssize_t store_mod_request(struct module_attribute *mattr,
131 struct module *mod,
132 const char *buffer, size_t count)
133{
134 char name[MODULE_NAME_LEN];
135 int ret;
136
137 if (count < 1 || count+1 > MODULE_NAME_LEN)
138 return -EINVAL;
139 memcpy(name, buffer, count);
140 name[count] = '\0';
141 if (name[count-1] == '\n')
142 name[count-1] = '\0';
143
144 ret = request_module(name);
145 if (ret < 0)
146 return ret;
147 return count;
148}
149
150static struct module_attribute mod_request = {
151 .attr = { .name = "mod_request", .mode = S_IWUSR, .owner = THIS_MODULE },
152 .store = store_mod_request,
153};
154
155#ifdef CONFIG_MODULE_UNLOAD
156static ssize_t store_mod_unload(struct module_attribute *mattr,
157 struct module *mod,
158 const char *buffer, size_t count)
159{
160 char name[MODULE_NAME_LEN];
161 int ret;
162
163 if (count < 1 || count+1 > MODULE_NAME_LEN)
164 return -EINVAL;
165 memcpy(name, buffer, count);
166 name[count] = '\0';
167 if (name[count-1] == '\n')
168 name[count-1] = '\0';
169
170 ret = delete_module(name, O_NONBLOCK);
171 if (ret < 0)
172 return ret;
173 return count;
174}
175
176static struct module_attribute mod_unload = {
177 .attr = { .name = "mod_unload", .mode = S_IWUSR, .owner = THIS_MODULE },
178 .store = store_mod_unload,
179};
180#endif
181
182static ssize_t show_mod_request_helper(struct module_attribute *mattr,
183 struct module *mod,
184 char *buffer)
185{
186 return sprintf(buffer, "%s\n", modprobe_path);
187}
188
189static ssize_t store_mod_request_helper(struct module_attribute *mattr,
190 struct module *mod,
191 const char *buffer, size_t count)
192{
193 if (count < 1 || count+1 > KMOD_PATH_LEN)
194 return -EINVAL;
195 memcpy(modprobe_path, buffer, count);
196 modprobe_path[count] = '\0';
197 if (modprobe_path[count-1] == '\n')
198 modprobe_path[count-1] = '\0';
199 return count;
200}
201
202static struct module_attribute mod_request_helper = {
203 .attr = {
204 .name = "mod_request_helper",
205 .mode = S_IWUSR | S_IRUGO,
206 .owner = THIS_MODULE
207 },
208 .show = show_mod_request_helper,
209 .store = store_mod_request_helper,
210};
211
212void __init kmod_sysfs_init(void)
213{
214 int ret;
215
216 kmod_mk.mod = THIS_MODULE;
217 kobj_set_kset_s(&kmod_mk, module_subsys);
218 kobject_set_name(&kmod_mk.kobj, "kmod");
219 kobject_init(&kmod_mk.kobj);
220 ret = kobject_add(&kmod_mk.kobj);
221 if (ret < 0)
222 goto out;
223
224 ret = sysfs_create_file(&kmod_mk.kobj, &mod_request_helper.attr);
225 ret = sysfs_create_file(&kmod_mk.kobj, &mod_request.attr);
226#ifdef CONFIG_MODULE_UNLOAD
227 ret = sysfs_create_file(&kmod_mk.kobj, &mod_unload.attr);
228#endif
229
230 kobject_uevent(&kmod_mk.kobj, KOBJ_ADD);
231out:
232 return;
233}
114#endif /* CONFIG_KMOD */ 234#endif /* CONFIG_KMOD */
115 235
116struct subprocess_info { 236struct subprocess_info {
diff --git a/kernel/module.c b/kernel/module.c
index 8a94e054230c..8c25b1a04fa6 100644
--- a/kernel/module.c
+++ b/kernel/module.c
@@ -653,20 +653,11 @@ static void wait_for_zero_refcount(struct module *mod)
653 mutex_lock(&module_mutex); 653 mutex_lock(&module_mutex);
654} 654}
655 655
656asmlinkage long 656int delete_module(const char *name, unsigned int flags)
657sys_delete_module(const char __user *name_user, unsigned int flags)
658{ 657{
659 struct module *mod; 658 struct module *mod;
660 char name[MODULE_NAME_LEN];
661 int ret, forced = 0; 659 int ret, forced = 0;
662 660
663 if (!capable(CAP_SYS_MODULE))
664 return -EPERM;
665
666 if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
667 return -EFAULT;
668 name[MODULE_NAME_LEN-1] = '\0';
669
670 if (mutex_lock_interruptible(&module_mutex) != 0) 661 if (mutex_lock_interruptible(&module_mutex) != 0)
671 return -EINTR; 662 return -EINTR;
672 663
@@ -727,6 +718,21 @@ sys_delete_module(const char __user *name_user, unsigned int flags)
727 return ret; 718 return ret;
728} 719}
729 720
721asmlinkage long
722sys_delete_module(const char __user *name_user, unsigned int flags)
723{
724 char name[MODULE_NAME_LEN];
725
726 if (!capable(CAP_SYS_MODULE))
727 return -EPERM;
728
729 if (strncpy_from_user(name, name_user, MODULE_NAME_LEN-1) < 0)
730 return -EFAULT;
731 name[MODULE_NAME_LEN-1] = '\0';
732
733 return delete_module(name, flags);
734}
735
730static void print_unload_info(struct seq_file *m, struct module *mod) 736static void print_unload_info(struct seq_file *m, struct module *mod)
731{ 737{
732 struct module_use *use; 738 struct module_use *use;
@@ -1068,7 +1074,8 @@ static inline void remove_sect_attrs(struct module *mod)
1068} 1074}
1069#endif /* CONFIG_KALLSYMS */ 1075#endif /* CONFIG_KALLSYMS */
1070 1076
1071static int module_add_modinfo_attrs(struct module *mod) 1077#ifdef CONFIG_SYSFS
1078int module_add_modinfo_attrs(struct module *mod)
1072{ 1079{
1073 struct module_attribute *attr; 1080 struct module_attribute *attr;
1074 struct module_attribute *temp_attr; 1081 struct module_attribute *temp_attr;
@@ -1094,7 +1101,7 @@ static int module_add_modinfo_attrs(struct module *mod)
1094 return error; 1101 return error;
1095} 1102}
1096 1103
1097static void module_remove_modinfo_attrs(struct module *mod) 1104void module_remove_modinfo_attrs(struct module *mod)
1098{ 1105{
1099 struct module_attribute *attr; 1106 struct module_attribute *attr;
1100 int i; 1107 int i;
@@ -1109,8 +1116,10 @@ static void module_remove_modinfo_attrs(struct module *mod)
1109 } 1116 }
1110 kfree(mod->modinfo_attrs); 1117 kfree(mod->modinfo_attrs);
1111} 1118}
1119#endif
1112 1120
1113static int mod_sysfs_init(struct module *mod) 1121#ifdef CONFIG_SYSFS
1122int mod_sysfs_init(struct module *mod)
1114{ 1123{
1115 int err; 1124 int err;
1116 1125
@@ -1133,7 +1142,7 @@ out:
1133 return err; 1142 return err;
1134} 1143}
1135 1144
1136static int mod_sysfs_setup(struct module *mod, 1145int mod_sysfs_setup(struct module *mod,
1137 struct kernel_param *kparam, 1146 struct kernel_param *kparam,
1138 unsigned int num_params) 1147 unsigned int num_params)
1139{ 1148{
@@ -1169,16 +1178,14 @@ out_unreg:
1169out: 1178out:
1170 return err; 1179 return err;
1171} 1180}
1181#endif
1172 1182
1173static void mod_kobject_remove(struct module *mod) 1183static void mod_kobject_remove(struct module *mod)
1174{ 1184{
1175 module_remove_modinfo_attrs(mod); 1185 module_remove_modinfo_attrs(mod);
1176 module_param_sysfs_remove(mod); 1186 module_param_sysfs_remove(mod);
1177 if (mod->mkobj.drivers_dir) 1187 kobject_unregister(mod->mkobj.drivers_dir);
1178 kobject_unregister(mod->mkobj.drivers_dir); 1188 kobject_unregister(mod->holders_dir);
1179 if (mod->holders_dir)
1180 kobject_unregister(mod->holders_dir);
1181
1182 kobject_unregister(&mod->mkobj.kobj); 1189 kobject_unregister(&mod->mkobj.kobj);
1183} 1190}
1184 1191
@@ -2345,6 +2352,7 @@ void print_modules(void)
2345 printk("\n"); 2352 printk("\n");
2346} 2353}
2347 2354
2355#ifdef CONFIG_SYSFS
2348static char *make_driver_name(struct device_driver *drv) 2356static char *make_driver_name(struct device_driver *drv)
2349{ 2357{
2350 char *driver_name; 2358 char *driver_name;
@@ -2419,6 +2427,7 @@ void module_remove_driver(struct device_driver *drv)
2419 } 2427 }
2420} 2428}
2421EXPORT_SYMBOL(module_remove_driver); 2429EXPORT_SYMBOL(module_remove_driver);
2430#endif
2422 2431
2423#ifdef CONFIG_MODVERSIONS 2432#ifdef CONFIG_MODVERSIONS
2424/* Generate the signature for struct module here, too, for modversions. */ 2433/* Generate the signature for struct module here, too, for modversions. */
diff --git a/kernel/params.c b/kernel/params.c
index 553cf7d6a4be..7a751570b56d 100644
--- a/kernel/params.c
+++ b/kernel/params.c
@@ -30,8 +30,6 @@
30#define DEBUGP(fmt, a...) 30#define DEBUGP(fmt, a...)
31#endif 31#endif
32 32
33static struct kobj_type module_ktype;
34
35static inline char dash2underscore(char c) 33static inline char dash2underscore(char c)
36{ 34{
37 if (c == '-') 35 if (c == '-')
@@ -391,6 +389,7 @@ struct module_param_attrs
391 struct param_attribute attrs[0]; 389 struct param_attribute attrs[0];
392}; 390};
393 391
392#ifdef CONFIG_SYSFS
394#define to_param_attr(n) container_of(n, struct param_attribute, mattr); 393#define to_param_attr(n) container_of(n, struct param_attribute, mattr);
395 394
396static ssize_t param_attr_show(struct module_attribute *mattr, 395static ssize_t param_attr_show(struct module_attribute *mattr,
@@ -426,6 +425,7 @@ static ssize_t param_attr_store(struct module_attribute *mattr,
426 return len; 425 return len;
427 return err; 426 return err;
428} 427}
428#endif
429 429
430#ifdef CONFIG_MODULES 430#ifdef CONFIG_MODULES
431#define __modinit 431#define __modinit
@@ -433,6 +433,7 @@ static ssize_t param_attr_store(struct module_attribute *mattr,
433#define __modinit __init 433#define __modinit __init
434#endif 434#endif
435 435
436#ifdef CONFIG_SYSFS
436/* 437/*
437 * param_sysfs_setup - setup sysfs support for one module or KBUILD_MODNAME 438 * param_sysfs_setup - setup sysfs support for one module or KBUILD_MODNAME
438 * @mk: struct module_kobject (contains parent kobject) 439 * @mk: struct module_kobject (contains parent kobject)
@@ -500,9 +501,7 @@ param_sysfs_setup(struct module_kobject *mk,
500 return mp; 501 return mp;
501} 502}
502 503
503
504#ifdef CONFIG_MODULES 504#ifdef CONFIG_MODULES
505
506/* 505/*
507 * module_param_sysfs_setup - setup sysfs support for one module 506 * module_param_sysfs_setup - setup sysfs support for one module
508 * @mod: module 507 * @mod: module
@@ -625,7 +624,6 @@ static void __init param_sysfs_builtin(void)
625 624
626 625
627/* module-related sysfs stuff */ 626/* module-related sysfs stuff */
628#ifdef CONFIG_SYSFS
629 627
630#define to_module_attr(n) container_of(n, struct module_attribute, attr); 628#define to_module_attr(n) container_of(n, struct module_attribute, attr);
631#define to_module_kobject(n) container_of(n, struct module_kobject, kobj); 629#define to_module_kobject(n) container_of(n, struct module_kobject, kobj);
@@ -673,6 +671,8 @@ static struct sysfs_ops module_sysfs_ops = {
673 .store = module_attr_store, 671 .store = module_attr_store,
674}; 672};
675 673
674static struct kobj_type module_ktype;
675
676static int uevent_filter(struct kset *kset, struct kobject *kobj) 676static int uevent_filter(struct kset *kset, struct kobject *kobj)
677{ 677{
678 struct kobj_type *ktype = get_ktype(kobj); 678 struct kobj_type *ktype = get_ktype(kobj);
@@ -686,19 +686,12 @@ static struct kset_uevent_ops module_uevent_ops = {
686 .filter = uevent_filter, 686 .filter = uevent_filter,
687}; 687};
688 688
689#else 689decl_subsys(module, &module_ktype, &module_uevent_ops);
690static struct sysfs_ops module_sysfs_ops = {
691 .show = NULL,
692 .store = NULL,
693};
694#endif
695 690
696static struct kobj_type module_ktype = { 691static struct kobj_type module_ktype = {
697 .sysfs_ops = &module_sysfs_ops, 692 .sysfs_ops = &module_sysfs_ops,
698}; 693};
699 694
700decl_subsys(module, &module_ktype, &module_uevent_ops);
701
702/* 695/*
703 * param_sysfs_init - wrapper for built-in params support 696 * param_sysfs_init - wrapper for built-in params support
704 */ 697 */
@@ -714,11 +707,21 @@ static int __init param_sysfs_init(void)
714 } 707 }
715 708
716 param_sysfs_builtin(); 709 param_sysfs_builtin();
710 kmod_sysfs_init();
717 711
718 return 0; 712 return 0;
719} 713}
720subsys_initcall(param_sysfs_init); 714subsys_initcall(param_sysfs_init);
721 715
716#else
717#if 0
718static struct sysfs_ops module_sysfs_ops = {
719 .show = NULL,
720 .store = NULL,
721};
722#endif
723#endif
724
722EXPORT_SYMBOL(param_set_byte); 725EXPORT_SYMBOL(param_set_byte);
723EXPORT_SYMBOL(param_get_byte); 726EXPORT_SYMBOL(param_get_byte);
724EXPORT_SYMBOL(param_set_short); 727EXPORT_SYMBOL(param_set_short);
diff --git a/lib/kobject.c b/lib/kobject.c
index 2782f49e906e..f4f6176dcd12 100644
--- a/lib/kobject.c
+++ b/lib/kobject.c
@@ -171,7 +171,7 @@ int kobject_shadow_add(struct kobject * kobj, struct dentry *shadow_parent)
171 return -ENOENT; 171 return -ENOENT;
172 if (!kobj->k_name) 172 if (!kobj->k_name)
173 kobj->k_name = kobj->name; 173 kobj->k_name = kobj->name;
174 if (!kobj->k_name) { 174 if (!*kobj->k_name) {
175 pr_debug("kobject attempted to be registered with no name!\n"); 175 pr_debug("kobject attempted to be registered with no name!\n");
176 WARN_ON(1); 176 WARN_ON(1);
177 return -EINVAL; 177 return -EINVAL;
@@ -326,6 +326,7 @@ int kobject_rename(struct kobject * kobj, const char *new_name)
326/** 326/**
327 * kobject_rename - change the name of an object 327 * kobject_rename - change the name of an object
328 * @kobj: object in question. 328 * @kobj: object in question.
329 * @new_parent: object's new parent
329 * @new_name: object's new name 330 * @new_name: object's new name
330 */ 331 */
331 332
diff --git a/sound/arm/aaci.c b/sound/arm/aaci.c
index 53675cf4de44..5190d7acdb9f 100644
--- a/sound/arm/aaci.c
+++ b/sound/arm/aaci.c
@@ -65,10 +65,12 @@ static void aaci_ac97_select_codec(struct aaci *aaci, struct snd_ac97 *ac97)
65 * SI1TxEn, SI2TxEn and SI12TxEn bits are set in the AACI_MAINCR 65 * SI1TxEn, SI2TxEn and SI12TxEn bits are set in the AACI_MAINCR
66 * register. 66 * register.
67 */ 67 */
68static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned short val) 68static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg,
69 unsigned short val)
69{ 70{
70 struct aaci *aaci = ac97->private_data; 71 struct aaci *aaci = ac97->private_data;
71 u32 v; 72 u32 v;
73 int timeout = 5000;
72 74
73 if (ac97->num >= 4) 75 if (ac97->num >= 4)
74 return; 76 return;
@@ -89,7 +91,11 @@ static void aaci_ac97_write(struct snd_ac97 *ac97, unsigned short reg, unsigned
89 */ 91 */
90 do { 92 do {
91 v = readl(aaci->base + AACI_SLFR); 93 v = readl(aaci->base + AACI_SLFR);
92 } while (v & (SLFR_1TXB|SLFR_2TXB)); 94 } while ((v & (SLFR_1TXB|SLFR_2TXB)) && timeout--);
95
96 if (!timeout)
97 dev_err(&aaci->dev->dev,
98 "timeout waiting for write to complete\n");
93 99
94 mutex_unlock(&aaci->ac97_sem); 100 mutex_unlock(&aaci->ac97_sem);
95} 101}
@@ -101,6 +107,8 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
101{ 107{
102 struct aaci *aaci = ac97->private_data; 108 struct aaci *aaci = ac97->private_data;
103 u32 v; 109 u32 v;
110 int timeout = 5000;
111 int retries = 10;
104 112
105 if (ac97->num >= 4) 113 if (ac97->num >= 4)
106 return ~0; 114 return ~0;
@@ -119,7 +127,13 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
119 */ 127 */
120 do { 128 do {
121 v = readl(aaci->base + AACI_SLFR); 129 v = readl(aaci->base + AACI_SLFR);
122 } while (v & SLFR_1TXB); 130 } while ((v & SLFR_1TXB) && timeout--);
131
132 if (!timeout) {
133 dev_err(&aaci->dev->dev, "timeout on slot 1 TX busy\n");
134 v = ~0;
135 goto out;
136 }
123 137
124 /* 138 /*
125 * Give the AC'97 codec more than enough time 139 * Give the AC'97 codec more than enough time
@@ -130,21 +144,35 @@ static unsigned short aaci_ac97_read(struct snd_ac97 *ac97, unsigned short reg)
130 /* 144 /*
131 * Wait for slot 2 to indicate data. 145 * Wait for slot 2 to indicate data.
132 */ 146 */
147 timeout = 5000;
133 do { 148 do {
134 cond_resched(); 149 cond_resched();
135 v = readl(aaci->base + AACI_SLFR) & (SLFR_1RXV|SLFR_2RXV); 150 v = readl(aaci->base + AACI_SLFR) & (SLFR_1RXV|SLFR_2RXV);
136 } while (v != (SLFR_1RXV|SLFR_2RXV)); 151 } while ((v != (SLFR_1RXV|SLFR_2RXV)) && timeout--);
137 152
138 v = readl(aaci->base + AACI_SL1RX) >> 12; 153 if (!timeout) {
139 if (v == reg) { 154 dev_err(&aaci->dev->dev, "timeout on RX valid\n");
140 v = readl(aaci->base + AACI_SL2RX) >> 4;
141 } else {
142 dev_err(&aaci->dev->dev,
143 "wrong ac97 register read back (%x != %x)\n",
144 v, reg);
145 v = ~0; 155 v = ~0;
156 goto out;
146 } 157 }
147 158
159 do {
160 v = readl(aaci->base + AACI_SL1RX) >> 12;
161 if (v == reg) {
162 v = readl(aaci->base + AACI_SL2RX) >> 4;
163 break;
164 } else if (--retries) {
165 dev_warn(&aaci->dev->dev,
166 "ac97 read back fail. retry\n");
167 continue;
168 } else {
169 dev_warn(&aaci->dev->dev,
170 "wrong ac97 register read back (%x != %x)\n",
171 v, reg);
172 v = ~0;
173 }
174 } while (retries);
175 out:
148 mutex_unlock(&aaci->ac97_sem); 176 mutex_unlock(&aaci->ac97_sem);
149 return v; 177 return v;
150} 178}
@@ -164,10 +192,70 @@ static inline void aaci_chan_wait_ready(struct aaci_runtime *aacirun)
164/* 192/*
165 * Interrupt support. 193 * Interrupt support.
166 */ 194 */
167static void aaci_fifo_irq(struct aaci *aaci, u32 mask) 195static void aaci_fifo_irq(struct aaci *aaci, int channel, u32 mask)
168{ 196{
197 if (mask & ISR_ORINTR) {
198 dev_warn(&aaci->dev->dev, "RX overrun on chan %d\n", channel);
199 writel(ICLR_RXOEC1 << channel, aaci->base + AACI_INTCLR);
200 }
201
202 if (mask & ISR_RXTOINTR) {
203 dev_warn(&aaci->dev->dev, "RX timeout on chan %d\n", channel);
204 writel(ICLR_RXTOFEC1 << channel, aaci->base + AACI_INTCLR);
205 }
206
207 if (mask & ISR_RXINTR) {
208 struct aaci_runtime *aacirun = &aaci->capture;
209 void *ptr;
210
211 if (!aacirun->substream || !aacirun->start) {
212 dev_warn(&aaci->dev->dev, "RX interrupt???");
213 writel(0, aacirun->base + AACI_IE);
214 return;
215 }
216 ptr = aacirun->ptr;
217
218 do {
219 unsigned int len = aacirun->fifosz;
220 u32 val;
221
222 if (aacirun->bytes <= 0) {
223 aacirun->bytes += aacirun->period;
224 aacirun->ptr = ptr;
225 spin_unlock(&aaci->lock);
226 snd_pcm_period_elapsed(aacirun->substream);
227 spin_lock(&aaci->lock);
228 }
229 if (!(aacirun->cr & CR_EN))
230 break;
231
232 val = readl(aacirun->base + AACI_SR);
233 if (!(val & SR_RXHF))
234 break;
235 if (!(val & SR_RXFF))
236 len >>= 1;
237
238 aacirun->bytes -= len;
239
240 /* reading 16 bytes at a time */
241 for( ; len > 0; len -= 16) {
242 asm(
243 "ldmia %1, {r0, r1, r2, r3}\n\t"
244 "stmia %0!, {r0, r1, r2, r3}"
245 : "+r" (ptr)
246 : "r" (aacirun->fifo)
247 : "r0", "r1", "r2", "r3", "cc");
248
249 if (ptr >= aacirun->end)
250 ptr = aacirun->start;
251 }
252 } while(1);
253 aacirun->ptr = ptr;
254 }
255
169 if (mask & ISR_URINTR) { 256 if (mask & ISR_URINTR) {
170 writel(ICLR_TXUEC1, aaci->base + AACI_INTCLR); 257 dev_dbg(&aaci->dev->dev, "TX underrun on chan %d\n", channel);
258 writel(ICLR_TXUEC1 << channel, aaci->base + AACI_INTCLR);
171 } 259 }
172 260
173 if (mask & ISR_TXINTR) { 261 if (mask & ISR_TXINTR) {
@@ -192,7 +280,7 @@ static void aaci_fifo_irq(struct aaci *aaci, u32 mask)
192 snd_pcm_period_elapsed(aacirun->substream); 280 snd_pcm_period_elapsed(aacirun->substream);
193 spin_lock(&aaci->lock); 281 spin_lock(&aaci->lock);
194 } 282 }
195 if (!(aacirun->cr & TXCR_TXEN)) 283 if (!(aacirun->cr & CR_EN))
196 break; 284 break;
197 285
198 val = readl(aacirun->base + AACI_SR); 286 val = readl(aacirun->base + AACI_SR);
@@ -233,7 +321,7 @@ static irqreturn_t aaci_irq(int irq, void *devid)
233 u32 m = mask; 321 u32 m = mask;
234 for (i = 0; i < 4; i++, m >>= 7) { 322 for (i = 0; i < 4; i++, m >>= 7) {
235 if (m & 0x7f) { 323 if (m & 0x7f) {
236 aaci_fifo_irq(aaci, m); 324 aaci_fifo_irq(aaci, i, m);
237 } 325 }
238 } 326 }
239 } 327 }
@@ -330,8 +418,9 @@ static struct snd_pcm_hardware aaci_hw_info = {
330 .periods_max = PAGE_SIZE / 16, 418 .periods_max = PAGE_SIZE / 16,
331}; 419};
332 420
333static int aaci_pcm_open(struct aaci *aaci, struct snd_pcm_substream *substream, 421static int __aaci_pcm_open(struct aaci *aaci,
334 struct aaci_runtime *aacirun) 422 struct snd_pcm_substream *substream,
423 struct aaci_runtime *aacirun)
335{ 424{
336 struct snd_pcm_runtime *runtime = substream->runtime; 425 struct snd_pcm_runtime *runtime = substream->runtime;
337 int ret; 426 int ret;
@@ -380,7 +469,7 @@ static int aaci_pcm_close(struct snd_pcm_substream *substream)
380 struct aaci *aaci = substream->private_data; 469 struct aaci *aaci = substream->private_data;
381 struct aaci_runtime *aacirun = substream->runtime->private_data; 470 struct aaci_runtime *aacirun = substream->runtime->private_data;
382 471
383 WARN_ON(aacirun->cr & TXCR_TXEN); 472 WARN_ON(aacirun->cr & CR_EN);
384 473
385 aacirun->substream = NULL; 474 aacirun->substream = NULL;
386 free_irq(aaci->dev->irq[0], aaci); 475 free_irq(aaci->dev->irq[0], aaci);
@@ -395,7 +484,7 @@ static int aaci_pcm_hw_free(struct snd_pcm_substream *substream)
395 /* 484 /*
396 * This must not be called with the device enabled. 485 * This must not be called with the device enabled.
397 */ 486 */
398 WARN_ON(aacirun->cr & TXCR_TXEN); 487 WARN_ON(aacirun->cr & CR_EN);
399 488
400 if (aacirun->pcm_open) 489 if (aacirun->pcm_open)
401 snd_ac97_pcm_close(aacirun->pcm); 490 snd_ac97_pcm_close(aacirun->pcm);
@@ -422,9 +511,15 @@ static int aaci_pcm_hw_params(struct snd_pcm_substream *substream,
422 if (err < 0) 511 if (err < 0)
423 goto out; 512 goto out;
424 513
425 err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params), 514 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK)
426 params_channels(params), 515 err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params),
427 aacirun->pcm->r[0].slots); 516 params_channels(params),
517 aacirun->pcm->r[0].slots);
518 else
519 err = snd_ac97_pcm_open(aacirun->pcm, params_rate(params),
520 params_channels(params),
521 aacirun->pcm->r[1].slots);
522
428 if (err) 523 if (err)
429 goto out; 524 goto out;
430 525
@@ -467,9 +562,9 @@ static int aaci_pcm_mmap(struct snd_pcm_substream *substream, struct vm_area_str
467 * Playback specific ALSA stuff 562 * Playback specific ALSA stuff
468 */ 563 */
469static const u32 channels_to_txmask[] = { 564static const u32 channels_to_txmask[] = {
470 [2] = TXCR_TX3 | TXCR_TX4, 565 [2] = CR_SL3 | CR_SL4,
471 [4] = TXCR_TX3 | TXCR_TX4 | TXCR_TX7 | TXCR_TX8, 566 [4] = CR_SL3 | CR_SL4 | CR_SL7 | CR_SL8,
472 [6] = TXCR_TX3 | TXCR_TX4 | TXCR_TX7 | TXCR_TX8 | TXCR_TX6 | TXCR_TX9, 567 [6] = CR_SL3 | CR_SL4 | CR_SL7 | CR_SL8 | CR_SL6 | CR_SL9,
473}; 568};
474 569
475/* 570/*
@@ -504,7 +599,7 @@ aaci_rule_channels(struct snd_pcm_hw_params *p, struct snd_pcm_hw_rule *rule)
504 chan_mask); 599 chan_mask);
505} 600}
506 601
507static int aaci_pcm_playback_open(struct snd_pcm_substream *substream) 602static int aaci_pcm_open(struct snd_pcm_substream *substream)
508{ 603{
509 struct aaci *aaci = substream->private_data; 604 struct aaci *aaci = substream->private_data;
510 int ret; 605 int ret;
@@ -519,7 +614,12 @@ static int aaci_pcm_playback_open(struct snd_pcm_substream *substream)
519 if (ret) 614 if (ret)
520 return ret; 615 return ret;
521 616
522 return aaci_pcm_open(aaci, substream, &aaci->playback); 617 if (substream->stream == SNDRV_PCM_STREAM_PLAYBACK) {
618 ret = __aaci_pcm_open(aaci, substream, &aaci->playback);
619 } else {
620 ret = __aaci_pcm_open(aaci, substream, &aaci->capture);
621 }
622 return ret;
523} 623}
524 624
525static int aaci_pcm_playback_hw_params(struct snd_pcm_substream *substream, 625static int aaci_pcm_playback_hw_params(struct snd_pcm_substream *substream,
@@ -540,11 +640,11 @@ static int aaci_pcm_playback_hw_params(struct snd_pcm_substream *substream,
540 * FIXME: double rate slots? 640 * FIXME: double rate slots?
541 */ 641 */
542 if (ret >= 0) { 642 if (ret >= 0) {
543 aacirun->cr = TXCR_FEN | TXCR_COMPACT | TXCR_TSZ16; 643 aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16;
544 aacirun->cr |= channels_to_txmask[channels]; 644 aacirun->cr |= channels_to_txmask[channels];
545 645
546 aacirun->fifosz = aaci->fifosize * 4; 646 aacirun->fifosz = aaci->fifosize * 4;
547 if (aacirun->cr & TXCR_COMPACT) 647 if (aacirun->cr & CR_COMPACT)
548 aacirun->fifosz >>= 1; 648 aacirun->fifosz >>= 1;
549 } 649 }
550 return ret; 650 return ret;
@@ -557,7 +657,7 @@ static void aaci_pcm_playback_stop(struct aaci_runtime *aacirun)
557 ie = readl(aacirun->base + AACI_IE); 657 ie = readl(aacirun->base + AACI_IE);
558 ie &= ~(IE_URIE|IE_TXIE); 658 ie &= ~(IE_URIE|IE_TXIE);
559 writel(ie, aacirun->base + AACI_IE); 659 writel(ie, aacirun->base + AACI_IE);
560 aacirun->cr &= ~TXCR_TXEN; 660 aacirun->cr &= ~CR_EN;
561 aaci_chan_wait_ready(aacirun); 661 aaci_chan_wait_ready(aacirun);
562 writel(aacirun->cr, aacirun->base + AACI_TXCR); 662 writel(aacirun->cr, aacirun->base + AACI_TXCR);
563} 663}
@@ -567,7 +667,7 @@ static void aaci_pcm_playback_start(struct aaci_runtime *aacirun)
567 u32 ie; 667 u32 ie;
568 668
569 aaci_chan_wait_ready(aacirun); 669 aaci_chan_wait_ready(aacirun);
570 aacirun->cr |= TXCR_TXEN; 670 aacirun->cr |= CR_EN;
571 671
572 ie = readl(aacirun->base + AACI_IE); 672 ie = readl(aacirun->base + AACI_IE);
573 ie |= IE_URIE | IE_TXIE; 673 ie |= IE_URIE | IE_TXIE;
@@ -615,7 +715,7 @@ static int aaci_pcm_playback_trigger(struct snd_pcm_substream *substream, int cm
615} 715}
616 716
617static struct snd_pcm_ops aaci_playback_ops = { 717static struct snd_pcm_ops aaci_playback_ops = {
618 .open = aaci_pcm_playback_open, 718 .open = aaci_pcm_open,
619 .close = aaci_pcm_close, 719 .close = aaci_pcm_close,
620 .ioctl = snd_pcm_lib_ioctl, 720 .ioctl = snd_pcm_lib_ioctl,
621 .hw_params = aaci_pcm_playback_hw_params, 721 .hw_params = aaci_pcm_playback_hw_params,
@@ -626,7 +726,133 @@ static struct snd_pcm_ops aaci_playback_ops = {
626 .mmap = aaci_pcm_mmap, 726 .mmap = aaci_pcm_mmap,
627}; 727};
628 728
729static int aaci_pcm_capture_hw_params(snd_pcm_substream_t *substream,
730 snd_pcm_hw_params_t *params)
731{
732 struct aaci *aaci = substream->private_data;
733 struct aaci_runtime *aacirun = substream->runtime->private_data;
734 int ret;
735
736 ret = aaci_pcm_hw_params(substream, aacirun, params);
737
738 if (ret >= 0) {
739 aacirun->cr = CR_FEN | CR_COMPACT | CR_SZ16;
740
741 /* Line in record: slot 3 and 4 */
742 aacirun->cr |= CR_SL3 | CR_SL4;
743
744 aacirun->fifosz = aaci->fifosize * 4;
745
746 if (aacirun->cr & CR_COMPACT)
747 aacirun->fifosz >>= 1;
748 }
749 return ret;
750}
751
752static void aaci_pcm_capture_stop(struct aaci_runtime *aacirun)
753{
754 u32 ie;
755
756 aaci_chan_wait_ready(aacirun);
757
758 ie = readl(aacirun->base + AACI_IE);
759 ie &= ~(IE_ORIE | IE_RXIE);
760 writel(ie, aacirun->base+AACI_IE);
761
762 aacirun->cr &= ~CR_EN;
763
764 writel(aacirun->cr, aacirun->base + AACI_RXCR);
765}
766
767static void aaci_pcm_capture_start(struct aaci_runtime *aacirun)
768{
769 u32 ie;
770
771 aaci_chan_wait_ready(aacirun);
772
773#ifdef DEBUG
774 /* RX Timeout value: bits 28:17 in RXCR */
775 aacirun->cr |= 0xf << 17;
776#endif
777
778 aacirun->cr |= CR_EN;
779 writel(aacirun->cr, aacirun->base + AACI_RXCR);
780
781 ie = readl(aacirun->base + AACI_IE);
782 ie |= IE_ORIE |IE_RXIE; // overrun and rx interrupt -- half full
783 writel(ie, aacirun->base + AACI_IE);
784}
785
786static int aaci_pcm_capture_trigger(snd_pcm_substream_t *substream, int cmd){
787
788 struct aaci *aaci = substream->private_data;
789 struct aaci_runtime *aacirun = substream->runtime->private_data;
790 unsigned long flags;
791 int ret = 0;
792
793 spin_lock_irqsave(&aaci->lock, flags);
794
795 switch (cmd) {
796 case SNDRV_PCM_TRIGGER_START:
797 aaci_pcm_capture_start(aacirun);
798 break;
799
800 case SNDRV_PCM_TRIGGER_RESUME:
801 aaci_pcm_capture_start(aacirun);
802 break;
803
804 case SNDRV_PCM_TRIGGER_STOP:
805 aaci_pcm_capture_stop(aacirun);
806 break;
807
808 case SNDRV_PCM_TRIGGER_SUSPEND:
809 aaci_pcm_capture_stop(aacirun);
810 break;
811
812 case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
813 break;
814
815 case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
816 break;
817
818 default:
819 ret = -EINVAL;
820 }
821
822 spin_unlock_irqrestore(&aaci->lock, flags);
823
824 return ret;
825}
629 826
827static int aaci_pcm_capture_prepare(snd_pcm_substream_t *substream)
828{
829 struct snd_pcm_runtime *runtime = substream->runtime;
830 struct aaci *aaci = substream->private_data;
831
832 aaci_pcm_prepare(substream);
833
834 /* allow changing of sample rate */
835 aaci_ac97_write(aaci->ac97, AC97_EXTENDED_STATUS, 0x0001); /* VRA */
836 aaci_ac97_write(aaci->ac97, AC97_PCM_LR_ADC_RATE, runtime->rate);
837 aaci_ac97_write(aaci->ac97, AC97_PCM_MIC_ADC_RATE, runtime->rate);
838
839 /* Record select: Mic: 0, Aux: 3, Line: 4 */
840 aaci_ac97_write(aaci->ac97, AC97_REC_SEL, 0x0404);
841
842 return 0;
843}
844
845static snd_pcm_ops_t aaci_capture_ops = {
846 .open = aaci_pcm_open,
847 .close = aaci_pcm_close,
848 .ioctl = snd_pcm_lib_ioctl,
849 .hw_params = aaci_pcm_capture_hw_params,
850 .hw_free = aaci_pcm_hw_free,
851 .prepare = aaci_pcm_capture_prepare,
852 .trigger = aaci_pcm_capture_trigger,
853 .pointer = aaci_pcm_pointer,
854 .mmap = aaci_pcm_mmap,
855};
630 856
631/* 857/*
632 * Power Management. 858 * Power Management.
@@ -666,7 +892,7 @@ static int aaci_resume(struct amba_device *dev)
666 892
667 893
668static struct ac97_pcm ac97_defs[] __devinitdata = { 894static struct ac97_pcm ac97_defs[] __devinitdata = {
669 [0] = { /* Front PCM */ 895 [0] = { /* Front PCM */
670 .exclusive = 1, 896 .exclusive = 1,
671 .r = { 897 .r = {
672 [0] = { 898 [0] = {
@@ -740,6 +966,7 @@ static int __devinit aaci_probe_ac97(struct aaci *aaci)
740 ret = snd_ac97_mixer(ac97_bus, &ac97_template, &ac97); 966 ret = snd_ac97_mixer(ac97_bus, &ac97_template, &ac97);
741 if (ret) 967 if (ret)
742 goto out; 968 goto out;
969 aaci->ac97 = ac97;
743 970
744 /* 971 /*
745 * Disable AC97 PC Beep input on audio codecs. 972 * Disable AC97 PC Beep input on audio codecs.
@@ -752,6 +979,7 @@ static int __devinit aaci_probe_ac97(struct aaci *aaci)
752 goto out; 979 goto out;
753 980
754 aaci->playback.pcm = &ac97_bus->pcms[0]; 981 aaci->playback.pcm = &ac97_bus->pcms[0];
982 aaci->capture.pcm = &ac97_bus->pcms[1];
755 983
756 out: 984 out:
757 return ret; 985 return ret;
@@ -801,7 +1029,7 @@ static int __devinit aaci_init_pcm(struct aaci *aaci)
801 struct snd_pcm *pcm; 1029 struct snd_pcm *pcm;
802 int ret; 1030 int ret;
803 1031
804 ret = snd_pcm_new(aaci->card, "AACI AC'97", 0, 1, 0, &pcm); 1032 ret = snd_pcm_new(aaci->card, "AACI AC'97", 0, 1, 1, &pcm);
805 if (ret == 0) { 1033 if (ret == 0) {
806 aaci->pcm = pcm; 1034 aaci->pcm = pcm;
807 pcm->private_data = aaci; 1035 pcm->private_data = aaci;
@@ -810,6 +1038,7 @@ static int __devinit aaci_init_pcm(struct aaci *aaci)
810 strlcpy(pcm->name, DRIVER_NAME, sizeof(pcm->name)); 1038 strlcpy(pcm->name, DRIVER_NAME, sizeof(pcm->name));
811 1039
812 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops); 1040 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, &aaci_playback_ops);
1041 snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, &aaci_capture_ops);
813 } 1042 }
814 1043
815 return ret; 1044 return ret;
@@ -817,15 +1046,15 @@ static int __devinit aaci_init_pcm(struct aaci *aaci)
817 1046
818static unsigned int __devinit aaci_size_fifo(struct aaci *aaci) 1047static unsigned int __devinit aaci_size_fifo(struct aaci *aaci)
819{ 1048{
820 void __iomem *base = aaci->base + AACI_CSCH1; 1049 struct aaci_runtime *aacirun = &aaci->playback;
821 int i; 1050 int i;
822 1051
823 writel(TXCR_FEN | TXCR_TSZ16 | TXCR_TXEN, base + AACI_TXCR); 1052 writel(CR_FEN | CR_SZ16 | CR_EN, aacirun->base + AACI_TXCR);
824 1053
825 for (i = 0; !(readl(base + AACI_SR) & SR_TXFF) && i < 4096; i++) 1054 for (i = 0; !(readl(aacirun->base + AACI_SR) & SR_TXFF) && i < 4096; i++)
826 writel(0, aaci->base + AACI_DR1); 1055 writel(0, aacirun->fifo);
827 1056
828 writel(0, base + AACI_TXCR); 1057 writel(0, aacirun->base + AACI_TXCR);
829 1058
830 /* 1059 /*
831 * Re-initialise the AACI after the FIFO depth test, to 1060 * Re-initialise the AACI after the FIFO depth test, to
@@ -872,6 +1101,12 @@ static int __devinit aaci_probe(struct amba_device *dev, void *id)
872 aaci->playback.base = aaci->base + AACI_CSCH1; 1101 aaci->playback.base = aaci->base + AACI_CSCH1;
873 aaci->playback.fifo = aaci->base + AACI_DR1; 1102 aaci->playback.fifo = aaci->base + AACI_DR1;
874 1103
1104 /*
1105 * Capture uses AACI channel 0
1106 */
1107 aaci->capture.base = aaci->base + AACI_CSCH1;
1108 aaci->capture.fifo = aaci->base + AACI_DR1;
1109
875 for (i = 0; i < 4; i++) { 1110 for (i = 0; i < 4; i++) {
876 void __iomem *base = aaci->base + i * 0x14; 1111 void __iomem *base = aaci->base + i * 0x14;
877 1112
@@ -907,7 +1142,7 @@ static int __devinit aaci_probe(struct amba_device *dev, void *id)
907 ret = snd_card_register(aaci->card); 1142 ret = snd_card_register(aaci->card);
908 if (ret == 0) { 1143 if (ret == 0) {
909 dev_info(&dev->dev, "%s, fifo %d\n", aaci->card->longname, 1144 dev_info(&dev->dev, "%s, fifo %d\n", aaci->card->longname,
910 aaci->fifosize); 1145 aaci->fifosize);
911 amba_set_drvdata(dev, aaci->card); 1146 amba_set_drvdata(dev, aaci->card);
912 return ret; 1147 return ret;
913 } 1148 }
diff --git a/sound/arm/aaci.h b/sound/arm/aaci.h
index 9175ff9ded01..924f69c1c44c 100644
--- a/sound/arm/aaci.h
+++ b/sound/arm/aaci.h
@@ -49,27 +49,27 @@
49#define AACI_DR4 0x0f0 /* data read/written fifo 4 */ 49#define AACI_DR4 0x0f0 /* data read/written fifo 4 */
50 50
51/* 51/*
52 * transmit fifo control register. P48 52 * TX/RX fifo control register (CR). P48
53 */ 53 */
54#define TXCR_FEN (1 << 16) /* fifo enable */ 54#define CR_FEN (1 << 16) /* fifo enable */
55#define TXCR_COMPACT (1 << 15) /* compact mode */ 55#define CR_COMPACT (1 << 15) /* compact mode */
56#define TXCR_TSZ16 (0 << 13) /* 16 bits */ 56#define CR_SZ16 (0 << 13) /* 16 bits */
57#define TXCR_TSZ18 (1 << 13) /* 18 bits */ 57#define CR_SZ18 (1 << 13) /* 18 bits */
58#define TXCR_TSZ20 (2 << 13) /* 20 bits */ 58#define CR_SZ20 (2 << 13) /* 20 bits */
59#define TXCR_TSZ12 (3 << 13) /* 12 bits */ 59#define CR_SZ12 (3 << 13) /* 12 bits */
60#define TXCR_TX12 (1 << 12) /* transmits slot 12 */ 60#define CR_SL12 (1 << 12)
61#define TXCR_TX11 (1 << 11) /* transmits slot 12 */ 61#define CR_SL11 (1 << 11)
62#define TXCR_TX10 (1 << 10) /* transmits slot 12 */ 62#define CR_SL10 (1 << 10)
63#define TXCR_TX9 (1 << 9) /* transmits slot 12 */ 63#define CR_SL9 (1 << 9)
64#define TXCR_TX8 (1 << 8) /* transmits slot 12 */ 64#define CR_SL8 (1 << 8)
65#define TXCR_TX7 (1 << 7) /* transmits slot 12 */ 65#define CR_SL7 (1 << 7)
66#define TXCR_TX6 (1 << 6) /* transmits slot 12 */ 66#define CR_SL6 (1 << 6)
67#define TXCR_TX5 (1 << 5) /* transmits slot 12 */ 67#define CR_SL5 (1 << 5)
68#define TXCR_TX4 (1 << 4) /* transmits slot 12 */ 68#define CR_SL4 (1 << 4)
69#define TXCR_TX3 (1 << 3) /* transmits slot 12 */ 69#define CR_SL3 (1 << 3)
70#define TXCR_TX2 (1 << 2) /* transmits slot 12 */ 70#define CR_SL2 (1 << 2)
71#define TXCR_TX1 (1 << 1) /* transmits slot 12 */ 71#define CR_SL1 (1 << 1)
72#define TXCR_TXEN (1 << 0) /* transmit enable */ 72#define CR_EN (1 << 0) /* transmit enable */
73 73
74/* 74/*
75 * status register bits. P49 75 * status register bits. P49
@@ -229,6 +229,7 @@ struct aaci {
229 /* AC'97 */ 229 /* AC'97 */
230 struct mutex ac97_sem; 230 struct mutex ac97_sem;
231 struct snd_ac97_bus *ac97_bus; 231 struct snd_ac97_bus *ac97_bus;
232 struct snd_ac97 *ac97;
232 233
233 u32 maincr; 234 u32 maincr;
234 spinlock_t lock; 235 spinlock_t lock;